Skip to content

Commit

Permalink
Support for Shelly Plus Mini Gen 3 series of devices, Shelly Plus UNI (
Browse files Browse the repository at this point in the history
…openhab#16335)

and Shelly BLU Gateway.

Signed-off-by: Markus Michels <markus7017@gmail.com>
Signed-off-by: Jørgen Austvik <jaustvik@acm.org>
  • Loading branch information
markus7017 authored and austvik committed Mar 27, 2024
1 parent 415f323 commit 5e8f604
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 28 deletions.
16 changes: 8 additions & 8 deletions bundles/org.openhab.binding.shelly/README.md
Expand Up @@ -28,8 +28,8 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
The binding supports both hardware generations

- Generation 1: The original Shelly devices like the Shelly 1, Shelly 2.5, Shelly Flood etc.
- Generation 2: The new Plus / Pro series of devices
- Shelly Plus Mini: Shelly Plus devices in compact format
- Generation 2: Plus / Pro series of devices
- Shelly Plus Mini: Shelly Plus devices in compact format (Gen 2+3)
- Shelly BLU: Bluetooth based series of devices

The binding provides the same feature set across all devices as good as possible and depending on device specific features.
Expand Down Expand Up @@ -95,13 +95,13 @@ The binding provides the same feature set across all devices as good as possible
| shellypluswdus | Shelly Plus Wall Dimmer US | SNDM-0013US |
| shellywalldisplay | Shelly Plus Wall Display | SAWD-0A1XX10EU1 |

### Generation 2 Plus Mini series
### Generation 2 Plus Mini series (incl. Gen 3)

| thing-type | Model | Vendor ID |
| -------------------- | -------------------------------------------------------- | ---------------------------- |
| shellymini1 | Shelly Plus 1 Mini with 1x relay | SNSW-001X8EU |
| shellymini1pm | Shelly Plus 1PM Mini with 1x relay + power meter | SNSW-001P8EU |
| shellyminipm | Shelly Plus PM Mini with 1x power meter | SNPM-001PCEU16 |
| thing-type | Model | Vendor ID |
| -------------------- | -------------------------------------------------------- | ------------------------------ |
| shellymini1 | Shelly Plus 1 Mini with 1x relay | SNSW-001X8EU, S3SW-001X8EU |
| shellymini1pm | Shelly Plus 1PM Mini with 1x relay + power meter | SNSW-001P8EU, S3SW-001P8EU |
| shellyminipm | Shelly Plus PM Mini with 1x power meter | SNPM-001PCEU16, S3PM-001PCEU16 |

### Generation 2 Pro series

Expand Down
2 changes: 1 addition & 1 deletion bundles/org.openhab.binding.shelly/pom.xml
Expand Up @@ -15,6 +15,6 @@
</properties>

<artifactId>org.openhab.binding.shelly</artifactId>
<name>openHAB Add-ons :: Bundles :: Shelly Binding Gen1+2</name>
<name>openHAB Add-ons :: Bundles :: Shelly Binding</name>

</project>
Expand Up @@ -104,6 +104,7 @@ public class ShellyBindingConstants {
THING_TYPE_SHELLYBLUBUTTON, //
THING_TYPE_SHELLYBLUDW, //
THING_TYPE_SHELLYBLUMOTION, //
THING_TYPE_SHELLYBLUGW, //

THING_TYPE_SHELLYPROTECTED, //
THING_TYPE_SHELLYUNKNOWN);
Expand Down
Expand Up @@ -403,12 +403,12 @@ public static String extractFwVersion(@Nullable String version) {
}

public static boolean isGeneration2(String thingType) {
return thingType.startsWith("shellyplus") || thingType.startsWith("shellypro")
|| thingType.startsWith("shellymini") || isBluSeries(thingType);
return thingType.startsWith("shellyplus") || thingType.startsWith("shellypro") || thingType.contains("mini")
|| isBluSeries(thingType);
}

public static boolean isBluSeries(String thingType) {
return thingType.startsWith("shellyblu");
return thingType.startsWith("shellyblu") && !thingType.startsWith(THING_TYPE_SHELLYBLUGW_STR);
}

public boolean coiotEnabled() {
Expand Down
Expand Up @@ -521,11 +521,26 @@ public class Shelly2DeviceConfigWiFi {
}

public static class Shelly2DeviceStatus {
public class Shelly2InputCounts {
public Integer total;
@SerializedName("by_minute")
public Double[] byMinute;
public Double xtotal;
@SerializedName("xby_minute")
public Double[] xbyMinute;
@SerializedName("minute_ts")
public Integer minuteTS;
}

public class Shelly2InputStatus {
public Integer id;
public Boolean state;
public Double percent; // analog input only
public ArrayList<String> errors;// shown only if at least one error is present.
public Double xpercent;
public Shelly2InputCounts counts;
public Double freq;
public Double xfreq;
}

public static class Shelly2DeviceStatusLight {
Expand Down
Expand Up @@ -143,7 +143,8 @@ public DiscoveryResult createResult(final ServiceInfo service) {
config.userId = bindingConfig.defaultUserId;
config.password = bindingConfig.defaultPassword;

boolean gen2 = "2".equals(service.getPropertyString("gen"));
String gen = getString(service.getPropertyString("gen"));
boolean gen2 = "2".equals(gen) || "3".equals(gen);
ShellyApiInterface api = null;
boolean auth = false;
ShellySettingsDevice devInfo;
Expand All @@ -152,7 +153,8 @@ public DiscoveryResult createResult(final ServiceInfo service) {
api.initialize();
devInfo = api.getDeviceInfo();
model = devInfo.type;
auth = devInfo.auth;
gen2 = !(devInfo.gen == 1); // gen 2+3
auth = getBool(devInfo.auth);
if (devInfo.name != null) {
deviceName = devInfo.name;
}
Expand Down
Expand Up @@ -40,6 +40,7 @@ public class ShellyThingCreator {
public static final String SHELLYDT_SHELLY2 = "SHSW-21";
public static final String SHELLYDT_SHELLY25 = "SHSW-25";
public static final String SHELLYDT_SHPRO = "SHSW-44";
public static final String SHELLYDT_4PRO = "SHPSW04P";
public static final String SHELLYDT_EM = "SHEM";
public static final String SHELLYDT_3EM = "SHEM-3";
public static final String SHELLYDT_HT = "SHHT-1";
Expand Down Expand Up @@ -79,6 +80,7 @@ public class ShellyThingCreator {
public static final String SHELLYDT_PLUSI4DC = "SNSN-0D24X";
public static final String SHELLYDT_PLUSHT = "SNSN-0013A";
public static final String SHELLYDT_PLUSSMOKE = "SNSN-0031Z";
public static final String SHELLYDT_PLUSUNI = "SNSN-0043X";
public static final String SHELLYDT_PLUSDIMMERUS = "SNDM-0013US";
public static final String SHELLYDT_PLUSDIMMER10V = "SNGW-0A11WW010";
public static final String SHELLYDT_PLUSWALLDISPLAY = "SAWD-0A1XX10EU1";
Expand Down Expand Up @@ -106,15 +108,20 @@ public class ShellyThingCreator {
public static final String SHELLYDT_PRO4PM_2 = "SPSW-104PE16EU";

// Shelly Plus Mini Series
// Shelly Mini Series
// Mini Generation 2
public static final String SHELLYDT_MINI1 = "SNSW-001X8EU";
public static final String SHELLYDT_MINIPM = "SNPM-001PCEU16";
public static final String SHELLYDT_MINI1PM = "SNSW-001P8EU";
// Mini Generation 3
public static final String SHELLYDT_MINI1G3_1 = "S3SW-001X8EU";
public static final String SHELLYDT_MINIG3_PM = "S3PM-001PCEU16";
public static final String SHELLYDT_MINIG3_1PM = "S3SW-001P8EU";

// Shelly BLU Series
public static final String SHELLYDT_BLUBUTTON = "SBBT";
public static final String SHELLYDT_BLUDW = "SBDW";
public static final String SHELLYDT_BLUMOTION = "SBMO";
public static final String SHELLYDT_BLUGW = "SNGW-BT01";

// Thing names
public static final String THING_TYPE_SHELLY1_STR = "shelly1";
Expand Down Expand Up @@ -195,6 +202,7 @@ public class ShellyThingCreator {
public static final String THING_TYPE_SHELLYBLUBUTTON_STR = THING_TYPE_SHELLYBLU_PREFIX + "button";
public static final String THING_TYPE_SHELLYBLUDW_STR = THING_TYPE_SHELLYBLU_PREFIX + "dw";
public static final String THING_TYPE_SHELLYBLUMOTION_STR = THING_TYPE_SHELLYBLU_PREFIX + "motion";
public static final String THING_TYPE_SHELLYBLUGW_STR = THING_TYPE_SHELLYBLU_PREFIX + "gw";

// Password protected or unknown device
public static final String THING_TYPE_SHELLYPROTECTED_STR = "shellydevice";
Expand Down Expand Up @@ -316,13 +324,16 @@ public class ShellyThingCreator {
public static final ThingTypeUID THING_TYPE_SHELLYBLUDW = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYBLUDW_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBLUMOTION = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBLUMOTION_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBLUGW = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYBLUGW_STR);

private static final Map<String, String> THING_TYPE_MAPPING = new LinkedHashMap<>();
static {
// mapping by device type id
THING_TYPE_MAPPING.put(SHELLYDT_1PM, THING_TYPE_SHELLY1PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_1L, THING_TYPE_SHELLY1L_STR);
THING_TYPE_MAPPING.put(SHELLYDT_1, THING_TYPE_SHELLY1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_SHPRO, THING_TYPE_SHELLY4PRO_STR);
THING_TYPE_MAPPING.put(SHELLYDT_4PRO, THING_TYPE_SHELLY4PRO_STR);
THING_TYPE_MAPPING.put(SHELLYDT_3EM, THING_TYPE_SHELLY3EM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_EM, THING_TYPE_SHELLYEM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_SHPLG_S, THING_TYPE_SHELLYPLUGS_STR);
Expand Down Expand Up @@ -368,6 +379,9 @@ public class ShellyThingCreator {
THING_TYPE_MAPPING.put(SHELLYDT_MINI1, THING_TYPE_SHELLYMINI1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_MINIPM, THING_TYPE_SHELLYMINIPM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_MINI1PM, THING_TYPE_SHELLYMINI1PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_MINI1G3_1, THING_TYPE_SHELLYMINI1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_MINIG3_PM, THING_TYPE_SHELLYMINIPM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_MINIG3_1PM, THING_TYPE_SHELLYMINI1PM_STR);

// Pro Series
THING_TYPE_MAPPING.put(SHELLYDT_PRO1, THING_TYPE_SHELLYPRO1_STR);
Expand Down Expand Up @@ -395,6 +409,7 @@ public class ShellyThingCreator {
THING_TYPE_MAPPING.put(SHELLYDT_BLUBUTTON, THING_TYPE_SHELLYBLUBUTTON_STR);
THING_TYPE_MAPPING.put(SHELLYDT_BLUDW, THING_TYPE_SHELLYBLUDW_STR);
THING_TYPE_MAPPING.put(SHELLYDT_BLUMOTION, THING_TYPE_SHELLYBLUMOTION_STR);
THING_TYPE_MAPPING.put(SHELLYDT_BLUGW, THING_TYPE_SHELLYBLUGW_STR);

// Wall displays
THING_TYPE_MAPPING.put(SHELLYDT_PLUSWALLDISPLAY, THING_TYPE_SHELLYPLUSWALLDISPLAY_STR);
Expand Down
Expand Up @@ -150,7 +150,7 @@ public ShellyBaseHandler(final Thing thing, final ShellyTranslationProvider tran
Map<String, String> properties = thing.getProperties();
String gen = getString(properties.get(PROPERTY_DEV_GEN));
String thingType = getThingType();
gen2 = "2".equals(gen) || ShellyDeviceProfile.isGeneration2(thingType);
gen2 = "2".equals(gen) || "3".equals(gen) || ShellyDeviceProfile.isGeneration2(thingType);
blu = ShellyDeviceProfile.isBluSeries(thingType);
this.api = !blu ? !gen2 ? new Shelly1HttpApi(thingName, this) : new Shelly2ApiRpc(thingName, thingTable, this)
: new ShellyBluApi(thingName, thingTable, this);
Expand Down Expand Up @@ -703,10 +703,6 @@ private boolean isWatchdogExpired() {
return false;
}

private boolean isWatchdogStarted() {
return watchdog > 0;
}

@Override
public void reinitializeThing() {
logger.debug("{}: Re-Initialize Thing", thingName);
Expand Down
Expand Up @@ -588,11 +588,12 @@ public void run() {
timer.schedule(task, delay * 1000);
}

protected Map<String, ShellyManagerInterface> getThingHandlers() {
protected @Nullable Map<String, ShellyManagerInterface> getThingHandlers() {
return handlerFactory.getThingHandlers();
}

protected @Nullable ShellyManagerInterface getThingHandler(String uid) {
return getThingHandlers().get(uid);
Map<String, ShellyManagerInterface> th = getThingHandlers();
return th != null ? th.get(uid) : null;
}
}
Expand Up @@ -7,14 +7,31 @@
<config-description uri="thing-type:shelly:blubattery">
<parameter name="deviceAddress" type="text" required="true">
<label>@text/thing-type.config.shelly.deviceAddress.label</label>
<description>@text/thing-type.config.shelly.deviceAddress.description</description>
<description>
@text/thing-type.config.shelly.deviceAddress.description</description>
</parameter>
<parameter name="lowBattery" type="integer" required="false">
<label>@text/thing-type.config.shelly.battery.lowBattery.label</label>
<description>@text/thing-type.config.shelly.battery.lowBattery.description</description>
<description>
@text/thing-type.config.shelly.battery.lowBattery.description</description>
<default>20</default>
<unitLabel>%</unitLabel>
</parameter>
</config-description>

<config-description uri="thing-type:shelly:blugw">
<parameter name="deviceIp" type="text" required="true">
<label>@text/thing-type.config.shelly.deviceIp.label</label>
<description>@text/thing-type.config.shelly.deviceIp.description</description>
<context>network-address</context>
</parameter>

<parameter name="enableBluGateway" type="boolean" required="false">
<label>@text/thing-type.config.shelly.enableBluGateway.label</label>
<description>
@text/thing-type.config.shelly.enableBluGateway.description</description>
<default>true</default>
</parameter>
</config-description>

</config-description:config-descriptions>
Expand Up @@ -103,9 +103,9 @@ thing-type.shelly.shellypluswdus.description = Shelly Wall Dimmer US Device
thing-type.shelly.shellyplus10v.description = Shelly Plus Dimmer 10V

# Plus Mini Devices
thing-type.shelly.shellyplusmini1.description = Shelly Plus Mini 1 - Single Relay Switch
thing-type.shelly.shellyplusminipm.description = Shelly Plus Mini PM - Power Meter
thing-type.shelly.shellyplusmini1pm.description = Shelly Plus Mini 1PM - Single Relay Switch with Power Meter
thing-type.shelly.shellymini1.description = Shelly Plus Mini 1 - Single Relay Switch
thing-type.shelly.shellyminipm.description = Shelly Plus Mini PM - Power Meter
thing-type.shelly.shellymini1pm.description = Shelly Plus Mini 1PM - Single Relay Switch with Power Meter

# Pro Devices
thing-type.shelly.shellypro1.description = Shelly Pro 1 - Single Relay Switch
Expand All @@ -122,6 +122,7 @@ thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch wit
thing-type.shelly.shellyblubutton.description = Shelly BLU Button 1
thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor
thing-type.shelly.shellyblumotion.description = Shelly BLU Motion Sensor
thing-type.shelly.shellyblugw.description = Shelly BLU Gateway

# Wall Displays
thing-type.shelly.shellywalldisplay.description = Shelly Wall Display with sensors and input/output
Expand All @@ -138,7 +139,7 @@ thing-type.config.shelly.password.description = Password for API access
thing-type.config.shelly.updateInterval.label = Status Interval
thing-type.config.shelly.updateInterval.description = Interval for the device status update
thing-type.config.shelly.enableBluGateway.label = Enable BLU Gateway Support
thing-type.config.shelly.enableBluGateway.description = Enables BLU Gateway support incl- auto-upload of the required script
thing-type.config.shelly.enableBluGateway.description = Enables BLU Gateway support including auto-upload of the required script
thing-type.config.shelly.eventsButton.label = Button Events
thing-type.config.shelly.eventsButton.description = Activates the Button Action URLS
thing-type.config.shelly.eventsPush.label = Push Events
Expand Down
Expand Up @@ -45,4 +45,16 @@
<representation-property>serviceName</representation-property>
<config-description-ref uri="thing-type:shelly:blubattery"/>
</thing-type>

<thing-type id="shellyblugw">
<label>Shelly BLU Gateway</label>
<description>@text/thing-type.shelly.shellyblugw.description</description>
<channel-groups>
<channel-group id="device" typeId="deviceStatus"/>
</channel-groups>

<representation-property>serviceName</representation-property>
<config-description-ref uri="thing-type:shelly:blugw"/>
</thing-type>

</thing:thing-descriptions>

0 comments on commit 5e8f604

Please sign in to comment.