Device network dropoff notification array

I’ve created two automations to notify me when my wifi or zigbee devices drop off the network. I’ve sucessfully made a group and automation for the wifi devices as they are all Shelly relays, and have the code here if anyone wants to use it.

After getting them both working, I set the wifi devices to only notify me if they’ve been off network for 5 minutes as they were generating a ton of notifications. However, all my zigbee devices are sensors, and I cant figure out out to get them to notify me without driving me nuts. I can’t figure out how to get a duration in the zigbee triggered automation. I’ve tried using “trigger.for” but it only generates errors and I can’t save the automation.

Does anyone have any advice to get make the zigbee side more palatable?

Working WiFi device notificationautomation:

alias: Shelly Drop Off Notification Array
description: ""
trigger:
  - platform: state
    entity_id:
      - group.shelly
    to: unavailable
    for:
      hours: 0
      minutes: 5
      seconds: 0
condition: []
action:
  - service: notify.mobile_app_rawbeef
    data:
      title: Shelly Device Dropped Out
      message: Check your shelly connections
  - service: notify.persistent_notification
    data:
      message: Check your shelly connections
      title: Shelly Device Dropped Out
mode: single

Nonfunctional Zigbee device notification automation:

alias: Zigbee Device Drop Out Notification
description: ""
trigger:
  - device_id: fd7088679d047090c8988b4ec74ea78a
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: 5b9d61ff45272c6101d69146a61e267d
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: 0d9c38d9959c874b60ef4e33613376ab
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: d53640fbeda02fc4f13f2c3c48dcaf21
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: 02230461cb2f580672b62ee43991ad6d
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: b11878abbbed22169790e24b5fb4987b
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: eceb71b25ceb34a4c229bcebe851344b
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: ae580d133a0bed17db02a1ee6853d567
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
  - device_id: c9c342de994c430a230564701f200bcc
    domain: zha
    platform: device
    type: device_offline
    subtype: device_offline
condition: []
action:
  - service: notify.mobile_app_pixel_3a
    data:
      message: Check your zigbee devices
      title: Zigbee Device Dropped Out
  - service: notify.persistent_notification
    data:
      message: Check your zigbee devices
      title: Zigbee Device Dropped Out
mode: single

If I remember correctly le_top (a.k.a. mdeweerd on GitHub) had some related custom workaround solution(s) for listing offline/unavailable Zigbee devices somehow (and maybe even a Blueprint?) using his ZHA Toolkit (zha-toolkit)? …however, IMHO a feature to at least list offline/unavailable Zigbee devices should ideally not really need to “hack” together a custom workaround solution for that but instead, preferably and optimally, be a default feature in the ZHA integration.

You can use

service: zha_toolkit.zha_devices
data:
  event_done: zha_devices

and get the “available” status in the event data provided for “zha_devices” (event name set in the example).

1 Like

I too would like to get this working.
I’ve got the zha toolkit successfully returning a list of available devices to a csv file, but the docs say you can also send it to an ‘event’.

Could someone assist in how I would trigger this as a service call in an automation.
Do I have to output it to csv to parse it ? If so, how might I go about that?
(I’m familiar with parsing data like this with in memory objects using jinja2).

UPDATE:- I could use a time based trigger to fire the automation and dump the data file, then use the file sensor to read it:-

But not sure thats the optimal way to do it ?

Hi @khvej8 - I’m not sure how your answer has anything to do with the question ?
I’m looking for a way to use the zha_toolkit service call to provide some kind of regular monitoring on the connection state of my ZHA devices.

Since posting the above, I’ve worked out how to listen for the event once the service called is fired, and use trigger.event.data to parse out the data.

Not really documented in HA, but I gathered how to extract the information from some forum posts:

Demonstration in this script:

alias: Loop over zha_devices, extract some device data
sequence:
  - parallel:
      - sequence:
          - wait_for_trigger:
              - platform: event
                event_type: zha_devices_ready
          - service: system_log.write
            data:
              logger: zha_devices
              level: error
              message: "{{ \"Got event %s\" % ( wait.trigger.event.data.devices ) }}"
          - repeat:
              for_each: "{{ wait.trigger.event.data.devices }}"
              sequence:
                - service: system_log.write
                  data:
                    logger: zha_devices
                    level: error
                    message: >-
                      {{ "Item '%s' Power: %s dBm Available: %s" % (
                      repeat.item.name, repeat.item.rssi, repeat.item.available
                      ) }}
      - service: zha_toolkit.zha_devices
        data:
          event_done: zha_devices_ready
mode: single

@le_top

You’re amazing, I’ll check it out.
One question I raised on another thread is how exactly did you figure out how to parse that zha service call ?

If it was an entity I could easily have used the dev tools template to figure out what to do, but as its event data, I’m not sure how I can use the dev tools to work out what to extract.

I can get the payload easily enough by listening for the event, but after that I’m stuck.

The main issue was accessing the data - in an automation you would access it using trigger.event.data (if this event would trigger the automation), but I prefered implementing a script.

Another issue was raising the event and then capturing the trigger, requiring parallel (which I did not find in a forum post, but I knew that parallel existed). Calling the zha_toolkit.zha_devices first, and then listening for it does not work because the event is thrown (and gone) before going to the next step in the sequence.

A final issue was that the wait variable was not available after the parallel action, so I added a sequence in which I put the “wait for trigger” and the other actions using the outcome of that wait because the wait_for_trigger data is available in the same sequence.

Also, I put zha_toolkit.zha_devices last because I assume that HA starts the actions in order so that it starts listening before the event can actually be raised.

As for how to then access the data (once I validated that wait.trigger.event.data was accessible after reading this post, you can see that I logged the data to the system log where you can then check it out, or you could listen for the zha_devices_ready event (because that is the name for event_done here) and then see there how to get to the data you want.

Thanks again.

I’m still slightly unclear about how to use the dev tools template section to work out how to break apart that service call data, as its not an entity in itself, and trigger.event.data is only available in the script itself.

The dev tools template will not help, DevTool > Events > Listen to Events does

not trigger.event.data, but wait.event.data

@le_top - yes indeed, and thats how I got the payload.

But I often use the templates section to experiment with a payload to work out how to template it.
But because the payload is from a service call and not an entity, I can’t work out a way of doing that.

And one final question… out of interest what are you using in your automation to trigger this ?

You could listen for the event in a script and then write the data to a state.
To do so, I added a service (zha_toolkit.ha_set_stateà to zha_toolkit because I could not find an existing method to write anything to any state I wanted from a script or automation.

Unfortunately, in this case, the event data is too big to be stored to a state.
I tried this script and HA reports that the size exceeds 255 characters for the state value.
Theoretically you might make this work by referring to a smaller part of the result (`wait.event.data.devices[0]…) but I think that all the data for a single item is still too much. This might help for other cases though.

alias: Store event data to sensor.debug_wait
sequence:
  - parallel:
      - sequence:
          - wait_for_trigger:
              - platform: event
                event_type: zha_devices_ready
          - service: system_log.write
            data:
              logger: zha_devices
              level: error
              message: "{{ \"Got event %s\" % ( wait.trigger.event.data.devices ) }}"
          - service: zha_toolkit.ha_set_state
            data:
              state_id: sensor.debug_wait
              state_attribute: wait
              attr_val: "{{ wait }}"
              allow_create: true
        alias: Wait for event and store its data to state attrubute
      - service: zha_toolkit.zha_devices
        data:
          event_done: zha_devices_ready
mode: single

Once event_data is (partially) in a state, I suppose that this is good enough to test representing it in the Developer Template view.

@le_top - super useful info again thankyou.
@khvej8 - no problem :wink:

@le_top - one last question.

Another alternative I’ve come up with is to enable the lqi entity in the ZHA integration, and I am now using the (HACS) auto entities dashboard card to provide a nice list of these dynamically.

However, I’d love to have an automation trigger if any one of these LQI values goes to unavailable.

The only way I can think of doing it is to create a state trigger, but I’d have to add every entity to that trigger. Ideally I’d love to create some kind of dynamic group that the automation can refer to. Any thoughts ?

And thanks again on the other thread.

You can use ha_set_state to write data to any state you like. If you use the script’s loop, then you can call ha_set_state for each device and set a different state each time.

Ok, I’m definitely starting to get somewhere with your help on this, and I’m now looking at only reporting on devices that are not available, but this has brought up some interesting observations.

Filtering on an if condition around:-

repeat.item.available | Bool() = = true

Returns more entities than I am expecting.

It seems the ZHA Toolkit determines available = false to not only be devices that have dropped off the network, but its also showing as false for things like smart plugs that are in the off state (although still on the network).

**UPDATE:- Its showing as false for ALL ZHA devices that are mains powered. Mostly my smart plugs, but also an aqara in wall switch.

Similarly, devices that have genuinely dropped off the network, or are fully powered off, can still show an LQI or RSSI value.

So my question is how does HA know the difference, and IIRC, when I setup ZHA you’re shown a dialog box with timings that HA will use to consider a device ‘offline’.

For my mains powered devices thats 7200 seconds (the default) which is 2 hours. But my last seen value for these devices is usually only a few seconds, because they report back regularly.

So it looks like I need more than just available = false, perhaps combined with a last seen datetime thats older than a certain value, because I can’t trust using the LQI or RSSI values either.

Hi

The values returned by zha_toolkit are directly those from zha - more specifically the “zha_gateway” value of the “zha” integration where devices is defined. It “only” does some filtering to build the CSV file when that is requested.

What does zha-network-card indicate ? - in my system the ‘available’ value is ok.
You could also report the value for ‘item.available’ by writing it to the log and you can also check in the Developer Tool > Events > Listen on Event how the available field is set - writing the CSV file and checking the available value is also a method.

The script I shared above did not seem to return invalid results.

Here is a configuration for my card where I notice a modifier x || "false" :

title: LovelaceTitle
views:
  - title: Zigbee
    path: zigbee
    panel: true
    badges: []
    cards:
      - type: custom:zha-network-card
        clickable: true
        columns:
          - name: Name
            prop: name
          - attr: available
            id: available
            modify: x || "false"
            name: Online
          - attr: manufacturer
            name: Manufacturer
          - attr: model
            name: Model
          - attr: ieee
            name: IEEE
          - name: NWK
            prop: nwk
          - attr: rssi
            name: RSSI
          - attr: lqi
            name: LQI
          - attr: last_seen
            name: Last Seen
          - attr: power_source
            name: Power Source
          - attr: quirk_class
            name: Quirk
        sort_by: available

Well, I’ve come home, checked the zha network card output, re-checked the zha toolkit script output and now everything matches up as expected. Its only reporting 2 devices offline, which is correct.

I’ll keep monitoring it, but thankyou so much for your time and patience as I learn more about HA.

1 Like

I never got an simple solution, but my workaround is the following:

I use the low battery automation from Louis’s video to let me know when an aqara device gets below 65% since that’s when they start getting stupid and drop off the network.