MQTT Light brightness to previous value when using the on button

Currently I’m testing Home Assistant next to my Domoticz installation that I used already some years. My devices are connected using MQTT which makes it possible to easily run both Domoticz and Home Assistant at the same time.
For the device discovery both (Domoticz and Home Assisant) are using MQTT Discovery.

My devices are detected correctly, the status is correct and I can control my devices.

There is only one annoying difference between Home Assistant and Domoticz and the control of light with brightness control (dimmers). I expect the following behaviour:

Previous state Action Expected behavior (Domoticz does this) Actual behavior with Home Assistant
Off On Light turns on to previous brightness Light turns on at 100% brightness
Off x % Light turns on to x % As expected
x % y % Light turns to y % As expected
Any Off Light turns off As expected

So the annoying part is the switch from Off to On, so just click on the On button at the dashboard, where Home Asssistant always sets my lights to full brightness.

Configuration details

Most devices are Z-Wave devices of serveral brands (Fibaro, Qubino), connected to Z-Wave using the Z-Wave JS UI project. Z-Wave JS UI is configured to use MQTT including auto disovery. For Domoticz this is a requirement, but I know Z-Wave JS UI can also be connected to Home Assistant using a websocket. But I like the way it is configured using MQTT as layer in between for all my devices. The other nice thing is that the MQTT discovery is grouping the entities per devices instead of seeing only the Z-Wave controller as a device.

The created auto discover configuration (done by Z-Wave JS UI) for a light with the issue is the following:

command_topic: zwave/95/38/1/targetValue/set
state_topic: zwave/95/38/1/currentValue
state_value_template: '{{ "OFF" if value_json.value == 0 else "ON" }}'
brightness_command_topic: zwave/95/38/1/targetValue/set
brightness_scale: 99
brightness_state_topic: zwave/95/38/1/currentValue
brightness_value_template: '{{ value_json.value }}'
on_command_type: brightness
device:
  identifiers:
    - zwavejs2mqtt_0xf1858849_node95
  manufacturer: Fibargroup
  model: Dimmer 2 (FGD212)
  name: Spots bureau werkkamer
  sw_version: '3.5'
name: Spots bureau werkkamer_dimmer_1
unique_id: zwavejs2mqtt_0xf1858849_95-38-1-currentValue
platform: mqtt

The MQTT messages I receive on the targetValue/set topic are:

Previous state Action Domoticz Home Assistant
Off On ON (255) 99
Off 10 % 10 10
10 % 60 % 59 59
60 % Off OFF (0) OFF (0)

Possible solutions

Tested using different autodiscover configurations

First I tried using different autodiscovery configurations. This to ensure there is not already a solution in place.

Changing the on_command_type

First I tried to change the on_command_type to last, this results in the following configuration:

command_topic: zwave/95/38/1/targetValue/set
state_topic: zwave/95/38/1/currentValue
state_value_template: '{{ "OFF" if value_json.value == 0 else "ON" }}'
brightness_command_topic: zwave/95/38/1/targetValue/set
brightness_scale: 99
brightness_state_topic: zwave/95/38/1/currentValue
brightness_value_template: '{{ value_json.value }}'
on_command_type: last
device:
  identifiers:
    - zwavejs2mqtt_0xf1858849_node95
  manufacturer: Fibargroup
  model: Dimmer 2 (FGD212)
  name: Spots bureau werkkamer
  sw_version: '3.5'
name: Spots bureau werkkamer_dimmer_1
unique_id: zwavejs2mqtt_0xf1858849_95-38-1-currentValue
platform: mqtt

Initially it looks like this solve the problem, but this results in other issues:

The MQTT messages I receive on the targetValue/set topic are:

Previous state Action Domoticz Home Assistant
Off On ON (255) ON (255)
Off 10 % 10 10 and ON (255)
10 % 60 % 59 59 and ON (255)
60 % Off OFF (0) OFF (0)

It was interesting to see that Domoticz is not doing anything with the on_command_type, so the behaviour remains the same.
Home Assistant is sending now two messages in case of a level change, this is exactly as documented. Problem is that these messages are sent to the Z-Wave device and this slows down the response and even sometimes the level is changed back to the previous value.

Actually I was not the first one that tried this, it was even implemented in the past, but reverted. More details can be found here: fix(hass): make dimmers turn on to previous brightness by brlodi · Pull Request #1360 · zwave-js/zwave-js-ui · GitHub

Using a MQTT template light

I updated the configuration to use a MQTT template light.
This results in the following configuration:

command_topic: zwave/95/38/1/targetValue/set
state_topic: zwave/95/38/1/currentValue
schema: template
state_template: '{{ "OFF" if value_json.value == 0 else "ON" }}'
brightness_template: '{{ value_json.value }}'
command_on_template: '{{ brightness if brightness is defined else 255 }}'
command_off_template: '0'
device:
  identifiers:
    - zwavejs2mqtt_0xf1858849_node95
  manufacturer: Fibargroup
  model: Dimmer 2 (FGD212)
  name: Spots bureau werkkamer
  sw_version: '3.5'
name: Spots bureau werkkamer_dimmer_3
unique_id: zwavejs2mqtt_0xf1858849_95-38-1-currentValue3
platform: mqtt

This results in two problems:

  • Domoticz is not detecting the device at all
  • Home Assistant is detecting the device as on on/off device, so I cannot set the brightness anymore.

Possible solutions

Hope the issue is clear now, I also have a some suggestions for a solution. Actually there are multiple possible solutions, but I have the preference for one.

  1. Use the issue in the Z-Wave JS UI project:
  • When using the set on_command_type to last solution, the problem of the multiple messages can possibly be solved in the Z-Wave JS UI projects.
    • Pros: No changes in Home Assistant needed.
    • Cons: As already mentioned in the reference link above, this will result in a lot of extra complexy and I think the current implementation of just passing the values from MQTT directly to te device is correct.
  1. Introduce a new “on_command_type”:
  • Introduce a new on_command_type: brightness_or_on which actually gives Home Assistant the same behaviour as the current Domoticz implementation. So only send the brightness when the brightness is set, otherwise send the payload_on or payload_off.
    • Pros: Relative easy change
    • Cons:
      • Even more command types
      • Using this feature requires a breaking change in the Z-Wave JS UI project, since you need the latest Home Assistant that supports this new command type
  1. Extend the “brightness_command_template” variables:
  • Currently there is already a brightness_command_template for the default light. This template only supports a single variable value which contains the scaled value. This single value make it impossible to detect if the action was a level change or just a simple on/off command. By introducing an extra variable brightness_provided (or maybe a better name), this value should be true on a level change and false in case of an on/off action.
    • Pros:
      • Relative easy change
      • Can be used as:
        brightness_command_template: '{{ value if (brightness_provided or value == 0) else 255 }}'
        
      • Or in a backwards compatible way, by setting the template to:
        brightness_command_template: '{{ (value if (brightness_provided or value == 0) else 255) if brightness_provided is defined else value }}'
        
    • Cons: None?

I think the best solution is solution 3.

Conclusion

I think it is a good idea to implement suggested solution 3. But before making any changes I would like to have the opinion of other users/experts. Maybe there are other solutions/suggestions.

Looking forward to some answers!

Created two pull request for this feature:
- Core:Add `brightness_provided` variable to MQTT light `brightness_command_template` to see the difference between a change brightness and on/off only action. by m-a-r-k-e · Pull Request #91125 · home-assistant/core · GitHub
- Documenation: Document 'brightness_provided' variable for MQTT light 'brightness_command_template' (feature core #91125) by m-a-r-k-e · Pull Request #26928 · home-assistant/home-assistant.io · GitHub

The issue is solved by another pull request: Do not allow mqtt lights to set brightness to zero by jbouwh · Pull Request #91296 · home-assistant/core · GitHub
The actual problem was a received zero value for the brightness. For more details see the discussion in Add `brightness_provided` variable to MQTT light `brightness_command_template` to see the difference between a change brightness and on/off only action. by m-a-r-k-e · Pull Request #91125 · home-assistant/core · GitHub

I know this topics is solved but I would like to query if there is an option to choose between the ‘Always 100% On’ or ‘Previous Level’. I do see a use case for both and currently use both in my Clipsal CBUS system.