Skip to content

Commit

Permalink
[mqtt.homeassistant] interpret a dimmable light as OFF properly from …
Browse files Browse the repository at this point in the history
…zigbee2mqtt (openhab#15925)

* [mqtt.homeassistant] interpret a dimmable light as OFF properly from zigbee2mqtt

zigbee2mqtt can send a brightness of say 99, with a state of OFF, when a bulb is
off. make sure if state is sent, it overrides all other inferences

* handle brightness but not color bulbs

---------

Signed-off-by: Cody Cutrer <[email protected]>
Signed-off-by: Jørgen Austvik <[email protected]>
  • Loading branch information
ccutrer authored and austvik committed Mar 27, 2024
1 parent d6021e7 commit 314bb1e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,26 +253,38 @@ public void updateChannelState(ChannelUID channel, State state) {
}
}

boolean off = false;
if (jsonState.state != null) {
onOffValue.update(onOffValue.parseCommand(new StringType(jsonState.state)));
off = onOffValue.getChannelState().equals(OnOffType.OFF);
if (brightnessValue.getChannelState() instanceof UnDefType) {
brightnessValue.update(brightnessValue.parseCommand((OnOffType) onOffValue.getChannelState()));
brightnessValue.update(off ? PercentType.ZERO : PercentType.HUNDRED);
}
if (colorValue.getChannelState() instanceof UnDefType) {
colorValue.update(colorValue.parseCommand((OnOffType) onOffValue.getChannelState()));
colorValue.update(off ? HSBType.BLACK : HSBType.WHITE);
}
}

PercentType brightness;
if (off) {
brightness = PercentType.ZERO;
} else if (brightnessValue.getChannelState() instanceof PercentType percentValue) {
brightness = percentValue;
} else {
brightness = PercentType.HUNDRED;
}

if (jsonState.brightness != null) {
brightnessValue.update(
brightnessValue.parseCommand(new DecimalType(Objects.requireNonNull(jsonState.brightness))));
if (!off) {
brightness = (PercentType) brightnessValue
.parseMessage(new DecimalType(Objects.requireNonNull(jsonState.brightness)));
}
brightnessValue.update(brightness);
if (colorValue.getChannelState() instanceof HSBType) {
HSBType color = (HSBType) colorValue.getChannelState();
colorValue.update(new HSBType(color.getHue(), color.getSaturation(),
(PercentType) brightnessValue.getChannelState()));
colorValue.update(new HSBType(color.getHue(), color.getSaturation(), brightness));
} else {
colorValue.update(new HSBType(DecimalType.ZERO, PercentType.ZERO,
(PercentType) brightnessValue.getChannelState()));
colorValue.update(new HSBType(DecimalType.ZERO, PercentType.ZERO, brightness));
}
}

Expand All @@ -284,9 +296,6 @@ public void updateChannelState(ChannelUID channel, State state) {
}

if (jsonState.color != null) {
PercentType brightness = brightnessValue.getChannelState() instanceof PercentType
? (PercentType) brightnessValue.getChannelState()
: PercentType.HUNDRED;
// This corresponds to "deprecated" color mode handling, since we're not checking which color
// mode is currently active.
// HS is highest priority, then XY, then RGB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ public void testBrightnessAndOnOff() throws InterruptedException {
assertState(component, Light.BRIGHTNESS_CHANNEL_ID,
new PercentType(new BigDecimal(128 * 100).divide(new BigDecimal(255), MathContext.DECIMAL128)));

publishMessage("zigbee2mqtt/light/state", "{ \"state\": \"OFF\", \"brightness\": 128 }");
assertState(component, Light.BRIGHTNESS_CHANNEL_ID, PercentType.ZERO);

sendCommand(component, Light.BRIGHTNESS_CHANNEL_ID, PercentType.HUNDRED);
assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\",\"brightness\":255}");

Expand Down

0 comments on commit 314bb1e

Please sign in to comment.