Skip to content

Commit a29aa0b

Browse files
committed
Integration of Plus RGBWPM and Pro RGBWPM
Signed-off-by: Markus Michels <markus7017@gmail.com>
1 parent c417fe3 commit a29aa0b

9 files changed

Lines changed: 398 additions & 110 deletions

File tree

bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyDevices.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public class ShellyDevices {
137137
public static final String SHELLYDT_PRO3EM_2 = "SPEM-003CEBEU120";
138138
public static final String SHELLYDT_PRO3EM3CT63 = "SPEM-003CEBEU63";
139139
public static final String SHELLYDT_PRO3EM400 = "SPEM-003CEBEU400";
140+
public static final String SHELLYDT_PRORGBWPM = "SPDC-0D5PE16EU";
140141

141142
// Shelly Plus Mini Series
142143
public static final String SHELLYDT_MINI_1 = "SNSW-001X8EU";
@@ -266,6 +267,7 @@ public class ShellyDevices {
266267
public static final ThingTypeUID THING_TYPE_SHELLYPRO3EM = new ThingTypeUID(BINDING_ID, "shellypro3em");
267268
public static final ThingTypeUID THING_TYPE_SHELLYPRO3EM63 = new ThingTypeUID(BINDING_ID, "shellypro3em63");
268269
public static final ThingTypeUID THING_TYPE_SHELLYPRO3EM400 = new ThingTypeUID(BINDING_ID, "shellypro3em400");
270+
public static final ThingTypeUID THING_TYPE_SHELLYPRORGBWPM = new ThingTypeUID(BINDING_ID, "shellyprorgbwpm");
269271

270272
// Shelly Blu series
271273
public static final ThingTypeUID THING_TYPE_SHELLYBLUBUTTON = new ThingTypeUID(BINDING_ID, "shellyblubutton");
@@ -289,7 +291,8 @@ public class ShellyDevices {
289291

290292
// RGBW2 devices
291293
public static final Set<ThingTypeUID> GROUP_RGBW2_THING_TYPES = Set.of( //
292-
THING_TYPE_SHELLYRGBW2_COLOR, THING_TYPE_SHELLYRGBW2_WHITE, THING_TYPE_SHELLYPLUSRGBWPM);
294+
THING_TYPE_SHELLYRGBW2_COLOR, THING_TYPE_SHELLYRGBW2_WHITE, THING_TYPE_SHELLYPLUSRGBWPM,
295+
THING_TYPE_SHELLYPRORGBWPM);
293296

294297
// All Light Bulbs / RGBW devices
295298
public static final Set<ThingTypeUID> GROUP_LIGHT_THING_TYPES = Stream
@@ -454,6 +457,7 @@ public class ShellyDevices {
454457
Map.entry(SHELLYDT_PRO3EM_2, THING_TYPE_SHELLYPRO3EM), //
455458
Map.entry(SHELLYDT_PRO3EM3CT63, THING_TYPE_SHELLYPRO3EM63), //
456459
Map.entry(SHELLYDT_PRO3EM400, THING_TYPE_SHELLYPRO3EM400), //
460+
Map.entry(SHELLYDT_PRORGBWPM, THING_TYPE_SHELLYPRORGBWPM), //
457461

458462
// BLU Series
459463
Map.entry(SHELLYDT_BLUBUTTON1, THING_TYPE_SHELLYBLUBUTTON),
@@ -618,6 +622,7 @@ public class ShellyDevices {
618622
Map.entry("shellypro3em63", THING_TYPE_SHELLYPRO3EM63), //
619623
Map.entry("shellypro3em3ct63", THING_TYPE_SHELLYPRO3EM63), //
620624
Map.entry("shellypro3em400", THING_TYPE_SHELLYPRO3EM400),
625+
Map.entry("shellyprorgbwpm", THING_TYPE_SHELLYPRORGBWPM), //
621626

622627
// Shelly BLU Series
623628
Map.entry("shellyblubutton", THING_TYPE_SHELLYBLUBUTTON), //

bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiClient.java

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
4545
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortLightStatus;
4646
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortStatusRelay;
47+
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusLight;
48+
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusLightChannel;
4749
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusRelay;
4850
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor;
4951
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtAnalogInput;
@@ -60,6 +62,7 @@
6062
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2DevConfigCover;
6163
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2DevConfigInput;
6264
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2DevConfigSwitch;
65+
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2GetConfigLight;
6366
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2GetConfigResult;
6467
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.ShellyDeviceConfigCB;
6568
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusLight;
@@ -80,6 +83,7 @@
8083
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2StatusEm1;
8184
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
8285
import org.openhab.binding.shelly.internal.handler.ShellyBaseHandler;
86+
import org.openhab.binding.shelly.internal.handler.ShellyColorUtils;
8387
import org.openhab.binding.shelly.internal.handler.ShellyComponents;
8488
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
8589
import org.openhab.core.types.State;
@@ -96,6 +100,7 @@ public class Shelly2ApiClient extends ShellyHttpClient {
96100
private final Logger logger = LoggerFactory.getLogger(Shelly2ApiClient.class);
97101
protected final Random random = new Random();
98102
protected final ShellyStatusRelay relayStatus = new ShellyStatusRelay();
103+
protected final ShellyStatusLight lightStatus = new ShellyStatusLight();
99104
protected final ShellyStatusSensor sensorData = new ShellyStatusSensor();
100105
protected final ArrayList<ShellyRollerStatus> rollerStatus = new ArrayList<>();
101106
protected @Nullable ShellyThingInterface thing;
@@ -159,7 +164,7 @@ public Shelly2ApiClient(String thingName, ShellyThingConfiguration config, HttpC
159164
SHELLY2_RSTATE_STOPPED, SHELLY_RSTATE_STOP, //
160165
SHELLY2_RSTATE_CALIB, SHELLY2_RSTATE_CALIB); // Gen2-only
161166

162-
protected static final Map<String, String> MAP_PROFILE = Map.of(//
167+
protected static final Map<String, String> MAP_DEVICE_PROFILE = Map.of(//
163168
SHELLY2_PROFILE_RELAY, SHELLY_CLASS_RELAY, //
164169
SHELLY2_PROFILE_COVER, SHELLY_CLASS_ROLLER, //
165170
SHELLY2_PROFILE_LIGHT, SHELLY_MODE_WHITE, //
@@ -246,6 +251,12 @@ protected boolean fillDeviceStatus(ShellySettingsStatus status, Shelly2DeviceSta
246251
updated |= updateEmStatus(11, status, result.em11, channelUpdate);
247252
updated |= updateRollerStatus(0, status, result.cover0, channelUpdate);
248253
updated |= updateDimmerStatus(0, status, result.light0, channelUpdate);
254+
updated |= updateDimmerStatus(1, status, result.light1, channelUpdate);
255+
updated |= updateLightStatus(0, status, result.light0, channelUpdate);
256+
updated |= updateLightStatus(1, status, result.light1, channelUpdate);
257+
updated |= updateLightStatus(2, status, result.light2, channelUpdate);
258+
updated |= updateLightStatus(3, status, result.light3, channelUpdate);
259+
updated |= updateLightStatus(4, status, result.light4, channelUpdate);
249260
updated |= updateRGBWStatus(0, status, result.rgbw0, channelUpdate);
250261
if (channelUpdate) {
251262
updated |= ShellyComponents.updateMeters(getThing(), status);
@@ -742,21 +753,6 @@ protected void fillDimmerSettings(ShellyDeviceProfile profile, Shelly2GetConfigR
742753
}
743754
}
744755

745-
protected void fillRgbwSettings(ShellyDeviceProfile profile, Shelly2GetConfigResult dc) {
746-
if (!profile.isRGBW2 || dc.rgbw0 == null) {
747-
return;
748-
}
749-
750-
List<ShellySettingsRgbwLight> lights = profile.settings.lights;
751-
if (lights != null) {
752-
ShellySettingsRgbwLight ls = lights.get(0);
753-
ls.autoOn = dc.rgbw0.autoOnDelay;
754-
ls.autoOff = dc.rgbw0.autoOffDelay;
755-
ls.name = dc.rgbw0.name;
756-
lights.set(0, ls);
757-
}
758-
}
759-
760756
private boolean updateDimmerStatus(int id, ShellySettingsStatus status, @Nullable Shelly2DeviceStatusLight value,
761757
boolean channelUpdate) throws ShellyApiException {
762758
ShellyDeviceProfile profile = getProfile();
@@ -778,6 +774,71 @@ private boolean updateDimmerStatus(int id, ShellySettingsStatus status, @Nullabl
778774
return channelUpdate ? ShellyComponents.updateDimmers(getThing(), status) : false;
779775
}
780776

777+
protected @Nullable ArrayList<@Nullable ShellySettingsRgbwLight> fillLightSettings(ShellyDeviceProfile profile,
778+
Shelly2GetConfigResult dc) {
779+
ArrayList<@Nullable ShellySettingsRgbwLight> lights = new ArrayList<>();
780+
addLightSettings(lights, dc.light0);
781+
addLightSettings(lights, dc.light1);
782+
addLightSettings(lights, dc.light2);
783+
addLightSettings(lights, dc.light3);
784+
return !lights.isEmpty() ? lights : null;
785+
}
786+
787+
private void addLightSettings(ArrayList<@Nullable ShellySettingsRgbwLight> lights,
788+
@Nullable Shelly2GetConfigLight cl) {
789+
if (cl == null) {
790+
return;
791+
}
792+
793+
ShellySettingsRgbwLight ls = new ShellySettingsRgbwLight();
794+
ls.defaultState = cl.initialState;
795+
ls.name = cl.name;
796+
ls.ison = false;
797+
ls.autoOn = getBool(cl.autoOn) ? cl.autoOnDelay : 0;
798+
ls.autoOff = getBool(cl.autoOff) ? cl.autoOffDelay : 0;
799+
lights.add(ls);
800+
}
801+
802+
private boolean updateLightStatus(int id, ShellySettingsStatus status, @Nullable Shelly2DeviceStatusLight value,
803+
boolean channelUpdate) throws ShellyApiException {
804+
ShellyDeviceProfile profile = getProfile();
805+
if (!profile.isLight || value == null) {
806+
return false;
807+
}
808+
if (value.id == null) { // fw 1.6.1
809+
value.id = id;
810+
}
811+
812+
ShellySettingsLight ls = status.lights.get(id);
813+
ShellyStatusLightChannel lc = new ShellyStatusLightChannel();
814+
ls.mode = profile.device.mode;
815+
ls.ison = lc.ison = value.output;
816+
ls.dcpower = getDouble(value.apower).intValue();
817+
if (value.brightness != null) {
818+
ls.brightness = lc.brightness = getDouble(value.brightness).intValue();
819+
}
820+
821+
status.lights.set(id, ls);
822+
lightStatus.lights.set(id, lc);
823+
824+
return channelUpdate ? ShellyComponents.updateLights(getThing(), lc, value.id, new ShellyColorUtils()) : false;
825+
}
826+
827+
protected void fillRgbwSettings(ShellyDeviceProfile profile, Shelly2GetConfigResult dc) {
828+
if (!profile.isRGBW2 || dc.rgbw0 == null) {
829+
return;
830+
}
831+
832+
List<ShellySettingsRgbwLight> lights = profile.settings.lights;
833+
if (lights != null) {
834+
ShellySettingsRgbwLight ls = lights.get(0);
835+
ls.autoOn = dc.rgbw0.autoOnDelay;
836+
ls.autoOff = dc.rgbw0.autoOffDelay;
837+
ls.name = dc.rgbw0.name;
838+
lights.set(0, ls);
839+
}
840+
}
841+
781842
private boolean updateRGBWStatus(int id, ShellySettingsStatus status, @Nullable Shelly2RGBWStatus value,
782843
boolean channelUpdate) throws ShellyApiException {
783844
ShellyDeviceProfile profile = getProfile();
@@ -934,6 +995,7 @@ private void postAlarms(@Nullable ArrayList<@Nullable String> errors) throws She
934995
addInputSettings(inputs, dc.input1);
935996
addInputSettings(inputs, dc.input2);
936997
addInputSettings(inputs, dc.input3);
998+
addInputSettings(inputs, dc.input4);
937999

9381000
return inputs;
9391001
}
@@ -956,6 +1018,7 @@ protected boolean updateInputStatus(ShellySettingsStatus status, Shelly2DeviceSt
9561018
updated |= addInputStatus(1, status, ds.input1, updateChannels);
9571019
updated |= addInputStatus(2, status, ds.input2, updateChannels);
9581020
updated |= addInputStatus(3, status, ds.input3, updateChannels);
1021+
updated |= addInputStatus(4, status, ds.input4, updateChannels);
9591022
status.inputs = relayStatus.inputs;
9601023
return updated;
9611024
}

bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiJsonDTO.java

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,26 @@ public static class Shelly2GetConfigLightDefault {
428428
public static class Shelly2GetConfigLightNightMode {
429429
public boolean enable;
430430
public Integer brightness;
431+
public Double[] rgb;
432+
public Double white;
433+
}
434+
435+
public static class Shelly2ConfigLightPresets {
436+
public static class Shelly2ConfigLightButtonPreset {
437+
Double brightness;
438+
public Double[] rgb;
439+
}
440+
441+
@SerializedName("button_doublepush")
442+
public Shelly2ConfigLightButtonPreset buttonDoublePush;
431443
}
432444

433445
public Integer id;
434446
public String name;
447+
@SerializedName("in_mode")
448+
public String inMode;
449+
@SerializedName("op_mode")
450+
public Integer operationalMode; // Dimmer0/1-10V PM Gen3: 0=-10VDC, 1=1-10VDC
435451
@SerializedName("initial_state")
436452
public String initialState;
437453
@SerializedName("auto_on")
@@ -442,10 +458,32 @@ public static class Shelly2GetConfigLightNightMode {
442458
public Double autoOnDelay;
443459
@SerializedName("auto_off_delay")
444460
public Double autoOffDelay;
461+
@SerializedName("transition_duration")
462+
public Double transitionDuration;
463+
@SerializedName("min_brightness_on_toggle")
464+
public Double minBrightnessOnToggle;
465+
@SerializedName("night_mode.enable")
466+
public Boolean nightModeEnable;
467+
@SerializedName("night_mode.brightness")
468+
public Integer nightModeBrightness;
469+
@SerializedName("night_mode.active_between")
470+
public String[] nightModeActive;
471+
@SerializedName("button_fade_rate")
472+
public Integer buttonFadeRate;
473+
@SerializedName("button_presets")
474+
public Shelly2ConfigLightPresets buttonPresets;
475+
@SerializedName("range_map")
476+
public Integer[] rangeMap;
477+
@SerializedName("power_limit")
478+
public Double powerLimit;
479+
@SerializedName("voltage_limit")
480+
public Double voltageLimit;
481+
@SerializedName("undervoltage_limit")
482+
public Double powerunderVoltageLimitLimit;
483+
@SerializedName("current_limit")
484+
public Double currentLimit;
445485
@SerializedName("default")
446486
public Shelly2GetConfigLightDefault defaultCfg;
447-
@SerializedName("night_mode")
448-
public Shelly2GetConfigLightNightMode nightMode;
449487
}
450488

451489
public class Shelly2DeviceConfigLed {
@@ -491,6 +529,8 @@ public class Shelly2DevConfigMqtt {
491529
public Shelly2DevConfigInput input2;
492530
@SerializedName("input:3")
493531
public Shelly2DevConfigInput input3;
532+
@SerializedName("input:4")
533+
public Shelly2DevConfigInput input4;
494534

495535
@SerializedName("switch:0")
496536
public Shelly2DevConfigSwitch switch0;
@@ -526,6 +566,14 @@ public class Shelly2DevConfigMqtt {
526566

527567
@SerializedName("light:0")
528568
public Shelly2GetConfigLight light0;
569+
@SerializedName("light:1")
570+
public Shelly2GetConfigLight light1;
571+
@SerializedName("light:2")
572+
public Shelly2GetConfigLight light2;
573+
@SerializedName("light:3")
574+
public Shelly2GetConfigLight light3;
575+
@SerializedName("light:4")
576+
public Shelly2GetConfigLight light4;
529577

530578
@SerializedName("rgbw:0")
531579
public Shelly2GetConfigLight rgbw0;
@@ -604,6 +652,20 @@ public class Shelly2InputStatus {
604652
}
605653

606654
public static class Shelly2DeviceStatusLight {
655+
public static class Shelly2DeviceStatusTransition {
656+
@SerializedName("target.output")
657+
public Boolean targetOutput;
658+
@SerializedName("target.brightness")
659+
public Double targetBrightness;
660+
@SerializedName("started_at")
661+
public Long startedAt;
662+
public Integer duration;
663+
}
664+
665+
public static class Shelly2DeviceStatusCalibration {
666+
public Integer progress;
667+
}
668+
607669
public Integer id;
608670
public String source;
609671
public Boolean output;
@@ -612,6 +674,19 @@ public static class Shelly2DeviceStatusLight {
612674
public Double timerStartedAt;
613675
@SerializedName("timer_duration")
614676
public Double timerDuration;
677+
public Shelly2DeviceStatusTransition transition;
678+
public Shelly2DeviceStatusTemp temperature;
679+
public Shelly2Energy aenergy;
680+
public Double apower;
681+
public Double voltage;
682+
public Double current;
683+
public Shelly2DeviceStatusCalibration calibration;
684+
685+
public String[] errors;
686+
// overcurrent, unsupported_load, cal_abort:interrupted, cal_abort:power_read, cal_abort:no_load,
687+
// cal_abort:no_synchro, cal_abort:non_dimmable, cal_abort:overpower, cal_abort:unsupported_load
688+
689+
public String[] flags; // no_load, uncalibrated
615690
}
616691

617692
public static class Shelly2DeviceStatusResult {
@@ -782,6 +857,8 @@ public static class Shelly2RGBWStatus {
782857
public Shelly2InputStatus input2;
783858
@SerializedName("input:3")
784859
public Shelly2InputStatus input3;
860+
@SerializedName("input:4")
861+
public Shelly2InputStatus input4;
785862
@SerializedName("input:100")
786863
public Shelly2InputStatus input100; // Digital Input from Add-On
787864

@@ -827,6 +904,14 @@ public static class Shelly2RGBWStatus {
827904

828905
@SerializedName("light:0")
829906
public Shelly2DeviceStatusLight light0;
907+
@SerializedName("light:1")
908+
public Shelly2DeviceStatusLight light1;
909+
@SerializedName("light:2")
910+
public Shelly2DeviceStatusLight light2;
911+
@SerializedName("light:3")
912+
public Shelly2DeviceStatusLight light3;
913+
@SerializedName("light:4")
914+
public Shelly2DeviceStatusLight light4;
830915

831916
@SerializedName("temperature:0")
832917
public Shelly2DeviceStatusTempId temperature0;

0 commit comments

Comments
 (0)