mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 23:22:02 +01:00
[shelly] Add support for Shelly Wall Dimmer US and Wall Display (#15051)
Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
parent
5629d75d60
commit
5bea9bcfdf
@ -90,6 +90,8 @@ The binding provides the same feature set across all devices as good as possible
|
||||
| shellyplusi4dc | Shelly Plus i4 with 4x DC input | SNSN-0D24X |
|
||||
| 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 |
|
||||
|
||||
### Generation 2 Pro series
|
||||
|
||||
@ -175,6 +177,7 @@ The binding can't communicate directly with the device, but the Plus/Pro series
|
||||
The binding automatically installs a script on the Shelly Device (oh-blu-scanner), which forwards the BLU events to the binding using the WebSocket channel.
|
||||
|
||||
Follow these steps to add the Shelly BLU Device to openHAB
|
||||
|
||||
- Make sure a Shelly is near by the BLU device, enable Bluetooh on this device (the Bluetooth Gateway mode is not required)
|
||||
- Add this thing to openHAB, make sure thing gets online
|
||||
- Enable "BLU Gateway Support" in the thing configuration of the Shelly device acting as gateway.
|
||||
@ -1202,6 +1205,16 @@ Channels lastEvent and eventCount are only available if input type is set to mom
|
||||
| battery | batteryLevel | Number | yes | Battery Level in % |
|
||||
| | lowBattery | Switch | yes | Low battery alert (< 20%) |
|
||||
|
||||
### Shelly Plus Wall Dimmer US (thing-type: shellypluswdus)
|
||||
|
||||
|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 Pro Series
|
||||
|
||||
@ -1405,6 +1418,22 @@ See notes on discovery of Shelly BLU devices above.
|
||||
| | lowBattery | Switch | yes | Low battery alert (< 20%) |
|
||||
| device | gatewayDevice | String | yes | Shelly forwarded last status update (BLU gateway), could vary from packet to packet |
|
||||
|
||||
## Shelly Wall Displays
|
||||
|
||||
| Group | Channel | Type | read-only | Description |
|
||||
| ------- | ----------- | -------- | --------- | --------------------------------------------------------------------------------- |
|
||||
| relay | output | Switch | r/w | 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 |
|
||||
| sensors | temperature | Number | yes | Temperature reported by the integrated sensor |
|
||||
| | humidity | Number | yes | Relative Humidity in percent reported by the integrated sensor |
|
||||
| | lux | Number | yes | Brightness in Lux reported by the integrated sensor |
|
||||
| | lastUpdate | DateTime | yes | Timestamp of the last update (any sensor value changed) |
|
||||
|
||||
## Full Example
|
||||
|
||||
### shelly.things
|
||||
|
@ -67,10 +67,22 @@ public class ShellyBindingConstants {
|
||||
THING_TYPE_SHELLYBUTTON1, //
|
||||
THING_TYPE_SHELLYBUTTON2, //
|
||||
THING_TYPE_SHELLMOTION, //
|
||||
|
||||
// Shelly Plus
|
||||
THING_TYPE_SHELLYPLUS1, //
|
||||
THING_TYPE_SHELLYPLUS1PM, //
|
||||
THING_TYPE_SHELLYPLUS2PM_RELAY, //
|
||||
THING_TYPE_SHELLYPLUS2PM_ROLLER, //
|
||||
THING_TYPE_SHELLYPLUSI4, //
|
||||
THING_TYPE_SHELLYPLUSI4DC, //
|
||||
THING_TYPE_SHELLYPLUSHT, //
|
||||
THING_TYPE_SHELLYPLUSSMOKE, //
|
||||
THING_TYPE_SHELLYPLUSPLUGS, //
|
||||
THING_TYPE_SHELLYPLUSPLUGUS, //
|
||||
THING_TYPE_SHELLYPLUSDIMMERUS, //
|
||||
THING_TYPE_SHELLYPLUSWALLDISPLAY, //
|
||||
|
||||
// Shelly Pro
|
||||
THING_TYPE_SHELLYPRO1, //
|
||||
THING_TYPE_SHELLYPRO1PM, //
|
||||
THING_TYPE_SHELLYPRO2_RELAY, //
|
||||
@ -79,14 +91,11 @@ public class ShellyBindingConstants {
|
||||
THING_TYPE_SHELLYPRO3, //
|
||||
THING_TYPE_SHELLYPRO3EM, //
|
||||
THING_TYPE_SHELLYPRO4PM, //
|
||||
THING_TYPE_SHELLYPLUSI4, //
|
||||
THING_TYPE_SHELLYPLUSI4DC, //
|
||||
THING_TYPE_SHELLYPLUSHT, //
|
||||
THING_TYPE_SHELLYPLUSSMOKE, //
|
||||
THING_TYPE_SHELLYPLUSPLUGS, //
|
||||
THING_TYPE_SHELLYPLUSPLUGUS, //
|
||||
|
||||
// Shelly BLU
|
||||
THING_TYPE_SHELLYBLUBUTTON, //
|
||||
THING_TYPE_SHELLYBLUDW, //
|
||||
|
||||
THING_TYPE_SHELLYPROTECTED, //
|
||||
THING_TYPE_SHELLYUNKNOWN);
|
||||
|
||||
|
@ -102,6 +102,8 @@ public class ShellyDeviceProfile {
|
||||
public boolean isIX = false; // true for a Shelly IX
|
||||
public boolean isTRV = false; // true for a Shelly TRV
|
||||
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 int minTemp = 0; // Bulb/Duo: Min Light Temp
|
||||
public int maxTemp = 0; // Bulb/Duo: Max Light Temp
|
||||
@ -138,9 +140,8 @@ public class ShellyDeviceProfile {
|
||||
name = getString(settings.name);
|
||||
deviceType = getString(settings.device.type);
|
||||
mac = getString(settings.device.mac);
|
||||
hostname = settings.device.hostname != null && !settings.device.hostname.isEmpty()
|
||||
? settings.device.hostname.toLowerCase()
|
||||
: "shelly-" + mac.toUpperCase().substring(6, 11);
|
||||
hostname = !getString(settings.device.hostname).isEmpty() ? settings.device.hostname.toLowerCase()
|
||||
: mac.length() >= 12 ? "shelly-" + mac.toUpperCase().substring(6, 11) : "unknown";
|
||||
mode = getString(settings.mode).toLowerCase();
|
||||
hwRev = settings.hwinfo != null ? getString(settings.hwinfo.hwRevision) : "";
|
||||
hwBatchId = settings.hwinfo != null ? getString(settings.hwinfo.batchId.toString()) : "";
|
||||
@ -193,7 +194,9 @@ public class ShellyDeviceProfile {
|
||||
|
||||
isBlu = thingType.startsWith("shellyblu"); // e.g. SBBT for BU Button
|
||||
|
||||
isDimmer = deviceType.equalsIgnoreCase(SHELLYDT_DIMMER) || deviceType.equalsIgnoreCase(SHELLYDT_DIMMER2);
|
||||
isDimmer = deviceType.equalsIgnoreCase(SHELLYDT_DIMMER) || deviceType.equalsIgnoreCase(SHELLYDT_DIMMER2)
|
||||
|| deviceType.equalsIgnoreCase(SHELLYDT_PLUSDIMMERUS)
|
||||
|| thingType.equalsIgnoreCase(THING_TYPE_SHELLYPLUSDIMMERUS_STR);
|
||||
isBulb = thingType.equals(THING_TYPE_SHELLYBULB_STR);
|
||||
isDuo = thingType.equals(THING_TYPE_SHELLYDUO_STR) || thingType.equals(THING_TYPE_SHELLYVINTAGE_STR)
|
||||
|| thingType.equals(THING_TYPE_SHELLYDUORGBW_STR);
|
||||
@ -217,10 +220,13 @@ public class ShellyDeviceProfile {
|
||||
|| thingType.equals(THING_TYPE_SHELLYPLUSI4DC_STR);
|
||||
isButton = thingType.equals(THING_TYPE_SHELLYBUTTON1_STR) || thingType.equals(THING_TYPE_SHELLYBUTTON2_STR)
|
||||
|| thingType.equals(THING_TYPE_SHELLYBLUBUTTON_STR);
|
||||
isSensor = isHT || isFlood || isDW || isSmoke || isGas || isButton || isUNI || isMotion || isSense || isTRV;
|
||||
hasBattery = isHT || isFlood || isDW || isSmoke || isButton || isMotion || isTRV;
|
||||
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);
|
||||
|
||||
isSensor = isHT || isFlood || isDW || isSmoke || isGas || isButton || isUNI || isMotion || isSense || isTRV
|
||||
|| isWall;
|
||||
hasBattery = isHT || isFlood || isDW || isSmoke || isButton || isMotion || isTRV;
|
||||
alwaysOn = !hasBattery || isMotion || isSense; // true means: device is reachable all the time (no sleep mode)
|
||||
}
|
||||
|
||||
|
@ -405,6 +405,7 @@ public class Shelly1ApiJsonDTO {
|
||||
public String pushShortUrl; // to access when roller stopped
|
||||
|
||||
// Status information
|
||||
public Integer id;
|
||||
public Boolean ison;
|
||||
public Boolean overpower;
|
||||
@SerializedName("is_valid")
|
||||
@ -756,7 +757,7 @@ public class Shelly1ApiJsonDTO {
|
||||
public ShellyStatusSensor.ShellyExtSwitchStatus extSwitch;
|
||||
|
||||
// Internal device temp
|
||||
public ShellySensorTmp tmp = new ShellySensorTmp(); // Shelly 1PM
|
||||
public ShellySensorTmp tmp; // Shelly 1PM
|
||||
public Double temperature; // Shelly 2.5
|
||||
public Boolean overtemperature;
|
||||
|
||||
@ -825,6 +826,8 @@ public class Shelly1ApiJsonDTO {
|
||||
public Integer brightness; // brightness: 0.100%
|
||||
@SerializedName("has_timer")
|
||||
public Boolean hasTimer;
|
||||
@SerializedName("timer_duration")
|
||||
public Integer timerDuration;
|
||||
}
|
||||
|
||||
public static class ShellyStatusRelay {
|
||||
|
@ -149,7 +149,7 @@ public class Shelly1CoIoTVersion1 extends Shelly1CoIoTProtocol implements Shelly
|
||||
break;
|
||||
case "current":
|
||||
updateChannel(updates, rGroup, CHANNEL_EMETER_CURRENT,
|
||||
toQuantityType(getDouble(s.value), DIGITS_VOLT, Units.AMPERE));
|
||||
toQuantityType(getDouble(s.value), DIGITS_AMPERE, Units.AMPERE));
|
||||
break;
|
||||
case "pf":
|
||||
updateChannel(updates, rGroup, CHANNEL_EMETER_PFACTOR, getDecimal(s.value));
|
||||
|
@ -90,7 +90,9 @@ public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterfa
|
||||
|
||||
@Override
|
||||
public ShellySettingsDevice getDeviceInfo() throws ShellyApiException {
|
||||
return callApi(SHELLY_URL_DEVINFO, ShellySettingsDevice.class);
|
||||
ShellySettingsDevice info = callApi(SHELLY_URL_DEVINFO, ShellySettingsDevice.class);
|
||||
info.gen = 1;
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,12 +32,14 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyFavPos;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyInputState;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyRollerStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySensorTmp;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDimmer;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsEMeter;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsInput;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsMeter;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRelay;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRoller;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortLightStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortStatusRelay;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusRelay;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor;
|
||||
@ -49,16 +51,19 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSe
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtVoltage;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellySensorBat;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellySensorHum;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellySensorLux;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2AuthRequest;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2AuthResponse;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2DevConfigCover;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2DevConfigInput;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2DevConfigSwitch;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfig.Shelly2GetConfigResult;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusLight;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult.Shelly2CoverStatus;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult.Shelly2DeviceStatusEm;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult.Shelly2DeviceStatusHumidity;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult.Shelly2DeviceStatusIlluminance;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult.Shelly2DeviceStatusPower;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult.Shelly2DeviceStatusSmoke;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult.Shelly2DeviceStatusTempId;
|
||||
@ -164,6 +169,8 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
}
|
||||
|
||||
ShellySettingsRelay rsettings = new ShellySettingsRelay();
|
||||
rsettings.id = cs.id;
|
||||
rsettings.isValid = cs.id != null;
|
||||
rsettings.name = cs.name;
|
||||
rsettings.ison = false;
|
||||
rsettings.autoOn = getBool(cs.autoOn) ? cs.autoOnDelay : 0;
|
||||
@ -177,7 +184,10 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
boolean channelUpdate) throws ShellyApiException {
|
||||
boolean updated = false;
|
||||
|
||||
if (result.temperature0 != null && !getProfile().isSensor) {
|
||||
if (result.temperature0 != null && result.temperature0.tC != null && !getProfile().isSensor) {
|
||||
if (status.tmp == null) {
|
||||
status.tmp = new ShellySensorTmp();
|
||||
}
|
||||
status.temperature = status.tmp.tC = result.temperature0.tC;
|
||||
}
|
||||
|
||||
@ -188,12 +198,14 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
updated |= updateRelayStatus(status, result.switch3, channelUpdate);
|
||||
updated |= updateEmStatus(status, result.em0, channelUpdate);
|
||||
updated |= updateRollerStatus(status, result.cover0, channelUpdate);
|
||||
updated |= updateDimmerStatus(status, result.light0, channelUpdate);
|
||||
if (channelUpdate) {
|
||||
updated |= ShellyComponents.updateMeters(getThing(), status);
|
||||
}
|
||||
|
||||
updateHumidityStatus(sensorData, result.humidity0);
|
||||
updateTemperatureStatus(sensorData, result.temperature0);
|
||||
updateIlluminanceStatus(sensorData, result.illuminance0);
|
||||
updateSmokeStatus(sensorData, result.smoke0);
|
||||
updateBatteryStatus(sensorData, result.devicepower0);
|
||||
updateAddonStatus(status, result);
|
||||
@ -222,7 +234,13 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
int duration = (int) (now() - rs.timerStartetAt);
|
||||
sr.timerRemaining = duration;
|
||||
}
|
||||
if (status.tmp == null) {
|
||||
status.tmp = new ShellySensorTmp();
|
||||
}
|
||||
if (rs.temperature != null) {
|
||||
if (status.tmp == null) {
|
||||
status.tmp = new ShellySensorTmp();
|
||||
}
|
||||
status.tmp.isValid = true;
|
||||
status.tmp.tC = rs.temperature.tC;
|
||||
status.tmp.tF = rs.temperature.tF;
|
||||
@ -231,8 +249,6 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
if (status.temperature == null || getDouble(rs.temperature.tC) > status.temperature) {
|
||||
status.temperature = sr.temperature;
|
||||
}
|
||||
} else {
|
||||
status.tmp.isValid = false;
|
||||
}
|
||||
if (rs.voltage != null) {
|
||||
if (status.voltage == null || rs.voltage > status.voltage) {
|
||||
@ -250,11 +266,11 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
|
||||
ShellySettingsMeter sm = new ShellySettingsMeter();
|
||||
ShellySettingsEMeter emeter = status.emeters.get(rs.id);
|
||||
sm.isValid = emeter.isValid = true;
|
||||
if (rs.apower != null) {
|
||||
sm.power = emeter.power = rs.apower;
|
||||
}
|
||||
if (rs.aenergy != null) {
|
||||
// Gen2 reports Watt, needs to be converted to W/h
|
||||
sm.total = emeter.total = rs.aenergy.total;
|
||||
sm.counters = rs.aenergy.byMinute;
|
||||
sm.timestamp = rs.aenergy.minuteTs;
|
||||
@ -278,6 +294,12 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
|
||||
private void updateMeter(ShellySettingsStatus status, int id, ShellySettingsMeter sm, ShellySettingsEMeter emeter,
|
||||
boolean channelUpdate) throws ShellyApiException {
|
||||
if (getProfile().numMeters == 0) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
@ -301,7 +323,6 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
|
||||
ShellySettingsMeter sm = new ShellySettingsMeter();
|
||||
ShellySettingsEMeter emeter = status.emeters.get(0);
|
||||
sm.isValid = emeter.isValid = true;
|
||||
if (em.aActPower != null) {
|
||||
sm.power = emeter.power = em.aActPower;
|
||||
}
|
||||
@ -322,7 +343,6 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
|
||||
sm = new ShellySettingsMeter();
|
||||
emeter = status.emeters.get(1);
|
||||
sm.isValid = emeter.isValid = true;
|
||||
if (em.bActPower != null) {
|
||||
sm.power = emeter.power = em.bActPower;
|
||||
}
|
||||
@ -446,6 +466,9 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
rs.duration = (int) (now() - cs.moveStartedAt.longValue());
|
||||
}
|
||||
if (cs.temperature != null && cs.temperature.tC > getDouble(status.temperature)) {
|
||||
if (status.tmp == null) {
|
||||
status.tmp = new ShellySensorTmp();
|
||||
}
|
||||
status.temperature = status.tmp.tC = getDouble(cs.temperature.tC);
|
||||
}
|
||||
if (cs.apower != null) {
|
||||
@ -482,6 +505,46 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
return updateChannels ? ShellyComponents.updateRoller((ShellyBaseHandler) getThing(), rs, cs.id) : false;
|
||||
}
|
||||
|
||||
protected void fillDimmerSettings(ShellyDeviceProfile profile, Shelly2GetConfigResult dc) {
|
||||
if (!profile.isDimmer || dc.light0 == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (profile.settings.dimmers != null) {
|
||||
ShellySettingsDimmer ds = profile.settings.dimmers.get(0);
|
||||
ds.autoOn = dc.light0.autoOnDelay;
|
||||
ds.autoOff = dc.light0.autoOffDelay;
|
||||
ds.name = dc.light0.name;
|
||||
profile.settings.dimmers.set(0, ds);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateDimmerStatus(ShellySettingsStatus status, @Nullable Shelly2DeviceStatusLight value,
|
||||
boolean channelUpdate) throws ShellyApiException {
|
||||
ShellyDeviceProfile profile = getProfile();
|
||||
if (!profile.isDimmer || value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ShellyShortLightStatus ds = status.dimmers.get(0);
|
||||
if (value.brightness != null) {
|
||||
ds.brightness = value.brightness.intValue();
|
||||
}
|
||||
ds.ison = value.output;
|
||||
ds.hasTimer = value.timerStartedAt != null;
|
||||
ds.timerDuration = getDuration(value.timerStartedAt, value.timerDuration);
|
||||
status.dimmers.set(0, ds);
|
||||
return channelUpdate ? ShellyComponents.updateDimmers(getThing(), status) : false;
|
||||
}
|
||||
|
||||
protected @Nullable Integer getDuration(@Nullable Double timerStartedAt, @Nullable Integer timerDuration) {
|
||||
if (timerStartedAt == null || timerDuration == null) {
|
||||
return null;
|
||||
}
|
||||
int duration = (int) (now() - timerStartedAt.longValue());
|
||||
return duration <= timerDuration ? timerDuration - duration : 0;
|
||||
}
|
||||
|
||||
// Addon
|
||||
private void updateAddonStatus(ShellySettingsStatus status, @Nullable Shelly2DeviceStatusResult ds)
|
||||
throws ShellyApiException {
|
||||
@ -544,6 +607,18 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
sdata.tmp.tF = value.tF;
|
||||
}
|
||||
|
||||
protected void updateIlluminanceStatus(ShellyStatusSensor sdata, @Nullable Shelly2DeviceStatusIlluminance value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (sdata.lux == null) {
|
||||
sdata.lux = new ShellySensorLux();
|
||||
}
|
||||
sdata.lux.isValid = value.lux != null;
|
||||
sdata.lux.value = value.lux;
|
||||
sdata.lux.illumination = value.illumination;
|
||||
}
|
||||
|
||||
protected void updateSmokeStatus(ShellyStatusSensor sdata, @Nullable Shelly2DeviceStatusSmoke value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
|
@ -47,6 +47,10 @@ public class Shelly2ApiJsonDTO {
|
||||
public static final String SHELLY2_COVER_CMD_OPEN = "Open";
|
||||
public static final String SHELLY2_COVER_CMD_CLOSE = "Close";
|
||||
public static final String SHELLY2_COVER_CMD_STOP = "Stop";
|
||||
public static final String SHELLYRPC_METHOD_LIGHT_STATUS = "Light.GetStatus";
|
||||
public static final String SHELLYRPC_METHOD_LIGHT_SET = "Light.Set";
|
||||
public static final String SHELLYRPC_METHOD_LIGHT_SETCONFIG = "Light.SetConfig";
|
||||
public static final String SHELLYRPC_METHOD_LED_SETCONFIG = "WD_UI.SetConfig";
|
||||
public static final String SHELLYRPC_METHOD_WIFIGETCONG = "Wifi.GetConfig";
|
||||
public static final String SHELLYRPC_METHOD_WIFISETCONG = "Wifi.SetConfig";
|
||||
public static final String SHELLYRPC_METHOD_ETHGETCONG = "Eth.GetConfig";
|
||||
@ -56,6 +60,7 @@ public class Shelly2ApiJsonDTO {
|
||||
public static final String SHELLYRPC_METHOD_CLOUDSET = "Cloud.SetConfig";
|
||||
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_SMOKE_SETCONFIG = "Smoke.SetConfig";
|
||||
public static final String SHELLYRPC_METHOD_SMOKE_MUTE = "Smoke.Mute";
|
||||
public static final String SHELLYRPC_METHOD_SCRIPT_LIST = "Script.List";
|
||||
@ -151,6 +156,12 @@ public class Shelly2ApiJsonDTO {
|
||||
public static final String SHELLY2_WAKEUPOCAUSE_UPDATE = "status_update";
|
||||
public static final String SHELLY2_WAKEUPOCAUSE_UNDEFINED = "undefined";
|
||||
|
||||
// Dimmer US: LED power modes
|
||||
public static final String SHELLY2_POWERLED_ON = "on";
|
||||
public static final String SHELLY2_POWERLED_OFF = "off";
|
||||
public static final String SHELLY2_POWERLED_MATCH = "match_output";
|
||||
public static final String SHELLY2_POWERLED_INVERT = "inverted_output";
|
||||
|
||||
public class Shelly2DevConfigBle {
|
||||
public Boolean enable;
|
||||
}
|
||||
@ -265,7 +276,7 @@ public class Shelly2ApiJsonDTO {
|
||||
}
|
||||
|
||||
public class Shelly2DevConfigInput {
|
||||
public String id;
|
||||
public Integer id;
|
||||
public String name;
|
||||
public String type;
|
||||
public Boolean invert;
|
||||
@ -276,7 +287,7 @@ public class Shelly2ApiJsonDTO {
|
||||
}
|
||||
|
||||
public class Shelly2DevConfigSwitch {
|
||||
public String id;
|
||||
public Integer id;
|
||||
public String name;
|
||||
|
||||
@SerializedName("in_mode")
|
||||
@ -367,6 +378,41 @@ public class Shelly2ApiJsonDTO {
|
||||
public Boolean mute;
|
||||
}
|
||||
|
||||
public static class Shelly2GetConfigLight {
|
||||
public static class Shelly2GetConfigLightDefault {
|
||||
public Integer brightness;
|
||||
}
|
||||
|
||||
public static class Shelly2GetConfigLightNightMode {
|
||||
public boolean enable;
|
||||
public Integer brightness;
|
||||
}
|
||||
|
||||
public Integer id;
|
||||
public String name;
|
||||
@SerializedName("initial_state")
|
||||
public String initialState;
|
||||
@SerializedName("auto_on")
|
||||
public Boolean autoOn;
|
||||
@SerializedName("auto_off")
|
||||
public Boolean autoOff;
|
||||
@SerializedName("auto_on_delay")
|
||||
public Double autoOnDelay;
|
||||
@SerializedName("auto_off_delay")
|
||||
public Double autoOffDelay;
|
||||
@SerializedName("default")
|
||||
public Shelly2GetConfigLightDefault defaultCfg;
|
||||
@SerializedName("night_mode")
|
||||
public Shelly2GetConfigLightNightMode nightMode;
|
||||
}
|
||||
|
||||
public class Shelly2DeviceConfigLed {
|
||||
@SerializedName("sys_led_enable")
|
||||
public Boolean sysLedEnable;
|
||||
@SerializedName("power_led")
|
||||
public String powerLed;
|
||||
}
|
||||
|
||||
public static class Shelly2GetConfigResult {
|
||||
|
||||
public class Shelly2DevConfigCloud {
|
||||
@ -392,6 +438,8 @@ public class Shelly2ApiJsonDTO {
|
||||
public Shelly2DevConfigMqtt mqtt;
|
||||
public Shelly2DeviceConfigSys sys;
|
||||
public Shelly2DeviceConfigWiFi wifi;
|
||||
@SerializedName("wd_ui")
|
||||
public Shelly2DeviceConfigLed led;
|
||||
|
||||
@SerializedName("input:0")
|
||||
public Shelly2DevConfigInput input0;
|
||||
@ -417,6 +465,9 @@ public class Shelly2ApiJsonDTO {
|
||||
@SerializedName("cover:0")
|
||||
public Shelly2DevConfigCover cover0;
|
||||
|
||||
@SerializedName("light:0")
|
||||
public Shelly2GetConfigLight light0;
|
||||
|
||||
@SerializedName("smoke:0")
|
||||
public Shelly2ConfigSmoke smoke0;
|
||||
}
|
||||
@ -460,6 +511,17 @@ public class Shelly2ApiJsonDTO {
|
||||
public ArrayList<String> errors;// shown only if at least one error is present.
|
||||
}
|
||||
|
||||
public static class Shelly2DeviceStatusLight {
|
||||
public Integer id;
|
||||
public String source;
|
||||
public Boolean output;
|
||||
public Double brightness;
|
||||
@SerializedName("timer_started_at")
|
||||
public Double timerStartedAt;
|
||||
@SerializedName("timer_duration")
|
||||
public Integer timerDuration;
|
||||
}
|
||||
|
||||
public static class Shelly2DeviceStatusResult {
|
||||
public class Shelly2DeviceStatusBle {
|
||||
|
||||
@ -501,6 +563,12 @@ public class Shelly2ApiJsonDTO {
|
||||
public Double rh;
|
||||
}
|
||||
|
||||
public class Shelly2DeviceStatusIlluminance {
|
||||
public Integer id;
|
||||
public Double lux;
|
||||
public String illumination;
|
||||
}
|
||||
|
||||
public class Shelly2DeviceStatusVoltage {
|
||||
public Integer id;
|
||||
public Double voltage;
|
||||
@ -618,6 +686,9 @@ public class Shelly2ApiJsonDTO {
|
||||
@SerializedName("cover:0")
|
||||
public Shelly2CoverStatus cover0;
|
||||
|
||||
@SerializedName("light:0")
|
||||
public Shelly2DeviceStatusLight light0;
|
||||
|
||||
@SerializedName("temperature:0")
|
||||
public Shelly2DeviceStatusTempId temperature0;
|
||||
@SerializedName("temperature:100")
|
||||
@ -635,6 +706,10 @@ public class Shelly2ApiJsonDTO {
|
||||
public Shelly2DeviceStatusHumidity humidity0;
|
||||
@SerializedName("humidity:100")
|
||||
public Shelly2DeviceStatusHumidity humidity100;
|
||||
|
||||
@SerializedName("illuminance:0")
|
||||
Shelly2DeviceStatusIlluminance illuminance0;
|
||||
|
||||
@SerializedName("smoke:0")
|
||||
public Shelly2DeviceStatusSmoke smoke0;
|
||||
|
||||
@ -751,6 +826,12 @@ public class Shelly2ApiJsonDTO {
|
||||
public Boolean autoOff;
|
||||
@SerializedName("auto_off_delay")
|
||||
public Double autoOffDelay;
|
||||
|
||||
// WD_UI.SetConfig
|
||||
@SerializedName("sys_led_enable")
|
||||
public Boolean sysLedEnable;
|
||||
@SerializedName("power_led")
|
||||
public String powerLed;
|
||||
}
|
||||
|
||||
public static class Shelly2RpcRequest {
|
||||
@ -764,6 +845,11 @@ public class Shelly2ApiJsonDTO {
|
||||
public Integer pos;
|
||||
public Boolean on;
|
||||
|
||||
// Dimmer / Light
|
||||
public Integer brightness;
|
||||
@SerializedName("toggle_after")
|
||||
public Integer toggleAfter;
|
||||
|
||||
// Shelly.SetAuth
|
||||
public String user;
|
||||
public String realm;
|
||||
|
@ -41,6 +41,7 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyOtaCheck
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyRollerStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySensorSleepMode;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDevice;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDimmer;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsEMeter;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsLogin;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsMeter;
|
||||
@ -60,6 +61,7 @@ import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceC
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfigAp;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceConfigAp.Shelly2DeviceConfigApRE;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceSettings;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusLight;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusResult;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2DeviceStatus.Shelly2DeviceStatusSys.Shelly2DeviceStatusSysAvlUpdate;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2NotifyEvent;
|
||||
@ -151,11 +153,9 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
if (config.enableBluGateway) {
|
||||
try {
|
||||
installScript(SHELLY2_BLU_GWSCRIPT);
|
||||
} catch (ShellyApiException e) {
|
||||
}
|
||||
try {
|
||||
installScript(SHELLY2_BLU_GWSCRIPT, config.enableBluGateway);
|
||||
} catch (ShellyApiException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +206,7 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
profile.deviceType = device.type;
|
||||
profile.mac = device.mac;
|
||||
profile.auth = device.auth;
|
||||
profile.isGen2 = device.gen == 2;
|
||||
if (config.serviceName.isEmpty()) {
|
||||
config.serviceName = getString(profile.hostname);
|
||||
}
|
||||
@ -275,7 +276,13 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
}
|
||||
}
|
||||
|
||||
profile.status.dimmers = profile.isDimmer ? new ArrayList<>() : null;
|
||||
if (profile.isDimmer) {
|
||||
profile.settings.dimmers = new ArrayList<>();
|
||||
profile.settings.dimmers.add(new ShellySettingsDimmer());
|
||||
profile.status.dimmers = new ArrayList<>();
|
||||
profile.status.dimmers.add(new ShellyShortLightStatus());
|
||||
fillDimmerSettings(profile, dc);
|
||||
}
|
||||
profile.status.lights = profile.isBulb ? new ArrayList<>() : null;
|
||||
profile.status.thermostats = profile.isTRV ? new ArrayList<>() : null;
|
||||
|
||||
@ -286,19 +293,25 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
checkSetWsCallback();
|
||||
}
|
||||
|
||||
if (dc.led != null) {
|
||||
profile.settings.ledStatusDisable = !getBool(dc.led.sysLedEnable);
|
||||
profile.settings.ledPowerDisable = getString(dc.led.powerLed).equals("off");
|
||||
}
|
||||
|
||||
profile.initialized = true;
|
||||
if (!discovery) {
|
||||
getStatus(); // make sure profile.status is initialized (e.g,. relay/meter status)
|
||||
asyncApiRequest(SHELLYRPC_METHOD_GETSTATUS); // request periodic status updates from device
|
||||
|
||||
try {
|
||||
logger.debug("{}: BLU Gateway support enabled for this device: {}", thingName, config.enableBluGateway);
|
||||
if (config.enableBluGateway) {
|
||||
if (getBool(profile.settings.bluetooth)) {
|
||||
installScript(SHELLY2_BLU_GWSCRIPT);
|
||||
} else {
|
||||
logger.debug("{}: Bluetooth needs to be enabled to activate BLU Gateway mode", thingName);
|
||||
if (config.enableBluGateway != null) {
|
||||
logger.debug("{}: BLU Gateway support is {} for this device", thingName,
|
||||
config.enableBluGateway ? "enabled" : "disabled");
|
||||
boolean bluetooth = getBool(profile.settings.bluetooth);
|
||||
if (config.enableBluGateway && !bluetooth) {
|
||||
logger.info("{}: Bluetooth needs to be enabled to activate BLU Gateway mode", thingName);
|
||||
}
|
||||
installScript(SHELLY2_BLU_GWSCRIPT, config.enableBluGateway && bluetooth);
|
||||
}
|
||||
} catch (ShellyApiException e) {
|
||||
logger.debug("{}: Device config failed", thingName, e);
|
||||
@ -340,24 +353,34 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
}
|
||||
}
|
||||
|
||||
protected void installScript(String script) throws ShellyApiException {
|
||||
String json = apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_LIST));
|
||||
ShellyScriptListResponse scriptList = gson.fromJson(json, ShellyScriptListResponse.class);
|
||||
protected void installScript(String script, boolean install) throws ShellyApiException {
|
||||
ShellyScriptListResponse scriptList = apiRequest(
|
||||
new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_LIST), ShellyScriptListResponse.class);
|
||||
Integer ourId = -1;
|
||||
String code = "";
|
||||
|
||||
logger.debug("{}: Install or restart script {} on Shelly Device", thingName, script);
|
||||
if (install) {
|
||||
logger.debug("{}: Install or restart script {} on Shelly Device", thingName, script);
|
||||
}
|
||||
boolean running = false, upload = false;
|
||||
if (scriptList != null) {
|
||||
for (ShellyScriptListEntry s : scriptList.scripts) {
|
||||
if (s.name.startsWith(script)) {
|
||||
ourId = s.id;
|
||||
running = s.running;
|
||||
logger.debug("{}: Script {} is already installed, id={}", thingName, script, ourId);
|
||||
}
|
||||
for (ShellyScriptListEntry s : scriptList.scripts) {
|
||||
if (s.name.startsWith(script)) {
|
||||
ourId = s.id;
|
||||
running = s.running;
|
||||
logger.debug("{}: Script {} is already installed, id={}", thingName, script, ourId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!install) {
|
||||
if (ourId != -1) {
|
||||
startScript(ourId, false);
|
||||
enableScript(script, false);
|
||||
logger.debug("{}: Script {} was disabledd, id={}", thingName, script, ourId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// get script code from bundle resources
|
||||
String file = BUNDLE_RESOURCE_SCRIPTS + "/" + script;
|
||||
ClassLoader cl = Shelly2ApiRpc.class.getClassLoader();
|
||||
@ -380,8 +403,9 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
} else {
|
||||
try {
|
||||
// verify that the same code version is active (avoid unnesesary flash updates)
|
||||
json = apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_GETCODE).withId(ourId));
|
||||
ShellyScriptResponse rsp = gson.fromJson(json, ShellyScriptResponse.class);
|
||||
ShellyScriptResponse rsp = apiRequest(
|
||||
new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_GETCODE).withId(ourId),
|
||||
ShellyScriptResponse.class);
|
||||
if (!rsp.data.trim().equals(code.trim())) {
|
||||
logger.debug("{}: A script version was found, update to newest one", thingName);
|
||||
upload = true;
|
||||
@ -397,27 +421,26 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
}
|
||||
|
||||
if (restart || (running && upload)) {
|
||||
json = apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_STOP).withId(ourId));
|
||||
// first stop running script
|
||||
startScript(ourId, false);
|
||||
running = false;
|
||||
}
|
||||
if (upload && ourId != -1) {
|
||||
// Delete existing script
|
||||
logger.debug("{}: Delete existing script", thingName);
|
||||
json = apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_DELETE).withId(ourId));
|
||||
apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_DELETE).withId(ourId));
|
||||
}
|
||||
|
||||
if (upload) {
|
||||
logger.debug("{}: Script will be installed...", thingName);
|
||||
|
||||
// Create new script, get id
|
||||
json = apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_CREATE).withName(script));
|
||||
ShellyScriptResponse rsp = gson.fromJson(json, ShellyScriptResponse.class);
|
||||
if (rsp != null) {
|
||||
ourId = rsp.id;
|
||||
logger.debug("{}: Script has been created, id={}", thingName, ourId);
|
||||
upload = true;
|
||||
}
|
||||
ShellyScriptResponse rsp = apiRequest(
|
||||
new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_CREATE).withName(script),
|
||||
ShellyScriptResponse.class);
|
||||
ourId = rsp.id;
|
||||
logger.debug("{}: Script has been created, id={}", thingName, ourId);
|
||||
upload = true;
|
||||
}
|
||||
|
||||
if (upload) {
|
||||
@ -437,17 +460,40 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
parms.append = true;
|
||||
} while (processed < length);
|
||||
running = false;
|
||||
|
||||
Shelly2RpcRequestParams params = new Shelly2RpcRequestParams().withConfig();
|
||||
params.config.enable = true;
|
||||
apiRequest(SHELLYRPC_METHOD_SCRIPT_SETCONFIG, params, String.class);
|
||||
}
|
||||
if (enableScript(script, true)) {
|
||||
logger.info("{}: Script {} was {} installed successful", thingName, thingName, script);
|
||||
}
|
||||
|
||||
if (!running) {
|
||||
// Script was created or is there and stopped -> start it
|
||||
json = apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_START).withId(ourId));
|
||||
logger.debug("{}: Script {} was {} successful", thingName, script,
|
||||
restart ? "restarted" : "installed and started");
|
||||
running = startScript(ourId, true);
|
||||
}
|
||||
logger.info("{}: Script {} {}", thingName, script,
|
||||
running ? "was successfully (re)started" : "failed to start");
|
||||
}
|
||||
|
||||
private boolean startScript(int ourId, boolean start) {
|
||||
if (ourId != -1) {
|
||||
try {
|
||||
apiRequest(new Shelly2RpcRequest()
|
||||
.withMethod(start ? SHELLYRPC_METHOD_SCRIPT_START : SHELLYRPC_METHOD_SCRIPT_STOP)
|
||||
.withId(ourId));
|
||||
return true;
|
||||
} catch (ShellyApiException e) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean enableScript(String script, boolean enable) {
|
||||
try {
|
||||
Shelly2RpcRequestParams params = new Shelly2RpcRequestParams().withConfig();
|
||||
params.config.name = script;
|
||||
params.config.enable = enable;
|
||||
apiRequest(SHELLYRPC_METHOD_SCRIPT_SETCONFIG, params, String.class);
|
||||
return true;
|
||||
} catch (ShellyApiException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,6 +565,15 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
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();
|
||||
@ -765,6 +820,44 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_COVER_SETPOS).withId(relayIndex).withPos(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellyStatusLight getLightStatus() throws ShellyApiException {
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellyShortLightStatus getLightStatus(int index) throws ShellyApiException {
|
||||
ShellyShortLightStatus status = new ShellyShortLightStatus();
|
||||
Shelly2DeviceStatusLight ls = apiRequest(
|
||||
new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_LIGHT_STATUS).withId(index),
|
||||
Shelly2DeviceStatusLight.class);
|
||||
status.ison = ls.output;
|
||||
status.hasTimer = ls.timerStartedAt != null;
|
||||
status.timerDuration = getDuration(ls.timerStartedAt, ls.timerDuration);
|
||||
if (ls.brightness != null) {
|
||||
status.brightness = ls.brightness.intValue();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrightness(int id, int brightness, boolean autoOn) throws ShellyApiException {
|
||||
Shelly2RpcRequestParams params = new Shelly2RpcRequestParams();
|
||||
params.id = id;
|
||||
params.brightness = brightness;
|
||||
params.on = brightness > 0;
|
||||
apiRequest(SHELLYRPC_METHOD_LIGHT_SET, params, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellyShortLightStatus setLightTurn(int id, String turnMode) throws ShellyApiException {
|
||||
Shelly2RpcRequestParams params = new Shelly2RpcRequestParams();
|
||||
params.id = id;
|
||||
params.on = turnMode.equals(SHELLY_API_ON);
|
||||
apiRequest(SHELLYRPC_METHOD_LIGHT_SET, params, String.class);
|
||||
return getLightStatus(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellyStatusSensor getSensorStatus() throws ShellyApiException {
|
||||
return sensorData;
|
||||
@ -772,10 +865,13 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
|
||||
@Override
|
||||
public void setAutoTimer(int index, String timerName, double value) throws ShellyApiException {
|
||||
Shelly2RpcRequest req = new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SWITCH_SETCONFIG).withId(index);
|
||||
|
||||
ShellyDeviceProfile profile = getProfile();
|
||||
boolean isLight = profile.isLight || profile.isDimmer;
|
||||
String method = isLight ? SHELLYRPC_METHOD_LIGHT_SETCONFIG : SHELLYRPC_METHOD_SWITCH_SETCONFIG;
|
||||
String component = isLight ? "Light" : "Switch";
|
||||
Shelly2RpcRequest req = new Shelly2RpcRequest().withMethod(method).withId(index);
|
||||
req.params.withConfig();
|
||||
req.params.config.name = "Switch" + index;
|
||||
req.params.config.name = component + index;
|
||||
if (timerName.equals(SHELLY_TIMER_AUTOON)) {
|
||||
req.params.config.autoOn = value > 0;
|
||||
req.params.config.autoOnDelay = value;
|
||||
@ -786,8 +882,23 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
apiRequest(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLedStatus(String ledName, boolean value) throws ShellyApiException {
|
||||
Shelly2RpcRequestParams params = new Shelly2RpcRequestParams().withConfig();
|
||||
params.id = 0;
|
||||
if (ledName.equals(SHELLY_LED_STATUS_DISABLE)) {
|
||||
params.config.sysLedEnable = value;
|
||||
} else if (ledName.equals(SHELLY_LED_POWER_DISABLE)) {
|
||||
params.config.powerLed = value ? SHELLY2_POWERLED_OFF : SHELLY2_POWERLED_MATCH;
|
||||
} else {
|
||||
throw new ShellyApiException("API call not implemented for this LED type");
|
||||
}
|
||||
apiRequest(SHELLYRPC_METHOD_LED_SETCONFIG, params, Shelly2WsConfigResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetMeterTotal(int id) throws ShellyApiException {
|
||||
apiRequest(new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_EMDATARESET).withId(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -899,20 +1010,6 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
* The following API calls are not yet relevant, because currently there a no Plus/Pro (Gen2) devices of those
|
||||
* categories (e.g. bulbs)
|
||||
*/
|
||||
@Override
|
||||
public void setLedStatus(String ledName, boolean value) throws ShellyApiException {
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellyStatusLight getLightStatus() throws ShellyApiException {
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellyShortLightStatus getLightStatus(int index) throws ShellyApiException {
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLightParm(int lightIndex, String parm, String value) throws ShellyApiException {
|
||||
@ -924,16 +1021,6 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellyShortLightStatus setLightTurn(int id, String turnMode) throws ShellyApiException {
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrightness(int id, int brightness, boolean autoOn) throws ShellyApiException {
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLightMode(String mode) throws ShellyApiException {
|
||||
throw new ShellyApiException("API call not implemented");
|
||||
@ -1058,10 +1145,12 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
if (response.result != null) {
|
||||
// return sub element result as requested class type
|
||||
json = gson.toJson(gson.fromJson(json, Shelly2RpcBaseMessage.class).result);
|
||||
return fromJson(gson, json, classOfT);
|
||||
boolean isString = response.result instanceof String;
|
||||
return fromJson(gson, isString && ((String) response.result).equalsIgnoreCase("null") ? "{}" : json,
|
||||
classOfT);
|
||||
} else {
|
||||
// return direct format
|
||||
return gson.fromJson(json, classOfT);
|
||||
return gson.fromJson(json, classOfT == String.class ? Shelly2RpcBaseMessage.class : classOfT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1069,8 +1158,8 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
|
||||
return apiRequest(request.method, request.params, classOfT);
|
||||
}
|
||||
|
||||
public String apiRequest(Shelly2RpcRequest request) throws ShellyApiException {
|
||||
return apiRequest(request.method, request.params, String.class);
|
||||
public void apiRequest(Shelly2RpcRequest request) throws ShellyApiException {
|
||||
apiRequest(request.method, request.params, Shelly2RpcBaseMessage.class);
|
||||
}
|
||||
|
||||
private String rpcPost(String postData) throws ShellyApiException {
|
||||
|
@ -24,15 +24,15 @@ import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2RpcNoti
|
||||
@NonNullByDefault
|
||||
public interface Shelly2RpctInterface {
|
||||
|
||||
public void onConnect(String deviceIp, boolean connected);
|
||||
void onConnect(String deviceIp, boolean connected);
|
||||
|
||||
public void onMessage(String decodedmessage);
|
||||
void onMessage(String decodedmessage);
|
||||
|
||||
public void onNotifyStatus(Shelly2RpcNotifyStatus message);
|
||||
void onNotifyStatus(Shelly2RpcNotifyStatus message);
|
||||
|
||||
public void onNotifyEvent(Shelly2RpcNotifyEvent message);
|
||||
void onNotifyEvent(Shelly2RpcNotifyEvent message);
|
||||
|
||||
public void onClose(int statusCode, String reason);
|
||||
void onClose(int statusCode, String reason);
|
||||
|
||||
public void onError(Throwable cause);
|
||||
void onError(Throwable cause);
|
||||
}
|
||||
|
@ -44,5 +44,5 @@ public class ShellyThingConfiguration {
|
||||
public String localPort = "8080";
|
||||
public String serviceName = "";
|
||||
|
||||
public boolean enableBluGateway = false;
|
||||
public Boolean enableBluGateway = false;
|
||||
}
|
||||
|
@ -79,6 +79,8 @@ public class ShellyThingCreator {
|
||||
public static final String SHELLYDT_PLUSI4DC = "SNSN-0D24X";
|
||||
public static final String SHELLYDT_PLUSHT = "SNSN-0013A";
|
||||
public static final String SHELLYDT_PLUSSMOKE = "SNSN-0031Z";
|
||||
public static final String SHELLYDT_PLUSDIMMERUS = "SNDM-0013US";
|
||||
public static final String SHELLYDT_PLUSWALLDISPLAY = "SAWD-0A1XX10EU1";
|
||||
|
||||
// Shelly Pro Series
|
||||
public static final String SHELLYDT_PRO1 = "SPSW-001XE16EU";
|
||||
@ -157,6 +159,8 @@ public class ShellyThingCreator {
|
||||
public static final String THING_TYPE_SHELLYPLUSSMOKE_STR = "shellyplussmoke";
|
||||
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";
|
||||
public static final String THING_TYPE_SHELLYPLUSWALLDISPLAY_STR = "shellywalldisplay";
|
||||
|
||||
// Shelly Pro Series
|
||||
public static final String THING_TYPE_SHELLYPRO1_STR = "shellypro1";
|
||||
@ -233,7 +237,7 @@ public class ShellyThingCreator {
|
||||
public static final ThingTypeUID THING_TYPE_SHELLYUNKNOWN = new ThingTypeUID(BINDING_ID,
|
||||
THING_TYPE_SHELLYUNKNOWN_STR);
|
||||
|
||||
// Shelly Plus/Pro
|
||||
// Shelly Plus
|
||||
public static final ThingTypeUID THING_TYPE_SHELLYPLUS1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPLUS1_STR);
|
||||
public static final ThingTypeUID THING_TYPE_SHELLYPLUS1PM = new ThingTypeUID(BINDING_ID,
|
||||
THING_TYPE_SHELLYPLUS1PM_STR);
|
||||
@ -253,6 +257,12 @@ public class ShellyThingCreator {
|
||||
THING_TYPE_SHELLYPLUSPLUGS_STR);
|
||||
public static final ThingTypeUID THING_TYPE_SHELLYPLUSPLUGUS = new ThingTypeUID(BINDING_ID,
|
||||
THING_TYPE_SHELLYPLUSPLUGUS_STR);
|
||||
public static final ThingTypeUID THING_TYPE_SHELLYPLUSDIMMERUS = new ThingTypeUID(BINDING_ID,
|
||||
THING_TYPE_SHELLYPLUSDIMMERUS_STR);
|
||||
public static final ThingTypeUID THING_TYPE_SHELLYPLUSWALLDISPLAY = new ThingTypeUID(BINDING_ID,
|
||||
THING_TYPE_SHELLYPLUSWALLDISPLAY_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,
|
||||
THING_TYPE_SHELLYPRO1PM_STR);
|
||||
@ -317,6 +327,7 @@ public class ShellyThingCreator {
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_PLUSI4, THING_TYPE_SHELLYPLUSI4_STR);
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_PLUSHT, THING_TYPE_SHELLYPLUSHT_STR);
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_PLUSSMOKE, THING_TYPE_SHELLYPLUSSMOKE_STR);
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_PLUSDIMMERUS, THING_TYPE_SHELLYPLUSDIMMERUS_STR);
|
||||
|
||||
// Pro Series
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_PRO1, THING_TYPE_SHELLYPRO1_STR);
|
||||
@ -343,6 +354,9 @@ public class ShellyThingCreator {
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_BLUBUTTON, THING_TYPE_SHELLYBLUBUTTON_STR);
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_BLUDW, THING_TYPE_SHELLYBLUDW_STR);
|
||||
|
||||
// Wall displays
|
||||
THING_TYPE_MAPPING.put(SHELLYDT_PLUSWALLDISPLAY, THING_TYPE_SHELLYPLUSWALLDISPLAY_STR);
|
||||
|
||||
// mapping by thing type
|
||||
THING_TYPE_MAPPING.put(THING_TYPE_SHELLY1_STR, THING_TYPE_SHELLY1_STR);
|
||||
THING_TYPE_MAPPING.put(THING_TYPE_SHELLY1PM_STR, THING_TYPE_SHELLY1PM_STR);
|
||||
@ -385,6 +399,8 @@ public class ShellyThingCreator {
|
||||
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPLUSI4_STR, THING_TYPE_SHELLYPLUSI4_STR);
|
||||
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPLUSHT_STR, THING_TYPE_SHELLYPLUSHT_STR);
|
||||
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPLUSSMOKE_STR, THING_TYPE_SHELLYPLUSSMOKE_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_SHELLYPRO1_STR, THING_TYPE_SHELLYPRO1_STR);
|
||||
THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPRO1PM_STR, THING_TYPE_SHELLYPRO1PM_STR);
|
||||
|
@ -20,22 +20,28 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.shelly.internal.api.ShellyApiException;
|
||||
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyRollerStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDimmer;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsEMeter;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsMeter;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRelay;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortLightStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyADC;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtTemperature.ShellyShortTemp;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyThermnostat;
|
||||
import org.openhab.binding.shelly.internal.provider.ShellyChannelDefinitions;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/***
|
||||
* The{@link ShellyComponents} implements updates for supplemental components
|
||||
* Meter will be used by Relay + Light; Sensor is part of H&T, Flood, Door Window, Sense
|
||||
@ -69,14 +75,12 @@ public class ShellyComponents {
|
||||
|
||||
Integer rssi = getInteger(status.wifiSta.rssi);
|
||||
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_RSSI, mapSignalStrength(rssi));
|
||||
if (getDouble(status.temperature) != SHELLY_API_INVTEMP) {
|
||||
if (status.tmp != null && !thingHandler.getProfile().isSensor) {
|
||||
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ITEMP,
|
||||
toQuantityType(getDouble(status.tmp.tC), DIGITS_NONE, SIUnits.CELSIUS));
|
||||
} else if (status.temperature != null) {
|
||||
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ITEMP,
|
||||
toQuantityType(getDouble(status.temperature), DIGITS_NONE, SIUnits.CELSIUS));
|
||||
}
|
||||
if (status.tmp != null && !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) {
|
||||
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ITEMP,
|
||||
toQuantityType(getDouble(status.temperature), DIGITS_NONE, SIUnits.CELSIUS));
|
||||
}
|
||||
thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_SLEEPTIME,
|
||||
toQuantityType(getInteger(status.sleepTime), Units.SECOND));
|
||||
@ -268,8 +272,8 @@ public class ShellyComponents {
|
||||
.createEMeterChannels(thingHandler.getThing(), profile, emeter, groupName));
|
||||
}
|
||||
|
||||
// convert Watt/Hour to kw/h
|
||||
double total = getDouble(emeter.total) / 1000 / 60;
|
||||
// convert Watt/h to KW/h
|
||||
double total = getDouble(emeter.total) / 1000;
|
||||
double totalReturned = getDouble(emeter.totalReturned) / 1000;
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_METER_CURRENTWATTS,
|
||||
toQuantityType(getDouble(emeter.power), DIGITS_WATT, Units.WATT));
|
||||
@ -332,7 +336,7 @@ public class ShellyComponents {
|
||||
// convert totalWatts into kw/h
|
||||
totalWatts = totalWatts / (60.0 * 1000.0);
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_METER_CURRENTWATTS,
|
||||
toQuantityType(getDouble(currentWatts), DIGITS_WATT, Units.WATT));
|
||||
toQuantityType(currentWatts, DIGITS_WATT, Units.WATT));
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_METER_TOTALKWH,
|
||||
toQuantityType(totalWatts, DIGITS_KWH, Units.KILOWATT_HOUR));
|
||||
|
||||
@ -537,6 +541,64 @@ public class ShellyComponents {
|
||||
return updated;
|
||||
}
|
||||
|
||||
public static boolean updateDimmers(ShellyThingInterface thingHandler, ShellySettingsStatus orgStatus)
|
||||
throws ShellyApiException {
|
||||
boolean updated = false;
|
||||
ShellyDeviceProfile profile = thingHandler.getProfile();
|
||||
if (profile.isDimmer) {
|
||||
// We need to fixup the returned Json: The dimmer returns light[] element, which is ok, but it doesn't have
|
||||
// the same structure as lights[] from Bulb,RGBW2 and Duo. The tag gets replaced by dimmers[] so that Gson
|
||||
// maps to a different structure (ShellyShortLight).
|
||||
Gson gson = new Gson();
|
||||
ShellySettingsStatus dstatus = !profile.isGen2
|
||||
? fromJson(gson, Shelly1ApiJsonDTO.fixDimmerJson(orgStatus.json), ShellySettingsStatus.class)
|
||||
: orgStatus;
|
||||
|
||||
int l = 0;
|
||||
for (ShellyShortLightStatus dimmer : dstatus.dimmers) {
|
||||
Integer r = l + 1;
|
||||
String groupName = profile.numRelays <= 1 ? CHANNEL_GROUP_DIMMER_CONTROL
|
||||
: CHANNEL_GROUP_DIMMER_CONTROL + r.toString();
|
||||
|
||||
if (!thingHandler.areChannelsCreated()) {
|
||||
thingHandler.updateChannelDefinitions(ShellyChannelDefinitions
|
||||
.createDimmerChannels(thingHandler.getThing(), profile, dstatus, l));
|
||||
}
|
||||
|
||||
ShellySettingsDimmer ds = profile.settings.dimmers.get(l);
|
||||
if (ds.name != null) {
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_OUTPUT_NAME, getStringType(ds.name));
|
||||
}
|
||||
|
||||
// On a status update we map a dimmer.ison = false to brightness 0 rather than the device's brightness
|
||||
// and send an OFF status to the same channel.
|
||||
// When the device's brightness is > 0 we send the new value to the channel and an ON command
|
||||
if (dimmer.ison) {
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Switch", OnOffType.ON);
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Value",
|
||||
toQuantityType((double) getInteger(dimmer.brightness), DIGITS_NONE, Units.PERCENT));
|
||||
} else {
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Switch", OnOffType.OFF);
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Value",
|
||||
toQuantityType(0.0, DIGITS_NONE, Units.PERCENT));
|
||||
}
|
||||
|
||||
if (profile.settings.dimmers != null) {
|
||||
ShellySettingsDimmer dsettings = profile.settings.dimmers.get(l);
|
||||
if (dsettings != null) {
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_TIMER_AUTOON,
|
||||
toQuantityType(getDouble(dsettings.autoOn), Units.SECOND));
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_TIMER_AUTOOFF,
|
||||
toQuantityType(getDouble(dsettings.autoOff), Units.SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
l++;
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
public static boolean updateTempChannel(@Nullable ShellyShortTemp sensor, ShellyThingInterface thingHandler,
|
||||
String channel) {
|
||||
return sensor != null ? updateTempChannel(thingHandler, CHANNEL_GROUP_SENSOR, channel, sensor.tC, "") : false;
|
||||
|
@ -28,6 +28,6 @@ public interface ShellyDeviceListener {
|
||||
/**
|
||||
* This method is called when new device information is received.
|
||||
*/
|
||||
public boolean onEvent(String ipAddress, String deviceName, String deviceIndex, String eventType,
|
||||
boolean onEvent(String ipAddress, String deviceName, String deviceIndex, String eventType,
|
||||
Map<String, String> parameters);
|
||||
}
|
||||
|
@ -19,9 +19,7 @@ import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.shelly.internal.api.ShellyApiException;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyRollerStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDimmer;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRelay;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortLightStatus;
|
||||
@ -42,8 +40,6 @@ import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/***
|
||||
* The{@link ShellyRelayHandler} handles light (bulb+rgbw2) specific commands and status. All other commands will be
|
||||
* handled by the generic thing handler.
|
||||
@ -193,7 +189,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
|
||||
if (brightness > 0) {
|
||||
api.setBrightness(lightId, brightness, config.brightnessAutoOn);
|
||||
} else {
|
||||
api.setRelayTurn(lightId, power == OnOffType.ON ? SHELLY_API_ON : SHELLY_API_OFF);
|
||||
api.setLightTurn(lightId, power == OnOffType.ON ? SHELLY_API_ON : SHELLY_API_OFF);
|
||||
if (brightness >= 0) { // ignore -1
|
||||
updateChannel(CHANNEL_COLOR_WHITE, CHANNEL_BRIGHTNESS + "$Value",
|
||||
toQuantityType((double) (power == OnOffType.ON ? brightness : 0), DIGITS_NONE, Units.PERCENT));
|
||||
@ -206,7 +202,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
|
||||
// map status to channels
|
||||
boolean updated = false;
|
||||
updated |= updateRelays(status);
|
||||
updated |= updateDimmers(status);
|
||||
updated |= ShellyComponents.updateDimmers(this, status);
|
||||
updated |= updateLed(status);
|
||||
return updated;
|
||||
}
|
||||
@ -300,12 +296,6 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void createDimmerChannels(ShellySettingsStatus dstatus, int idx) {
|
||||
if (!areChannelsCreated()) {
|
||||
updateChannelDefinitions(ShellyChannelDefinitions.createDimmerChannels(getThing(), profile, dstatus, idx));
|
||||
}
|
||||
}
|
||||
|
||||
private void createRollerChannels(ShellyRollerStatus roller) {
|
||||
if (!areChannelsCreated()) {
|
||||
updateChannelDefinitions(ShellyChannelDefinitions.createRollerChannels(getThing(), roller));
|
||||
@ -356,63 +346,6 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Relay/Roller channels
|
||||
*
|
||||
* @param th Thing Handler instance
|
||||
* @param profile ShellyDeviceProfile
|
||||
* @param status Last ShellySettingsStatus
|
||||
*
|
||||
* @throws ShellyApiException
|
||||
*/
|
||||
public boolean updateDimmers(ShellySettingsStatus orgStatus) throws ShellyApiException {
|
||||
boolean updated = false;
|
||||
if (profile.isDimmer) {
|
||||
// We need to fixup the returned Json: The dimmer returns light[] element, which is ok, but it doesn't have
|
||||
// the same structure as lights[] from Bulb,RGBW2 and Duo. The tag gets replaced by dimmers[] so that Gson
|
||||
// maps to a different structure (ShellyShortLight).
|
||||
Gson gson = new Gson();
|
||||
ShellySettingsStatus dstatus = fromJson(gson, Shelly1ApiJsonDTO.fixDimmerJson(orgStatus.json),
|
||||
ShellySettingsStatus.class);
|
||||
|
||||
logger.trace("{}: Updating {} dimmers(s)", thingName, dstatus.dimmers.size());
|
||||
int l = 0;
|
||||
for (ShellyShortLightStatus dimmer : dstatus.dimmers) {
|
||||
Integer r = l + 1;
|
||||
String groupName = profile.numRelays <= 1 ? CHANNEL_GROUP_DIMMER_CONTROL
|
||||
: CHANNEL_GROUP_DIMMER_CONTROL + r.toString();
|
||||
|
||||
createDimmerChannels(dstatus, l);
|
||||
|
||||
// On a status update we map a dimmer.ison = false to brightness 0 rather than the device's brightness
|
||||
// and send an OFF status to the same channel.
|
||||
// When the device's brightness is > 0 we send the new value to the channel and an ON command
|
||||
if (dimmer.ison) {
|
||||
updated |= updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Switch", OnOffType.ON);
|
||||
updated |= updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Value",
|
||||
toQuantityType((double) getInteger(dimmer.brightness), DIGITS_NONE, Units.PERCENT));
|
||||
} else {
|
||||
updated |= updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Switch", OnOffType.OFF);
|
||||
updated |= updateChannel(groupName, CHANNEL_BRIGHTNESS + "$Value",
|
||||
toQuantityType(0.0, DIGITS_NONE, Units.PERCENT));
|
||||
}
|
||||
|
||||
if (profile.settings.dimmers != null) {
|
||||
ShellySettingsDimmer dsettings = profile.settings.dimmers.get(l);
|
||||
if (dsettings != null) {
|
||||
updated |= updateChannel(groupName, CHANNEL_TIMER_AUTOON,
|
||||
toQuantityType(getDouble(dsettings.autoOn), Units.SECOND));
|
||||
updated |= updateChannel(groupName, CHANNEL_TIMER_AUTOOFF,
|
||||
toQuantityType(getDouble(dsettings.autoOff), Units.SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
l++;
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update LED channels
|
||||
*
|
||||
|
@ -39,85 +39,86 @@ import org.openhab.core.types.StateOption;
|
||||
@NonNullByDefault
|
||||
public interface ShellyThingInterface {
|
||||
|
||||
public ShellyDeviceProfile getProfile(boolean forceRefresh) throws ShellyApiException;
|
||||
ShellyDeviceProfile getProfile(boolean forceRefresh) throws ShellyApiException;
|
||||
|
||||
public @Nullable List<StateOption> getStateOptions(ChannelTypeUID uid);
|
||||
@Nullable
|
||||
List<StateOption> getStateOptions(ChannelTypeUID uid);
|
||||
|
||||
public double getChannelDouble(String group, String channel);
|
||||
double getChannelDouble(String group, String channel);
|
||||
|
||||
public boolean updateChannel(String group, String channel, State value);
|
||||
boolean updateChannel(String group, String channel, State value);
|
||||
|
||||
public boolean updateChannel(String channelId, State value, boolean force);
|
||||
boolean updateChannel(String channelId, State value, boolean force);
|
||||
|
||||
public void setThingOnline();
|
||||
void setThingOnline();
|
||||
|
||||
public void setThingOffline(ThingStatusDetail detail, String messageKey, Object... arguments);
|
||||
void setThingOffline(ThingStatusDetail detail, String messageKey, Object... arguments);
|
||||
|
||||
public boolean isStopping();
|
||||
boolean isStopping();
|
||||
|
||||
public String getThingType();
|
||||
String getThingType();
|
||||
|
||||
public ThingStatus getThingStatus();
|
||||
ThingStatus getThingStatus();
|
||||
|
||||
public ThingStatusDetail getThingStatusDetail();
|
||||
ThingStatusDetail getThingStatusDetail();
|
||||
|
||||
public boolean isThingOnline();
|
||||
boolean isThingOnline();
|
||||
|
||||
public boolean requestUpdates(int requestCount, boolean refreshSettings);
|
||||
boolean requestUpdates(int requestCount, boolean refreshSettings);
|
||||
|
||||
public void triggerUpdateFromCoap();
|
||||
void triggerUpdateFromCoap();
|
||||
|
||||
public void reinitializeThing();
|
||||
void reinitializeThing();
|
||||
|
||||
public void restartWatchdog();
|
||||
void restartWatchdog();
|
||||
|
||||
public void publishState(String channelId, State value);
|
||||
void publishState(String channelId, State value);
|
||||
|
||||
public boolean areChannelsCreated();
|
||||
boolean areChannelsCreated();
|
||||
|
||||
public State getChannelValue(String group, String channel);
|
||||
State getChannelValue(String group, String channel);
|
||||
|
||||
public boolean updateInputs(ShellySettingsStatus status);
|
||||
boolean updateInputs(ShellySettingsStatus status);
|
||||
|
||||
public void updateChannelDefinitions(Map<String, Channel> dynChannels);
|
||||
void updateChannelDefinitions(Map<String, Channel> dynChannels);
|
||||
|
||||
public void postEvent(String event, boolean force);
|
||||
void postEvent(String event, boolean force);
|
||||
|
||||
public void triggerChannel(String group, String channelID, String event);
|
||||
void triggerChannel(String group, String channelID, String event);
|
||||
|
||||
public void triggerButton(String group, int idx, String value);
|
||||
void triggerButton(String group, int idx, String value);
|
||||
|
||||
public ShellyDeviceStats getStats();
|
||||
ShellyDeviceStats getStats();
|
||||
|
||||
public void resetStats();
|
||||
void resetStats();
|
||||
|
||||
public Thing getThing();
|
||||
Thing getThing();
|
||||
|
||||
public String getThingName();
|
||||
String getThingName();
|
||||
|
||||
public ShellyThingConfiguration getThingConfig();
|
||||
ShellyThingConfiguration getThingConfig();
|
||||
|
||||
public HttpClient getHttpClient();
|
||||
HttpClient getHttpClient();
|
||||
|
||||
public String getProperty(String key);
|
||||
String getProperty(String key);
|
||||
|
||||
public void updateProperties(String key, String value);
|
||||
void updateProperties(String key, String value);
|
||||
|
||||
public boolean updateWakeupReason(@Nullable List<Object> valueArray);
|
||||
boolean updateWakeupReason(@Nullable List<Object> valueArray);
|
||||
|
||||
public ShellyApiInterface getApi();
|
||||
ShellyApiInterface getApi();
|
||||
|
||||
public ShellyDeviceProfile getProfile();
|
||||
ShellyDeviceProfile getProfile();
|
||||
|
||||
public long getScheduledUpdates();
|
||||
long getScheduledUpdates();
|
||||
|
||||
public void fillDeviceStatus(ShellySettingsStatus status, boolean updated);
|
||||
void fillDeviceStatus(ShellySettingsStatus status, boolean updated);
|
||||
|
||||
public boolean checkRepresentation(String key);
|
||||
boolean checkRepresentation(String key);
|
||||
|
||||
public void incProtMessages();
|
||||
void incProtMessages();
|
||||
|
||||
public void incProtErrors();
|
||||
void incProtErrors();
|
||||
|
||||
public void startScan();
|
||||
void startScan();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class ShellyChannelDefinitions {
|
||||
public static final String ITEMT_POWER = "Number:Power";
|
||||
public static final String ITEMT_ENERGY = "Number:Energy";
|
||||
public static final String ITEMT_VOLT = "Number:ElectricPotential";
|
||||
public static final String ITEMT_AMP = "Number:ElectricPotential";
|
||||
public static final String ITEMT_AMP = "Number:ElectricCurrent";
|
||||
public static final String ITEMT_ANGLE = "Number:Angle";
|
||||
public static final String ITEMT_DISTANCE = "Number:Length";
|
||||
public static final String ITEMT_SPEED = "Number:Speed";
|
||||
@ -129,8 +129,8 @@ public class ShellyChannelDefinitions {
|
||||
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ITEMP, "deviceTemp", ITEMT_TEMP))
|
||||
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_WAKEUP, "sensorWakeup", ITEMT_STRING))
|
||||
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS, "meterAccuWatts", ITEMT_POWER))
|
||||
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL, "meterAccuTotal", ITEMT_POWER))
|
||||
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED, "meterAccuReturned", 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_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))
|
||||
@ -191,7 +191,7 @@ public class ShellyChannelDefinitions {
|
||||
// Power Meter
|
||||
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_METER_CURRENTWATTS, "meterWatts", ITEMT_POWER))
|
||||
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_METER_TOTALKWH, "meterTotal", ITEMT_ENERGY))
|
||||
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_METER_LASTMIN1, "lastPower1", ITEMT_ENERGY))
|
||||
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_METER_LASTMIN1, "lastPower1", ITEMT_POWER))
|
||||
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_LAST_UPDATE, "lastUpdate", ITEMT_DATETIME))
|
||||
|
||||
// EMeter
|
||||
@ -215,7 +215,7 @@ public class ShellyChannelDefinitions {
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION, "sensorMotion", ITEMT_SWITCH))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION_TS, "motionTimestamp", ITEMT_DATETIME))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION_ACT, "motionActive", ITEMT_SWITCH))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_VIBRATION, "vibration", ITEMT_SWITCH))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_VIBRATION, "sensorVibration", ITEMT_SWITCH))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_FLOOD, "sensorFlood", ITEMT_SWITCH))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_SMOKE, "sensorSmoke", ITEMT_SWITCH))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MUTE, "sensorMute", ITEMT_SWITCH))
|
||||
@ -304,13 +304,14 @@ public class ShellyChannelDefinitions {
|
||||
&& ((status.temperature != null && getDouble(status.temperature) != SHELLY_API_INVTEMP)
|
||||
|| (status.tmp != null && getDouble(status.tmp.tC) != SHELLY_API_INVTEMP))) {
|
||||
// Only some devices report the internal device temp
|
||||
addChannel(thing, add, status.tmp != null || status.temperature != null, CHGR_DEVST, CHANNEL_DEVST_ITEMP);
|
||||
addChannel(thing, add,
|
||||
!profile.isLight && (status.temperature != null || (status.tmp != null && !profile.isSensor)),
|
||||
CHGR_DEVST, CHANNEL_DEVST_ITEMP);
|
||||
}
|
||||
addChannel(thing, add, profile.settings.sleepTime != null, CHGR_SENSOR, CHANNEL_SENSOR_SLEEPTIME);
|
||||
|
||||
// If device has more than 1 meter the channel accumulatedWatts receives the accumulated value
|
||||
boolean accuChannel = (((status.meters != null) && (status.meters.size() > 1) && !profile.isRoller
|
||||
&& !profile.isRGBW2) || ((status.emeters != null && status.emeters.size() > 1)));
|
||||
boolean accuChannel = profile.numMeters > 1 && !profile.isRoller && !profile.isRGBW2;
|
||||
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);
|
||||
@ -350,9 +351,11 @@ public class ShellyChannelDefinitions {
|
||||
}
|
||||
|
||||
// Shelly 1/1PM and Plus 1/1PM Addon
|
||||
if (profile.settings.extSwitch != null && profile.settings.extSwitch.input0 != null
|
||||
&& idx == getInteger(profile.settings.extSwitch.input0.relayNum)) {
|
||||
addChannel(thing, add, true, CHGR_SENSOR, CHANNEL_ESENSOR_INPUT + (idx + 1));
|
||||
boolean addon = profile.settings.extSwitch != null && profile.settings.extSwitch.input0 != null
|
||||
&& idx == getInteger(profile.settings.extSwitch.input0.relayNum);
|
||||
if (addon) {
|
||||
addChannel(thing, add, addon, CHGR_SENSOR,
|
||||
CHANNEL_ESENSOR_INPUT + (profile.settings.extSwitch.input0.relayNum + 1));
|
||||
}
|
||||
if (profile.status.extTemperature != null) {
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP1);
|
||||
@ -361,7 +364,8 @@ public class ShellyChannelDefinitions {
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor4 != null, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP4);
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor5 != null, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP5);
|
||||
}
|
||||
addChannel(thing, add, profile.status.extHumidity != null, CHGR_SENSOR, CHANNEL_ESENSOR_HUMIDITY);
|
||||
addChannel(thing, add, profile.status.extHumidity != null && profile.status.extHumidity.sensor1 != null,
|
||||
CHGR_SENSOR, CHANNEL_ESENSOR_HUMIDITY);
|
||||
addChannel(thing, add, profile.status.extVoltage != null, CHGR_SENSOR, CHANNEL_ESENSOR_VOLTAGE);
|
||||
addChannel(thing, add, profile.status.extDigitalInput != null, CHGR_SENSOR, CHANNEL_ESENSOR_DIGITALINPUT);
|
||||
addChannel(thing, add, profile.status.extAnalogInput != null, CHGR_SENSOR, CHANNEL_ESENSOR_ANALOGINPUT);
|
||||
@ -379,6 +383,7 @@ public class ShellyChannelDefinitions {
|
||||
|
||||
if (profile.settings.dimmers != null) {
|
||||
ShellySettingsDimmer ds = profile.settings.dimmers.get(idx);
|
||||
addChannel(thing, add, ds.name != null, group, CHANNEL_OUTPUT_NAME);
|
||||
addChannel(thing, add, ds.autoOn != null, group, CHANNEL_TIMER_AUTOON);
|
||||
addChannel(thing, add, ds.autoOff != null, group, CHANNEL_TIMER_AUTOOFF);
|
||||
ShellyShortLightStatus dss = dstatus.dimmers.get(idx);
|
||||
@ -473,7 +478,7 @@ public class ShellyChannelDefinitions {
|
||||
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, emeter.total != null && profile.numMeters > 1, group, CHANNEL_EMETER_RESETTOTAL); // 3EM
|
||||
addChannel(thing, newChannels, profile.is3EM, group, CHANNEL_EMETER_RESETTOTAL); // 3EM
|
||||
addChannel(thing, newChannels, true, group, CHANNEL_LAST_UPDATE);
|
||||
return newChannels;
|
||||
}
|
||||
@ -505,7 +510,8 @@ public class ShellyChannelDefinitions {
|
||||
addChannel(thing, newChannels, sdata.sensor.vibration != null, CHANNEL_GROUP_SENSOR,
|
||||
CHANNEL_SENSOR_VIBRATION);
|
||||
}
|
||||
if (sdata.accel != null) { // DW2
|
||||
// Create tilt for DW/DW2, for BLU DW create channel even tilt is currently not reported
|
||||
if (sdata.accel != null || (profile.isBlu && sdata.lux != null)) {
|
||||
addChannel(thing, newChannels, sdata.accel.tilt != null, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_TILT);
|
||||
}
|
||||
|
||||
|
@ -89,4 +89,33 @@
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
<config-description uri="thing-type:shelly:dimmer-gen2">
|
||||
<parameter name="deviceIp" type="text" required="true">
|
||||
<label>@text/thing-type.config.shelly.deviceIp.label</label>
|
||||
<description>@text/thing-type.config.shelly.deviceIp.description</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="userId" type="text" required="false">
|
||||
<label>@text/thing-type.config.shelly.userId.label</label>
|
||||
<description>@text/thing-type.config.shelly.userId.description</description>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="false">
|
||||
<label>@text/thing-type.config.shelly.password.label</label>
|
||||
<description>@text/thing-type.config.shelly.password.description</description>
|
||||
<context>password</context>
|
||||
</parameter>
|
||||
<parameter name="brightnessAutoOn" type="boolean" required="false">
|
||||
<label>@text/thing-type.config.shelly.light.brightnessAutoOn.label</label>
|
||||
<description>@text/thing-type.config.shelly.light.brightnessAutoOn.description</description>
|
||||
<default>true</default>
|
||||
</parameter>
|
||||
<parameter name="updateInterval" type="integer" min="10" required="true" unit="s">
|
||||
<label>@text/thing-type.config.shelly.updateInterval.label</label>
|
||||
<description>@text/thing-type.config.shelly.updateInterval.description</description>
|
||||
<default>60</default>
|
||||
<unitLabel>seconds</unitLabel>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</config-description:config-descriptions>
|
||||
|
@ -88,6 +88,22 @@ thing-type.shelly.shellytrv.description = Shelly TRV (Radiator value, battery po
|
||||
thing-type.shelly.shellyix3.description = Shelly ix3 (Activation Device with 3 inputs)
|
||||
thing-type.shelly.shellypludht.description = Shelly Plus HT - Temperature and Humidity Sensor
|
||||
|
||||
# Plus Devices
|
||||
thing-type.shelly.shellyplus1.description = Shelly Plus 1 (Single Relay Switch)
|
||||
thing-type.shelly.shellyplus1pm.description = Shelly Plus 1PM - Single Relay Switch with Power Meter
|
||||
thing-type.shelly.shellyplus2-relay.description = Shelly Plus 2PM - Dual Relay Switch with Power Meter
|
||||
thing-type.shelly.shellyplus2pm-roller.description = Shelly Plus 2PM - Roller Control with Power Meter
|
||||
thing-type.shelly.shellyplusplug.description = Shelly Plus Plug S/IT/UK/US . Outlet with Power Meter
|
||||
thing-type.shelly.shellyplusi4.description = Shelly Plus i4 - 4xInput 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.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
|
||||
|
||||
# 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
|
||||
@ -97,31 +113,10 @@ thing-type.shelly.shellypro2pm-roller.description = Shelly Pro 2PM - Roller Cont
|
||||
thing-type.shelly.shellypro3.description = Shelly Pro 3 - 3xRelay Switch
|
||||
thing-type.shelly.shellypro3em.description = Shelly Pro 3EM - 3xPower Meter
|
||||
thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch with Power Meter
|
||||
|
||||
# Plus devices
|
||||
thing-type.shelly.shellyplus1.description = Shelly Plus 1 (Single Relay Switch)
|
||||
thing-type.shelly.shellyplus1pm.description = Shelly Plus 1PM - Single Relay Switch with Power Meter
|
||||
thing-type.shelly.shellyplus2-relay.description = Shelly Plus 2PM - Dual Relay Switch with Power Meter
|
||||
thing-type.shelly.shellyplus2pm-roller.description = Shelly Plus 2PM - Roller Control with Power Meter
|
||||
thing-type.shelly.shellyplusplug.description = Shelly Plus Plug S/IT/UK/US . Outlet with Power Meter
|
||||
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.shellyplusi4.description = Shelly Plus i4 - 4xInput Device
|
||||
thing-type.shelly.shellyplusi4dc.description = Shelly Plus i4DC - 4xDC Input Device
|
||||
|
||||
# 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.shellypro2-relay.description = Shelly Pro 2 - Dual Relay Switch
|
||||
thing-type.shelly.shellypro2-roller.description = Shelly Pro 2 - Roller Control
|
||||
thing-type.shelly.shellypro2pm-relay.description= Shelly Pro 2PM - Dual 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.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
|
||||
# BLU devices
|
||||
thing-type.shelly.shellypblubutton.description = Shelly BLU Button
|
||||
thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor
|
||||
|
||||
# thing config - shellydevice
|
||||
thing-type.config.shelly.deviceIp.label = IP Address
|
||||
|
@ -479,7 +479,7 @@
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Current</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.2f %unit%">
|
||||
</state>
|
||||
@ -490,24 +490,36 @@
|
||||
<label>@text/channel-type.shelly.meterAccuWatts.label</label>
|
||||
<description>@text/channel-type.shelly.meterAccuWatts.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.2f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="meterAccuTotal" advanced="true">
|
||||
<item-type>Number:Power</item-type>
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>@text/channel-type.shelly.meterAccuTotal.label</label>
|
||||
<description>@text/channel-type.shelly.meterAccuTotal.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.3f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="meterAccuReturned" advanced="true">
|
||||
<item-type>Number:Power</item-type>
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>@text/channel-type.shelly.meterAccuReturned.label</label>
|
||||
<description>@text/channel-type.shelly.meterAccuReturned.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.3f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
@ -521,10 +533,14 @@
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="lastPower1" advanced="true">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>@text/channel-type.shelly.lastPower1.label</label>
|
||||
<description>@text/channel-type.shelly.lastPower1.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.3f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
@ -533,7 +549,6 @@
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>@text/channel-type.shelly.meterTotal.label</label>
|
||||
<description>@text/channel-type.shelly.meterTotal.description</description>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.3f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
@ -543,6 +558,10 @@
|
||||
<label>@text/channel-type.shelly.meterReturned.label</label>
|
||||
<description>@text/channel-type.shelly.meterReturned.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.3f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
@ -551,6 +570,7 @@
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>@text/channel-type.shelly.meterVoltage.label</label>
|
||||
<description>@text/channel-type.shelly.meterVoltage.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Voltage</tag>
|
||||
@ -560,13 +580,13 @@
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="meterCurrent">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>@text/channel-type.shelly.meterCurrent.label</label>
|
||||
<description>@text/channel-type.shelly.meterCurrent.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
<tag>Current</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.3f %unit%">
|
||||
</state>
|
||||
|
@ -290,4 +290,18 @@
|
||||
<config-description-ref uri="thing-type:shelly:relay-gen2"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="shellypluswdus">
|
||||
<label>Shelly Plus Dimmer US</label>
|
||||
<description>@text/thing-type.shelly.shellypluswdus.description</description>
|
||||
<category>DimmableLight</category>
|
||||
<channel-groups>
|
||||
<channel-group id="relay" typeId="dimmerChannel"/>
|
||||
<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:dimmer-gen2"/>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
|
@ -32,4 +32,16 @@
|
||||
<config-description-ref uri="thing-type:shelly:battery-gen2"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="shellywalldisplay">
|
||||
<label>Shelly Wall Display</label>
|
||||
<description>@text/thing-type.shelly.shellywalldisplay.description</description>
|
||||
<category>Sensor</category>
|
||||
<channel-groups>
|
||||
<channel-group id="sensors" typeId="sensorData"/>
|
||||
<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:thing-descriptions>
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* This script uses the BLE scan functionality in scripting to pass scan reults to openHAB
|
||||
* Supported BLU Devices: SBBT , SBDW
|
||||
* Version 0.2
|
||||
*/
|
||||
|
||||
let ALLTERCO_DEVICE_NAME_PREFIX = ["SBBT", "SBDW"];
|
||||
@ -147,21 +148,11 @@ function scanCB(ev, res) {
|
||||
}
|
||||
}
|
||||
|
||||
// retry several times to start the scanner if script was started before
|
||||
// BLE infrastructure was up in the Shelly
|
||||
function startBLEScan() {
|
||||
let bleScanSuccess = BLE.Scanner.Start({ duration_ms: SCAN_DURATION, active: true }, scanCB);
|
||||
if( bleScanSuccess === false ) {
|
||||
Timer.set(1000, false, startBLEScan);
|
||||
} else {
|
||||
console.log('Success: OH-BLU Event Gateway running');
|
||||
}
|
||||
}
|
||||
|
||||
let BLEConfig = Shelly.getComponentConfig('ble');
|
||||
if(BLEConfig.enable === false) {
|
||||
console.log('Error: BLE not enabled');
|
||||
console.log('Error: BLE not enabled, unable to start OH-BLU Scanner');
|
||||
} else {
|
||||
Timer.set(1000, false, startBLEScan);
|
||||
BLE.Scanner.Start({ duration_ms: SCAN_DURATION, active: true }, scanCB);
|
||||
console.log('OH-BLU Event Gateway running');
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user