| shellyplusht | Shelly Plus HT with temperature + humidity sensor | SNSN-0013A |
| shellyplussmoke | Shelly Plus Smoke sensor | SNSN-0031Z |
| shellypluswdus | Shelly Plus Wall Dimmer US | SNDM-0013US |
-| shellypluswalldisplay| Shelly Plus Wall Display | SAWD-0A1XX10EU1 |
+| shellywalldisplay | Shelly Plus Wall Display | SAWD-0A1XX10EU1 |
+
+### Generation 2 Plus Mini series
+| thing-type | Model | Vendor ID |
+| -------------------- | -------------------------------------------------------- | ---------------------------- |
+| shellymini1 | Shelly Plus 1 Mini with 1x relay | SNSW-001X16EU |
+| shellymini1pm | Shelly Plus 1PM Mini with 1x relay + power meter | SNPM-001PCEU16 |
+| shellyminipm | Shelly Plus PM Mini with 1x power meter | SNSW-001P8EU |
+
### Generation 2 Pro series
### Shelly Plus Wall Dimmer US (thing-type: shellypluswdus)
-|Group | Channel |Type |read-only |Description |
-|-------|-------------|---------|----------|------------------------------------------------------------------------------------|
+|Group | Channel |Type |read-only |Description |
+|-------|-------------|---------|-----------|-----------------------------------------------------------------------------------|
| relay | brightness | Dimmer | r/w | Currently selected brightness. |
| | outputName | String | yes | Logical name of this relay output as configured in the Shelly App |
| | autoOn | Number | r/w | Relay #1: Sets a timer to turn the device ON after every OFF command; in seconds |
| | autoOff | Number | r/w | Relay #1: Sets a timer to turn the device OFF after every ON command; in seconds |
| | timerActive | Switch | yes | Relay #1: ON: An auto-on/off timer is active |
-|
+
+## Shelly Plus Mini Series
+
+### Shelly Plus 1 Mini (thing-type: shellymini1)
+
+| Group | Channel | Type | read-only | Description |
+| ----- | ----------- | ------- | --------- | --------------------------------------------------------------------------------- |
+| relay | output | Switch | r/w | Relay #1: Controls the relay's output channel (on/off) |
+| | outputName | String | yes | Logical name of this relay output as configured in the Shelly App |
+| | input | Switch | yes | ON: Input/Button is powered, see General Notes on Channels |
+| | autoOn | Number | r/w | Relay #1: Sets a timer to turn the device ON after every OFF command; in seconds |
+| | autoOff | Number | r/w | Relay #1: Sets a timer to turn the device OFF after every ON command; in seconds |
+| | timerActive | Switch | yes | Relay #1: ON: An auto-on/off timer is active |
+| | button | Trigger | yes | Event trigger, see section Button Events |
+
+### Shelly Plus 1PM Mini (thing-type: shellymini1pm)
+
+| Group | Channel | Type | read-only | Description |
+| ----- | ------------ | -------- | --------- | --------------------------------------------------------------------------------- |
+| relay | output | Switch | r/w | Relay #1: Controls the relay's output channel (on/off) |
+| | outputName | String | yes | Logical name of this relay output as configured in the Shelly App |
+| | input | Switch | yes | ON: Input/Button is powered, see General Notes on Channels |
+| | autoOn | Number | r/w | Relay #1: Sets a timer to turn the device ON after every OFF command; in seconds |
+| | autoOff | Number | r/w | Relay #1: Sets a timer to turn the device OFF after every ON command; in seconds |
+| | timerActive | Switch | yes | Relay #1: ON: An auto-on/off timer is active |
+| | button | Trigger | yes | Event trigger, see section Button Events |
+| meter | currentWatts | Number | yes | Current power consumption in Watts |
+| | lastPower1 | Number | yes | Energy consumption for a round minute, 1 minute ago |
+| | totalKWH | Number | yes | Total energy consumption in kwh since the device powered up (resets on restart) |
+| | lastUpdate | DateTime | yes | Timestamp of the last measurement |
+
+
+### Shelly Plus PM Mini (thing-type: shellyminipm)
+
+| Group | Channel | Type | read-only | Description |
+| ----- | ------------ | -------- | --------- | --------------------------------------------------------------------------------- |
+| meter | currentWatts | Number | yes | Current power consumption in Watts |
+| | lastPower1 | Number | yes | Energy consumption for a round minute, 1 minute ago |
+| | totalKWH | Number | yes | Total energy consumption in kwh since the device powered up (resets on restart) |
+| | lastUpdate | DateTime | yes | Timestamp of the last measurement |
+
## Shelly Pro Series
THING_TYPE_SHELLYPLUSPLUGS, //
THING_TYPE_SHELLYPLUSPLUGUS, //
THING_TYPE_SHELLYPLUSDIMMERUS, //
+
+ // Shelly Wall Display
THING_TYPE_SHELLYPLUSWALLDISPLAY, //
+ // Shelly Plus Mini
+ THING_TYPE_SHELLYMINI1, //
+ THING_TYPE_SHELLYMINIPM, //
+ THING_TYPE_SHELLYMINI1PM, //
+
// Shelly Pro
THING_TYPE_SHELLYPRO1, //
THING_TYPE_SHELLYPRO1PM, //
THING_TYPE_SHELLYPRO2PM_ROLLER, //
THING_TYPE_SHELLYPRO3, //
THING_TYPE_SHELLYPRO3EM, //
+ THING_TYPE_SHELLYPROEM50, //
THING_TYPE_SHELLYPRO4PM, //
// Shelly BLU
public static final String CHANNEL_EMETER_VOLTAGE = "voltage";
public static final String CHANNEL_EMETER_CURRENT = "current";
public static final String CHANNEL_EMETER_PFACTOR = "powerFactor";
- public static final String CHANNEL_EMETER_RESETTOTAL = "resetTotals";
public static final String CHANNEL_GROUP_SENSOR = "sensors";
public static final String CHANNEL_SENSOR_TEMP = "temperature";
public static final String CHANNEL_DEVST_ACCUWATTS = "accumulatedWatts";
public static final String CHANNEL_DEVST_ACCUTOTAL = "accumulatedWTotal";
public static final String CHANNEL_DEVST_ACCURETURNED = "accumulatedReturned";
+ public static final String CHANNEL_DEVST_RESETTOTAL = "resetTotals";
public static final String CHANNEL_DEVST_CHARGER = "charger";
public static final String CHANNEL_DEVST_UPDATE = "updateAvailable";
public static final String CHANNEL_DEVST_SELFTTEST = "selfTest";
*/
package org.openhab.binding.shelly.internal;
+import static org.openhab.binding.shelly.internal.ShellyBindingConstants.SUPPORTED_THING_TYPES_UIDS;
import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@NonNullByDefault
@Component(service = { ThingHandlerFactory.class, ShellyHandlerFactory.class }, configurationPid = "binding.shelly")
public class ShellyHandlerFactory extends BaseThingHandlerFactory {
- private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = ShellyBindingConstants.SUPPORTED_THING_TYPES_UIDS;
-
private final Logger logger = LoggerFactory.getLogger(ShellyHandlerFactory.class);
private final HttpClient httpClient;
private final ShellyTranslationProvider messages;
public boolean isSmoke = false; // true for Shelly Smoke
public boolean isWall = false; // true: Shelly Wall Display
public boolean is3EM = false; // true for Shelly 3EM and Pro 3EM
+ public boolean isEM50 = false; // true for Shelly Pro EM50
public int minTemp = 0; // Bulb/Duo: Min Light Temp
public int maxTemp = 0; // Bulb/Duo: Max Light Temp
|| thingType.equals(THING_TYPE_SHELLYBLUBUTTON_STR);
isTRV = thingType.equals(THING_TYPE_SHELLYTRV_STR);
isWall = thingType.equals(THING_TYPE_SHELLYPLUSWALLDISPLAY_STR);
- is3EM = thingType.equals(THING_TYPE_SHELLY3EM_STR) || thingType.equals(THING_TYPE_SHELLYPRO3EM_STR);
+ is3EM = thingType.equals(THING_TYPE_SHELLY3EM_STR) || thingType.startsWith(THING_TYPE_SHELLYPRO3EM_STR);
+ isEM50 = thingType.startsWith(THING_TYPE_SHELLYPROEM50_STR);
isSensor = isHT || isFlood || isDW || isSmoke || isGas || isButton || isUNI || isMotion || isSense || isTRV
|| isWall;
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2InputStatus;
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2RelayStatus;
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2RpcBaseMessage;
+import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2StatusEm1;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyBaseHandler;
import org.openhab.binding.shelly.internal.handler.ShellyComponents;
protected @Nullable ArrayList<@Nullable ShellySettingsRelay> fillRelaySettings(ShellyDeviceProfile profile,
Shelly2GetConfigResult dc) {
- if (dc.switch0 == null) {
- return null;
- }
ArrayList<@Nullable ShellySettingsRelay> relays = new ArrayList<>();
addRelaySettings(relays, dc.switch0);
addRelaySettings(relays, dc.switch1);
addRelaySettings(relays, dc.switch2);
addRelaySettings(relays, dc.switch3);
- return relays;
+ addRelaySettings(relays, dc.switch100);
+ return relays.size() > 0 ? relays : null;
}
private void addRelaySettings(ArrayList<@Nullable ShellySettingsRelay> relays,
updated |= updateRelayStatus(status, result.switch1, channelUpdate);
updated |= updateRelayStatus(status, result.switch2, channelUpdate);
updated |= updateRelayStatus(status, result.switch3, channelUpdate);
+ updated |= updateRelayStatus(status, result.switch100, channelUpdate);
+ updated |= updateRelayStatus(status, result.pm10, channelUpdate);
updated |= updateEmStatus(status, result.em0, channelUpdate);
+ updated |= updateEmStatus(status, result.em10, channelUpdate);
+ updated |= updateEmStatus(status, result.em11, channelUpdate);
updated |= updateRollerStatus(status, result.cover0, channelUpdate);
updated |= updateDimmerStatus(status, result.light0, channelUpdate);
if (channelUpdate) {
return false;
}
ShellyDeviceProfile profile = getProfile();
- if (rs.id >= profile.numRelays) {
- throw new IllegalArgumentException("Update for invalid relay index");
+
+ ShellySettingsRelay rstatus;
+ ShellyShortStatusRelay sr;
+ int rIdx = getRelayIdx(profile, rs.id);
+ if (profile.hasRelays) {
+ if (rIdx == -1) {
+ throw new IllegalArgumentException("Update for invalid relay index");
+ }
+ rstatus = status.relays.get(rIdx);
+ sr = relayStatus.relays.get(rIdx);
+ } else {
+ rstatus = new ShellySettingsRelay();
+ sr = new ShellyShortStatusRelay();
+ rIdx = rs.id;
}
- ShellySettingsRelay rstatus = status.relays.get(rs.id);
- ShellyShortStatusRelay sr = relayStatus.relays.get(rs.id);
sr.isValid = rstatus.isValid = true;
sr.name = rstatus.name = status.name;
if (rs.output != null) {
status.temperature = sr.temperature;
}
}
+
if (rs.voltage != null) {
if (status.voltage == null || rs.voltage > status.voltage) {
status.voltage = rs.voltage;
}
ShellySettingsMeter sm = new ShellySettingsMeter();
- ShellySettingsEMeter emeter = status.emeters.get(rs.id);
+ ShellySettingsEMeter emeter = status.emeters != null ? status.emeters.get(rIdx) : new ShellySettingsEMeter();
if (rs.apower != null) {
sm.power = emeter.power = rs.apower;
}
emeter.pf = rs.pf;
}
- // Update internal structures
- status.relays.set(rs.id, rstatus);
- relayStatus.relays.set(rs.id, sr);
- updateMeter(status, rs.id, sm, emeter, channelUpdate);
- return channelUpdate ? ShellyComponents.updateRelay((ShellyBaseHandler) getThing(), status, rs.id) : false;
+ if (profile.hasRelays) {
+ // Update internal structures
+ status.relays.set(rIdx, rstatus);
+ relayStatus.relays.set(rIdx, sr);
+ }
+
+ updateMeter(status, rIdx, sm, emeter, channelUpdate);
+ return channelUpdate && profile.hasRelays
+ ? ShellyComponents.updateRelay((ShellyBaseHandler) getThing(), status, rIdx)
+ : false;
+ }
+
+ private int getRelayIdx(ShellyDeviceProfile profile, @Nullable Integer id) {
+ if (id != null && profile.settings.relays != null) {
+ int idx = 0;
+ for (ShellySettingsRelay relay : profile.settings.relays) {
+ if (relay.isValid && relay.id != null && relay.id.intValue() == id.intValue()) {
+ return idx;
+ }
+ }
+ idx++;
+ }
+ return -1;
}
private void updateMeter(ShellySettingsStatus status, int id, ShellySettingsMeter sm, ShellySettingsEMeter emeter,
}
sm.isValid = sm.power != null || sm.total != null;
emeter.isValid = emeter.current != null || emeter.voltage != null || emeter.power != null;
- emeter.isValid = emeter.current != null || emeter.voltage != null || emeter.power != null;
status.meters.set(id, sm);
status.emeters.set(id, emeter);
relayStatus.meters.set(id, sm);
}
+ private boolean updateEmStatus(ShellySettingsStatus status, @Nullable Shelly2StatusEm1 em, boolean channelUpdate)
+ throws ShellyApiException {
+ if (em == null) {
+ return false;
+ }
+
+ ShellySettingsMeter sm = new ShellySettingsMeter();
+ ShellySettingsEMeter emeter = status.emeters.get(em.id);
+ if (em.actPower != null) {
+ sm.power = emeter.power = em.actPower;
+ }
+ if (em.aptrPower != null) {
+ emeter.totalReturned = em.aptrPower;
+ }
+ if (em.voltage != null) {
+ emeter.voltage = em.voltage;
+ }
+ if (em.current != null) {
+ emeter.current = em.current;
+ }
+ if (em.pf != null) {
+ emeter.pf = em.pf;
+ }
+ // Update internal structures
+ updateMeter(status, em.id, sm, emeter, channelUpdate);
+
+ postAlarms(em.errors);
+ return channelUpdate ? ShellyComponents.updateMeters(getThing(), status) : false;
+ }
+
private boolean updateEmStatus(ShellySettingsStatus status, @Nullable Shelly2DeviceStatusEm em,
boolean channelUpdate) throws ShellyApiException {
if (em == null) {
// Update internal structures
updateMeter(status, 0, sm, emeter, channelUpdate);
- sm = new ShellySettingsMeter();
- emeter = status.emeters.get(1);
- if (em.bActPower != null) {
- sm.power = emeter.power = em.bActPower;
- }
- if (em.bAprtPower != null) {
- emeter.totalReturned = em.bAprtPower;
- }
- if (em.bVoltage != null) {
- emeter.voltage = em.bVoltage;
- }
- if (em.bCurrent != null) {
- emeter.current = em.bCurrent;
- }
- if (em.bPF != null) {
- emeter.pf = em.bPF;
+ if (status.emeters.size() > 1) {
+ sm = new ShellySettingsMeter();
+ emeter = status.emeters.get(1);
+ sm.isValid = emeter.isValid = true;
+ if (em.bActPower != null) {
+ sm.power = emeter.power = em.bActPower;
+ }
+ if (em.bAprtPower != null) {
+ emeter.totalReturned = em.bAprtPower;
+ }
+ if (em.bVoltage != null) {
+ emeter.voltage = em.bVoltage;
+ }
+ if (em.bCurrent != null) {
+ emeter.current = em.bCurrent;
+ }
+ if (em.bPF != null) {
+ emeter.pf = em.bPF;
+ }
+ // Update internal structures
+ updateMeter(status, 1, sm, emeter, channelUpdate);
}
- // Update internal structures
- updateMeter(status, 1, sm, emeter, channelUpdate);
- sm = new ShellySettingsMeter();
- emeter = status.emeters.get(2);
- sm.isValid = emeter.isValid = true;
- if (em.cActPower != null) {
- sm.power = emeter.power = em.cActPower;
- }
- if (em.cAprtPower != null) {
- emeter.totalReturned = em.cAprtPower;
- }
- if (em.cVoltage != null) {
- emeter.voltage = em.cVoltage;
- }
- if (em.cCurrent != null) {
- emeter.current = em.cCurrent;
- }
- if (em.cPF != null) {
- emeter.pf = em.cPF;
+ if (status.emeters.size() > 2) {
+ sm = new ShellySettingsMeter();
+ emeter = status.emeters.get(2);
+ sm.isValid = emeter.isValid = true;
+ if (em.cActPower != null) {
+ sm.power = emeter.power = em.cActPower;
+ }
+ if (em.cAprtPower != null) {
+ emeter.totalReturned = em.cAprtPower;
+ }
+ if (em.cVoltage != null) {
+ emeter.voltage = em.cVoltage;
+ }
+ if (em.cCurrent != null) {
+ emeter.current = em.cCurrent;
+ }
+ if (em.cPF != null) {
+ emeter.pf = em.cPF;
+ }
+ // Update internal structures
+ updateMeter(status, 2, sm, emeter, channelUpdate);
}
- // Update internal structures
- updateMeter(status, 2, sm, emeter, channelUpdate);
return channelUpdate ? ShellyComponents.updateMeters(getThing(), status) : false;
}
}
}
if (cs.voltage != null) {
+ if (status.voltage == null || cs.voltage > status.voltage) {
+ status.voltage = cs.voltage;
+ }
emeter.voltage = cs.voltage;
}
if (cs.current != null) {
public static final String SHELLYRPC_METHOD_WSGETCONFIG = "WS.GetConfig";
public static final String SHELLYRPC_METHOD_WSSETCONFIG = "WS.SetConfig";
public static final String SHELLYRPC_METHOD_EMDATARESET = "EMData.DeleteAllData";
+ public static final String SHELLYRPC_METHOD_EM1DATARESET = "EM1Data.DeleteAllData";
public static final String SHELLYRPC_METHOD_SMOKE_SETCONFIG = "Smoke.SetConfig";
public static final String SHELLYRPC_METHOD_SMOKE_MUTE = "Smoke.Mute";
public static final String SHELLYRPC_METHOD_SCRIPT_LIST = "Script.List";
public Boolean monitorPhaseSequence;
}
+ public class Shelly2DevConfigPm1 {
+ public Integer id;
+ public String name;
+ }
+
public class Shelly2DevConfigCover {
public class Shelly2DeviceConfigCoverMotor {
@SerializedName("idle_power_thr")
public Shelly2DevConfigSwitch switch2;
@SerializedName("switch:3")
public Shelly2DevConfigSwitch switch3;
+ @SerializedName("switch:100")
+ public Shelly2DevConfigSwitch switch100; // Pro 3EM Add-On
@SerializedName("em:0")
public Shelly2DevConfigEm em0;
+ @SerializedName("em1:0")
+ public Shelly2DevConfigEm em10;
+ @SerializedName("em1:1")
+ public Shelly2DevConfigEm em11;
+ @SerializedName("pm1:0")
+ public Shelly2DevConfigPm1 pm10;
@SerializedName("cover:0")
public Shelly2DevConfigCover cover0;
public Shelly2RelayStatus switch2;
@SerializedName("switch:3")
public Shelly2RelayStatus switch3;
+ @SerializedName("switch:100")
+ public Shelly2RelayStatus switch100; // Pro 3EM Add-On
+
+ @SerializedName("pm1:0")
+ public Shelly2RelayStatus pm10;
@SerializedName("em:0")
- Shelly2DeviceStatusEm em0;
+ public Shelly2DeviceStatusEm em0;
@SerializedName("emdata:0")
- Shelly2DeviceStatusEmData emdata0;
+ public Shelly2DeviceStatusEmData emdata0;
+ @SerializedName("em1:0")
+ public Shelly2StatusEm1 em10;
+ @SerializedName("em1:1")
+ public Shelly2StatusEm1 em11;
+ @SerializedName("em1data:0")
+ public Shelly2DeviceStatusEmData em1data0;
@SerializedName("cover:0")
public Shelly2CoverStatus cover0;
public String[] errors;
}
+ public static class Shelly2Pm1Status {
+ public Integer id;
+ public String source;
+ public Boolean output;
+ @SerializedName("timer_started_at")
+ public Double timerStartetAt;
+ @SerializedName("timer_duration")
+ public Integer timerDuration;
+ public Double apower;
+ public Double voltage;
+ public Double current;
+ public Double pf;
+ public Shelly2Energy aenergy;
+ public Shelly2DeviceStatusTemp temperature;
+ public String[] errors;
+ }
+
+ public static class Shelly2StatusEm1 {
+ public Integer id;
+ public Double current;
+ public Double voltage;
+ @SerializedName("act_power")
+ public Double actPower;
+ @SerializedName("aprt_power")
+ public Double aptrPower;
+ public Double pf;
+ public String calibration;
+ public ArrayList<String> errors;
+ }
+
public static class Shelly2DeviceStatusTemp {
public Double tC;
public Double tF;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.*;
+import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.THING_TYPE_SHELLYPRO2_RELAY_STR;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.io.BufferedReader;
}
}
- if (dc.em0 != null) {
+ // handle special cases, because there is no indicator for a meter in GetConfig
+ // Pro 3EM has 3 meters
+ // Pro 2 has 2 relays, but no meters
+ // Mini PM has 1 meter, but no relay
+ if (thingType.equals(THING_TYPE_SHELLYPRO2_RELAY_STR)) {
+ profile.numMeters = 0;
+ } else if (dc.pm10 != null) {
+ profile.numMeters = 1;
+ } else if (dc.em0 != null) {
profile.numMeters = 3;
+ } else if (dc.em10 != null) {
+ profile.numMeters = 2;
}
if (profile.numMeters > 0) {
toQuantityType(getDouble(status.tmp.tC), DIGITS_NONE, SIUnits.CELSIUS));
}
- if (status.meters.size() > 0) {
- boolean validMeter = false;
- for (ShellySettingsMeter meter : status.meters) {
- validMeter |= meter.isValid;
- }
- if (!validMeter) {
- profile.numMeters = 0;
- }
- }
profile.status = status;
if (updated) {
getThing().restartWatchdog();
return relayStatus;
}
+ @SuppressWarnings("null")
@Override
public void setRelayTurn(int id, String turnMode) throws ShellyApiException {
+ ShellyDeviceProfile profile = getProfile();
+ int rIdx = id;
+ if (profile.settings.relays != null) {
+ Integer rid = profile.settings.relays.get(id).id;
+ if (rid != null) {
+ rIdx = rid;
+ }
+ }
Shelly2RpcRequestParams params = new Shelly2RpcRequestParams();
- params.id = id;
+ params.id = rIdx;
params.on = SHELLY_API_ON.equals(turnMode);
apiRequest(SHELLYRPC_METHOD_SWITCH_SET, params, String.class);
}
@Override
public void resetMeterTotal(int id) throws ShellyApiException {
- apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_EMDATARESET).withId(id));
+ apiRequest(new Shelly2RpcRequest()
+ .withMethod(getProfile().is3EM ? SHELLYRPC_METHOD_EMDATARESET : SHELLYRPC_METHOD_EM1DATARESET)
+ .withId(id));
}
@Override
public static final String SHELLYDT_PRO2PM_ROLLER_3 = "SPSW-202PE16EU-roller";
public static final String SHELLYDT_PRO3 = "SPSW-003XE16EU";
public static final String SHELLYDT_PRO3EM = "SPEM-003CEBEU";
+ public static final String SHELLYDT_PROEM50 = "SPEM-002CEBEU50";
public static final String SHELLYDT_PRO4PM = "SPSW-004PE16EU";
public static final String SHELLYDT_PRO4PM_2 = "SPSW-104PE16EU";
+ // Shelly Plus Mini Series
+ // Shelly Mini Series
+ public static final String SHELLYDT_MINI1 = "SNSW-001X8EU";
+ public static final String SHELLYDT_MINIPM = "SNPM-001PCEU16";
+ public static final String SHELLYDT_MINI1PM = "SNSW-001P8EU";
+
// Shelly BLU Series
public static final String SHELLYDT_BLUBUTTON = "SBBT";
public static final String SHELLYDT_BLUDW = "SBDW";
public static final String THING_TYPE_SHELLYPLUSPLUGS_STR = "shellyplusplug";
public static final String THING_TYPE_SHELLYPLUSPLUGUS_STR = "shellyplusplugus";
public static final String THING_TYPE_SHELLYPLUSDIMMERUS_STR = "shellypluswdus";
+
+ // Shelly Wall Display
public static final String THING_TYPE_SHELLYPLUSWALLDISPLAY_STR = "shellywalldisplay";
+ // Shelly Plus Mini Series
+ public static final String THING_TYPE_SHELLYMINI1_STR = "shelly1mini";
+ public static final String THING_TYPE_SHELLYMINIPM_STR = "shellypmmini";
+ public static final String THING_TYPE_SHELLYMINI1PM_STR = "shelly1pmmini";
+
// 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_SHELLYPRO2PM_ROLLER_STR = "shellypro2pm-roller";
public static final String THING_TYPE_SHELLYPRO3_STR = "shellypro3";
public static final String THING_TYPE_SHELLYPRO3EM_STR = "shellypro3em";
+ public static final String THING_TYPE_SHELLYPROEM50_STR = "shellyproem50";
public static final String THING_TYPE_SHELLYPRO4PM_STR = "shellypro4pm";
// Shelly BLU Series
public static final ThingTypeUID THING_TYPE_SHELLYPLUSWALLDISPLAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUSWALLDISPLAY_STR);
+ // Shelly Plus Mini Series
+ public static final ThingTypeUID THING_TYPE_SHELLYMINI1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYMINI1_STR);
+ public static final ThingTypeUID THING_TYPE_SHELLYMINIPM = new ThingTypeUID(BINDING_ID,
+ THING_TYPE_SHELLYMINIPM_STR);
+ public static final ThingTypeUID THING_TYPE_SHELLYMINI1PM = new ThingTypeUID(BINDING_ID,
+ THING_TYPE_SHELLYMINI1PM_STR);
+
// Shelly Pro
public static final ThingTypeUID THING_TYPE_SHELLYPRO1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPRO1_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO1PM = new ThingTypeUID(BINDING_ID,
public static final ThingTypeUID THING_TYPE_SHELLYPRO3 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPRO3_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO3EM = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO3EM_STR);
+ public static final ThingTypeUID THING_TYPE_SHELLYPROEM50 = new ThingTypeUID(BINDING_ID,
+ THING_TYPE_SHELLYPROEM50_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO4PM = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO4PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUSSMOKE, THING_TYPE_SHELLYPLUSSMOKE_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUSDIMMERUS, THING_TYPE_SHELLYPLUSDIMMERUS_STR);
+ // Plus Mini Series
+ 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);
+
// Pro Series
THING_TYPE_MAPPING.put(SHELLYDT_PRO1, THING_TYPE_SHELLYPRO1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO1_2, THING_TYPE_SHELLYPRO1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2PM_ROLLER_2, THING_TYPE_SHELLYPRO2PM_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2PM_ROLLER_3, THING_TYPE_SHELLYPRO2PM_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO3, THING_TYPE_SHELLYPRO3_STR);
+ THING_TYPE_MAPPING.put(SHELLYDT_PROEM50, THING_TYPE_SHELLYPROEM50_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO3EM, THING_TYPE_SHELLYPRO3EM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO4PM, THING_TYPE_SHELLYPRO4PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO4PM_2, THING_TYPE_SHELLYPRO4PM_STR);
- // Blu Series
+ // BLU Series
THING_TYPE_MAPPING.put(SHELLYDT_BLUBUTTON, THING_TYPE_SHELLYBLUBUTTON_STR);
THING_TYPE_MAPPING.put(SHELLYDT_BLUDW, THING_TYPE_SHELLYBLUDW_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPLUSDIMMERUS_STR, THING_TYPE_SHELLYPLUSDIMMERUS_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPLUSWALLDISPLAY_STR, THING_TYPE_SHELLYPLUSWALLDISPLAY_STR);
+ THING_TYPE_MAPPING.put(THING_TYPE_SHELLYMINI1_STR, THING_TYPE_SHELLYMINI1_STR);
+ THING_TYPE_MAPPING.put(THING_TYPE_SHELLYMINIPM_STR, THING_TYPE_SHELLYMINIPM_STR);
+ THING_TYPE_MAPPING.put(THING_TYPE_SHELLYMINI1PM_STR, THING_TYPE_SHELLYMINI1PM_STR);
+
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO1_STR, THING_TYPE_SHELLYPRO1_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO1PM_STR, THING_TYPE_SHELLYPRO1PM_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO2PM_RELAY_STR, THING_TYPE_SHELLYPRO2PM_RELAY_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO2PM_ROLLER_STR, THING_TYPE_SHELLYPRO2PM_ROLLER_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO2_RELAY_STR, THING_TYPE_SHELLYPRO2_RELAY_STR);
+ THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPROEM50_STR, THING_TYPE_SHELLYPROEM50_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO3EM_STR, THING_TYPE_SHELLYPRO3EM_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO3_STR, THING_TYPE_SHELLYPRO3_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO4PM_STR, THING_TYPE_SHELLYPRO4PM_STR);
Integer rssi = getInteger(status.wifiSta.rssi);
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_RSSI, mapSignalStrength(rssi));
- if (status.tmp != null && !thingHandler.getProfile().isSensor && status.tmp.tC != SHELLY_API_INVTEMP) {
+ if (status.tmp != null && getBool(status.tmp.isValid) && !thingHandler.getProfile().isSensor
+ && status.tmp.tC != SHELLY_API_INVTEMP) {
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ITEMP,
toQuantityType(getDouble(status.tmp.tC), DIGITS_NONE, SIUnits.CELSIUS));
} else if (status.temperature != null && status.temperature != SHELLY_API_INVTEMP) {
logger.debug("{}: Set Auto-OFF timer to {}", thingName, command);
api.setAutoTimer(rIndex, SHELLY_TIMER_AUTOOFF, getNumber(command).doubleValue());
break;
- case CHANNEL_EMETER_RESETTOTAL:
+ case CHANNEL_DEVST_RESETTOTAL:
logger.debug("{}: Reset Meter Totals", thingName);
- int mIndex = Integer.parseInt(substringAfter(groupName, CHANNEL_GROUP_METER)) - 1;
- api.resetMeterTotal(mIndex);
- updateChannel(groupName, CHANNEL_EMETER_RESETTOTAL, OnOffType.OFF);
+ api.resetMeterTotal(0); // currently there is only 1 emdata component
+ updateChannel(groupName, CHANNEL_DEVST_RESETTOTAL, OnOffType.OFF);
break;
}
return true;
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS, "meterAccuWatts", ITEMT_POWER))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL, "meterAccuTotal", ITEMT_ENERGY))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED, "meterAccuReturned", ITEMT_ENERGY))
+ .add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_RESETTOTAL, "meterResetTotals", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_VOLTAGE, "supplyVoltage", ITEMT_VOLT))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_CHARGER, "charger", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_LED_STATUS_DISABLE, "ledStatusDisable", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_VOLTAGE, "meterVoltage", ITEMT_VOLT))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_CURRENT, "meterCurrent", ITEMT_AMP))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_PFACTOR, "meterPowerFactor", ITEMT_NUMBER))
- .add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_RESETTOTAL, "meterResetTotals", ITEMT_SWITCH))
// Sensors
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TEMP, "sensorTemp", ITEMT_TEMP))
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS);
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL);
addChannel(thing, add, accuChannel && (status.emeters != null), CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED);
+ addChannel(thing, add, profile.is3EM || profile.isEM50, CHGR_DEVST, CHANNEL_DEVST_RESETTOTAL); // 3EM
addChannel(thing, add, status.voltage != null || profile.settings.supplyVoltage != null, CHGR_DEVST,
CHANNEL_DEVST_VOLTAGE);
addChannel(thing, add,
addChannel(thing, newChannels, emeter.voltage != null, group, CHANNEL_EMETER_VOLTAGE);
addChannel(thing, newChannels, emeter.current != null, group, CHANNEL_EMETER_CURRENT);
addChannel(thing, newChannels, emeter.pf != null, group, CHANNEL_EMETER_PFACTOR); // EM has no PF. but power
- addChannel(thing, newChannels, profile.is3EM, group, CHANNEL_EMETER_RESETTOTAL); // 3EM
addChannel(thing, newChannels, true, group, CHANNEL_LAST_UPDATE);
return newChannels;
}
<type>binding</type>
<name>@text/addon.shelly.name</name>
<description>@text/addon.shelly.description</description>
+ <connection>local</connection>
<config-description>
<parameter name="defaultUserId" type="text">
thing-type.shelly.shellyplusi4dc.description = Shelly Plus i4DC - 4xDC Input Device
thing-type.shelly.shellyplusht.description = Shelly Plus HT - Humidity and Temperature sensor with display
thing-type.shelly.shellyplussmoke.description = Shelly Plus Smoke - Smoke Detector with Alarm
-thing-type.shelly.shellyplussmoke.description = Shelly Plus Smoke - Smoke Detector with Alarm
thing-type.shelly.shellypluswdus.description = Shelly Wall Dimmer US Device
# Wall displays
thing-type.shelly.shellywalldisplay.description = Shelly Plus Wall Display with sensors and input/output
+# 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
+
# Pro Devices
thing-type.shelly.shellypro1.description = Shelly Pro 1 - Single Relay Switch
thing-type.shelly.shellypro1pm.description = Shelly Pro 1PM - Single Relay Switch with Power Meter
thing-type.shelly.shellypro2pm-roller.description = Shelly Pro 2PM - Roller Control with Power Meter
thing-type.shelly.shellypro3.description = Shelly Pro 3 - 3xRelay Switch
thing-type.shelly.shellypro3em.description = Shelly Pro 3EM - 3xPower Meter
+thing-type.shelly.shellyproem50.description = Shelly Pro EM-50 - 3xPower Meter + 1xOutput
thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch with Power Meter
# BLU devices
thing-type.shelly.shellypblubutton.description = Shelly BLU Button
thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor
+ # Wall Displays
+ thing-type.shelly.shellywalldisplay.description = Shelly Wall Display with sensors and input/output
+
# thing config - shellydevice
thing-type.config.shelly.deviceIp.label = IP Address
thing-type.config.shelly.deviceIp.description = IP Address of the Shelly device
channel-group-type.shelly.iXChannel2.label = Input 2
channel-group-type.shelly.iXChannel3.label = Input 3
channel-group-type.shelly.iXChannel4.label = Input 4
+channel-group-type.shelly.iXChannel.label = Input
channel-group-type.shelly.iXChannel.description = Input Status
channel-group-type.shelly.rollerControl.label = Roller Control
channel-group-type.shelly.rollerControl.description = Controlling the roller mode
<description>@text/thing-type.shelly.shellyix3.description</description>
<channel-groups>
<channel-group id="status1" typeId="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel1.label</label>
+ <label>@text/channel-group-type.shelly.iXChannel1.label</label>
</channel-group>
<channel-group id="status2" typeId="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel2.label</label>
+ <label>@text/channel-group-type.shelly.iXChannel2.label</label>
</channel-group>
<channel-group id="status3" typeId="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel3.label</label>
+ <label>@text/channel-group-type.shelly.iXChannel3.label</label>
</channel-group>
<channel-group id="device" typeId="deviceStatus"/>
</channel-groups>
</channel-group-type>
<channel-group-type id="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel.label</label>
- <description>@text/channel-group-type.shelly.ixChannel.description</description>
+ <label>@text/channel-group-type.shelly.iXChannel.label</label>
+ <description>@text/channel-group-type.shelly.iXChannel.description</description>
</channel-group-type>
<channel-group-type id="rollerControl">
<description>@text/thing-type.shelly.shellyplusi4.description</description>
<channel-groups>
<channel-group id="status1" typeId="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel1.label</label>
+ <label>@text/channel-group-type.shelly.iXChannel1.label</label>
</channel-group>
<channel-group id="status2" typeId="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel2.label</label>
+ <label>@text/channel-group-type.shelly.iXChannel2.label</label>
</channel-group>
<channel-group id="status3" typeId="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel3.label</label>
+ <label>@text/channel-group-type.shelly.iXChannel3.label</label>
</channel-group>
<channel-group id="status4" typeId="ixChannel">
- <label>@text/channel-group-type.shelly.ixChannel4.label</label>
+ <label>@text/channel-group-type.shelly.iXChannel4.label</label>
</channel-group>
<channel-group id="device" typeId="deviceStatus"/>
</channel-groups>
<config-description-ref uri="thing-type:shelly:relay-gen2"/>
</thing-type>
+ <thing-type id="shelly1mini">
+ <label>ShellyPlus 1 Mini</label>
+ <description>@text/thing-type.shelly.shelly1mini.description</description>
+ <channel-groups>
+ <channel-group id="relay" typeId="relayChannel"/>
+ <channel-group id="device" typeId="deviceStatus"/>
+ </channel-groups>
+
+ <representation-property>serviceName</representation-property>
+ <config-description-ref uri="thing-type:shelly:relay-gen2"/>
+ </thing-type>
+
+
+ <thing-type id="shellypmmini">
+ <label>ShellyPlus PM Mini</label>
+ <description>@text/thing-type.shelly.shellypmmini.description</description>
+ <channel-groups>
+ <channel-group id="meter" typeId="meter"/>
+ <channel-group id="device" typeId="deviceStatus"/>
+ </channel-groups>
+
+ <representation-property>serviceName</representation-property>
+ <config-description-ref uri="thing-type:shelly:relay-gen2"/>
+ </thing-type>
+
+ <thing-type id="shelly1pmmini">
+ <label>ShellyPlus 1PM Mini</label>
+ <description>@text/thing-type.shelly.shelly1pmmini.description</description>
+ <channel-groups>
+ <channel-group id="relay" typeId="relayChannel"/>
+ <channel-group id="meter" typeId="meter"/>
+ <channel-group id="device" typeId="deviceStatus"/>
+ </channel-groups>
+
+ <representation-property>serviceName</representation-property>
+ <config-description-ref uri="thing-type:shelly:relay-gen2"/>
+ </thing-type>
+
<thing-type id="shellypro1">
<label>ShellyPro 1</label>
<config-description-ref uri="thing-type:shelly:relay"/>
</thing-type>
+ <thing-type id="shellyproem50">
+ <label>Shelly Pro EM-50</label>
+ <description>@text/thing-type.shelly.shellyproem50.description</description>
+ <channel-groups>
+ <channel-group id="meter1" typeId="meter">
+ <label>@text/channel-group-type.shelly.meter1.label</label>
+ </channel-group>
+ <channel-group id="meter2" typeId="meter">
+ <label>@text/channel-group-type.shelly.meter2.label</label>
+ </channel-group>
+ <channel-group id="relay" typeId="relayChannel"/>
+ <channel-group id="device" typeId="deviceStatus"/>
+ </channel-groups>
+
+ <representation-property>serviceName</representation-property>
+ <config-description-ref uri="thing-type:shelly:relay"/>
+ </thing-type>
+
<thing-type id="shellypro4pm">
<label>ShellyPro 4PM</label>
<description>@text/thing-type.shelly.shellypro4pm.description</description>