Error calling zwave.test_node in automations and scripts to revive dead zwave nodes

Pretty much every time I restart home assistant there’s a few zwave nodes (Zooz) that just don’t want to play nice (marked dead, usually with “CacheLoad”). I can fix this easy enough by going to the zwave configuration screen and manually clicking “test node” on each of them, but I want it automated.

I created an automation that should just fix them whenever they’re dead. Didn’t work.

I created an automation that tries running the service call at startup. Didn’t work.

I tried a script that only tries to call zwave.test_node for a single node. Didn’t work.

I keep getting the same error: 'Service zwave.test_node not found'

Has anyone come across this issue before?

Relevant parts of my config file:

automation:
  - id: on_hass_startup
    alias: 'On HA startup ...'
    trigger:
      platform: homeassistant
      # Event can also be 'shutdown'
      event: start
    action:
      - service: zwave.test_node
        data:
          node_id: 12
      - service: zwave.test_node
        data:
          node_id: 13

  - id: fix_dead_zwave_nodes
    alias: "Fix dead zwave nodes"
    trigger:
      - platform: state
        entity_id: zwave.dining_room
        to: 'dead'
        for:
          minutes: 1
      - platform: state
        entity_id: zwave.kitchen_dimmer
        to: 'dead'
        for:
          minutes: 1
    action:
      - service: zwave.test_node
        data_template:
          node_id: '{{trigger.to_state.attributes.node_id}}'

script:
  fix_dead_zwave_nodes_12:
    alias: "Fix dead zwave nodes - 12"
    sequence:
      - service: zwave.test_node
        data:
          node_id: 12
  fix_dead_zwave_nodes_13:
    alias: "Fix dead zwave nodes - 13"
    sequence:
      - service: zwave.test_node
        data:
          node_id: 13

Log for failed automations:

2019-01-30 08:38:21 ERROR (MainThread) [homeassistant.components.automation] Error while executing automation automation.on_ha_startup. Service not found for call_service at pos 1: (ServiceNotFound(...), 'Service zwave.test_node not found')
2019-01-30 08:40:27 ERROR (MainThread) [homeassistant.components.automation] Error while executing automation automation.fix_zwave. Service not found for call_service at pos 1: (ServiceNotFound(...), 'Service zwave.test_node not found')

Log for failed script:

2019-01-30 09:54:54 ERROR (MainThread) [homeassistant.core] Error executing service <ServiceCall script.fix_dead_zwave_nodes_13 (c:54ae76f7cad94d56934299e72e4d4f6c)>
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/core.py", line 1138, in _safe_execute
    await self._execute_service(handler, service_call)
  File "/usr/src/app/homeassistant/core.py", line 1151, in _execute_service
    await handler.func(service_call)
  File "/usr/src/app/homeassistant/components/script.py", line 123, in service_handler
    context=service.context)
  File "/usr/src/app/homeassistant/components/script.py", line 181, in async_turn_on
    kwargs.get(ATTR_VARIABLES), context)
  File "/usr/src/app/homeassistant/helpers/script.py", line 131, in async_run
    await self._handle_action(action, variables, context)
  File "/usr/src/app/homeassistant/helpers/script.py", line 210, in _handle_action
    action, variables, context)
  File "/usr/src/app/homeassistant/helpers/script.py", line 299, in _async_call_service
    context=context
  File "/usr/src/app/homeassistant/helpers/service.py", line 85, in async_call_from_config
    domain, service_name, service_data, blocking=blocking, context=context)
  File "/usr/src/app/homeassistant/core.py", line 1106, in async_call
    raise ServiceNotFound(domain, service) from None
homeassistant.exceptions.ServiceNotFound: (ServiceNotFound(...), 'Service zwave.test_node not found')
1 Like

You can’t call zwave services until the zwave component registers the functions. This happens after the Z-Wave network is up and running. The Z-Wave network always takes time to start and will always be later than the home assistant start event.

You can trigger on a service registered instead. Here’s a snippet from one of my automations:

  trigger:
  - event_data:
      domain: zwave
      service: set_config_parameter
    event_type: service_registered
    platform: event

Awesome. Looks like that’s what I was missing to get this to work. For those who run into the same thing, here’s how I solved it:

automation:
  - id: on_zwave_network_ready
    initial_state: on
    trigger:
      ### either of these options will work as trigger
      - platform: event
        event_type: zwave.network_ready
      # - platform: event
        # event_type: service_registered
        # event_data:
          # domain: zwave
          # service: test_node
    action:
      - condition: template
        value_template: >-
          {%- for entity in states.zwave if (entity.state == 'dead') -%}
            {%- if loop.first -%}
              true
            {%- endif -%}
          {%- endfor -%}
      - service: script.turn_on
        data:
          entity_id: script.fix_dead_zwave_nodes_command



script:

  fix_dead_zwave_nodes_command:
    alias: "Fix dead zwave nodes (command)"
    sequence:
      - service: zwave.test_node
        data_template:
          node_id: >-
            {%- for entity in states.zwave if (entity.state == 'dead') -%}
              {%- if loop.first -%}
                {{ entity.attributes.node_id | int }}
              {%- endif -%}
            {%- endfor -%}
      - service: script.turn_on
        data:
          entity_id: script.fix_dead_zwave_nodes_loop

  fix_dead_zwave_nodes_loop:
    alias: "Fix dead zwave nodes (loop)"
    sequence:
      - delay: 00:00:05
      - condition: template
        value_template: >-
          {%- for entity in states.zwave if (entity.state == 'dead') -%}
            {%- if loop.first -%}
              true
            {%- endif -%}
          {%- endfor -%}
      - service: script.turn_on
        data:
          entity_id: script.fix_dead_zwave_nodes_command

If that works for you, great. Just be careful with the zwave.network_ready event. That event is independent of the service registration, and will trigger before. Depending on the timing you might still end up with the same errors. That was the case with my automation, which is why I switched to triggering on the service registration instead.

1 Like

You’re exactly right. I ended up having the same issue come up once or twice so I changed to using the service registered method and it’s been working ever since. Major thanks!

I’m pretty new with HA but I have the problem my zwave nodes don’t react immediately after I press the button in HA. Once I triggered a few nodes it seems like the responsiveness increases. So it feels likes the whole system falls a sleep and after a few shakes it’s up and running.
Would your code solve this issue? Can I just paste this in my config file?

1 Like

That doesn’t sound like my issue, but I don’t think there’s any problem with adding the code to your config. The worst case is that it doesn’t do anything (or maybe it loops infinitely? I’m really not sure, lol).

Depending on your config, you probably won’t be able to simply copy and paste: the automations need to be under the “automation:” section and the scripts need to be under the “script:” section. I have mine in a package file to avoid worrying altogether.

It looks like I didn’t update the code I used after my last comment in this thread, so here’s the latest version:

# Zwave fixes

automation:
  - id: fix_dead_zwave_nodes
    initial_state: on
    trigger:
      ### Event "network_ready" won't work reliably. Use "service_registered"
      ### - platform: event
        ### event_type: zwave.network_ready
      - platform: event
        event_type: service_registered
        event_data:
          domain: zwave
          service: test_node
    action:
      - condition: template
        value_template: >-
          {%- for entity in states.zwave if (entity.state == 'dead') -%}
            {%- if loop.first -%}
              true
            {%- endif -%}
          {%- endfor -%}
      - service: script.turn_on
        data:
          entity_id: script.fix_dead_zwave_nodes_command
  - id: notify_zwave_is_done
    initial_state: on
    trigger:
      - platform: state
        entity_id: script.fix_dead_zwave_nodes_loop
        from: 'on'
        to: 'off'
        for: '00:00:10'
    action:
      - service: persistent_notification.create
        data:
          message: "Zwave node fixing complete"
          # title: "done"
          notification_id: zwave

script:
  fix_dead_zwave_nodes_command:
    alias: "Fix dead zwave nodes (command)"
    sequence:
      - service: zwave.test_node
        data_template:
          node_id: >-
            {%- for entity in states.zwave if (entity.state == 'dead') -%}
              {%- if loop.first -%}
                {{ entity.attributes.node_id | int }}
              {%- endif -%}
            {%- endfor -%}
      - service: script.turn_on
        data:
          entity_id: script.fix_dead_zwave_nodes_loop

  fix_dead_zwave_nodes_loop:
    alias: "Fix dead zwave nodes (loop)"
    sequence:
      - delay: 00:00:05
      - condition: template
        value_template: >-
          {%- for entity in states.zwave if (entity.state == 'dead') -%}
            {%- if loop.first -%}
              true
            {%- endif -%}
          {%- endfor -%}
      - service: script.turn_on
        data:
          entity_id: script.fix_dead_zwave_nodes_command

You may also want to try healing your network and making sure you have nodes that are close enough together to mesh nicely.