Western Digital My Cloud

This doesn’t work. I installed the snmp package in my HA terminal window but I learned that’s not permanent after a reboot. Otherwise, that would have worked.

I’m a little further along now. I successfully installed the pyscript integration. I wrote a very simple service to convert an input parameter from HEX to ASCII. It works great with the Developer Tools if I manually pass the hex sensor value. Now I’m not sure how to pass the actual entity sensor value as a variable and get the result.

On my phone, but basically the idea would be:

{{ (int("0x31", base=16) - 48)*100 + (int("0x31", base=16) - 48)*10 + (int("0x36", base=16) - 48) }}

Replace the hex string parts by slicing the original string. Convert from base 16 and subtract 48 (ordinal value for ASCII character 0), etc.

Makes sense. Where would I do this?

I should clarify that I got the pyscript to convert from hex to ascii with the entity value. but I have no idea how to either set another variable with the service output using an automation or use the service output in a lovelace dashboard card.

I was thinking:
Create an Automation that runs every 5 mins.
The automation runs the service with the entity that has the hex value.
The service sets another entity value with the converted string.
Use that second entity in the dashboards.

This seems like a lot and I’m not sure I can set a second entity value. How would I manually create that entity? Sensor Template doesn’t make sense.

Could you perhaps clarify a bit more what you’re doing and where you are getting values from? The hex string: Is that the state of an SNMP sensor (trap)? Where is the Python script you’re referring to coming into the picture? Or are you just experimenting with a script (outside of HA) to parse the values?

You can’t “update” a sensor by setting a value from within HA if it’s set by another integration, neither can you add an attribute and value to it. I don’t know if you could do it via the API.

Personally, I’d just make a new template sensor where you can set the state and any attributes that you’d like all in one go based on the original sensor. You can control the icon, name and device class also there.

If you can give me the original sensor name I can type out a solution a bit later.

EDIT:

sensor:
  - platform: template
    sensors:
      wd_cloud_temp:
        friendly_name: "WD Cloud Temperature"
        unit_of_measurement: "°"
        value_template: "{{ (int(states('sensor.something')[-6:-4], base=16) - 48)*100 + (int(states('sensor.something')[-4:-2], base=16) - 48)*10 + (int(states('sensor.something')[-2:], base=16) - 48) }}"

Or:

template:
  - sensor:
      - name: "WD Cloud Temperature"
        unit_of_measurement: "°"
        state: "{{ (int(states('sensor.something')[-6:-4], base=16) - 48)*100 + (int(states('sensor.something')[-4:-2], base=16) - 48)*10 + (int(states('sensor.something')[-2:], base=16) - 48) }}"

Based on:

{% set sensor = '0x43656e746967726164653a3437200946616872656e686569743a313136' %}
{{ (int(sensor[-6:-4], base=16) - 48)*100 + (int(sensor[-4:-2], base=16) - 48)*10 + (int(sensor[-2:], base=16) - 48) }}
1 Like

Not sure why I didn’t think of a template sensor. I’m going to try that.

Thanks again. The value_template statement worked perfectly. I’m not sure why I didn’t think of template sensors. I have others. I was overcomplicating things.

1 Like

Hi all,

Firstly, i want to say thank you to everyone that has posted, it pointed me in the right direction allowing me to display some meaningful stats from my “MyCloud EX2 Ultra”

As such, i thought i’d share in the hope it may help others:

Final result: Love Lace UI card
EX2-card

How it works:
The data is collected via SNMP queries from Node Red, the payload formatted in a usable manner, and then sent to custom entities allowing the data to be exposed to Home Assistant / Love Lace UI.

I’m using a custom card (from HACS - vertical-stack-in-card), and the code is:

type: custom:vertical-stack-in-card
title: EX2 Ultra NAS
cards:
  - type: gauge
    name: Disk usage
    entity: sensor.nas_diskpercentused
    min: 0
    max: 100
    severity:
      green: 0
      yellow: 45
      red: 90
    needle: true
  - type: glance
    show_name: false
    entities:
      - entity: sensor.nas_temprature
        name: Temp
        icon: mdi:thermometer-low
      - entity: sensor.nas_uptime
        name: Uptime
        icon: mdi:chart-timeline-variant-shimmer
  - type: glance
    show_icon: false
    entities:
      - entity: sensor.nas_diskcapacity
        name: 'Capacity:'
      - entity: sensor.nas_diskusage
        name: 'Used:'
      - entity: sensor.nas_diskfree
        name: 'Free:'

And for the Node Red flow:

[{"id":"b724648aef7e329f","type":"group","z":"1b6a095.7f55cf7","name":"WD EX2 Ultra SNMP queries","style":{"stroke":"#92d04f","fill":"#e3f3d3","fill-opacity":"0.6","label":true,"color":"#0070c0"},"nodes":["88e133bc1808a21a","602f8d14ec73f71c","08b41def0b9a98f9","53997450868c9442","1c7a7b676efa1c55","ee8a5f4a75567bcb","16292bcf74abd204","e818a9bd9a324128","677a3b4e076e916e","a64e64e32b8c9bd4","2d99cc3126646528","a7732d0f158590e3","4d99a3f62dc1bd25","8f2f872054cb118e","641d3b2b9d9cf55f","8c465ff341c89415","e008579a086ab391","9236d42249b7e21b","05f0defdb3111549","be17066c2365d73e","586df903fb7afe81","3cafe0c987a42a02"],"x":34,"y":2739,"w":1392,"h":442},{"id":"88e133bc1808a21a","type":"snmp","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","host":"10.0.0.5","community":"public","version":"2c","oids":"1.3.6.1.2.1.25.1.1.0","timeout":5,"name":"NAS Up-Time","x":560,"y":2780,"wires":[["08b41def0b9a98f9","08b41def0b9a98f9"]]},{"id":"602f8d14ec73f71c","type":"inject","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Query","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":390,"y":2780,"wires":[["88e133bc1808a21a","88e133bc1808a21a"]]},{"id":"08b41def0b9a98f9","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Format SNMP payload","func":"// Timetick conversion below - used to caculate hours / days etc.\n//\n// timeticks / 100 = seconds\n// timeticks / 6000 = minutes\n// timeticks / 360000 = hours\n// timeticks / 8640000 = days\n\n// Code to convert \"up-time\" to both hours and days.\nmsg.UpTimeDays = (msg.payload[0].value/8640000).toFixed(1) +\" Days\"; //timeticks / 8640000 = days\nmsg.UpTimeHours = (msg.payload[0].value/360000 ).toFixed(2) +\" Hours\" ; //timeticks / 360000 = hours\n\n// Code to display the \"up-time\" in hours if it's less than 1 day\nif ((msg.UpTimeDays).includes(\"0.\")) {\n msg.Uptime = msg.UpTimeHours;\n } else {\n msg.Uptime = msg.UpTimeDays;\n}\n\n\nmsg.payload = msg.Uptime;\nreturn msg\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":2780,"wires":[["3cafe0c987a42a02","3cafe0c987a42a02"]]},{"id":"53997450868c9442","type":"inject","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Query","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":390,"y":2960,"wires":[["1c7a7b676efa1c55","1c7a7b676efa1c55"]]},{"id":"1c7a7b676efa1c55","type":"snmp","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","host":"10.0.0.5","community":"public","version":"2c","oids":"1.3.6.1.2.1.25.2.3.1.5.60,\n1.3.6.1.2.1.25.2.3.1.4.60,\n1.3.6.1.2.1.25.2.3.1.6.60","timeout":5,"name":"NAS Disk Info","x":560,"y":2960,"wires":[["ee8a5f4a75567bcb","ee8a5f4a75567bcb"]]},{"id":"ee8a5f4a75567bcb","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Format SNMP payload","func":"// The storage is in the format of: \"Allocation units\"\n// It took a while to work out how to convert, but the math is: \"disk alocation unit size\" multiplied by \"allocation units\" = disk size in bytes\n// With the capacity converted to a usable storage metric, we can perform some math to convert it to: mb / gb / tb\n\n// There are some other useful variables below - use whatever you find useful :)\n\n// Allocate the storage units to variables\nmsg.SizeAllocationUnits = (msg.payload[0].value)\nmsg.AllocationUnits = (msg.payload[1].value)\nmsg.StorageUsedUnits = (msg.payload[2].value)\n\n// Code to convert the disk \"allocation units\" to an actual usable size (\"disk alocation unit size\" multiplied by \"allocation units\")\n//msg.SizeB = (msg.SizeAllocationUnits * msg.AllocationUnits)\n//msg.SizeKB = (msg.SizeAllocationUnits * msg.AllocationUnits / 1024)\n//msg.SizeMB = (msg.SizeAllocationUnits * msg.AllocationUnits / 1024 / 1024).toFixed(2)\nmsg.SizeTB_raw_capacity = (msg.SizeAllocationUnits * msg.AllocationUnits / 1000 / 1000 / 1000 / 1000).toFixed(2)\nmsg.SizeGBString = (msg.SizeAllocationUnits * msg.AllocationUnits / 1024 / 1024 / 1024).toFixed(2)\nmsg.SizeGBComma = parseFloat(((msg.SizeAllocationUnits * msg.AllocationUnits / 1024 / 1024 / 1024).toFixed(0))).toLocaleString();\nmsg.SizeTB = (msg.SizeAllocationUnits * msg.AllocationUnits / 1024 / 1024 / 1024 / 1024).toFixed(2)\n\n\n// Code to convert the disk \"allocation units\" to an actual usable size (\"disk alocation unit size\" multiplied by \"allocation units\")\n//msg.UsedB = (msg.StorageUsedUnits * msg.AllocationUnits)\n//msg.UsedKB = (msg.StorageUsedUnits * msg.AllocationUnits / 1024)\n//msg.UsedMB = (msg.StorageUsedUnits * msg.AllocationUnits / 1024 / 1024).toFixed(2)\nmsg.UsedGBString = (msg.StorageUsedUnits * msg.AllocationUnits / 1024 / 1024 / 1024).toFixed(2)\nmsg.UsedGBComma = parseFloat((msg.StorageUsedUnits * msg.AllocationUnits / 1024 / 1024 / 1024).toFixed(0)).toLocaleString();\nmsg.UsedTB = (msg.StorageUsedUnits * msg.AllocationUnits / 1024 / 1024 / 1024 / 1024).toFixed(2)\n\n\n// a bit of math to determine the free space\n//msg.FreeB = (msg.SizeB - msg.UsedB)\n//msg.FreeKB = (msg.SizeKB - msg.UsedKB)\n//msg.FreeMB = (msg.SizeMB - msg.UsedMB).toFixed(2)\nmsg.FreeGBString = (msg.SizeGBString - msg.UsedGBString).toFixed(2)\nmsg.FreeGBComma = parseFloat((msg.SizeGBString - msg.UsedGBString)).toLocaleString();\nmsg.FreeTB = (msg.SizeTB - msg.UsedTB).toFixed(2)\n\n\n// a bit of code to determine the percentage of use / free space - variables for both\nmsg.PercentFree = ( ((msg.SizeAllocationUnits * msg.AllocationUnits) - msg.StorageUsedUnits * msg.AllocationUnits) / (msg.SizeAllocationUnits * msg.AllocationUnits) * 100).toFixed(0)\nmsg.PercentUsed = ((msg.StorageUsedUnits * msg.AllocationUnits)/ (msg.SizeAllocationUnits * msg.AllocationUnits)* 100).toFixed(0)\n\n\nreturn msg\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":2960,"wires":[["a7732d0f158590e3","641d3b2b9d9cf55f","8f2f872054cb118e","e008579a086ab391","be17066c2365d73e","a7732d0f158590e3","8f2f872054cb118e","641d3b2b9d9cf55f","e008579a086ab391","be17066c2365d73e"]]},{"id":"16292bcf74abd204","type":"inject","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Query","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":390,"y":3140,"wires":[["e818a9bd9a324128","e818a9bd9a324128"]]},{"id":"e818a9bd9a324128","type":"snmp","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","host":"10.0.0.5","community":"public","version":"2c","oids":"1.3.6.1.4.1.5127.1.1.1.8.1.10.1.5.1,\n1.3.6.1.4.1.5127.1.1.1.8.1.10.1.5.2","timeout":5,"name":"NAS System Temperature","x":590,"y":3140,"wires":[["677a3b4e076e916e","677a3b4e076e916e"]]},{"id":"677a3b4e076e916e","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Format SNMP payload","func":"// Code to get the disk tempratures, fix up the string and display the average temp.\nmsg.Disk1 = parseInt((msg.payload[0].value).replace(\"Centigrade:\",\"\"));\nmsg.Disk2 = parseInt((msg.payload[1].value).replace(\"Centigrade:\",\"\"));\nmsg.AverageDiskTemp = ((msg.Disk1 + msg.Disk2) /2);\n\nmsg.payload = msg.AverageDiskTemp;\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":3140,"wires":[["a64e64e32b8c9bd4","a64e64e32b8c9bd4"]]},{"id":"a64e64e32b8c9bd4","type":"ha-entity","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"nas.temprature","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.temprature"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:nas"},{"property":"unit_of_measurement","value":"c"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.temprature","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1280,"y":3140,"wires":[[]]},{"id":"2d99cc3126646528","type":"ha-entity","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"nas.diskcapacity","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskcapacity"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"tb"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskcapacity","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1280,"y":2840,"wires":[[]]},{"id":"a7732d0f158590e3","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Payload","func":"//msg.payload = msg.SizeTB;\nmsg.payload = msg.SizeTB_raw_capacity;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":2840,"wires":[["2d99cc3126646528","2d99cc3126646528"]]},{"id":"4d99a3f62dc1bd25","type":"ha-entity","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"nas.diskfree","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskfree"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"tb"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskfree","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1270,"y":2960,"wires":[[]]},{"id":"8f2f872054cb118e","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.FreeTB;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":2960,"wires":[["4d99a3f62dc1bd25","4d99a3f62dc1bd25"]]},{"id":"641d3b2b9d9cf55f","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.UsedTB;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":2900,"wires":[["8c465ff341c89415","8c465ff341c89415"]]},{"id":"8c465ff341c89415","type":"ha-entity","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"nas.diskusage","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskusage"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"tb"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskusage","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1280,"y":2900,"wires":[[]]},{"id":"e008579a086ab391","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.PercentFree;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":3020,"wires":[["9236d42249b7e21b","9236d42249b7e21b"]]},{"id":"9236d42249b7e21b","type":"ha-entity","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"nas.diskpercentfree","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskpercentfree"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"%"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskpercentfree","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1290,"y":3020,"wires":[[]]},{"id":"05f0defdb3111549","type":"poll-state","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Poll NAS power switch","server":"c619ecc5.a1f0d","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"900","updateIntervalType":"num","updateIntervalUnits":"seconds","outputinitially":true,"outputonchanged":true,"entity_id":"switch.lounge_nas_energy","state_type":"str","halt_if":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"x":160,"y":2960,"wires":[["88e133bc1808a21a","1c7a7b676efa1c55","e818a9bd9a324128","1c7a7b676efa1c55","e818a9bd9a324128","88e133bc1808a21a"],[]]},{"id":"be17066c2365d73e","type":"function","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.PercentUsed;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":3080,"wires":[["586df903fb7afe81","586df903fb7afe81"]]},{"id":"586df903fb7afe81","type":"ha-entity","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"nas.diskpercentused","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskpercentused"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"%"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskpercentused","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1300,"y":3080,"wires":[[]]},{"id":"3cafe0c987a42a02","type":"ha-entity","z":"1b6a095.7f55cf7","g":"b724648aef7e329f","name":"nas.uptime","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.uptime"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:nas"},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.uptime","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1270,"y":2780,"wires":[[]]},{"id":"c619ecc5.a1f0d","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30"}]

For others somewhat new to this, let me save you my hour of trial and error finding the correct syntax. Here’s what did it for me:

sensor:
- platform: snmp
    name: "NAS System Temp"
    host: 192.168.9.100
    baseoid: 1.3.6.1.4.1.5127.1.1.1.8.1.7.0
    community: !secret SNMP
    version: "2c"
    scan_interval: 60
- platform: template
    sensors:
      nas_system_temperature:
        friendly_name: "NAS System Temperature"
        unit_of_measurement: "°F"
        value_template: "{{ (int(states('sensor.nas_system_temp')[-6:-4], base=16) - 48)*100 + (int(states('sensor.nas_system_temp')[-4:-2], base=16) - 48)*10 + (int(states('sensor.nas_system_temp')[-2:], base=16) - 48) }}"

Having said that, there is still an issue with the above code. Right now it displays 1096 as the value based on the HEX string 0x43656e746967726164653a3336200946616872656e686569743a3936
Which makes sense seeing as 3a is ASCI for : (the next char after 9). So the temp is only 2 digits instead of 3. (And we get 10 (the next number after 9) as the first digit)
How can we programmatically catch the temp being only 2 digits? In every case, the string will end in 3axxyyzz. Where 3a is the colon HEX code, and then xx, yy and zz are the 3 HEX digits of the temperature, and zz is an optional character if the temp is under 100 degrees F.
(And potentially (since I am European), we can also then write a similar statement for Celsius which starts at the first 3a and ends with 20 (space). But then we need to check it every 2 chars (and not see a 3a when really it’s 03:a4 or something))
Or could we convert the whole string from HEX to an ASCII sentence and then just parse out the temp by looking for the actual : in the string? Using a value.split(‘Fahrenheit:’) or something?

I know what’s needed, I just lack the syntactical skills to execute it.

I can’t type out a full solution now, but here are some hints:

To convert a hex string to ASCII, there’s no Jinja2 or HA templating built-in ways. Luckily, Petro has typed up the algorithm.

Once you have that, you can use a regex.

I just quickly made a regex in Python (experiment with this in your template editor):

import re
h = "0x43656e746967726164653a3336200946616872656e686569743a3936"
s = bytearray.fromhex(h[2:]).decode()  # 'Centigrade:36 \tFahrenheit:96'
m = re.search(":(\d+).+?\:(\d+)", s)
m.groups()  # ('36', '96')

Thanks for this. I like the vertical stack, and used that on mine as well.

I also used your NodeRed code, as the SNMP from HA kept failing (sensors Unavailable. And sometimes they’d suddenly show up days later, but not consistently).
I did edit a few things. Like updating your temp units to “°C” (Which allowed HA to show it to me in the GUI as °F).
In addition, I completely redid your disk space. Rather than looking at allocation units, I grabbed 1.3.6.1.4.1.5127.1.1.1.8.1.9.1.5.1 for disk size (which returns 3.6T for my 4TB system), and just stripped the T from it. At these sizes, I’m not too concerned about more decimals. But that makes the function easier to get total, used and free size.
And since I didn’t have a switch to look at if the NAS was up, I just (for simplicity’s sake) used an inject node to kick this off every 15 minutes.
Here’s my code in case anyone else wants to use it

[{"id":"b724648aef7e329f","type":"group","z":"9e354d802036d78a","name":"WD EX2 Ultra SNMP queries","style":{"stroke":"#92d04f","fill":"#e3f3d3","fill-opacity":"0.6","label":true,"color":"#0070c0"},"nodes":["88e133bc1808a21a","602f8d14ec73f71c","08b41def0b9a98f9","53997450868c9442","1c7a7b676efa1c55","ee8a5f4a75567bcb","16292bcf74abd204","e818a9bd9a324128","677a3b4e076e916e","a64e64e32b8c9bd4","2d99cc3126646528","a7732d0f158590e3","4d99a3f62dc1bd25","8f2f872054cb118e","641d3b2b9d9cf55f","8c465ff341c89415","e008579a086ab391","9236d42249b7e21b","be17066c2365d73e","586df903fb7afe81","3cafe0c987a42a02","f6bd7d82dc07d2cb","deebc32c42f350cd","fb72868fa2e7cceb","18b0551be066270f","917bcf570eb10663","e1ee6e618dcf3da8"],"x":34,"y":79,"w":1152,"h":562},{"id":"88e133bc1808a21a","type":"snmp","z":"9e354d802036d78a","g":"b724648aef7e329f","host":"hostname","community":"string","version":"2c","oids":"1.3.6.1.2.1.25.1.1.0","timeout":5,"name":"NAS Up-Time","x":360,"y":120,"wires":[["08b41def0b9a98f9"]]},{"id":"602f8d14ec73f71c","type":"inject","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Query","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":120,"wires":[["88e133bc1808a21a"]]},{"id":"08b41def0b9a98f9","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Format SNMP payload","func":"// Timetick conversion below - used to caculate hours / days etc.\n//\n// timeticks / 100 = seconds\n// timeticks / 6000 = minutes\n// timeticks / 360000 = hours\n// timeticks / 8640000 = days\n\n// Code to convert \"up-time\" to both hours and days.\nmsg.UpTimeDays = (msg.payload[0].value/8640000).toFixed(1) +\" Days\"; //timeticks / 8640000 = days\nmsg.UpTimeHours = (msg.payload[0].value/360000 ).toFixed(2) +\" Hours\" ; //timeticks / 360000 = hours\n\n// Code to display the \"up-time\" in hours if it's less than 1 day\nif ((msg.UpTimeDays).includes(\"0.\")) {\n msg.Uptime = msg.UpTimeHours;\n } else {\n msg.Uptime = msg.UpTimeDays;\n}\n\n\nmsg.payload = msg.Uptime;\nreturn msg\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":120,"wires":[["3cafe0c987a42a02"]]},{"id":"53997450868c9442","type":"inject","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Query","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":300,"wires":[["1c7a7b676efa1c55"]]},{"id":"1c7a7b676efa1c55","type":"snmp","z":"9e354d802036d78a","g":"b724648aef7e329f","host":"hostname","community":"string","version":"2c","oids":"1.3.6.1.4.1.5127.1.1.1.8.1.9.1.5.1,\n1.3.6.1.4.1.5127.1.1.1.8.1.9.1.6.1","timeout":5,"name":"NAS Disk Info","x":360,"y":300,"wires":[["ee8a5f4a75567bcb"]]},{"id":"ee8a5f4a75567bcb","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Format SNMP payload","func":"msg.SizeTB = parseFloat((msg.payload[0].value).replace(\"T\",\"\"))\nmsg.FreeTB = parseFloat((msg.payload[1].value).replace(\"T\",\"\"))\nmsg.UsedTB = (msg.SizeTB - msg.FreeTB).toFixed(1)\n\nmsg.PercentUsed = ((msg.UsedTB / msg.SizeTB) * 100).toFixed(0)\nmsg.PercentFree = ((msg.FreeTB / msg.SizeTB) * 100).toFixed(0)\n\nreturn msg\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":300,"wires":[["a7732d0f158590e3","641d3b2b9d9cf55f","8f2f872054cb118e","e008579a086ab391","be17066c2365d73e"]]},{"id":"16292bcf74abd204","type":"inject","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Query","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":480,"wires":[["e818a9bd9a324128"]]},{"id":"e818a9bd9a324128","type":"snmp","z":"9e354d802036d78a","g":"b724648aef7e329f","host":"hostname","community":"string","version":"2c","oids":"1.3.6.1.4.1.5127.1.1.1.8.1.7.0,\n1.3.6.1.4.1.5127.1.1.1.8.1.10.1.5.1,\n1.3.6.1.4.1.5127.1.1.1.8.1.10.1.5.2","timeout":5,"name":"NAS System Temperature","x":390,"y":480,"wires":[["677a3b4e076e916e"]]},{"id":"677a3b4e076e916e","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Format SNMP payload","func":"// Code to get the disk temperatures, fix up the string and display the average temp.\nmsg.System = parseInt((msg.payload[0].value.split('Fahrenheit:')[1]));\nmsg.Disk1 = parseInt((msg.payload[1].value).replace(\"Centigrade:\",\"\"));\nmsg.Disk2 = parseInt((msg.payload[2].value).replace(\"Centigrade:\",\"\"));\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":480,"wires":[["f6bd7d82dc07d2cb","deebc32c42f350cd","18b0551be066270f"]]},{"id":"a64e64e32b8c9bd4","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.disk1","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.disk1"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:nas"},{"property":"unit_of_measurement","value":"°C"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.temprature","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1020,"y":480,"wires":[[]]},{"id":"2d99cc3126646528","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.diskcapacity","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskcapacity"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"TB"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskcapacity","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1040,"y":180,"wires":[[]]},{"id":"a7732d0f158590e3","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"//msg.payload = msg.SizeTB;\nmsg.payload = msg.SizeTB;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":180,"wires":[["2d99cc3126646528"]]},{"id":"4d99a3f62dc1bd25","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.diskfree","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskfree"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"TB"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskfree","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1030,"y":300,"wires":[[]]},{"id":"8f2f872054cb118e","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.FreeTB;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":300,"wires":[["4d99a3f62dc1bd25"]]},{"id":"641d3b2b9d9cf55f","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.UsedTB;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":240,"wires":[["8c465ff341c89415"]]},{"id":"8c465ff341c89415","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.diskusage","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskusage"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"TB"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskusage","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1040,"y":240,"wires":[[]]},{"id":"e008579a086ab391","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.PercentFree;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":360,"wires":[["9236d42249b7e21b"]]},{"id":"9236d42249b7e21b","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.diskpercentfree","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskpercentfree"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"%"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskpercentfree","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1050,"y":360,"wires":[[]]},{"id":"be17066c2365d73e","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.PercentUsed;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":420,"wires":[["586df903fb7afe81"]]},{"id":"586df903fb7afe81","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.diskpercentused","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.diskpercentused"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:harddisk"},{"property":"unit_of_measurement","value":"%"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.diskpercentused","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1060,"y":420,"wires":[[]]},{"id":"3cafe0c987a42a02","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.uptime","server":"c619ecc5.a1f0d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.uptime"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:nas"},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[{"property":"entity_id","value":"sensor.nas.uptime","valueType":"str"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1030,"y":120,"wires":[[]]},{"id":"f6bd7d82dc07d2cb","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.Disk1;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":480,"wires":[["a64e64e32b8c9bd4"]]},{"id":"deebc32c42f350cd","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.Disk2;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":540,"wires":[["fb72868fa2e7cceb"]]},{"id":"fb72868fa2e7cceb","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.disk2","server":"4f28a876.524b58","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.disk2"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:nas"},{"property":"unit_of_measurement","value":"°C"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":1020,"y":540,"wires":[[]]},{"id":"18b0551be066270f","type":"function","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"Payload","func":"msg.payload = msg.System;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":600,"wires":[["917bcf570eb10663"]]},{"id":"917bcf570eb10663","type":"ha-entity","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"nas.temp","server":"4f28a876.524b58","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nas.temp"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:nas"},{"property":"unit_of_measurement","value":"°F"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":1020,"y":600,"wires":[[]]},{"id":"e1ee6e618dcf3da8","type":"inject","z":"9e354d802036d78a","g":"b724648aef7e329f","name":"15 Mins","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"900","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":140,"y":200,"wires":[["88e133bc1808a21a","1c7a7b676efa1c55","e818a9bd9a324128"]]},{"id":"c619ecc5.a1f0d","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30"},{"id":"4f28a876.524b58","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]
1 Like

I know I’m coming in late on this.

I know nothing about Unix so the things above are way above my head, but I am exploring them. I only have the single drive MyCloud box that I’ve been told is now no longer supported by WD! So SNMP won’t work if I have read stuff correctly. So i’ll be looking at the stats thing from EventuallyFixed (Why create the stats directory 4 levels down below mnt? my mnt has nothing in it!).

However, I’ve done a little messing around and found that my WD drive, in SSH, does the nc thing and I can type in a message that I can receive in Node-Red TCP Input node. So I was thinking, is there a way to pull all the stats I want by a script that runs say hourly and then passes that to Node-Red as a comma separated list? Once in Node-Red I would know how to deal with it.

I know nothing about unix or php but am trying to follow what you have done here.

php is running on my device as I can do the phpinfo() thing.

I’ve created a directory under /var/www called stats

My Cloud drive does not have anything under /mnt. Do I still need to do the whole HD/HD_a2/Nas_Prog/stats thing, or can i make a shorter path? I’ll do it anyway, but I don’t understand why.

My pressing question for now is where do I put the php files?

Edit: So I’ve now done the HD/HD_a2… thing as well as the ln thing. I’ve also created the disk.php file in the stats directory, modified to suit what I get when I type df. It works if I run it locally. Now I’m assuming i can go to any browser and type in http://192.168.x.y/stats/disk.php I would see the result of executing the php file. but all I get is Not Found blah blah.
I’ve tried making the disk.php executable (chmod) but still no joy. I’d like to get this working before I move on to the HA bit.

Hi Graham,

Wow, this thread has really exploded since I last looked! :smiley:

My NAS device is an EX4100. The file system layout my device has been the same since OS3 through to OS5:

  • /mnt/HD/HD_a2 contains the user directories, and other system folders and files
  • /shares contains unix symbolic links to the user areas only

Because the file system layout of your device is different to mine, I guess that you don’t have an EX4100. What is the model you have?

I’m writing this from memory, but the steps are

  1. Create a folder in an area where the Western Digital OS will not wipe it upon a reboot. For example, you might create a user (and therefore a folder on the file system) for this purpose
  2. Put the php files inside it
  3. ssh on to the device
  4. At the unix prompt, find the user share folder and note the full path to it.
  5. Go to the /var/www folder, and create a unix symbolic link to the folder that contains the php files

Assuming that the web server of the NAS

  • Can run php code (it can, as you said above)
  • Is able to see the directory containing the php files (which is what the symbolic link should achieve)
  • Normally serves files from /var/www (which is pretty standard in the unix world, but this is WD are dealing with…)
  • And all of the unix call-outs contained within the php code are available in the OS

It all ought to hang together, and just work.

Thanks for getting back to me.

The device is just a WD My Cloud network drive. I have 2 of them, about 8 years old, one as my general backup disk and the other as an NFS/SMB server for my security cameras. The UI gives no other clue as to the model.

You are right about stuff getting deleted on reboot!

I’ve now created a Share called Graham with a sub directory called stats and put the disk.php in it. It’s good being there as it’s permanent and I can edit it from windows with Notepad++.

In the ssh terminal I can type “php disk.php” and I get the JSON string output as expected.

I’ve created the symbolic link using “ln -s /shares/Graham/stats /var/www/stats” and can now see the stats directory under www with the disk.php in it. I can also run it from there.

I assumed that I could then type “http://192.168.xxx.yyy/stats/disk.php” into a browser and I would see the JSON output there. That would then give me the confidence all was well and I would move on to the HA side of things, but still I am getting the following error message

"Not Found
The requested URL /stats/disk.php was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request."

Since the browser URL is the same format as per your example in the HA code, I assume that will not work either. Perhaps I am just wrong on this point. Or, is there something else I must do in ssh to enable the URL to work?

On a different track, I have piped the disk.php into “nc 192.168.xxx.zzz port” and successfully got the JSON into a Node-Red TCP Input node. Perhaps there’s a way to get a script that runs on the MyCloud drive every hour, say, that does just that, but my knowledge of unix is minimal.

Thanks again.

Hmmm. One of these must be true…

  1. The web server on your machine does not serve from /var/www
  2. The web server cannot see the directory /shares/Graham/stats
  3. The web server can serve from /var/www, but cannot execute php from /var/www

I suggest that you test point 1 by creating a ‘Hello World’ html file, at /var/www/helloworld.html, then try & navigate to “http://192.168.xxx.yyy/helloworld.html”

You can test Point 2 by creating the same file in /shares/Graham/stats, and navigating to http://…/stats/helloworld.html

If it works, this is a valid place for html files, and the web server of the machine is pointed at it. It does not confirm that .php files can run from here, but it’s a start.

Perhaps using an .htaccess file here can help?

If not, there is some discovery for you to do, to find where the web server root directory is. Perhaps the output of the phpinfo.php can help…

If you want to go down the scripting route, you’ll need to do something like…

  • First create and then distribute your ssh keys to the machines, to allow a passwordless ssh log in.
  • Create a script, probably using a heredoc, to execute on the target machine the commands you want in the ssh session.
  • Create a ‘shell_command’ configuration section in your configuration.yaml
  • Create an automation in HASS to execute the script referenced in thh shell_command.

In case you want to use them, I have put my shell scripts in my GitHub repository.

Thanks.

Tried the Hello World and can confirm it works with “IP/Graham/stats/helloworld.html” but not with “IP/stats/helloworld.html” nor “IP/helloworld.html” even if I put the file in /var/www.

Thinking about it, to get into the regular GUI I have to enter a username and password. Then the URL is displayed as “IP/UI/” wherever I navigate around the system. I can see what assume to be all the directories/files under /var/www but it’s quite complex in structure. I’ve tried locating the php file in various directories and messing with permissions and groups but no joy. I think I’ll give up on that approach.

I’m still thinking of just SSHing in after a reboot and running a never ending script calling the php and sending the output via TCP to be received by Node-Red. That avoids any of the SSH stuff in your original post which with my level of unix just went above my head. I just need to research crontab or a do while true { php, sleep} sort of script now.

It’s been fun learning about unix and php though so not time wasted.

The problem with a cron task on the NAS is that (at least on the WD EX4100) you cannot get at it in a permanent way: On my device, the crontab is completely rewritten at ~3am.

So I got around that by using Home Assistant Automations as a ‘cron’, that called a script. That script had a command to ssh in to the NAS (a password-less log in using ssh keys) and use a heredoc to execute the shell scripts I referred to above.

Oh, I guess that IP/Graham/stats/phpinfo.php does not work?

I’ve got crontab working every 2 minutes (for now) and it doesn’t appear to be stopped/deleted after 24hrs. I’m using it to run your (mostly) php script for the disk sizes and then nc the json output to a Node-red TCP input node listening on a particular port. This then just passes it on to an mqtt output node.
The crontab line is

*/2 * * * * php /shares/myshare/disk.php | nc -w 1 192.168.xxx.yyy 12345

In the configuration.yaml I have a sensor which picks up the Percentage Used…

sensor:
# MQTT sensors to receive data fromt the WDMyCam Cloud (See Node-Red flow 5)
  - platform: mqtt
    unique_id: sunny_mqtt_0022
    state_topic: disk/disk/wdcamcloud
    name: "wdcamcloud_percent_used"
    unit_of_measurement: '%'
    value_template: "{{value_json.disk.percent.used}}"

I haven’t tried a reboot but it’s quite a simple thing to re-input. EDIT: Done a reboot and the crontab entries persist. :slight_smile:

Now I’ve proven it works, I’m going to add more of your scripts and sensors. Thanks for the pointers.