Skip to content

Commit 5e935e7

Browse files
committed
[shelly] Fix WebSocket status push skipping hybrid profile secondary components
ShellyComponents.updateLightMode() skipped its entire update loop whenever profile.inColor was true, so a hybrid Pro RGBWW PM profile's secondary CCT/Light component never received brightness/temp channel updates pushed over the WebSocket, even though the caller had already computed the correct per-component index for it. Skip only the color slot's own index instead of bailing out for the whole method. Signed-off-by: Markus Michels <markus7017@gmail.com>
1 parent 45c4d90 commit 5e935e7

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,12 +881,17 @@ public static boolean updateLightMode(ShellyThingInterface thingHandler, ShellyS
881881
throws ShellyApiException {
882882
boolean updated = false;
883883
ShellyDeviceProfile profile = thingHandler.getProfile();
884-
if (profile.isRGBW2 && !profile.inColor) {
884+
if (profile.isRGBW2) {
885885
if (!thingHandler.areChannelsCreated()) {
886886
return false;
887887
}
888888
List<ShellySettingsLight> lights = orgStatus.lights;
889889
for (int i = 0; i < lights.size(); i++) {
890+
if (profile.isColorComponent(i)) {
891+
// color component is handled by updateRGBW(); this loop only covers CCT/Light components
892+
// (a hybrid profile's secondary component(s), or all of them for a plain white-mode RGBW2)
893+
continue;
894+
}
890895
ShellySettingsLight light = lights.get(i);
891896
String groupName = profile.getControlGroup(i);
892897
OnOffType power = getOnOff(light.ison);

bundles/org.openhab.binding.shelly/src/test/java/org/openhab/binding/shelly/internal/handler/ShellyComponentsTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import static org.mockito.Mockito.*;
2020
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
2121
import static org.openhab.binding.shelly.internal.ShellyDevices.*;
22+
import static org.openhab.binding.shelly.internal.api.ShellyLightApiComponentDTO.API_COMPONENT_CCT;
23+
import static org.openhab.binding.shelly.internal.api.ShellyLightApiComponentDTO.API_COMPONENT_RGB;
2224
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.SHELLY_ALWD_ROLLER_TURN_CLOSE;
2325
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.SHELLY_ALWD_ROLLER_TURN_OPEN;
2426
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.SHELLY_API_INVTEMP;
@@ -40,8 +42,10 @@
4042
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyRollerStatus;
4143
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDimmer;
4244
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsEMeter;
45+
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsLight;
4346
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsMeter;
4447
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRelay;
48+
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRgbwLight;
4549
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
4650
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortLightStatus;
4751
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor;
@@ -833,6 +837,28 @@ void updateSensorsMutePresentUpdatesSensorsMuteForSmoke() throws Exception {
833837
verify(handler, never()).postEvent(any(), anyBoolean());
834838
}
835839

840+
@Test
841+
void updateLightModeHybridProfileSkipsColorSlotAndUpdatesSecondaryComponent() throws Exception {
842+
ShellyDeviceProfile profile = proRgbwwPmHybridProfile();
843+
ShellyThingInterface handler = mockHandler(profile);
844+
845+
ShellySettingsStatus status = new ShellySettingsStatus();
846+
ShellySettingsLight colorLight = new ShellySettingsLight(); // settings.lights[0], the "rgb" color slot
847+
ShellySettingsLight cctLight = new ShellySettingsLight(); // settings.lights[1], the "cct" secondary slot
848+
cctLight.ison = true;
849+
cctLight.brightness = 42;
850+
cctLight.temp = 4000;
851+
status.lights = new ArrayList<>(List.of(colorLight, cctLight));
852+
853+
boolean updated = ShellyComponents.updateLightMode(handler, status);
854+
855+
assertThat(updated, is(true));
856+
verify(handler, never()).updateChannel(eq(CHANNEL_GROUP_LIGHT_CONTROL), anyString(), any());
857+
verify(handler).updateChannel(eq(CHANNEL_GROUP_LIGHT_INDEX + "1"), eq(CHANNEL_BRIGHTNESS + "$Switch"),
858+
eq(OnOffType.ON));
859+
verify(handler).updateChannel(eq(CHANNEL_GROUP_LIGHT_INDEX + "1"), eq(CHANNEL_COLOR_TEMP), any());
860+
}
861+
836862
private static ShellyThingInterface relayHandlerWith(ShellySettingsStatus profileStatus) {
837863
ShellyDeviceProfile profile = new ShellyDeviceProfile(THING_TYPE_SHELLYPLUS1PM);
838864
profile.isSensor = false;
@@ -930,6 +956,18 @@ private static ShellyDeviceProfile gen1RollerProfile() {
930956
return profile;
931957
}
932958

959+
// Pro RGBWW PM "rgbcct" profile: settings.lights[0] is the color (rgb) component, [1] is the secondary cct one
960+
private static ShellyDeviceProfile proRgbwwPmHybridProfile() {
961+
ShellyDeviceProfile profile = new ShellyDeviceProfile(THING_TYPE_SHELLYPRORGBWWPM);
962+
profile.inColor = true;
963+
ShellySettingsRgbwLight colorComponent = new ShellySettingsRgbwLight();
964+
colorComponent.apiComponent = API_COMPONENT_RGB;
965+
ShellySettingsRgbwLight cctComponent = new ShellySettingsRgbwLight();
966+
cctComponent.apiComponent = API_COMPONENT_CCT;
967+
profile.settings.lights = new ArrayList<>(List.of(colorComponent, cctComponent));
968+
return profile;
969+
}
970+
933971
@Test
934972
void deviceTotalKwhEm1dataPresentUsesDeviceTotal() {
935973
ShellyDeviceProfile profile = emeterProfile(true, 2);

0 commit comments

Comments
 (0)