[shelly] Add support for Shelly Plus Mini series, Pro EM-50 and various bug fixes (#15205)

* Shelly BLU support, various fixes
* Shelly Dimmer US added
* Reference to org.eclipse.jetty.websocket updated to 9.4.50.v20221201
* Support for Shelly Wall Display added
* Fixed #15052: channel totalKWH and totalRetruned: correct value is kw/h
(API value needs to be converted from Watt/Min to kw/h)
* Regular power meter returns Watt/Min, the EM/3EM meter returns W/h; this
needs to be handled differently
* Gen2 power meter returns Watt, which needs to be converted to W/h
(and then gets converted to kw&/h for the channel update)
* bug fixes around channel creation, some xml channel declarations fixed
* Support for 1Mini, 1PM Mini and PM Mini added
* Avoid NPE for devices having relay(s), but no meter (like Pro 2); README
updated
* Shelly Pro 3EM-50 added; fixes #15151, #15152 and more
* fix #15218 (only 1 device#resetTotals channel)
* Fix Pro EM50 (it's not a 3EM-50): thing type name is now shellyproem50,
use EM1DataDeleteAllData method rather then EMDataDeleteAllData
* <connection>local</connection> added to addon.xml
* channel group names for i4 fixed, Plus-Roller now has voltage

Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
Markus Michels 2023-07-14 21:59:45 +02:00 committed by GitHub
parent b9bd454b8d
commit bfbbf3504f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 387 additions and 93 deletions

View File

@ -91,7 +91,15 @@ The binding provides the same feature set across all devices as good as possible
| shellyplusht | Shelly Plus HT with temperature + humidity sensor | SNSN-0013A | | shellyplusht | Shelly Plus HT with temperature + humidity sensor | SNSN-0013A |
| shellyplussmoke | Shelly Plus Smoke sensor | SNSN-0031Z | | shellyplussmoke | Shelly Plus Smoke sensor | SNSN-0031Z |
| shellypluswdus | Shelly Plus Wall Dimmer US | SNDM-0013US | | 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 ### Generation 2 Pro series
@ -1207,14 +1215,54 @@ Channels lastEvent and eventCount are only available if input type is set to mom
### Shelly Plus Wall Dimmer US (thing-type: shellypluswdus) ### 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. | | relay | brightness | Dimmer | r/w | Currently selected brightness. |
| | outputName | String | yes | Logical name of this relay output as configured in the Shelly App | | | 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 | | | 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 | | | 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 | | | 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 ## Shelly Pro Series

View File

@ -80,8 +80,15 @@ public class ShellyBindingConstants {
THING_TYPE_SHELLYPLUSPLUGS, // THING_TYPE_SHELLYPLUSPLUGS, //
THING_TYPE_SHELLYPLUSPLUGUS, // THING_TYPE_SHELLYPLUSPLUGUS, //
THING_TYPE_SHELLYPLUSDIMMERUS, // THING_TYPE_SHELLYPLUSDIMMERUS, //
// Shelly Wall Display
THING_TYPE_SHELLYPLUSWALLDISPLAY, // THING_TYPE_SHELLYPLUSWALLDISPLAY, //
// Shelly Plus Mini
THING_TYPE_SHELLYMINI1, //
THING_TYPE_SHELLYMINIPM, //
THING_TYPE_SHELLYMINI1PM, //
// Shelly Pro // Shelly Pro
THING_TYPE_SHELLYPRO1, // THING_TYPE_SHELLYPRO1, //
THING_TYPE_SHELLYPRO1PM, // THING_TYPE_SHELLYPRO1PM, //
@ -90,6 +97,7 @@ public class ShellyBindingConstants {
THING_TYPE_SHELLYPRO2PM_ROLLER, // THING_TYPE_SHELLYPRO2PM_ROLLER, //
THING_TYPE_SHELLYPRO3, // THING_TYPE_SHELLYPRO3, //
THING_TYPE_SHELLYPRO3EM, // THING_TYPE_SHELLYPRO3EM, //
THING_TYPE_SHELLYPROEM50, //
THING_TYPE_SHELLYPRO4PM, // THING_TYPE_SHELLYPRO4PM, //
// Shelly BLU // Shelly BLU
@ -165,7 +173,6 @@ public class ShellyBindingConstants {
public static final String CHANNEL_EMETER_VOLTAGE = "voltage"; public static final String CHANNEL_EMETER_VOLTAGE = "voltage";
public static final String CHANNEL_EMETER_CURRENT = "current"; public static final String CHANNEL_EMETER_CURRENT = "current";
public static final String CHANNEL_EMETER_PFACTOR = "powerFactor"; 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_GROUP_SENSOR = "sensors";
public static final String CHANNEL_SENSOR_TEMP = "temperature"; public static final String CHANNEL_SENSOR_TEMP = "temperature";
@ -253,6 +260,7 @@ public class ShellyBindingConstants {
public static final String CHANNEL_DEVST_ACCUWATTS = "accumulatedWatts"; public static final String CHANNEL_DEVST_ACCUWATTS = "accumulatedWatts";
public static final String CHANNEL_DEVST_ACCUTOTAL = "accumulatedWTotal"; public static final String CHANNEL_DEVST_ACCUTOTAL = "accumulatedWTotal";
public static final String CHANNEL_DEVST_ACCURETURNED = "accumulatedReturned"; 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_CHARGER = "charger";
public static final String CHANNEL_DEVST_UPDATE = "updateAvailable"; public static final String CHANNEL_DEVST_UPDATE = "updateAvailable";
public static final String CHANNEL_DEVST_SELFTTEST = "selfTest"; public static final String CHANNEL_DEVST_SELFTTEST = "selfTest";

View File

@ -12,11 +12,11 @@
*/ */
package org.openhab.binding.shelly.internal; 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 static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -58,8 +58,6 @@ import io.reactivex.annotations.NonNull;
@NonNullByDefault @NonNullByDefault
@Component(service = { ThingHandlerFactory.class, ShellyHandlerFactory.class }, configurationPid = "binding.shelly") @Component(service = { ThingHandlerFactory.class, ShellyHandlerFactory.class }, configurationPid = "binding.shelly")
public class ShellyHandlerFactory extends BaseThingHandlerFactory { 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 Logger logger = LoggerFactory.getLogger(ShellyHandlerFactory.class);
private final HttpClient httpClient; private final HttpClient httpClient;
private final ShellyTranslationProvider messages; private final ShellyTranslationProvider messages;

View File

@ -104,6 +104,7 @@ public class ShellyDeviceProfile {
public boolean isSmoke = false; // true for Shelly Smoke public boolean isSmoke = false; // true for Shelly Smoke
public boolean isWall = false; // true: Shelly Wall Display public boolean isWall = false; // true: Shelly Wall Display
public boolean is3EM = false; // true for Shelly 3EM and Pro 3EM 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 minTemp = 0; // Bulb/Duo: Min Light Temp
public int maxTemp = 0; // Bulb/Duo: Max Light Temp public int maxTemp = 0; // Bulb/Duo: Max Light Temp
@ -222,7 +223,8 @@ public class ShellyDeviceProfile {
|| thingType.equals(THING_TYPE_SHELLYBLUBUTTON_STR); || thingType.equals(THING_TYPE_SHELLYBLUBUTTON_STR);
isTRV = thingType.equals(THING_TYPE_SHELLYTRV_STR); isTRV = thingType.equals(THING_TYPE_SHELLYTRV_STR);
isWall = thingType.equals(THING_TYPE_SHELLYPLUSWALLDISPLAY_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 isSensor = isHT || isFlood || isDW || isSmoke || isGas || isButton || isUNI || isMotion || isSense || isTRV
|| isWall; || isWall;

View File

@ -70,6 +70,7 @@ import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceS
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2InputStatus; 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.Shelly2RelayStatus;
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2RpcBaseMessage; 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.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyBaseHandler; import org.openhab.binding.shelly.internal.handler.ShellyBaseHandler;
import org.openhab.binding.shelly.internal.handler.ShellyComponents; import org.openhab.binding.shelly.internal.handler.ShellyComponents;
@ -151,15 +152,13 @@ public class Shelly2ApiClient extends ShellyHttpClient {
protected @Nullable ArrayList<@Nullable ShellySettingsRelay> fillRelaySettings(ShellyDeviceProfile profile, protected @Nullable ArrayList<@Nullable ShellySettingsRelay> fillRelaySettings(ShellyDeviceProfile profile,
Shelly2GetConfigResult dc) { Shelly2GetConfigResult dc) {
if (dc.switch0 == null) {
return null;
}
ArrayList<@Nullable ShellySettingsRelay> relays = new ArrayList<>(); ArrayList<@Nullable ShellySettingsRelay> relays = new ArrayList<>();
addRelaySettings(relays, dc.switch0); addRelaySettings(relays, dc.switch0);
addRelaySettings(relays, dc.switch1); addRelaySettings(relays, dc.switch1);
addRelaySettings(relays, dc.switch2); addRelaySettings(relays, dc.switch2);
addRelaySettings(relays, dc.switch3); addRelaySettings(relays, dc.switch3);
return relays; addRelaySettings(relays, dc.switch100);
return relays.size() > 0 ? relays : null;
} }
private void addRelaySettings(ArrayList<@Nullable ShellySettingsRelay> relays, private void addRelaySettings(ArrayList<@Nullable ShellySettingsRelay> relays,
@ -196,7 +195,11 @@ public class Shelly2ApiClient extends ShellyHttpClient {
updated |= updateRelayStatus(status, result.switch1, channelUpdate); updated |= updateRelayStatus(status, result.switch1, channelUpdate);
updated |= updateRelayStatus(status, result.switch2, channelUpdate); updated |= updateRelayStatus(status, result.switch2, channelUpdate);
updated |= updateRelayStatus(status, result.switch3, 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.em0, channelUpdate);
updated |= updateEmStatus(status, result.em10, channelUpdate);
updated |= updateEmStatus(status, result.em11, channelUpdate);
updated |= updateRollerStatus(status, result.cover0, channelUpdate); updated |= updateRollerStatus(status, result.cover0, channelUpdate);
updated |= updateDimmerStatus(status, result.light0, channelUpdate); updated |= updateDimmerStatus(status, result.light0, channelUpdate);
if (channelUpdate) { if (channelUpdate) {
@ -219,12 +222,22 @@ public class Shelly2ApiClient extends ShellyHttpClient {
return false; return false;
} }
ShellyDeviceProfile profile = getProfile(); 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.isValid = rstatus.isValid = true;
sr.name = rstatus.name = status.name; sr.name = rstatus.name = status.name;
if (rs.output != null) { if (rs.output != null) {
@ -250,6 +263,7 @@ public class Shelly2ApiClient extends ShellyHttpClient {
status.temperature = sr.temperature; status.temperature = sr.temperature;
} }
} }
if (rs.voltage != null) { if (rs.voltage != null) {
if (status.voltage == null || rs.voltage > status.voltage) { if (status.voltage == null || rs.voltage > status.voltage) {
status.voltage = rs.voltage; status.voltage = rs.voltage;
@ -265,7 +279,7 @@ public class Shelly2ApiClient extends ShellyHttpClient {
} }
ShellySettingsMeter sm = new ShellySettingsMeter(); 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) { if (rs.apower != null) {
sm.power = emeter.power = rs.apower; sm.power = emeter.power = rs.apower;
} }
@ -285,11 +299,29 @@ public class Shelly2ApiClient extends ShellyHttpClient {
emeter.pf = rs.pf; emeter.pf = rs.pf;
} }
// Update internal structures if (profile.hasRelays) {
status.relays.set(rs.id, rstatus); // Update internal structures
relayStatus.relays.set(rs.id, sr); status.relays.set(rIdx, rstatus);
updateMeter(status, rs.id, sm, emeter, channelUpdate); relayStatus.relays.set(rIdx, sr);
return channelUpdate ? ShellyComponents.updateRelay((ShellyBaseHandler) getThing(), status, rs.id) : false; }
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, private void updateMeter(ShellySettingsStatus status, int id, ShellySettingsMeter sm, ShellySettingsEMeter emeter,
@ -299,12 +331,41 @@ public class Shelly2ApiClient extends ShellyHttpClient {
} }
sm.isValid = sm.power != null || sm.total != null; 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;
emeter.isValid = emeter.current != null || emeter.voltage != null || emeter.power != null;
status.meters.set(id, sm); status.meters.set(id, sm);
status.emeters.set(id, emeter); status.emeters.set(id, emeter);
relayStatus.meters.set(id, sm); 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, private boolean updateEmStatus(ShellySettingsStatus status, @Nullable Shelly2DeviceStatusEm em,
boolean channelUpdate) throws ShellyApiException { boolean channelUpdate) throws ShellyApiException {
if (em == null) { if (em == null) {
@ -341,46 +402,51 @@ public class Shelly2ApiClient extends ShellyHttpClient {
// Update internal structures // Update internal structures
updateMeter(status, 0, sm, emeter, channelUpdate); updateMeter(status, 0, sm, emeter, channelUpdate);
sm = new ShellySettingsMeter(); if (status.emeters.size() > 1) {
emeter = status.emeters.get(1); sm = new ShellySettingsMeter();
if (em.bActPower != null) { emeter = status.emeters.get(1);
sm.power = emeter.power = em.bActPower; 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);
} }
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);
sm = new ShellySettingsMeter(); if (status.emeters.size() > 2) {
emeter = status.emeters.get(2); sm = new ShellySettingsMeter();
sm.isValid = emeter.isValid = true; emeter = status.emeters.get(2);
if (em.cActPower != null) { sm.isValid = emeter.isValid = true;
sm.power = emeter.power = em.cActPower; 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);
} }
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);
return channelUpdate ? ShellyComponents.updateMeters(getThing(), status) : false; return channelUpdate ? ShellyComponents.updateMeters(getThing(), status) : false;
} }
@ -482,6 +548,9 @@ public class Shelly2ApiClient extends ShellyHttpClient {
} }
} }
if (cs.voltage != null) { if (cs.voltage != null) {
if (status.voltage == null || cs.voltage > status.voltage) {
status.voltage = cs.voltage;
}
emeter.voltage = cs.voltage; emeter.voltage = cs.voltage;
} }
if (cs.current != null) { if (cs.current != null) {

View File

@ -61,6 +61,7 @@ public class Shelly2ApiJsonDTO {
public static final String SHELLYRPC_METHOD_WSGETCONFIG = "WS.GetConfig"; public static final String SHELLYRPC_METHOD_WSGETCONFIG = "WS.GetConfig";
public static final String SHELLYRPC_METHOD_WSSETCONFIG = "WS.SetConfig"; public static final String SHELLYRPC_METHOD_WSSETCONFIG = "WS.SetConfig";
public static final String SHELLYRPC_METHOD_EMDATARESET = "EMData.DeleteAllData"; 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_SETCONFIG = "Smoke.SetConfig";
public static final String SHELLYRPC_METHOD_SMOKE_MUTE = "Smoke.Mute"; public static final String SHELLYRPC_METHOD_SMOKE_MUTE = "Smoke.Mute";
public static final String SHELLYRPC_METHOD_SCRIPT_LIST = "Script.List"; public static final String SHELLYRPC_METHOD_SCRIPT_LIST = "Script.List";
@ -322,6 +323,11 @@ public class Shelly2ApiJsonDTO {
public Boolean monitorPhaseSequence; public Boolean monitorPhaseSequence;
} }
public class Shelly2DevConfigPm1 {
public Integer id;
public String name;
}
public class Shelly2DevConfigCover { public class Shelly2DevConfigCover {
public class Shelly2DeviceConfigCoverMotor { public class Shelly2DeviceConfigCoverMotor {
@SerializedName("idle_power_thr") @SerializedName("idle_power_thr")
@ -458,9 +464,17 @@ public class Shelly2ApiJsonDTO {
public Shelly2DevConfigSwitch switch2; public Shelly2DevConfigSwitch switch2;
@SerializedName("switch:3") @SerializedName("switch:3")
public Shelly2DevConfigSwitch switch3; public Shelly2DevConfigSwitch switch3;
@SerializedName("switch:100")
public Shelly2DevConfigSwitch switch100; // Pro 3EM Add-On
@SerializedName("em:0") @SerializedName("em:0")
public Shelly2DevConfigEm em0; public Shelly2DevConfigEm em0;
@SerializedName("em1:0")
public Shelly2DevConfigEm em10;
@SerializedName("em1:1")
public Shelly2DevConfigEm em11;
@SerializedName("pm1:0")
public Shelly2DevConfigPm1 pm10;
@SerializedName("cover:0") @SerializedName("cover:0")
public Shelly2DevConfigCover cover0; public Shelly2DevConfigCover cover0;
@ -677,11 +691,22 @@ public class Shelly2ApiJsonDTO {
public Shelly2RelayStatus switch2; public Shelly2RelayStatus switch2;
@SerializedName("switch:3") @SerializedName("switch:3")
public Shelly2RelayStatus switch3; public Shelly2RelayStatus switch3;
@SerializedName("switch:100")
public Shelly2RelayStatus switch100; // Pro 3EM Add-On
@SerializedName("pm1:0")
public Shelly2RelayStatus pm10;
@SerializedName("em:0") @SerializedName("em:0")
Shelly2DeviceStatusEm em0; public Shelly2DeviceStatusEm em0;
@SerializedName("emdata:0") @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") @SerializedName("cover:0")
public Shelly2CoverStatus cover0; public Shelly2CoverStatus cover0;
@ -793,6 +818,36 @@ public class Shelly2ApiJsonDTO {
public String[] errors; 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 static class Shelly2DeviceStatusTemp {
public Double tC; public Double tC;
public Double tF; public Double tF;

View File

@ -15,6 +15,7 @@ package org.openhab.binding.shelly.internal.api2;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*; import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*; 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.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 static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -251,8 +252,18 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
} }
} }
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; profile.numMeters = 3;
} else if (dc.em10 != null) {
profile.numMeters = 2;
} }
if (profile.numMeters > 0) { if (profile.numMeters > 0) {
@ -565,15 +576,6 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
toQuantityType(getDouble(status.tmp.tC), DIGITS_NONE, SIUnits.CELSIUS)); 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; profile.status = status;
if (updated) { if (updated) {
getThing().restartWatchdog(); getThing().restartWatchdog();
@ -780,10 +782,19 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
return relayStatus; return relayStatus;
} }
@SuppressWarnings("null")
@Override @Override
public void setRelayTurn(int id, String turnMode) throws ShellyApiException { 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(); Shelly2RpcRequestParams params = new Shelly2RpcRequestParams();
params.id = id; params.id = rIdx;
params.on = SHELLY_API_ON.equals(turnMode); params.on = SHELLY_API_ON.equals(turnMode);
apiRequest(SHELLYRPC_METHOD_SWITCH_SET, params, String.class); apiRequest(SHELLYRPC_METHOD_SWITCH_SET, params, String.class);
} }
@ -898,7 +909,9 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
@Override @Override
public void resetMeterTotal(int id) throws ShellyApiException { 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 @Override

View File

@ -100,9 +100,16 @@ public class ShellyThingCreator {
public static final String SHELLYDT_PRO2PM_ROLLER_3 = "SPSW-202PE16EU-roller"; public static final String SHELLYDT_PRO2PM_ROLLER_3 = "SPSW-202PE16EU-roller";
public static final String SHELLYDT_PRO3 = "SPSW-003XE16EU"; public static final String SHELLYDT_PRO3 = "SPSW-003XE16EU";
public static final String SHELLYDT_PRO3EM = "SPEM-003CEBEU"; 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 = "SPSW-004PE16EU";
public static final String SHELLYDT_PRO4PM_2 = "SPSW-104PE16EU"; 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 // Shelly BLU Series
public static final String SHELLYDT_BLUBUTTON = "SBBT"; public static final String SHELLYDT_BLUBUTTON = "SBBT";
public static final String SHELLYDT_BLUDW = "SBDW"; public static final String SHELLYDT_BLUDW = "SBDW";
@ -160,8 +167,15 @@ public class ShellyThingCreator {
public static final String THING_TYPE_SHELLYPLUSPLUGS_STR = "shellyplusplug"; public static final String THING_TYPE_SHELLYPLUSPLUGS_STR = "shellyplusplug";
public static final String THING_TYPE_SHELLYPLUSPLUGUS_STR = "shellyplusplugus"; public static final String THING_TYPE_SHELLYPLUSPLUGUS_STR = "shellyplusplugus";
public static final String THING_TYPE_SHELLYPLUSDIMMERUS_STR = "shellypluswdus"; public static final String THING_TYPE_SHELLYPLUSDIMMERUS_STR = "shellypluswdus";
// Shelly Wall Display
public static final String THING_TYPE_SHELLYPLUSWALLDISPLAY_STR = "shellywalldisplay"; 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 // Shelly Pro Series
public static final String THING_TYPE_SHELLYPRO1_STR = "shellypro1"; public static final String THING_TYPE_SHELLYPRO1_STR = "shellypro1";
public static final String THING_TYPE_SHELLYPRO1PM_STR = "shellypro1pm"; public static final String THING_TYPE_SHELLYPRO1PM_STR = "shellypro1pm";
@ -170,6 +184,7 @@ public class ShellyThingCreator {
public static final String THING_TYPE_SHELLYPRO2PM_ROLLER_STR = "shellypro2pm-roller"; 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_SHELLYPRO3_STR = "shellypro3";
public static final String THING_TYPE_SHELLYPRO3EM_STR = "shellypro3em"; 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"; public static final String THING_TYPE_SHELLYPRO4PM_STR = "shellypro4pm";
// Shelly BLU Series // Shelly BLU Series
@ -262,6 +277,13 @@ public class ShellyThingCreator {
public static final ThingTypeUID THING_TYPE_SHELLYPLUSWALLDISPLAY = new ThingTypeUID(BINDING_ID, public static final ThingTypeUID THING_TYPE_SHELLYPLUSWALLDISPLAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUSWALLDISPLAY_STR); 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 // Shelly Pro
public static final ThingTypeUID THING_TYPE_SHELLYPRO1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPRO1_STR); 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_SHELLYPRO1PM = new ThingTypeUID(BINDING_ID,
@ -275,6 +297,8 @@ public class ShellyThingCreator {
public static final ThingTypeUID THING_TYPE_SHELLYPRO3 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPRO3_STR); 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, public static final ThingTypeUID THING_TYPE_SHELLYPRO3EM = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO3EM_STR); 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, public static final ThingTypeUID THING_TYPE_SHELLYPRO4PM = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO4PM_STR); THING_TYPE_SHELLYPRO4PM_STR);
@ -329,6 +353,11 @@ public class ShellyThingCreator {
THING_TYPE_MAPPING.put(SHELLYDT_PLUSSMOKE, THING_TYPE_SHELLYPLUSSMOKE_STR); THING_TYPE_MAPPING.put(SHELLYDT_PLUSSMOKE, THING_TYPE_SHELLYPLUSSMOKE_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUSDIMMERUS, THING_TYPE_SHELLYPLUSDIMMERUS_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 // Pro Series
THING_TYPE_MAPPING.put(SHELLYDT_PRO1, THING_TYPE_SHELLYPRO1_STR); 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_PRO1_2, THING_TYPE_SHELLYPRO1_STR);
@ -346,11 +375,12 @@ public class ShellyThingCreator {
THING_TYPE_MAPPING.put(SHELLYDT_PRO2PM_ROLLER_2, THING_TYPE_SHELLYPRO2PM_ROLLER_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_PRO2PM_ROLLER_3, THING_TYPE_SHELLYPRO2PM_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO3, THING_TYPE_SHELLYPRO3_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_PRO3EM, THING_TYPE_SHELLYPRO3EM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO4PM, THING_TYPE_SHELLYPRO4PM_STR); THING_TYPE_MAPPING.put(SHELLYDT_PRO4PM, THING_TYPE_SHELLYPRO4PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO4PM_2, 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_BLUBUTTON, THING_TYPE_SHELLYBLUBUTTON_STR);
THING_TYPE_MAPPING.put(SHELLYDT_BLUDW, THING_TYPE_SHELLYBLUDW_STR); THING_TYPE_MAPPING.put(SHELLYDT_BLUDW, THING_TYPE_SHELLYBLUDW_STR);
@ -402,11 +432,16 @@ public class ShellyThingCreator {
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPLUSDIMMERUS_STR, THING_TYPE_SHELLYPLUSDIMMERUS_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_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_SHELLYPRO1_STR, THING_TYPE_SHELLYPRO1_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO1PM_STR, THING_TYPE_SHELLYPRO1PM_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_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_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_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_SHELLYPRO3EM_STR, THING_TYPE_SHELLYPRO3EM_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO3_STR, THING_TYPE_SHELLYPRO3_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); THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO4PM_STR, THING_TYPE_SHELLYPRO4PM_STR);

View File

@ -75,7 +75,8 @@ public class ShellyComponents {
Integer rssi = getInteger(status.wifiSta.rssi); Integer rssi = getInteger(status.wifiSta.rssi);
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_RSSI, mapSignalStrength(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, thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ITEMP,
toQuantityType(getDouble(status.tmp.tC), DIGITS_NONE, SIUnits.CELSIUS)); toQuantityType(getDouble(status.tmp.tC), DIGITS_NONE, SIUnits.CELSIUS));
} else if (status.temperature != null && status.temperature != SHELLY_API_INVTEMP) { } else if (status.temperature != null && status.temperature != SHELLY_API_INVTEMP) {

View File

@ -133,11 +133,10 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
logger.debug("{}: Set Auto-OFF timer to {}", thingName, command); logger.debug("{}: Set Auto-OFF timer to {}", thingName, command);
api.setAutoTimer(rIndex, SHELLY_TIMER_AUTOOFF, getNumber(command).doubleValue()); api.setAutoTimer(rIndex, SHELLY_TIMER_AUTOOFF, getNumber(command).doubleValue());
break; break;
case CHANNEL_EMETER_RESETTOTAL: case CHANNEL_DEVST_RESETTOTAL:
logger.debug("{}: Reset Meter Totals", thingName); logger.debug("{}: Reset Meter Totals", thingName);
int mIndex = Integer.parseInt(substringAfter(groupName, CHANNEL_GROUP_METER)) - 1; api.resetMeterTotal(0); // currently there is only 1 emdata component
api.resetMeterTotal(mIndex); updateChannel(groupName, CHANNEL_DEVST_RESETTOTAL, OnOffType.OFF);
updateChannel(groupName, CHANNEL_EMETER_RESETTOTAL, OnOffType.OFF);
break; break;
} }
return true; return true;

View File

@ -131,6 +131,7 @@ public class ShellyChannelDefinitions {
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS, "meterAccuWatts", ITEMT_POWER)) .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_ACCUTOTAL, "meterAccuTotal", ITEMT_ENERGY))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED, "meterAccuReturned", 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_VOLTAGE, "supplyVoltage", ITEMT_VOLT))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_CHARGER, "charger", ITEMT_SWITCH)) .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_DEVST, CHANNEL_LED_STATUS_DISABLE, "ledStatusDisable", ITEMT_SWITCH))
@ -200,7 +201,6 @@ public class ShellyChannelDefinitions {
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_VOLTAGE, "meterVoltage", ITEMT_VOLT)) .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_CURRENT, "meterCurrent", ITEMT_AMP))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_PFACTOR, "meterPowerFactor", ITEMT_NUMBER)) .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 // Sensors
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TEMP, "sensorTemp", ITEMT_TEMP)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TEMP, "sensorTemp", ITEMT_TEMP))
@ -315,6 +315,7 @@ public class ShellyChannelDefinitions {
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS); addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS);
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL); addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL);
addChannel(thing, add, accuChannel && (status.emeters != null), CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED); 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, addChannel(thing, add, status.voltage != null || profile.settings.supplyVoltage != null, CHGR_DEVST,
CHANNEL_DEVST_VOLTAGE); CHANNEL_DEVST_VOLTAGE);
addChannel(thing, add, addChannel(thing, add,
@ -478,7 +479,6 @@ public class ShellyChannelDefinitions {
addChannel(thing, newChannels, emeter.voltage != null, group, CHANNEL_EMETER_VOLTAGE); addChannel(thing, newChannels, emeter.voltage != null, group, CHANNEL_EMETER_VOLTAGE);
addChannel(thing, newChannels, emeter.current != null, group, CHANNEL_EMETER_CURRENT); 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, 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); addChannel(thing, newChannels, true, group, CHANNEL_LAST_UPDATE);
return newChannels; return newChannels;
} }

View File

@ -6,6 +6,7 @@
<type>binding</type> <type>binding</type>
<name>@text/addon.shelly.name</name> <name>@text/addon.shelly.name</name>
<description>@text/addon.shelly.description</description> <description>@text/addon.shelly.description</description>
<connection>local</connection>
<config-description> <config-description>
<parameter name="defaultUserId" type="text"> <parameter name="defaultUserId" type="text">

View File

@ -98,12 +98,16 @@ thing-type.shelly.shellyplusi4.description = Shelly Plus i4 - 4xInput Device
thing-type.shelly.shellyplusi4dc.description = Shelly Plus i4DC - 4xDC Input Device 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.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.shellyplussmoke.description = Shelly Plus Smoke - Smoke Detector with Alarm
thing-type.shelly.shellypluswdus.description = Shelly Wall Dimmer US Device thing-type.shelly.shellypluswdus.description = Shelly Wall Dimmer US Device
# Wall displays # Wall displays
thing-type.shelly.shellywalldisplay.description = Shelly Plus Wall Display with sensors and input/output 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 # Pro Devices
thing-type.shelly.shellypro1.description = Shelly Pro 1 - Single Relay Switch 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.shellypro1pm.description = Shelly Pro 1PM - Single Relay Switch with Power Meter
@ -112,12 +116,16 @@ thing-type.shelly.shellypro2pm-relay.description= Shelly Pro 2PM - Dual Relay Sw
thing-type.shelly.shellypro2pm-roller.description = Shelly Pro 2PM - Roller Control 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.shellypro3.description = Shelly Pro 3 - 3xRelay Switch
thing-type.shelly.shellypro3em.description = Shelly Pro 3EM - 3xPower Meter 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 thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch with Power Meter
# BLU devices # BLU devices
thing-type.shelly.shellypblubutton.description = Shelly BLU Button thing-type.shelly.shellypblubutton.description = Shelly BLU Button
thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor 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 config - shellydevice
thing-type.config.shelly.deviceIp.label = IP Address thing-type.config.shelly.deviceIp.label = IP Address
thing-type.config.shelly.deviceIp.description = IP Address of the Shelly device thing-type.config.shelly.deviceIp.description = IP Address of the Shelly device
@ -203,6 +211,7 @@ channel-group-type.shelly.iXChannel1.label = Input 1
channel-group-type.shelly.iXChannel2.label = Input 2 channel-group-type.shelly.iXChannel2.label = Input 2
channel-group-type.shelly.iXChannel3.label = Input 3 channel-group-type.shelly.iXChannel3.label = Input 3
channel-group-type.shelly.iXChannel4.label = Input 4 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.iXChannel.description = Input Status
channel-group-type.shelly.rollerControl.label = Roller Control channel-group-type.shelly.rollerControl.label = Roller Control
channel-group-type.shelly.rollerControl.description = Controlling the roller mode channel-group-type.shelly.rollerControl.description = Controlling the roller mode

View File

@ -285,13 +285,13 @@
<description>@text/thing-type.shelly.shellyix3.description</description> <description>@text/thing-type.shelly.shellyix3.description</description>
<channel-groups> <channel-groups>
<channel-group id="status1" typeId="ixChannel"> <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>
<channel-group id="status2" typeId="ixChannel"> <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>
<channel-group id="status3" typeId="ixChannel"> <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>
<channel-group id="device" typeId="deviceStatus"/> <channel-group id="device" typeId="deviceStatus"/>
</channel-groups> </channel-groups>
@ -316,8 +316,8 @@
</channel-group-type> </channel-group-type>
<channel-group-type id="ixChannel"> <channel-group-type id="ixChannel">
<label>@text/channel-group-type.shelly.ixChannel.label</label> <label>@text/channel-group-type.shelly.iXChannel.label</label>
<description>@text/channel-group-type.shelly.ixChannel.description</description> <description>@text/channel-group-type.shelly.iXChannel.description</description>
</channel-group-type> </channel-group-type>
<channel-group-type id="rollerControl"> <channel-group-type id="rollerControl">

View File

@ -80,16 +80,16 @@
<description>@text/thing-type.shelly.shellyplusi4.description</description> <description>@text/thing-type.shelly.shellyplusi4.description</description>
<channel-groups> <channel-groups>
<channel-group id="status1" typeId="ixChannel"> <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>
<channel-group id="status2" typeId="ixChannel"> <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>
<channel-group id="status3" typeId="ixChannel"> <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>
<channel-group id="status4" typeId="ixChannel"> <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>
<channel-group id="device" typeId="deviceStatus"/> <channel-group id="device" typeId="deviceStatus"/>
</channel-groups> </channel-groups>
@ -121,6 +121,44 @@
<config-description-ref uri="thing-type:shelly:relay-gen2"/> <config-description-ref uri="thing-type:shelly:relay-gen2"/>
</thing-type> </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"> <thing-type id="shellypro1">
<label>ShellyPro 1</label> <label>ShellyPro 1</label>
@ -254,6 +292,24 @@
<config-description-ref uri="thing-type:shelly:relay"/> <config-description-ref uri="thing-type:shelly:relay"/>
</thing-type> </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"> <thing-type id="shellypro4pm">
<label>ShellyPro 4PM</label> <label>ShellyPro 4PM</label>
<description>@text/thing-type.shelly.shellypro4pm.description</description> <description>@text/thing-type.shelly.shellypro4pm.description</description>