Skip to content

Commit

Permalink
[shelly] Auto-numbering for channel labels & bugfixes (#13066)
Browse files Browse the repository at this point in the history
* - new device types added
- min firmware set to 1.8.2
- unit for gas concentration fixed (ppm)
- Auto numbering on channel labels for groups with multiple instances
(add sequence suffix)
- API and Thing interfaces defined to restrict access to those classes
- fix on TRV boost update via CoAP
- fix for status.temperature and status.uptime, internalTemp channels
- don’t use meter timestamp if not present (RGBW2)
- low battery indicator for sensor devices fixed
- device detection based on model/type improved
- various messages/translations fixed/improved
- README updated (missing thing types added)

Signed-off-by: Markus Michels <markus7017@gmail.com> (github: markus7017)
Signed-off-by: Markus Michels <markus7017@gmail.com>

* missing properties added

Signed-off-by: Markus Michels <markus7017@gmail.com> (github: markus7017)
Signed-off-by: Markus Michels <markus7017@gmail.com>

* minor changes

Signed-off-by: Markus Michels <markus7017@gmail.com> (github: markus7017)
Signed-off-by: Markus Michels <markus7017@gmail.com>

* markdown fixed

Signed-off-by: Markus Michels <markus7017@gmail.com> (github: markus7017)
Signed-off-by: Markus Michels <markus7017@gmail.com>

* review changes applied

Signed-off-by: Markus Michels <markus7017@gmail.com>

* shelly_de.properties restored from main branch

Signed-off-by: Markus Michels <markus7017@gmail.com>
  • Loading branch information
markus7017 authored Jul 19, 2022
1 parent d814640 commit 4f8c172
Show file tree
Hide file tree
Showing 33 changed files with 817 additions and 280 deletions.
41 changes: 39 additions & 2 deletions bundles/org.openhab.binding.shelly/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
| shellyplugs | Shelly Plug-S | SHPLG-S |
| shellyem | Shelly EM with integrated Power Meters | SHEM |
| shellyem3 | Shelly 3EM with 3 integrated Power Meter | SHEM-3 |
| shellyrgbw2 | Shelly RGB Controller | SHRGBW2 |
| shellybulb | Shelly Bulb in Color or White Mode | SHBLB-1 |
| shellyrgbw2-color | Shelly RGBW2 Controller in Color Mode | SHRGBW2 |
| shellyrgbw2-white | Shelly RGBW2 Controller in White Mode | SHRGBW2 |
| shellybulb-color | Shelly Bulb in Color Mode | SHBLB-1 |
| shellybulb-white | Shelly Bulb in White Mode | SHBLB-1 |
| shellybulbduo | Shelly Duo White | SHBDUO-1 |
| shellybulbduo | Shelly Duo White G10 | SHBDUO-1 |
| shellycolorbulb | Shelly Duo Color G10 | SHCB-1 |
Expand All @@ -55,6 +57,7 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
| shellyflood | Shelly Flood Sensor | SHWT-1 |
| shellysmoke | Shelly Smoke Sensor | SHSM-1 |
| shellymotion | Shelly Motion Sensor | SHMOS-01 |
| shellymotion2 | Shelly Motion Sensor 2 | SHMOS-02 |
| shellygas | Shelly Gas Sensor | SHGS-1 |
| shellydw | Shelly Door/Window | SHDW-1 |
| shellydw2 | Shelly Door/Window 2 | SHDW-2 |
Expand Down Expand Up @@ -742,6 +745,23 @@ Using the Thing configuration option `brightnessAutoOn` you could decide if the
`true`: Brightness will be set and device output is powered = light turns on with the new brightness
`false`: Brightness will be set, but output stays unchanged so light will not be switched on when it's currently off.

### Shelly RGBW2 in White Mode (thing-type: shellyrgbw2-color)

|Group |Channel |Type |read-only|Description |
|----------|-------------|---------|---------|-----------------------------------------------------------------------|
|control |power |Switch |r/w |Switch light ON/OFF |
| |input |Switch |yes |State of Input |
| |autoOn |Number |r/w |Sets a timer to turn the device ON after every OFF; in sec |
| |autoOff |Number |r/w |Sets a timer to turn the device OFF after every ON: in sec |
| |timerActive |Switch |yes |ON: An auto-on/off timer is active |
|color | | | |Color settings: only valid in COLOR mode |
| |hsb |HSB |r/w |Represents the color picker (HSBType), control r/g/b, but not white |
|meter |currentWatts |Number |yes |Current power consumption in Watts (all channels) |

Please note that the settings of channel group color are only valid in color mode and vice versa for white mode.
The current firmware doesn't support the timestamp report for the meters.
The binding emulates this by using the system time on every update.

### Shelly RGBW2 in White Mode (thing-type: shellyrgbw2-white)

|Group |Channel |Type |read-only|Description |
Expand Down Expand Up @@ -845,6 +865,23 @@ You have a Motion controlling your light.
You switch off the light and want to leave the room, but the motion sensor immediately switches light back on.
Using 'sensorSleepTime' you could suppress motion events while leaving the room, e.g. for 5sec and the light doesn's switch on.

### Shelly Motion 2 (thing-type: shellymotion2)

|Group |Channel |Type |read-only|Description |
|----------|---------------|---------|---------|---------------------------------------------------------------------|
|sensors |motion |Switch |yes |ON: Motion was detected |
| |motionTimestamp|DateTime |yes |Time when motion started/was detected |
| |lux |Number |yes |Brightness in Lux |
| |illumination |String |yes |Current illumination: dark/twilight/bright |
| |temperature |Number |yes |Temperature measured by the sensor |
| |vibration |Switch |yes |ON: Vibration detected |
| |charger |Switch |yes |ON: USB charging cable is connected external power supply activated. |
| |motionActive |Switch |yes |ON: Motion detection is currently active |
| |sensorSleepTime|Number |no |Specifies the number of sec the sensor should not report events ]
| |lastUpdate |DateTime |yes |Timestamp of the last update (any sensor value changed) |
|battery |batteryLevel |Number |yes |Battery Level in % |
| |lowBattery |Switch |yes |Low battery alert (< 20%) |

### Shelly TRV (thing-type: shellytrv)

Note: You might need to reboot the device to enable the discovery mode for 3 minutes(use the Web UI).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,29 @@ public class ShellyBindingConstants {
public static final String THING_TYPE_SHELLYSENSE_STR = "shellysense";
public static final String THING_TYPE_SHELLYTRV_STR = "shellytrv";
public static final String THING_TYPE_SHELLYMOTION_STR = "shellymotion";
public static final String THING_TYPE_SHELLYMOTION2_STR = "shellymotion2";
public static final String THING_TYPE_SHELLYBUTTON1_STR = "shellybutton1";
public static final String THING_TYPE_SHELLYBUTTON2_STR = "shellybutton2";
public static final String THING_TYPE_SHELLYUNI_STR = "shellyuni";

// Shelly Plus Seriens
public static final String THING_TYPE_SHELLYPLUS1_STR = "shellyplus1";
public static final String THING_TYPE_SHELLYPLUS1PM_STR = "shellyplus1pm";
public static final String THING_TYPE_SHELLYPLUS2PM_RELAY_STR = "shellyplus2pm-relay";
public static final String THING_TYPE_SHELLYPLUS2PM_ROLLER_STR = "shellyplus2pm-roller";
public static final String THING_TYPE_SHELLYPLUSI4_STR = "shellyplusi4";
public static final String THING_TYPE_SHELLYPLUSHT_STR = "shellyplusht";
public static final String THING_TYPE_SHELLYPLUSPLUGUS_STR = "shellyplusplugus";

// Shelly Pro Series
public static final String THING_TYPE_SHELLYPRO1_STR = "shellypro1";
public static final String THING_TYPE_SHELLYPRO1PM_STR = "shellypro1pm";
public static final String THING_TYPE_SHELLYPRO2_RELAY_STR = "shellypro2-relay";
public static final String THING_TYPE_SHELLYPRO2_ROLLER_STR = "shellypro2-roller";
public static final String THING_TYPE_SHELLYPRO2PM_RELAY_STR = "shellypro2pm-relay";
public static final String THING_TYPE_SHELLYPRO2PM_ROLLER_STR = "shellypro2pm-roller";
public static final String THING_TYPE_SHELLYPRO4PM_STR = "shellypro4pm";

public static final String THING_TYPE_SHELLYPROTECTED_STR = "shellydevice";
public static final String THING_TYPE_SHELLYUNKNOWN_STR = "shellyunknown";

Expand Down Expand Up @@ -107,6 +127,24 @@ public class ShellyBindingConstants {
public static final String SHELLYDT_UNI = "SHUNI-1";
public static final String SHELLYDT_TRV = "SHTRV-01";

// Shelly Plus Series
public static final String SHELLYDT_PLUS1 = "SNSW-001X16EU";
public static final String SHELLYDT_PLUS1PM = "SNSW-001P16EU";
public static final String SHELLYDT_PLUS2PM_RELAY = "SNSW-002P16EU-relay";
public static final String SHELLYDT_PLUS2PM_ROLLER = "SNSW-002P16EU-roller";
public static final String SHELLYDT_PLUSPLUGUS = "SNPL-00116US";
public static final String SHELLYDT_PLUSI4 = "SNSN-0024X";
public static final String SHELLYDT_PLUSHT = "SNSN-0013A";

// Shelly Pro Series
public static final String SHELLYDT_PRO1 = "SPSW-001XE16EU";
public static final String SHELLYDT_PRO1PM = "SPSW-001PE16EU";
public static final String SHELLYDT_PRO2_RELAY = "SPSW-002XE16EU-relay";
public static final String SHELLYDT_PRO2_ROLLER = "SPSW-002XE16EU-roller";
public static final String SHELLYDT_PRO2PM_RELAY = "SPSW-002PE16EU-relay";
public static final String SHELLYDT_PRO2PM_ROLLER = "SPSW-002PE16EU-roller";
public static final String SHELLYDT_PRO4PM = "SPSW-004PE16EU";

// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_SHELLY1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1_STR);
public static final ThingTypeUID THING_TYPE_SHELLY1L = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1L_STR);
Expand Down Expand Up @@ -186,6 +224,7 @@ public class ShellyBindingConstants {
public static final String PROPERTY_DEV_NAME = "deviceName";
public static final String PROPERTY_DEV_TYPE = "deviceType";
public static final String PROPERTY_DEV_MODE = "deviceMode";
public static final String PROPERTY_DEV_GEN = "deviceGeneration";
public static final String PROPERTY_HWREV = "deviceHwRev";
public static final String PROPERTY_HWBATCH = "deviceHwBatch";
public static final String PROPERTY_UPDATE_PERIOD = "devUpdatePeriod";
Expand Down Expand Up @@ -340,7 +379,7 @@ public class ShellyBindingConstants {
public static final String CHANNEL_BUTTON_TRIGGER2 = CHANNEL_BUTTON_TRIGGER + "2";

public static final String SERVICE_TYPE = "_http._tcp.local.";
public static final String SHELLY_API_MIN_FWVERSION = "v1.5.7";// v1.5.7+
public static final String SHELLY_API_MIN_FWVERSION = "v1.8.2";
public static final String SHELLY_API_MIN_FWCOIOT = "v1.6";// v1.6.0+
public static final String SHELLY_API_FWCOIOT2 = "v1.8";// CoAP 2 with FW 1.8+
public static final String SHELLY_API_FW_110 = "v1.10"; // FW 1.10 or newer detected, activates some add feature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -29,6 +28,8 @@
import org.openhab.binding.shelly.internal.handler.ShellyManagerInterface;
import org.openhab.binding.shelly.internal.handler.ShellyProtectedHandler;
import org.openhab.binding.shelly.internal.handler.ShellyRelayHandler;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
import org.openhab.binding.shelly.internal.handler.ShellyThingTable;
import org.openhab.binding.shelly.internal.provider.ShellyTranslationProvider;
import org.openhab.binding.shelly.internal.util.ShellyUtils;
import org.openhab.core.io.net.http.HttpClientFactory;
Expand Down Expand Up @@ -63,7 +64,7 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory {
private final ShellyTranslationProvider messages;
private final ShellyCoapServer coapServer;

private final Map<String, ShellyBaseHandler> deviceListeners = new ConcurrentHashMap<>();
private final ShellyThingTable thingTable;
private ShellyBindingConfiguration bindingConfig = new ShellyBindingConfiguration();
private String localIP = "";
private int httpPort = -1;
Expand All @@ -77,8 +78,9 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory {
*/
@Activate
public ShellyHandlerFactory(@Reference NetworkAddressService networkAddressService,
@Reference ShellyTranslationProvider translationProvider, @Reference HttpClientFactory httpClientFactory,
ComponentContext componentContext, Map<String, Object> configProperties) {
@Reference ShellyTranslationProvider translationProvider, @Reference ShellyThingTable thingTable,
@Reference HttpClientFactory httpClientFactory, ComponentContext componentContext,
Map<String, Object> configProperties) {
logger.debug("Activate Shelly HandlerFactory");
super.activate(componentContext);
messages = translationProvider;
Expand All @@ -100,6 +102,7 @@ public ShellyHandlerFactory(@Reference NetworkAddressService networkAddressServi
}
logger.debug("Using OH HTTP port {}", httpPort);

this.thingTable = thingTable;
this.coapServer = new ShellyCoapServer();

// Promote Shelly Manager usage
Expand Down Expand Up @@ -137,8 +140,8 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {

if (handler != null) {
String uid = thing.getUID().getAsString();
deviceListeners.put(uid, handler);
logger.debug("Thing handler for uid {} added, total things = {}", uid, deviceListeners.size());
thingTable.addThing(uid, handler);
logger.debug("Thing handler for uid {} added, total things = {}", uid, thingTable.size());
return handler;
}

Expand All @@ -147,7 +150,11 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
}

public Map<String, ShellyManagerInterface> getThingHandlers() {
return new HashMap<>(deviceListeners);
Map<String, ShellyManagerInterface> table = new HashMap<>();
for (Map.Entry<String, ShellyThingInterface> entry : thingTable.getTable().entrySet()) {
table.put(entry.getKey(), (ShellyManagerInterface) entry.getValue());
}
return table;
}

/**
Expand All @@ -157,7 +164,7 @@ public Map<String, ShellyManagerInterface> getThingHandlers() {
protected synchronized void removeHandler(@NonNull ThingHandler thingHandler) {
if (thingHandler instanceof ShellyBaseHandler) {
String uid = thingHandler.getThing().getUID().getAsString();
deviceListeners.remove(uid);
thingTable.removeThing(uid);
}
}

Expand All @@ -172,8 +179,8 @@ protected synchronized void removeHandler(@NonNull ThingHandler thingHandler) {
public void onEvent(String ipAddress, String deviceName, String componentIndex, String eventType,
Map<String, String> parameters) {
logger.trace("{}: Dispatch event to thing handler", deviceName);
for (Map.Entry<String, ShellyBaseHandler> listener : deviceListeners.entrySet()) {
ShellyBaseHandler thingHandler = listener.getValue();
for (Map.Entry<String, ShellyThingInterface> listener : thingTable.getTable().entrySet()) {
ShellyBaseHandler thingHandler = (ShellyBaseHandler) listener.getValue();
if (thingHandler.onEvent(ipAddress, deviceName, componentIndex, eventType, parameters)) {
// event processed
return;
Expand Down
Loading

0 comments on commit 4f8c172

Please sign in to comment.