LZW36 Fan/Dimmer Switch

That is very interesting. If HA were to have that information for the individual endpoints would it know what to do with them at this point? Is it possible to have device endpoints displayed differently in HA at this time?

I am not sure. The only information I have been able to find on the subject is in this post. I asked the question on the github page, hopefully I get an answer.

It looks like it is currently not possible. Although the ozwdaemon collects the information, it does not currently publish it to Home Assistant (although it is feasible).

I believe that it is. At least, the Zooz ZEN30 has found a way to show two different entities in totally different domains (light vs switch). The second device listed here is a switch, and the first is a light.

Hi, coming here from the HA Github issue that was linked… Thought I’d try to help and clear up some things. I’m not a Z-Wave expert by any means, but I like to read the docs and help with HA support, so here I am. :slight_smile:

There are two, maybe three problems here. First, the way HA determines how entities are created. Directly related is that the LZW36 is a multi-channel device. Another is that this device is Z-Wave Plus V2.

As already mentioned, Home Assistant with the new OZW integration only creates fan entities for devices that advertise themselves as Fan Switches. A “Fan Switch” is a Device Type (DT) that is defined by the Z-Wave Plus Device Type specification. There are two other specifications, the original Z-Wave DT and the new Z-Wave Plus V2 DT. HA’s OZW integration only supports the Z-Wave Plus device type.

My GE fan switch is not Z-Wave Plus, so it takes on the Multilevel Switch Generic Device Class as defined by that version of the spec. There is no Fan Switch in that version. The generic device class is GENERIC_TYPE_SWITCH_MULTILEVEL, and the specific device class is SPECIFIC_TYPE_POWER_SWITCH_MULTILEVEL. This looks exactly like a dimmer switch. This is why HA uses the manufacturer ID and product ID/Type as a “workaround” in the old zwave integration to detect it instead.

I also have a Homeseer fan switch that is programmed as a Fan Switch DT, which was added to Z-Wave Plus. The generic device class is GENERIC_TYPE_SWITCH_MULTILEVEL, and the specific device class SPECIFIC_TYPE_FAN_SWITCH. Those two device classes, along with the Multilevel Switch Command Class, is how HA decides it is a fan.

The LZW36 (which I don’t own) says it is Z-Wave Plus V2. If that’s true, the Z-Wave Plus V2 Device Types spec doesn’t define a fan type anymore! It seems they’ve dropped the fan specific class for some reason (simplification?). In fact they call out Fan Switch DT as a example type that should be a Multilevel Switch DT in V2:

The Multilevel Switch Device Type is intended for products that can be switched between more than 2 discrete levels or states, such a light dimmer, water valve or a fan.

The Multilevel Switch DT is required to use generic device class GENERIC_TYPE_SWITCH_MULTILEVEL and specific class SPECIFIC_TYPE_NOT_USED. Based on the posts here, it seems the LZW36 is following the spec.

So if you are abiding by the spec for Z-Wave Plus V2, then you cannot program a specific type of SPECIFIC_TYPE_FAN_SWITCH. Sounds like a dead end then? I don’t know anything about how the V2 certification works and if you’re able to deviate from it, but the spec is pretty clear that it is a requirement. To add to this, I could find one other product in the ZWave DB that is a Z-Wave Plus V2 Fan Controller, and it too is certified as a “Z-Wave Device Type: Multilevel Switch”. If you browse for Z-Wave Plus fan controllers you’ll find them certified as “Z-Wave Device Type: Fan Switch”.

This is the next problem, but it is solvable. HA does know about the different endpoints, but it currently has no way of knowing that they are different device types.

Let’s pretend the LZW36 actually did report one endpoint as a dimmer and another as a fan switch in the Z-Wave Plus DT style. As long as the Node Information Frame (NIF) advertises the device as a dimmer, HA will continue to consider it that way.

The generic and specific types that HA uses for discovery are from the Node Information Frame of the device. Even if the device correctly reports different classes with the Multi Channel Capability Report, OZW will not tell HA about it. If you look at the OZW code it saves the endpoint values (I don’t think they’re persisted in the cache though), but the application (in this case ozwdaemon) doesn’t use the endpoint values in any way.

HA could support this scenario. First, ozwdaemon would need to expose the per-endpoint values in the MQTT payloads it sends, and then HA would need to recognize the per-endpoint values when it determines which entities to create. Since it already knows about endpoints that part shouldn’t be difficult.

This is an interesting observation, but I’m not sure it’s really helpful in the end.

That is the “Z-Wave Plus Assigned Icon Types”, which is reported via the Z-Wave Plus Info Command Class. The intent was/is to use this to display some (terrible) icons in an application. The icon types are defined by the standard. My HomeSeer fan switch does report “Fan Switch”.

The icon is supposed to be reported individually for each endpoint (I have a device that doesn’t). Based on the cache file posted above, you can see that it is, or at least the root and endpoints are different:

                                <Value type="short" genre="system" instance="1" index="1" label="InstallerIcon" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="-32768" max="32767" value="7168">
                                        <Help>Icon File to use for the Installer Application</Help>
                                </Value>
                                <Value type="short" genre="system" instance="2" index="1" label="InstallerIcon" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="-32768" max="32767" value="1536">
                                        <Help>Icon File to use for the Installer Application</Help>
                                </Value>
                                <Value type="short" genre="system" instance="3" index="1" label="InstallerIcon" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="-32768" max="32767" value="1536">
                                        <Help>Icon File to use for the Installer Application</Help>
                                </Value>

We can look at the Assigned Icon Types document to see what these mean.

Endpoint 1 is 7168:

ICON_TYPE_GENERIC_DIMMER_WALL_SWITCH
Dimmer Wall Switch
This icon is intented for the installer and user icon types in the root device of a Multi Channel device implementing a wall controller. A user interface should not show the root device. The user icon type of each wall controller End Point should be either ICON_TYPE_GENERIC_LIGHT_DIMMER_SWITCH, ICON_TYPE_GENERIC_ON_OFF_POWER_SWITCH.

Endpoint 2 and 3 are 1536:

ICON_TYPE_GENERIC_LIGHT_DIMMER_SWITCH
Generic Light Dimmer icon
This icon is intented for user icon types

So looks like Inovelli is again following the spec, but notice the phrasing says should be. That terminology usually means it’s not a requirement, just a strong suggestion. So maybe the device could report Fan Switch instead for that endpoint? I’m not sure who decides what a device/endpoint will report, does the vendor set it?

Of course, you could also hack the device XML file to override the detected values if you wanted.

The spec says “Icon types do not affect the operation of a product or how it is certified.” Does that mean applications shouldn’t consider it in determining behavior? Kind of sounds like you wouldn’t want to rely on it. Is there any hub on the market that uses this information?

Either way, you’d still need to get Home Assistant to implement it. Might be useful for a control panel or something. As for behavior, it’s probably easier just to go with the manufacturer based workarounds at that point, because then you can also support non-Plus devices.

Zooz isn’t really doing anything special here. When HA sees the Binary Switch command class, it just creates a switch, there is nothing else it considers. Because they are different command classes, Binary Switch vs. Multilevel Switch, there is no ambiguity.

Here’s a list of documents for reference. If I got something wrong, I’m happy to be corrected.

  • SDS10242 Z-Wave Device Class Specification
  • SDS11847 Z-Wave Plus Device Type Specification
  • SDS14224 Z-Wave Plus v2 Device Type Specification
  • SDS13738 Z-Wave Plus Assigned Icon Types
4 Likes

In fact there is already one workaround that considers the endpoint (instance), so it would be possible.

Dang man, very useful information! Indeed, exactly what we need in this conversation. I know that our manufacturer is very stringent on following the Z-wave spec and they will not deviate from it.

So assuming that is the case and there is not anything I can do via the device firmware, is there anything I can do via the device xml config file to accomplish what people are wanting?

If not, is there any HA custom modification that I can put in a knowledge base article to accomplish it?

Edit: I’m hoping for someone to provide some step-by-step instructions that I can put in our KB. :slight_smile:

I would definitely love to see something done in the device config XML or potentially even in HA core. In the meantime, this is what I’ve done, maybe it can be of help to some people.

fan:
  - platform: template
    fans:
      lzw36_switch_fan_template:
        friendly_name: "LZW36 Switch Fan"
        value_template: "{{ states('light.lzw36_switch_fan_level') }}"
        speed_template: >
          {% if is_state('light.lzw36_switch_fan_level', 'off') %}
            {{ state_attr('fan.lzw36_switch_fan_template', 'speed') }}
          {% elif state_attr('light.lzw36_switch_fan_level', 'brightness') > 170 %}
            high
          {% elif state_attr('light.lzw36_switch_fan_level', 'brightness') > 85 %}
            medium
          {% elif state_attr('light.lzw36_switch_fan_level', 'brightness') > 1 %}
            low
          {% endif %}
        turn_on:
          service: light.turn_on
          entity_id: light.lzw36_switch_fan_level
        turn_off:
          service: light.turn_off
          entity_id: light.lzw36_switch_fan_level
        set_speed:
          service: light.turn_on
          entity_id: light.lzw36_switch_fan_level
          data_template:
            brightness: >
              {% if speed == "high" %}
                255
              {% elif speed == "medium" %}
                170
              {% elif speed == "low" %}
                85
              {% endif %}
        speeds:
          - 'low'
          - 'medium'
          - 'high'

Then I just expose the template fan to things and everything works great.

3 Likes

I don’t think there is a solution purely in OZW that you could do right now. You can’t override device classes in XML files. It would be a useful feature, but when I last asked about it, it wasn’t favorably received. Perhaps someone who owns this device and is invested in the outcome would want to submit an issue to OZW and see if there is some kind of solution that could be implemented. Otherwise, it’s going to be up to every client application to implement it.

For the native HA integration (OZW 1.4), the workaround.py file would need to be updated to include this product, and the component override function would need to be updated to detect based on endpoint (to distinguish the light and fan endpoints). Doesn’t look very difficult. (I tried to link the HA Github code for where the solution would be implemented, but was blocked by this forum).

For the ozw beta integration (OZW 1.6) there are currently no manufacturer workarounds, so that would need to be created from scratch. For lack of other ideas, I would do something similar as the native one. Anyone could implement this.

Not sure if I broke something else but, link to my gist adding support for instance based component remapping, as well as added the light/fan component override. If someone else can test this out will try to put in a PR for this.

entity_id is no longer allowed in templates as of 0.115. Has anyone figured out a way to make the template work without it?

Here’s what I have. Replace “light.bedroom_overhead_fan” with whatever the name of your fan’s “light” entity is. Change unique_id to whatever you want; it’s required if you want to assign the fan to an “Area”. And you can change speed_count to whatever your fan supports.

configuration.yaml:

script:
  turn_on_bedroom_fan_to_specified_power:
    alias: Turn on bedroom fan to specified power
    sequence:
    - service: light.turn_on
      data:
        brightness_pct: '{{ percentage|float }}'
        transition: 0
      target:
        entity_id: light.bedroom_overhead_fan
    mode: single
  turn_off_bedroom_fan:
    alias: Turn off bedroom fan
    sequence:
    - service: light.turn_off
      target:
        entity_id: light.bedroom_overhead_fan
      data:
        transition: 0
    mode: single
  turn_on_bedroom_fan_to_2_3_power:
    alias: Turn on bedroom fan to 2/3 power
    sequence:
    - service: light.turn_on
      data:
        brightness_pct: 66
        transition: 0
      target:
        entity_id: light.bedroom_overhead_fan
    mode: single

fan:
  - platform: template
    fans:
      bedroom_overhead_fan_template:
        friendly_name: Bedroom Fan
        unique_id: 265484c8-ee6e-4f24-aa66-9150f7f2d338
        value_template: "{{ states('light.bedroom_overhead_fan') }}"
        percentage_template: "{{ state_attr('light.bedroom_overhead_fan','brightness')|float / 2.55 }}"
        turn_on:
          service: script.turn_on_bedroom_fan_to_2_3_power
        turn_off:
          service: script.turn_off_bedroom_fan
        set_percentage:
          service: script.turn_on_bedroom_fan_to_specified_power
          data:
            percentage: "{{ percentage }}"
        speed_count: 3
1 Like

Here is my fan using the new template, also added support for breezy mode:

  master_bedroom_fan:
    friendly_name: "Master Bedroom Fan"
    value_template: >-
      {% if is_state('light.master_bedroom_fan_control', 'on') %}
        on
      {% else %}
        off
      {% endif %}
    percentage_template: "{{ (state_attr('light.master_bedroom_fan_control','brightness') | int /255*100) | int}}"
    turn_on:
      service: light.turn_on
      entity_id: light.master_bedroom_fan_control
    turn_off:
      service: light.turn_off
      entity_id: light.master_bedroom_fan_control
    speed_count: 3
    set_percentage:
      service: light.turn_on
      entity_id: light.master_bedroom_fan_control
      data_template:
        brightness_pct: "{{percentage}}"
    set_preset_mode:
      service: light.turn_on
      entity_id: light.master_bedroom_fan_control
      data_template:
        brightness_pct: "1"
    preset_modes:
      - 'breezy'
2 Likes

This is working to set the fan speed for me, but every time I set the speed or turn the fan on, the light comes on as well. Am I missing something?

What happens when you turn the light on?

Same problem. What I missed was that at some point, ZWaveJSToMQTT refreshed my entity list and created a fan entity that solves all of my problems. Now I can set the fan independently from the light with no YAML work.