Persistent Zwave names even after replacing sensor or readding to controller

I need the Zwave device names to be persistent possibly for years. Now part of the name comes from node id, and node id is one thing I cannot control. If my device malfunctions and I have to buy a new one, I don’t have a control to give the new device the old device’s node id. Or worse, if my Zwave controller has to be replaced or reset, then all the Zwave sensors loose their node id’s.

I use OZW control panel to add new nodes. When I add a new node, I also give it unique name. Home assistant then can use that name but currently it also adds node id to end of name. I need to get rid of that node id in HA names. I personally check that all device names are unique.

I plan to install InfluxDB and save values of sensors for years. I need the sensor values to have persistent names.

I hope all the places that have to be changed are in /components/zwave.py.
There the functions that use node_id are _node_object_id, _object_id, ZWaveDeviceEntity.unique_id, so not much changes.

This should be easy to put as configurable option with config[“zwave”].get and current behavior as default.

And of cause there’s the problem that if your node id’s change, you have to go over all your automation code and change the device names to new ones. I would like it better to have some kind of separation of physical and logical device names.

I have a LOT of z-wave devices on my automation system, in fact, they make up 95% of all my devices, so I understand your concern.

All you have to do is create representations of them with the template platforms for each device type. This basically gives you an alias to the actual device that you can reference in all of your scripts, and if you have to replace a device and it is on a different node or has a completely different name, you only have to change it in one place in the configuration.yaml, as all your scripts and automations will be referencing the alias. The sensor template is really nice, because the window/door sensors always report “on” and “off” in lowercase, which I think looks stupid for a window to be on or off, but with the template, you can have it say “Open” and “Closed” and that is what will appear in the frontend, which makes more sense for a window or door.

Anyway, here are two examples. The first one is for a z-wave wall outlet switch that I have one of my lamps plugged into and the second one is for a z-wave window sensor I have in my living room.

# Example configuration.yaml entry for a z-wave switch
switch:
  - platform: template
    switches:
      living_room_lamp:
        friendly_name: 'Living Room Lamp'
        value_template: '{{states.switch.everspring_an157_plugin_appliance_module_switch_17.state}}'
        turn_on:
          service: switch.turn_on
          entity_id: switch.everspring_an157_plugin_appliance_module_switch_17
        turn_off:
          service: switch.turn_off
          entity_id: switch.everspring_an157_plugin_appliance_module_switch_17

Now you can reference your lamp in all of your automations as switch.living_room_lamp
If you replace the device, you only have to replace its device name in a single location in the configuaration.yaml file

# Example configuration.yaml entry for a z-wave window/door sensor
sensor:
  - platform: template
    sensors:
      window_living_room:
          friendly_name: "Living Room Window"
          value_template: >-
            {%- if is_state("binary_sensor.ecolink_doorwindow_sensor_sensor_15", "on") -%}
              Open
            {%- else -%}
              Closed
            {%- endif %}

And here you can reference this in all of your automations as sensor.window_living_room, and again, you only have to change its reference in one spot in the configuration.yaml if you have to replace the device, since all your scripts will still be referencing sensor.window_living_room

You can do this for all of your other device types as well.

Now, personally, I didn’t change the names of my devices in OZW because I knew I was going to make virtual representations of them, so I just have a document in dropbox where I keep track of which device is on which node, but in your case, if you changed them in OZW, and you create these virtual representations, you will have two switches, one called living_room_lamp_17 and one called living_room_lamp without the node id, which is not a big deal really, as you will only reference living_room_lamp in your automations.

5 Likes

That’s a good way to do it, but right now I have about 80 sensor readings or settings if I count every attribute devices have.

Yeah, that can be a bit daunting having to create a separate sensor template for each individual attribute of each sensor. I have separate sensors for each battery attribute as well as each state, so you end up with a LOT of sensors in your configuration, but, in the long run it was worth the time and effort for me to flesh them all out this way, and I only had to do it once, so now that everything is done, I only have to add a few sensors here and there as I buy new devices, but my entire automation system is future proofed, so I didn’t mind the extra work initially.

The best outcome I can think of is for Home Assistant to check for a hard coded device name in the open zwave config file at the time it pulls each device in for the first time, and if there is one, use the hard coded name without the node id, and only use node id’s for devices without a name in the config file.

3 Likes

Speaking of templating Z-Wave sensors: in my experience, the templates don’t work as reliably as their original Z-Wave sensors. I’ll give an example with a door sensor I use:

  • when I open and close the door a few times in a row, the logbook will show the Z-Wave sensor switching back and forth between on and off, but it doesn’t show the template sensor going back and forth between Open and Closed accordingly: instead, it only seems to log the final state change
  • as a result of the above, the template sensor’s history in the UI (showing Open/Closed) is incomplete
  • an automation using the template sensor as a trigger didn’t seem to fire correctly, so I quickly switched it over to use the Z-Wave sensor directly and it’s been working perfectly ever since (although I may have jumped to conclusions too quickly on that one)

The strange bit is the template sensor reflects the state change correctly in realtime in the UI as I open and close the door, HASS just doesn’t seem to keep track of it as well as it does of the original Z-Wave sensor.

I haven’t tested opening and closing in a quick, short term succession, but so far my history has been showing all Open/Closed of my templates. Also, none of my automations, scripts, scenes, etc are using the actual z-wave devices. They are all tied to the templates and I haven’t had a single one not fire correctly. Thats weird.

I’m using the Z-Stick Gen5 on a Raspberry Pi 2. What is your setup? I guess it could depend on the z-wave controller, speed/processing power of the system running HASS, other applications or services running on the device, or even network congestion. Though you did say that calling the device directly always worked, so that would probably rule out most of those. Not sure of the process HASS uses to update templates, so not really sure where the breakdown could be.

I am running my RPi without any GUI desktop as I removed xserver and all references to any desktop environment, so it is completely terminal only and everything runs buttery smooth and fires instantly every time.

1 Like

As I said, I may have jumped to conclusions too quickly. I may change back to using templated devices instead of the Z-Wave devices directly and give it another test run. But that will have to wait until I have less projects on my hand lol.

I’m using the Aeotec Z-Stick Gen5 also, but on a Raspberry Pi 3 with Raspbian Jessie Lite.

Could you elaborate on the stuff you’ve uninstalled? Or maybe provide me with a link? Just like you, I use my RPi through SSH only. It may not make much difference (if any at all), but no point in having things installed I never intend on using. Thanks!

Seems there has to a lot of code to make this own logical-physical device mapping layer.
Would it not be easier if it was already a feature of HA?

‘A clever person solves a problem. A wise person avoids it.’
Albert Einstein

3 Likes

Well, you are already running the lite version of Raspbian, while I had the Raspbian full installed, so I had every bloated piece of software that came pre-installed, so even after uninstalling a TON of stuff, I am positive that your RPi 3 with Raspbian lite still has a lot less than mine does.

I have 2 other Pi’s that I have lite installed on, and after this ordeal, I’ll never install the full version again. Can’t say exactly what I uninstalled, as I spent about a week looking through forums and reading articles about sliming down Raspbian from full, so I got quite a lot of stuff uninstalled through a lot of different sources. Wish I had used the lite version from the beginning.

1 Like

FYI, InfluxDB does to have UPDATE-statement so you cannot update data with sql afterwards.
So if your node id changes, you simply cannot update the old data’s node id so that node id’s will be persistent in InfluxDB.
What you can do is stop Home Assistant, move new data to temp, insert old data to start of new data table, insert temp table to new data table and start Home Assistant. Easy…
When you have to rewrite your old data every time node id changes and device names are changed in code, your SD wears out faster.
InfluxDB does not support joins between tables so you cannot create a mapping table there. (Join&Merge was removed in v.0.9)

Any way to do the same with a ge dimmer switch that shows up as an entity id like light.[name]_level_2? Thanks

1 Like

Is it Zwave? My code works for all zwave devices.
I just updated to 0.29.6. Not much to change but just have to know where to.
Vote for change, so it might be included in official version.

Marko, I meant to ask how to do a similar alias as mentioned in #2 above. Sorry for the confusion.

Did you have any luck getting this work with a dimmer?

@Marko, do you have a pointer to your code?

Also did you have any luck getting it added to the official version?

And lastly, how difficult would it be to change it to allow for a arbitrary mapping, e.g. reading the entity_id -> alias mapping from the config and applying it to all nodes.

Maybe I am missing something but the proposed template version seems to make it really hard to get the dimming exposed for example. My lights are all cold “light.ge_*” and show a brightness adjuster in the UI, if I use the switch that will be gone, AFAICT?

Here’s what I am doing for my zwave switches to use tidy names in my config files. I don’t have dimmers, so this is just for switches.

Define the aliases I want in a text file at ~/.homeassistant/aliases/switch.txt

fairy_lights_switch_24_0                fairy_lights                Fairy Lights
office_lights_spots_2_0                 office_spotlights           Office Spotlights
office_lights_pendant_2_0_2             office_pendant_light        Office Pendant
garage_lights_fluorescents_23_0         garage_fluorescent_lights   Garage Fluorescents
garage_lights_external_lantern_23_0_2   garage_external_light       Garage Outside Light

Config generator at ~/.homeassistant/aliases/generate-switch-aliases.py

#!/usr/bin/env python
import re
import sys

header = """- platform: template
  switches:"""
print(header)

regex = re.compile(r'(?P<fullname>[^\s]+)\s+(?P<alias>[^\s]+)\s+(?P<friendlyname>.+)?')

for line in sys.stdin:
  m = regex.match(line)

  fullname = m.group('fullname')
  friendlyname = m.group('friendlyname')
  alias = m.group('alias')

  print("    %s:" % alias)
  if friendlyname is not None:
    print("      friendly_name: %s" % friendlyname)
  print("      value_template: \"{{ is_state('switch.%s', 'on') }}\"" % fullname)
  print("      entity_id:")
  print("        - switch.%s" % fullname)
  print("      turn_on:")
  print("        service: switch.turn_on")
  print("        entity_id: switch.%s" % fullname)
  print("      turn_off:")
  print("        service: switch.turn_off")
  print("        entity_id: switch.%s" % fullname)
  print("")

My configuration.yaml looks like this for switches:

switch:         !include_dir_merge_list switches/

And i generate an aliases.yaml file like so:

cd ~/.homeassistant
chmod +x ./aliases/generate-switch-aliases.py
cat aliases/switch.txt | ./aliases/generate-switch-aliases.py  > ./switches/aliases.yaml

This creates the ./switches/aliases.yaml file, which looks like this:

 - platform: template
   switches:
     fairy_lights:
       friendly_name: Fairy Lights
       value_template: "{{ is_state('switch.fairy_lights_switch_24_0', 'on') }}"
       entity_id:
         - switch.fairy_lights_switch_24_0
       turn_on:
         service: switch.turn_on
         entity_id: switch.fairy_lights_switch_24_0
       turn_off:
         service: switch.turn_off
         entity_id: switch.fairy_lights_switch_24_0

     office_spotlights:
       friendly_name: Office Spotlights
       value_template: "{{ is_state('switch.office_lights_spots_2_0', 'on') }}"
       entity_id:
         - switch.office_lights_spots_2_0
       turn_on:
         service: switch.turn_on
         entity_id: switch.office_lights_spots_2_0
       turn_off:
         service: switch.turn_off
         entity_id: switch.office_lights_spots_2_0

     etc...

Then replace every instance of the full zwave name with the new alias, eg replace switch.office_lights_spots_2_0 with switch.office_spotlights

I do the replacing automatically like this. (safe to run every time you change aliases, as long as you understand what it does!)

    find . -name '*.yaml' ! -name 'aliases.yaml' -exec echo sed -i '' \
    $(cat aliases/switch.txt  | while read fullname aliasname friendly ; \
    do echo -n "-e 's/$fullname/$aliasname/g' " ; done)  {} + | bash

If I or someone else ever bother to bake the device name/aliasing into the zwave component properly, i’ll remove my switches/aliases.yaml file and name them via the zwave component somehow.

I’m content with this setup for now - if i have to replace a zwave switch, or change whatever tech I’m using to control the lights, I can keep using the same switch name in hass. And my config files read a lot better :slight_smile:

7 Likes

Obviously the problem the developers were wanting to avoid is having two or more devices with the same id.

One solution might be to allow use of a device’s friendly_name, and run a duplicate-name-finder whenever the devices are loaded.

Another solution might be to add an optional id field (which would be subject to duplicate checking). This could then be used as an optional unique reference to a device.

Of course, the best solution would be to have a UI for manipulating all device information, but I bet that’s already planned-for!