Zwave node failure visability/notification

I couldn’t find a way to make one sensor that would tell me if there was a failed zwave node on the front end.

Using info from this post Howto create battery alert without creating a template for every device I was able to make one.

sensor:

  zwave_failures:
    value_template: >
      {% macro is_failed() %}
      {%- set value = true -%}
      {%- set domains = ['zwave'] -%}
      {%- for domain in domains -%}
      {%- for item in states[domain] if ((item.attributes.is_failed is defined and item.attributes['is_failed'] == value))-%}
      {% if (item.attributes.is_failed is defined and item.attributes['is_failed'] == value) -%}
      {{ item.name }}{% endif -%}
      {%- endfor -%}
      {%- endfor -%}
      {% endmacro %}
      {{ is_failed() |trim != "" }}

card:

image

It seems to work but I haven’t had one fail yet.

Feedback is welcome and thanks to everyone who contributed to the linked post!

UPDATE: It seems to work well!

6 Likes

Good idea,

do you also have a way to tell whether Zwave works at all?
I had the Zwave stick slip out of the usb port a little bit so it was not available anymore.
This was completely undetected by HASS so everything looked Ok… except that all values eventually became stale. The zwave status for all devices was reported to be OK (including the controller itself)…

@jo-me

Good idea let me look into it!

It might have to be a command line sensor…

I am thinking something like this for a command line sensor…

ls -ltr /dev/tty*|tail -n 1 | grep -o /dev/ttyACM0

I will have to test when I get home.

Yes, or even more simple (depending on what is needed for display):

pi@hassbian:~ $ ls /dev/ttyACM* | wc -l
1

This returns the number of lines found in the output so the amount of devices starting with ttyACM.

1 Like

Nice! This is why I love HA and Linux. Endless possibilities!!

Exactly what I’m looking for…I dropped your code into my config file under sensor block…the config checks out, but when I reload the output isn’t true or false, it’s the variable definition { is_failed() |trim != “” } …any thoughts?

  - platform: template
    sensors:
      zwave_failures:
        value_template: >
          {% macro is_failed() %}
          {%- set value = true -%}
          {%- set domains = ['zwave'] -%}
          {%- for domain in domains -%}
          {%- for item in states[domain] if ((item.attributes.is_failed is defined and item.attributes['is_failed'] == value))-%}
          {% if (item.attributes.is_failed is defined and item.attributes['is_failed'] == value) -%}
          {{ item.name }}{% endif -%}
          {%- endfor -%}
          {%- endfor -%}
          {% endmacro %}
          { is_failed() |trim != "" }}

sensors

Hey sorry about that @joelgarnick

The last line of the code I missed a curly bracket/brace.

It should be this…

{{ is_failed() |trim != "" }}

That should do it and I fixed it in my original post.

You can paste all the code into the Jinja template editor to confirm.

Side note: If that Hall Closet door sensor is a contact sensor then you can make another sensor that will have it show open or closed instead of on or off.

  hall_closet_door:
    value_template: '{% if is_state("binary_sensor.unknown_id021f_unknown_type0003_id0101_sensor_4", "on") %}Open{% elif states.binary_sensor.unknown_id021f_unknown_type0003_id0101_sensor_4, "off" %}Closed{% else %}Check Battery{% endif %}'
    entity_id: binary_sensor.unknown_id021f_unknown_type0003_id0101_sensor_4

Replace any entry “binary_sensor.unknown_id021f_unknown_type0003_id0101_sensor_4” with the entity id of your sensor.

I just ran with

- alias: dead node detection
  trigger:
    platform: template
    value_template: >
      {%- for state in states.zwave -%}
        {%- if state.state == "dead" -%}
          true
        {%- endif -%}
      {%- endfor -%}
  condition:
    - condition: state
      entity_id: input_boolean.zwave_up
      state: 'on'
  action:
    - service: notify.me
      data:
        message: >
          node {{ trigger.entity_id }}  has died
    - service: zwave.test_network
3 Likes

What automation are you using to trigger input_boolean.zwave_up ?

I found this somewhere ages ago, but this is really handy so nothing works until all nodes have been queried after a HASS restart.

- alias: Mark zwave as up
  trigger:
    platform: event
    event_type: zwave.network_ready
  action:
    - service: homeassistant.turn_on
      entity_id:
        - input_boolean.zwave_up
1 Like

Thanks, found it in the mean time! Cheers!

This seems to have stopped working for me in 82.1. I noticed this in the event log.
“Template sensor zwave_failures has no entity ids configured to track nor were we able to extract the entities to track from the value template(s). This entity will only be able to be updated manually.”

Does anybody know how I should update the dead node template to get it working again?

@weok I get the same error message. Did you resolve it ?
Thanks in advance

@Rigobert, I had to add an entity list to the sensor to get it working again.

  - platform: template
    sensors:
      zwave_failures:
        entity_id:
          - zwave.back_porch
          - zwave.bubble
          - zwave.bubble_closet
          - zwave.bubble_fan
          - zwave.cat_door
          - zwave.dining_room
          - zwave.dryer
          - zwave.foyer
          - zwave.front_porch
          - zwave.fuzzy_lane
          - zwave.fuzzy_lane_closet
          - zwave.fuzzy_lane_fan
          - zwave.hall_bar
          - zwave.hall_bath
          - zwave.kitchen
          - zwave.kitchen_bar
          - zwave.living_room
          - zwave.living_room_fan
          - zwave.master_bath_toilet
          - zwave.master_bath_vanity
          - zwave.mermaid_room
          - zwave.mermaid_room_closet
          - zwave.mermaid_room
          - zwave.music_room
          - zwave.music_room_fan
          - zwave.music_room_outlet
          - zwave.unknown_node_33
        friendly_name: "Z-Wave Dead Nodes"
        value_template: >
          {% macro is_failed() %}
          {%- set value = true -%}
          {%- set domains = ['zwave'] -%}
          {%- for domain in domains -%}
          {%- for item in states[domain] if ((item.attributes.is_failed is defined and item.attributes['is_failed'] == value))-%}
          {% if (item.attributes.is_failed is defined and item.attributes['is_failed'] == value) -%}
          {{ item.name }}{% endif -%}
          {%- endfor -%}
          {%- endfor -%}
          {% endmacro %}
          {{ is_failed() |trim != "" }}

This works well and doesn’t need to have a pre-built list or groups. I just run it every 4 hours.

    ########################################
    zwave_health_check:
      alias: zwave_health_check

      sequence:
        - condition: template
          value_template: >-
            {{ states.zwave | selectattr('attributes.is_failed', 'defined') | selectattr('attributes.is_failed','==', True ) | list | length >= 1 }}
        
        - wait_template: "{{ is_state('script.notify_all_engines' , 'off') }}"
     
        - service: script.notify_all_engines
          data_template:
            title: "Zwave Errors"
            who: "john"
            message: >-
              {%- set Zwave_errors = states.zwave | selectattr('attributes.is_failed', 'defined') | selectattr('attributes.is_failed','==', True ) | map(attribute='name') | list | join(', ') -%}
              Zwave Errors in the following devices: {{ Zwave_errors }}
1 Like

@jwelter - Can you include the entire code… The fact that zwave_health_check: is all the way at the left margin is kinda confusing me… and are you triggering it from another automation somewhere?

It’s a script.

Here is the automation that calls it:

##########################################################
## Time Interval Automations
##########################################################
- alias: Time Interval
  initial_state: True

  trigger:
    - platform: time_pattern
      hours: "/3"
      minutes: 00
      seconds: 00

  action:
    - service: script.zwave_health_check

For anyone else finding this in Google and then finding that it doesn’t work with Z-Wave JS, see this post for ideas: ZwaveJS - obtaining device / node status ("Ready" etc)