From 0d73ed8150b4b1caf376f613a1a9c5ece4368abc Mon Sep 17 00:00:00 2001 From: Markus Michels Date: Thu, 4 Aug 2022 08:42:29 +0200 Subject: [PATCH] [shelly] Minor bugfixes from hardening (#13200) * Minor bugfixes from hardening Signed-off-by: Markus Michels * review changes applied Signed-off-by: Markus Michels * controlProfile is type String Signed-off-by: Markus Michels --- bundles/org.openhab.binding.shelly/README.md | 4 +- .../internal/ShellyBindingConstants.java | 15 +-- .../shelly/internal/ShellyHandlerFactory.java | 11 +- .../internal/api/ShellyApiInterface.java | 2 + .../internal/api/ShellyDeviceProfile.java | 33 +++--- .../internal/api1/Shelly1ApiJsonDTO.java | 73 ++++++------- .../internal/api1/Shelly1CoIoTVersion2.java | 5 +- .../shelly/internal/api1/Shelly1HttpApi.java | 6 +- .../internal/handler/ShellyBaseHandler.java | 70 +++++++++--- .../internal/handler/ShellyComponents.java | 95 +++++++++++++++- .../internal/handler/ShellyLightHandler.java | 7 +- .../internal/handler/ShellyRelayHandler.java | 101 +++--------------- .../internal/manager/ShellyManagerPage.java | 8 +- .../provider/ShellyChannelDefinitions.java | 57 +++++----- .../shelly/internal/util/ShellyUtils.java | 6 +- .../resources/OH-INF/i18n/shelly.properties | 12 +-- .../main/resources/OH-INF/thing/device.xml | 7 -- .../{lights.xml => shellyGen1_lights.xml} | 30 +----- .../thing/{relay.xml => shellyGen1_relay.xml} | 0 .../{sensor.xml => shellyGen1_sensor.xml} | 12 ++- 20 files changed, 302 insertions(+), 252 deletions(-) rename bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/{lights.xml => shellyGen1_lights.xml} (91%) rename bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/{relay.xml => shellyGen1_relay.xml} (100%) rename bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/{sensor.xml => shellyGen1_sensor.xml} (98%) diff --git a/bundles/org.openhab.binding.shelly/README.md b/bundles/org.openhab.binding.shelly/README.md index e4d3ffa5b..6de414e9d 100644 --- a/bundles/org.openhab.binding.shelly/README.md +++ b/bundles/org.openhab.binding.shelly/README.md @@ -906,12 +906,12 @@ You should calibrate the valve using the device Web UI or Shelly App before star |control |targetTemp |Number |no |Temperature in °C: 4=Low/Min; 5..30=target temperature;31=Hi/Max | | |position |Dimmer |no |Set valve to manual mode (0..100%) disables auto-temp) | | |mode |String |no |Switch between manual and automatic mode | -| |profile |Number |no |Select profile: 0=disable, 1-n: profile index from Shelly Web App | +| |selectedProfile|String |no |Select profile: Profile name or 0=disable, 1-n: profile index | | |boost |Number |no |Enable/disable boost mode (full heating power) | | |boostTimer |Number |no |Number of minutes to heat at full power while boost mode is enabled | +| |schedule |Switch |yes |ON: Schedule is active | |battery |batteryLevel |Number |yes |Battery Level in % | | |batteryAlert |Switch |yes |Low battery alert | -|device |schedule |Switch |yes |ON: Schedule is active | ### Shelly Button 1 or 2 (thing-type: shellybutton1 / shellybutton2) diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java index 2c0e00f10..7179eed18 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java @@ -134,12 +134,14 @@ public class ShellyBindingConstants { public static final String CHANNEL_SENSOR_ALARM_STATE = "alarmState"; public static final String CHANNEL_SENSOR_ERROR = "lastError"; - public static final String CHANNEL_CONTROL_SETTEMP = "targetTemp"; // Shelly TRV: target temp - public static final String CHANNEL_CONTROL_POSITION = "position"; // Shelly TRV: Valve position - public static final String CHANNEL_CONTROL_MODE = "mode"; // Shelly TRV - public static final String CHANNEL_CONTROL_PROFILE = "profile"; // Shelly TRV - public static final String CHANNEL_CONTROL_BCONTROL = "boost"; // Shelly TRV - public static final String CHANNEL_CONTROL_BTIMER = "boostTimer"; // Shelly TRV + // TRV + public static final String CHANNEL_CONTROL_SETTEMP = "targetTemp"; + public static final String CHANNEL_CONTROL_POSITION = "position"; + public static final String CHANNEL_CONTROL_MODE = "mode"; + public static final String CHANNEL_CONTROL_PROFILE = "selectedProfile"; + public static final String CHANNEL_CONTROL_BCONTROL = "boost"; + public static final String CHANNEL_CONTROL_BTIMER = "boostTimer"; + public static final String CHANNEL_CONTROL_SCHEDULE = "schedule"; // External sensors for Shelly1/1PM public static final String CHANNEL_ESENDOR_TEMP1 = CHANNEL_SENSOR_TEMP + "1"; @@ -192,7 +194,6 @@ public class ShellyBindingConstants { public static final String CHANNEL_DEVST_SELFTTEST = "selfTest"; public static final String CHANNEL_DEVST_VOLTAGE = "supplyVoltage"; public static final String CHANNEL_DEVST_CALIBRATED = "calibrated"; - public static final String CHANNEL_DEVST_SCHEDULE = "schedule"; public static final String CHANNEL_LED_STATUS_DISABLE = "statusLed"; public static final String CHANNEL_LED_POWER_DISABLE = "powerLed"; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java index a2cab8c4f..2ec06f032 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java @@ -63,7 +63,6 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory { private final HttpClient httpClient; private final ShellyTranslationProvider messages; private final Shelly1CoapServer coapServer; - private final ShellyThingTable thingTable; private ShellyBindingConfiguration bindingConfig = new ShellyBindingConfiguration(); private String localIP = ""; @@ -82,10 +81,10 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory { @Reference HttpClientFactory httpClientFactory, ComponentContext componentContext, Map configProperties) { super.activate(componentContext); - messages = translationProvider; - // Save bindingConfig & pass it to all registered listeners - bindingConfig.updateFromProperties(configProperties); + this.messages = translationProvider; + this.thingTable = thingTable; + bindingConfig.updateFromProperties(configProperties); localIP = bindingConfig.localIP; if (localIP.isEmpty()) { localIP = ShellyUtils.getString(networkAddressService.getPrimaryIpv4HostAddress()); @@ -101,7 +100,6 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory { } logger.debug("Using OH HTTP port {}", httpPort); - this.thingTable = thingTable; this.coapServer = new Shelly1CoapServer(); } @@ -124,7 +122,8 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory { } else if (thingType.equals(THING_TYPE_SHELLYBULB_STR) || thingType.equals(THING_TYPE_SHELLYDUO_STR) || thingType.equals(THING_TYPE_SHELLYRGBW2_COLOR_STR) || thingType.equals(THING_TYPE_SHELLYRGBW2_WHITE_STR) - || thingType.equals(THING_TYPE_SHELLYDUORGBW_STR)) { + || thingType.equals(THING_TYPE_SHELLYRGBW2_WHITE_STR) || thingType.equals(THING_TYPE_SHELLYDUORGBW_STR) + || thingType.equals(THING_TYPE_SHELLYVINTAGE_STR)) { logger.debug("{}: Create new thing of type {} using ShellyLightHandler", thing.getLabel(), thingTypeUID.toString()); handler = new ShellyLightHandler(thing, messages, bindingConfig, coapServer, localIP, httpPort, httpClient); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java index e267de7e8..12e99f08a 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java @@ -35,6 +35,8 @@ import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration; public interface ShellyApiInterface { public boolean isInitialized(); + public void initialize() throws ShellyApiException; + public void setConfig(String thingName, ShellyThingConfiguration config); public ShellySettingsDevice getDeviceInfo() throws ShellyApiException; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java index 2d576a27e..8b0965ea3 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java @@ -30,6 +30,7 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettings import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRelay; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRgbwLight; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus; +import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyThermnostat; import org.openhab.binding.shelly.internal.util.ShellyVersionDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,6 +61,7 @@ public class ShellyDeviceProfile { public String hostname = ""; public String name = ""; + public String model = ""; public String mode = ""; public boolean discoverable = true; public boolean auth = false; @@ -154,18 +156,6 @@ public class ShellyDeviceProfile { numMeters = inColor ? 1 : getInteger(settings.device.numOutputs); } - if (settings.sleepMode != null) { - // Sensor, usually 12h, H&T in USB mode 10min - updatePeriod = getString(settings.sleepMode.unit).equalsIgnoreCase("m") ? settings.sleepMode.period * 60 // minutes - : settings.sleepMode.period * 3600; // hours - updatePeriod += 60; // give 1min extra - } else if ((settings.coiot != null) && settings.coiot.updatePeriod != null && !isTRV) { - // Derive from CoAP update interval, usually 2*15+10s=40sec -> 70sec - updatePeriod = Math.max(UPDATE_SETTINGS_INTERVAL_SECONDS, 2 * getInteger(settings.coiot.updatePeriod)) + 10; - } else { - updatePeriod = UPDATE_SETTINGS_INTERVAL_SECONDS + 10; - } - initialized = true; return this; } @@ -244,8 +234,11 @@ public class ShellyDeviceProfile { return CHANNEL_GROUP_RELAY_CONTROL; } else if (hasRelays) { return numRelays <= 1 ? CHANNEL_GROUP_RELAY_CONTROL : CHANNEL_GROUP_RELAY_CONTROL + idx; + } else if (isRGBW2) { + return settings.lights == null || settings.lights.size() <= 1 ? CHANNEL_GROUP_LIGHT_CONTROL + : CHANNEL_GROUP_LIGHT_CHANNEL + idx; } else if (isLight) { - return numRelays <= 1 ? CHANNEL_GROUP_LIGHT_CONTROL : CHANNEL_GROUP_LIGHT_CONTROL + idx; + return CHANNEL_GROUP_LIGHT_CONTROL; } else if (isButton) { return CHANNEL_GROUP_STATUS; } else if (isSensor) { @@ -337,6 +330,20 @@ public class ShellyDeviceProfile { return -1; } + public String getValueProfile(int profileId) { + int id = profileId; + if (settings.thermostats != null) { + ShellyThermnostat t = settings.thermostats.get(0); + id = profileId == 0 ? getInteger(t.profile) : profileId; + if (id <= 0) { + return "DISABLED"; + } + return id <= t.profileNames.length ? getString(t.profileNames[id - 1]) : "" + id; + } + + return "" + id; + } + public static String extractFwVersion(@Nullable String version) { if (version != null) { // fix version e.g. 20210319-122304/v.1.10-Dimmer1-gfd4cc10 (with v.1. instead of v1.) diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1ApiJsonDTO.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1ApiJsonDTO.java index 4cf98d396..ed3257bff 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1ApiJsonDTO.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1ApiJsonDTO.java @@ -15,6 +15,7 @@ package org.openhab.binding.shelly.internal.api1; import java.util.ArrayList; import java.util.List; +import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyMotionSettings; import org.openhab.core.thing.CommonTriggerEvents; @@ -265,8 +266,6 @@ public class Shelly1ApiJsonDTO { public String fw; public Boolean auth; public Integer gen; - - @SerializedName("coiot") // Shelly Motion Multicast Endpoint public String coiot; public Integer longid; @@ -409,10 +408,6 @@ public class Shelly1ApiJsonDTO { public Boolean overpower; @SerializedName("is_valid") public Boolean isValid; - @SerializedName("ext_temperature") - public ShellyStatusSensor.ShellyExtTemperature extTemperature; // Shelly 1/1PM: sensor values - @SerializedName("ext_humidity") - public ShellyStatusSensor.ShellyExtHumidity extHumidity; // Shelly 1/1PM: sensor values } public static class ShellySettingsDimmer { @@ -566,22 +561,22 @@ public class Shelly1ApiJsonDTO { public static class ShellySettingsGlobal { // https://shelly-api-docs.shelly.cloud/#shelly1pm-settings - public ShellySettingsDevice device; + public ShellySettingsDevice device = new ShellySettingsDevice(); @SerializedName("wifi_ap") - public ShellySettingsWiFiAp wifiAp; + public ShellySettingsWiFiAp wifiAp = new ShellySettingsWiFiAp(); @SerializedName("wifi_sta") - public ShellySettingsWiFiNetwork wifiSta; + public ShellySettingsWiFiNetwork wifiSta = new ShellySettingsWiFiNetwork(); @SerializedName("wifi_sta1") - public ShellySettingsWiFiNetwork wifiSta1; + public ShellySettingsWiFiNetwork wifiSta1 = new ShellySettingsWiFiNetwork(); @SerializedName("wifirecovery_reboot_enabled") public Boolean wifiRecoveryReboot; // FW 1.10+ @SerializedName("ap_roaming") public ShellyApRoaming apRoaming; // FW 1.10+ - public ShellySettingsMqtt mqtt; // not used for now - public ShellySettingsSntp sntp; // not used for now - public ShellySettingsCoiot coiot; // Firmware 1.6+ - public ShellySettingsLogin login; + public ShellySettingsMqtt mqtt = new ShellySettingsMqtt(); + public ShellySettingsSntp sntp = new ShellySettingsSntp(); + public ShellySettingsCoiot coiot = new ShellySettingsCoiot(); + public ShellySettingsLogin login = new ShellySettingsLogin(); @SerializedName("pin_code") public String pinCode; @SerializedName("coiot_execute_enable") @@ -590,8 +585,8 @@ public class Shelly1ApiJsonDTO { public Boolean discoverable; // FW 1.6+ public String fw; @SerializedName("build_info") - public ShellySettingsBuildInfo buildInfo; - public ShellyStatusCloud cloud; + public ShellySettingsBuildInfo buildInfo = new ShellySettingsBuildInfo(); + public ShellyStatusCloud cloud = new ShellyStatusCloud(); @SerializedName("sleep_mode") public ShellySensorSleepMode sleepMode; // FW 1.6 @SerializedName("external_power") @@ -610,19 +605,22 @@ public class Shelly1ApiJsonDTO { @SerializedName("max_power") public Double maxPower; public Boolean calibrated; - - public ArrayList relays; - public ArrayList rollers; - public ArrayList dimmers; - public ArrayList lights; - public ArrayList emeters; - public ArrayList inputs; // ix3 - public ArrayList thermostats; // TRV - public Double voltage; // AC voltage for Shelly 2.5 @SerializedName("supply_voltage") public Long supplyVoltage; // Shelly 1PM/1L: 0=110V, 1=220V + public @Nullable ArrayList relays; + public @Nullable ArrayList inputs; // ix3 + public @Nullable ArrayList dimmers; + public @Nullable ArrayList rollers; + public @Nullable ArrayList lights; + public @Nullable ArrayList emeters; + public @Nullable ArrayList thermostats; // TRV + @SerializedName("ext_temperature") + public ShellyStatusSensor.ShellyExtTemperature extTemperature; // Shelly 1/1PM: sensor values + @SerializedName("ext_humidity") + public ShellyStatusSensor.ShellyExtHumidity extHumidity; // Shelly 1/1PM: sensor values + @SerializedName("temperature_units") public String temperatureUnits = "C"; // Either'C'or'F' @@ -703,9 +701,9 @@ public class Shelly1ApiJsonDTO { public String name; // FW 1.8: Symbolic Device name is configurable @SerializedName("wifi_sta") - public ShellySettingsWiFiNetwork wifiSta; // WiFi client configuration. See /settings/sta for details - public ShellyStatusCloud cloud; - public ShellyStatusMqtt mqtt; + public ShellySettingsWiFiNetwork wifiSta = new ShellySettingsWiFiNetwork(); + public ShellyStatusCloud cloud = new ShellyStatusCloud(); + public ShellyStatusMqtt mqtt = new ShellyStatusMqtt(); public String time; public Integer serial = -1; @@ -717,21 +715,23 @@ public class Shelly1ApiJsonDTO { public Integer cfgChangedCount; // FW 1.8 @SerializedName("actions_stats") public ShellyActionsStats astats; - - public ArrayList relays; public Double voltage; // Shelly 2.5 - public ArrayList rollers; public Integer input; // RGBW2 has no JSON array - public ArrayList inputs; - public ArrayList lights; + public ArrayList relays; + public ArrayList rollers; public ArrayList dimmers; + public ArrayList inputs; public ArrayList meters; public ArrayList emeters; + @SerializedName("ext_temperature") + public ShellyStatusSensor.ShellyExtTemperature extTemperature; // Shelly 1/1PM: sensor values + @SerializedName("ext_humidity") + public ShellyStatusSensor.ShellyExtHumidity extHumidity; // Shelly 1/1PM: sensor values // Internal device temp - public ShellySensorTmp tmp; // Shelly 1PM - public Double temperature = SHELLY_API_INVTEMP; // Shelly 2.5 + public ShellySensorTmp tmp = new ShellySensorTmp(); // Shelly 1PM + public Double temperature; // Shelly 2.5 public Boolean overtemperature; // Shelly Dimmer only @@ -742,7 +742,8 @@ public class Shelly1ApiJsonDTO { public Boolean calibrated; public ArrayList thermostats; - public ShellySettingsUpdate update; + public ShellySettingsUpdate update = new ShellySettingsUpdate(); + @SerializedName("ram_total") public Long ramTotal; @SerializedName("ram_free") diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java index 432ff3878..cd84004b2 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java @@ -106,8 +106,9 @@ public class Shelly1CoIoTVersion2 extends Shelly1CoIoTProtocol implements Shelly break; case "3117": // S, mode, 0-5 (0=disabled) value = getDouble(s.value).intValue(); - updateChannel(updates, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_PROFILE, getDecimal(value)); - updateChannel(updates, CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_SCHEDULE, getOnOff(value > 0)); + updateChannel(updates, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_PROFILE, + getStringType(profile.getValueProfile((int) value))); + updateChannel(updates, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE, getOnOff(value > 0)); break; case "3118": // Valve state updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_STATE, diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java index 9c6b8b7f2..af5d75477 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java @@ -37,6 +37,7 @@ import org.openhab.binding.shelly.internal.api.ShellyApiResult; import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile; import org.openhab.binding.shelly.internal.api.ShellyHttpClient; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyOtaCheckResult; +import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyRollerStatus; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySendKeyList; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySenseKeyCode; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDevice; @@ -151,8 +152,9 @@ public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterfa try { json = httpRequest(SHELLY_URL_STATUS); // Dimmer2 returns invalid json type for loaderror :-( - json = getString(json.replace("\"loaderror\":0,", "\"loaderror\":false,")); - json = getString(json.replace("\"loaderror\":1,", "\"loaderror\":true,")); + json = json.replace("\"loaderror\":0,", "\"loaderror\":false,") + .replace("\"loaderror\":1,", "\"loaderror\":true,") + .replace("\"tmp\":{\"value\": \"null\",", "\"tmp\":{\"value\": null,"); ShellySettingsStatus status = fromJson(gson, json, ShellySettingsStatus.class); status.json = json; return status; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java index 4c8e0d370..025c8f53e 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java @@ -39,6 +39,7 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyInputSta import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyOtaCheckResult; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDevice; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus; +import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyThermnostat; import org.openhab.binding.shelly.internal.api1.Shelly1CoapHandler; import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO; import org.openhab.binding.shelly.internal.api1.Shelly1CoapServer; @@ -87,14 +88,14 @@ public class ShellyBaseHandler extends BaseThingHandler protected final ShellyApiInterface api; private final HttpClient httpClient; - protected ShellyBindingConfiguration bindingConfig; + private ShellyBindingConfiguration bindingConfig; protected ShellyThingConfiguration config = new ShellyThingConfiguration(); protected ShellyDeviceProfile profile = new ShellyDeviceProfile(); // init empty profile to avoid NPE protected ShellyDeviceStats stats = new ShellyDeviceStats(); private final Shelly1CoapHandler coap; public boolean autoCoIoT = false; - public final ShellyTranslationProvider messages; + private final ShellyTranslationProvider messages; protected boolean stopping = false; private boolean channelsCreated = false; @@ -108,7 +109,7 @@ public class ShellyBaseHandler extends BaseThingHandler // delay before enabling channel private final int cacheCount = UPDATE_SETTINGS_INTERVAL_SECONDS / UPDATE_STATUS_INTERVAL_SECONDS; - protected final ShellyChannelCache cache; + private final ShellyChannelCache cache; private String localIP = ""; private String localPort = ""; @@ -225,7 +226,7 @@ public class ShellyBaseHandler extends BaseThingHandler * * @throws ShellyApiException e.g. http returned non-ok response, check e.getMessage() for details. */ - private boolean initializeThing() throws ShellyApiException { + public boolean initializeThing() throws ShellyApiException { // Init from thing type to have a basic profile, gets updated when device info is received from API stopping = false; refreshSettings = false; @@ -251,7 +252,7 @@ public class ShellyBaseHandler extends BaseThingHandler // Initialize API access, exceptions will be catched by initialize() ShellySettingsDevice devInfo = api.getDeviceInfo(); - if (getBool(devInfo.auth) && config.userId.isEmpty()) { + if (getBool(devInfo.auth) && config.password.isEmpty()) { setThingOffline(ThingStatusDetail.CONFIGURATION_ERROR, "offline.conf-error-no-credentials"); return false; } @@ -274,11 +275,26 @@ public class ShellyBaseHandler extends BaseThingHandler // New Shelly devices might use a different endpoint for the CoAP listener tmpPrf.coiotEndpoint = devInfo.coiot; } + if (tmpPrf.settings.sleepMode != null && !tmpPrf.isTRV) { + // Sensor, usually 12h, H&T in USB mode 10min + tmpPrf.updatePeriod = getString(tmpPrf.settings.sleepMode.unit).equalsIgnoreCase("m") + ? tmpPrf.settings.sleepMode.period * 60 // minutes + : tmpPrf.settings.sleepMode.period * 3600; // hours + tmpPrf.updatePeriod += 60; // give 1min extra + } else if ((tmpPrf.settings.coiot != null) && tmpPrf.settings.coiot.updatePeriod != null) { + // Derive from CoAP update interval, usually 2*15+10s=40sec -> 70sec + tmpPrf.updatePeriod = Math.max(UPDATE_SETTINGS_INTERVAL_SECONDS, + 2 * getInteger(tmpPrf.settings.coiot.updatePeriod)) + 10; + } else { + tmpPrf.updatePeriod = UPDATE_SETTINGS_INTERVAL_SECONDS + 10; + } + tmpPrf.auth = devInfo.auth; // missing in /settings tmpPrf.status = api.getStatus(); tmpPrf.updateFromStatus(tmpPrf.status); showThingConfig(tmpPrf); + // update thing properties checkVersion(tmpPrf, tmpPrf.status); if (config.eventsCoIoT && (tmpPrf.settings.coiot != null) && (tmpPrf.settings.coiot.enabled != null)) { @@ -385,14 +401,39 @@ public class ShellyBaseHandler extends BaseThingHandler : 0; api.setSleepTime(value); break; + case CHANNEL_CONTROL_SCHEDULE: + if (profile.isTRV) { + logger.debug("{}: {} Valve schedule/profile", thingName, + command == OnOffType.ON ? "Enable" : "Disable"); + api.setValveProfile(0, + command == OnOffType.OFF ? 0 : profile.status.thermostats.get(0).profile); + } + break; case CHANNEL_CONTROL_PROFILE: logger.debug("{}: Select profile {}", thingName, command); - int profile = (int) getNumber(command); - if (profile < 0 || profile > 5) { - logger.warn("{}: Invalid profile Id {} requested", thingName, profile); - break; + int id = -1; + if (command instanceof Number) { + id = (int) getNumber(command); + } else { + String cmd = command.toString(); + if (isDigit(cmd.charAt(0))) { + id = Integer.parseInt(cmd); + } else if (cmd.equalsIgnoreCase("DISABLED")) { + id = 0; + } else if (profile.settings.thermostats != null) { + ShellyThermnostat t = profile.settings.thermostats.get(0); + for (int i = 0; i < t.profileNames.length; i++) { + if (t.profileNames[i].equalsIgnoreCase(cmd)) { + id = i + 1; + } + } + } + } + if (id < 0 || id > 5) { + logger.warn("{}: Invalid profile Id {} requested", thingName, profile); + } else { + api.setValveProfile(0, id); } - api.setValveProfile(0, profile); break; case CHANNEL_CONTROL_MODE: logger.debug("{}: Set mode to {}", thingName, command); @@ -567,9 +608,10 @@ public class ShellyBaseHandler extends BaseThingHandler updateStatus(ThingStatus.ONLINE); // request 3 updates in a row (during the first 2+3*3 sec) - logger.debug("{}: Thing went online, request status update", thingName); requestUpdates(profile.alwaysOn ? 3 : 1, !channelsCreated); } + + // Restart watchdog when status update was successful (no exception) restartWatchdog(); } @@ -695,7 +737,7 @@ public class ShellyBaseHandler extends BaseThingHandler if (force || !lastAlarm.equals(event) || (lastAlarm.equals(event) && now() > stats.lastAlarmTs + HEALTH_CHECK_INTERVAL_SEC)) { - switch (event) { + switch (event.toUpperCase()) { case "": case "0": // DW2 1.8 case SHELLY_WAKEUPT_SENSOR: @@ -957,7 +999,7 @@ public class ShellyBaseHandler extends BaseThingHandler * @param thingType thing type acc. to the xml definition * @param mode Device mode (e.g. relay, roller) */ - private void changeThingType(String thingType, String mode) { + protected void changeThingType(String thingType, String mode) { ThingTypeUID thingTypeUID = ShellyThingCreator.getThingTypeUID(thingType, "", mode); if (!thingTypeUID.equals(THING_TYPE_SHELLYUNKNOWN)) { logger.debug("{}: Changing thing type to {}", getThing().getLabel(), thingTypeUID); @@ -1034,7 +1076,7 @@ public class ShellyBaseHandler extends BaseThingHandler int idx = 0; boolean multiInput = status.inputs.size() >= 2; // device has multiple SW (inputs) for (ShellyInputState input : status.inputs) { - String group = profile.getControlGroup(idx); + String group = profile.getInputGroup(idx); String suffix = multiInput ? profile.getInputSuffix(idx) : ""; if (!areChannelsCreated()) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java index 34f94f9ff..b22666754 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java @@ -20,8 +20,10 @@ 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.ShellyRollerStatus; 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.ShellyStatusSensor; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyADC; @@ -29,6 +31,7 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyThermnos import org.openhab.binding.shelly.internal.provider.ShellyChannelDefinitions; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OpenClosedType; +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; @@ -86,6 +89,83 @@ public class ShellyComponents { return false; // device status never triggers update } + public static boolean updateRelay(ShellyBaseHandler thingHandler, ShellySettingsStatus status, int id) { + ShellyDeviceProfile profile = thingHandler.getProfile(); + ShellySettingsRelay rsettings = profile.settings.relays.get(id); + ShellySettingsRelay relay = status.relays.get(id); + + boolean updated = false; + if (relay.isValid == null || relay.isValid) { + String groupName = profile.getControlGroup(id); + updated |= thingHandler.updateChannel(groupName, CHANNEL_OUTPUT_NAME, getStringType(rsettings.name)); + + if (getBool(relay.overpower)) { + thingHandler.postEvent(ALARM_TYPE_OVERPOWER, false); + } + + updated |= thingHandler.updateChannel(groupName, CHANNEL_OUTPUT, getOnOff(relay.ison)); + updated |= thingHandler.updateChannel(groupName, CHANNEL_TIMER_ACTIVE, getOnOff(relay.hasTimer)); + if (status.extTemperature != null) { + // Shelly 1/1PM support up to 3 external sensors + // for whatever reason those are not represented as an array, but 3 elements + if (status.extTemperature.sensor1 != null) { + updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP1, + toQuantityType(getDouble(status.extTemperature.sensor1.tC), DIGITS_TEMP, SIUnits.CELSIUS)); + } + if (status.extTemperature.sensor2 != null) { + updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP2, + toQuantityType(getDouble(status.extTemperature.sensor2.tC), DIGITS_TEMP, SIUnits.CELSIUS)); + } + if (status.extTemperature.sensor3 != null) { + updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP3, + toQuantityType(getDouble(status.extTemperature.sensor3.tC), DIGITS_TEMP, SIUnits.CELSIUS)); + } + } + if ((status.extHumidity != null) && (status.extHumidity.sensor1 != null)) { + updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_HUM, + toQuantityType(getDouble(status.extHumidity.sensor1.hum), DIGITS_PERCENT, Units.PERCENT)); + } + + // Update Auto-ON/OFF timer + updated |= thingHandler.updateChannel(groupName, CHANNEL_TIMER_AUTOON, + toQuantityType(getDouble(rsettings.autoOn), Units.SECOND)); + updated |= thingHandler.updateChannel(groupName, CHANNEL_TIMER_AUTOOFF, + toQuantityType(getDouble(rsettings.autoOff), Units.SECOND)); + } + return updated; + } + + public static boolean updateRoller(ShellyBaseHandler thingHandler, ShellyRollerStatus control, int id) + throws ShellyApiException { + ShellyDeviceProfile profile = thingHandler.getProfile(); + boolean updated = false; + if (getBool(control.isValid)) { + String groupName = profile.getControlGroup(id); + if (control.name != null) { + updated |= thingHandler.updateChannel(groupName, CHANNEL_OUTPUT_NAME, getStringType(control.name)); + } + + String state = getString(control.state); + if (state.equals(SHELLY_ALWD_ROLLER_TURN_STOP)) { + if (control.currentPos != null) { + // only valid in stop state + int pos = Math.max(SHELLY_MIN_ROLLER_POS, Math.min(control.currentPos, SHELLY_MAX_ROLLER_POS)); + updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_CONTROL, + toQuantityType((double) (SHELLY_MAX_ROLLER_POS - pos), Units.PERCENT)); + updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_POS, + toQuantityType((double) pos, Units.PERCENT)); + } + } + + updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_STATE, new StringType(state)); + updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_STOPR, + getStringType(control.stopReason)); + updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_SAFETY, + getOnOff(control.safetySwitch)); + } + return updated; + } + /** * Update Meter channel * @@ -111,8 +191,12 @@ public class ShellyComponents { int m = 0; if (!profile.isEMeter) { for (ShellySettingsMeter meter : status.meters) { + if (m >= profile.numMeters) { + // Shelly1: reports status.meters[0].is_valid = true, but even doesn't have a meter + meter.isValid = false; + } if (getBool(meter.isValid) || profile.isLight) { // RGBW2-white doesn't report valid flag - // correctly in white mode + // correctly in white mode String groupName = profile.getMeterGroup(m); if (!thingHandler.areChannelsCreated()) { // skip for Shelly Bulb: JSON has a meter, but values don't get updated @@ -302,7 +386,7 @@ public class ShellyComponents { // Shelly TRV ShellyThermnostat t = status.thermostats.get(0); ShellyThermnostat ps = profile.settings.thermostats.get(0); - int bminutes = getInteger(t.boostMinutes) > 0 ? getInteger(t.boostMinutes) + int bminutes = getInteger(t.boostMinutes) >= 0 ? getInteger(t.boostMinutes) : getInteger(ps.boostMinutes); updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_BCONTROL, getOnOff(getInteger(t.boostMinutes) > 0)); @@ -310,10 +394,11 @@ public class ShellyComponents { toQuantityType((double) bminutes, DIGITS_NONE, Units.MINUTE)); updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_MODE, getStringType(getBool(t.targetTemp.enabled) ? SHELLY_TRV_MODE_AUTO : SHELLY_TRV_MODE_MANUAL)); - updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_PROFILE, - getDecimal(getBool(t.schedule) ? t.profile + 1 : 0)); - updated |= thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_SCHEDULE, + int pid = getBool(t.schedule) ? getInteger(t.profile) : 0; + updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE, getOnOff(t.schedule)); + updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_PROFILE, + getStringType(profile.getValueProfile(pid))); if (t.tmp != null) { Double temp = convertToC(t.tmp.value, getString(t.tmp.units)); updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_TEMP, diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java index ea506aa0a..6a1944338 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java @@ -350,8 +350,11 @@ public class ShellyLightHandler extends ShellyBaseHandler { if (profile.settings.lights != null) { // Channel control/timer ShellySettingsRgbwLight ls = profile.settings.lights.get(lightId); - updated |= updateChannel(controlGroup, CHANNEL_TIMER_AUTOON, getDecimal(ls.autoOn)); - updated |= updateChannel(controlGroup, CHANNEL_TIMER_AUTOOFF, getDecimal(ls.autoOff)); + updated |= updateChannel(controlGroup, CHANNEL_TIMER_AUTOON, + toQuantityType(getDouble(ls.autoOn), Units.SECOND)); + updated |= updateChannel(controlGroup, CHANNEL_TIMER_AUTOOFF, + toQuantityType(getDouble(ls.autoOff), Units.SECOND)); + updated |= updateChannel(controlGroup, CHANNEL_LIGHT_POWER, col.power); updated |= updateChannel(controlGroup, CHANNEL_TIMER_ACTIVE, getOnOff(light.hasTimer)); updated |= updateChannel(controlGroup, CHANNEL_LIGHT_POWER, col.power); } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java index 34fbb7c9a..174817a99 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java @@ -23,11 +23,8 @@ 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.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.Shelly1CoapServer; import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration; import org.openhab.binding.shelly.internal.provider.ShellyChannelDefinitions; @@ -37,9 +34,7 @@ import org.openhab.core.library.types.IncreaseDecreaseType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; import org.openhab.core.library.types.StopMoveType; -import org.openhab.core.library.types.StringType; import org.openhab.core.library.types.UpDownType; -import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -228,7 +223,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler { if ((command == UpDownType.UP && getString(rstatus.state).equals(SHELLY_ALWD_ROLLER_TURN_OPEN)) || (command == UpDownType.DOWN && getString(rstatus.state).equals(SHELLY_ALWD_ROLLER_TURN_CLOSE))) { - logger.debug("{}: Roller is already moving ({}), ignore command {}", thingName, + logger.debug("{}: Roller is already in requested position ({}), ignore command {}", thingName, getString(rstatus.state), command); requestUpdates(1, false); return; @@ -305,7 +300,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler { /** * Auto-create relay channels depending on relay type/mode */ - private void createRelayChannels(ShellyStatusRelay relay, int idx) { + private void createRelayChannels(ShellySettingsRelay relay, int idx) { if (!areChannelsCreated()) { updateChannelDefinitions(ShellyChannelDefinitions.createRelayChannels(getThing(), profile, relay, idx)); } @@ -350,93 +345,23 @@ public class ShellyRelayHandler extends ShellyBaseHandler { } } - if (profile.hasRelays && !profile.isRoller && !profile.isDimmer) { - logger.trace("{}: Updating {} relay(s)", thingName, profile.numRelays); - int i = 0; - ShellyStatusRelay rstatus = api.getRelayStatus(i); - for (ShellyShortStatusRelay relay : rstatus.relays) { - createRelayChannels(rstatus, i); - if ((relay.isValid == null) || relay.isValid) { - String groupName = profile.getControlGroup(i); - ShellySettingsRelay rs = profile.settings.relays.get(i); - updated |= updateChannel(groupName, CHANNEL_OUTPUT_NAME, getStringType(rs.name)); - - if (getBool(relay.overpower)) { - postEvent(ALARM_TYPE_OVERPOWER, false); - } - - updated |= updateChannel(groupName, CHANNEL_OUTPUT, getOnOff(relay.ison)); - updated |= updateChannel(groupName, CHANNEL_TIMER_ACTIVE, getOnOff(relay.hasTimer)); - if (rstatus.extTemperature != null) { - // Shelly 1/1PM support up to 3 external sensors - // for whatever reason those are not represented as an array, but 3 elements - if (rstatus.extTemperature.sensor1 != null) { - updated |= updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP1, toQuantityType( - getDouble(rstatus.extTemperature.sensor1.tC), DIGITS_TEMP, SIUnits.CELSIUS)); - } - if (rstatus.extTemperature.sensor2 != null) { - updated |= updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP2, toQuantityType( - getDouble(rstatus.extTemperature.sensor2.tC), DIGITS_TEMP, SIUnits.CELSIUS)); - } - if (rstatus.extTemperature.sensor3 != null) { - updated |= updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP3, toQuantityType( - getDouble(rstatus.extTemperature.sensor3.tC), DIGITS_TEMP, SIUnits.CELSIUS)); - } - } - if ((rstatus.extHumidity != null) && (rstatus.extHumidity.sensor1 != null)) { - updated |= updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_HUM, toQuantityType( - getDouble(rstatus.extHumidity.sensor1.hum), DIGITS_PERCENT, Units.PERCENT)); - } - - // Update Auto-ON/OFF timer - ShellySettingsRelay rsettings = profile.settings.relays.get(i); - if (rsettings != null) { - updated |= updateChannel(groupName, CHANNEL_TIMER_AUTOON, - toQuantityType(getDouble(rsettings.autoOn), Units.SECOND)); - updated |= updateChannel(groupName, CHANNEL_TIMER_AUTOOFF, - toQuantityType(getDouble(rsettings.autoOff), Units.SECOND)); - } - } + if (profile.hasRelays && !profile.isRoller) { + logger.trace("{}: Updating {} relay(s)", thingName, profile.numRelays); + for (int i = 0; i < status.relays.size(); i++) { + createRelayChannels(status.relays.get(i), i); + updated |= ShellyComponents.updateRelay(this, status, i); i++; } - } else if (profile.hasRelays && profile.isRoller && (status.rollers != null)) { + } else { // Check for Relay in Roller Mode logger.trace("{}: Updating {} rollers", thingName, profile.numRollers); - int i = 0; - - for (ShellySettingsRoller roller : status.rollers) { - if (roller.isValid) { - ShellyRollerStatus control = api.getRollerStatus(i); - Integer relayIndex = i + 1; - String groupName = profile.numRollers > 1 ? CHANNEL_GROUP_ROL_CONTROL + relayIndex.toString() - : CHANNEL_GROUP_ROL_CONTROL; - - createRollerChannels(control); - - if (control.name != null) { - updated |= updateChannel(groupName, CHANNEL_OUTPUT_NAME, getStringType(control.name)); - } - - String state = getString(control.state); - if (state.equals(SHELLY_ALWD_ROLLER_TURN_STOP)) { // only valid in stop state - int pos = Math.max(SHELLY_MIN_ROLLER_POS, Math.min(control.currentPos, SHELLY_MAX_ROLLER_POS)); - logger.debug("{}: REST Update roller position: control={}, position={}", thingName, - SHELLY_MAX_ROLLER_POS - pos, pos); - updated |= updateChannel(groupName, CHANNEL_ROL_CONTROL_CONTROL, - toQuantityType((double) (SHELLY_MAX_ROLLER_POS - pos), Units.PERCENT)); - updated |= updateChannel(groupName, CHANNEL_ROL_CONTROL_POS, - toQuantityType((double) pos, Units.PERCENT)); - scheduledUpdates = 1; // one more poll and then stop - } - - updated |= updateChannel(groupName, CHANNEL_ROL_CONTROL_STATE, new StringType(state)); - updated |= updateChannel(groupName, CHANNEL_ROL_CONTROL_STOPR, getStringType(control.stopReason)); - updated |= updateChannel(groupName, CHANNEL_ROL_CONTROL_SAFETY, getOnOff(control.safetySwitch)); - - i++; - } + for (int i = 0; i < profile.numRollers; i++) { + ShellyRollerStatus roller = status.rollers.get(i); + createRollerChannels(roller); + updated |= ShellyComponents.updateRoller(this, roller, i); } } + return updated; } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java index a1fad7dc3..0efd3276b 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java @@ -212,11 +212,11 @@ public class ShellyManagerPage { ShellyDeviceStats stats = th.getStats(); properties.putAll(stats.asProperties()); - for (Map.Entry p : thing.getConfiguration().getProperties().entrySet()) { + for (Map.Entry p : thing.getConfiguration().getProperties().entrySet()) { String key = p.getKey(); - if (p.getValue() != null) { - String value = p.getValue().toString(); - properties.put(key, value); + Object o = p.getValue(); + if (o != null) { + properties.put(key, o.toString()); } } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java index 670d953a5..51a0141ec 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java @@ -38,9 +38,7 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettings import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsRgbwLight; 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.ShellyStatusLightChannel; -import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusRelay; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor; import org.openhab.binding.shelly.internal.handler.ShellyThingInterface; import org.openhab.core.thing.Channel; @@ -89,6 +87,7 @@ public class ShellyChannelDefinitions { private static final String CHGR_RELAY = CHANNEL_GROUP_RELAY_CONTROL; private static final String CHGR_ROLLER = CHANNEL_GROUP_ROL_CONTROL; private static final String CHGR_LIGHT = CHANNEL_GROUP_LIGHT_CONTROL; + private static final String CHGR_LIGHTCH = CHANNEL_GROUP_LIGHT_CHANNEL; private static final String CHGR_STATUS = CHANNEL_GROUP_STATUS; private static final String CHGR_METER = CHANNEL_GROUP_METER; private static final String CHGR_SENSOR = CHANNEL_GROUP_SENSOR; @@ -122,7 +121,6 @@ public class ShellyChannelDefinitions { .add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_HEARTBEAT, "heartBeat", ITEMT_DATETIME)) .add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_UPDATE, "updateAvailable", ITEMT_SWITCH)) .add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_CALIBRATED, "calibrated", ITEMT_SWITCH)) - .add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_SCHEDULE, "deviceSchedule", ITEMT_SWITCH)) // Relay .add(new ShellyChannel(m, CHGR_RELAY, CHANNEL_OUTPUT_NAME, "outputName", ITEMT_STRING)) @@ -151,16 +149,28 @@ public class ShellyChannelDefinitions { .add(new ShellyChannel(m, CHGR_ROLLER, CHANNEL_STATUS_EVENTCOUNT, "eventCount", ITEMT_NUMBER)) .add(new ShellyChannel(m, CHGR_ROLLER, CHANNEL_EVENT_TRIGGER, "system:button", "system:button")) - // RGBW2 - .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_LIGHT_POWER, "system:power", ITEMT_SWITCH)) + // Bulb/Duo/Vintage .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_INPUT, "inputState", ITEMT_SWITCH)) .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_BUTTON_TRIGGER, "system:button", ITEMT_STRING)) .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_STATUS_EVENTTYPE, "lastEvent", ITEMT_STRING)) .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_STATUS_EVENTCOUNT, "eventCount", ITEMT_NUMBER)) + .add(new ShellyChannel(m, CHANNEL_GROUP_WHITE_CONTROL, CHANNEL_BRIGHTNESS, "whiteBrightness", + ITEMT_DIMMER)) + .add(new ShellyChannel(m, CHANNEL_GROUP_WHITE_CONTROL, CHANNEL_COLOR_TEMP, "whiteTemp", ITEMT_DIMMER)) + + // RGBW2-color + .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_LIGHT_POWER, "system:power", ITEMT_SWITCH)) .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_TIMER_AUTOON, "timerAutoOn", ITEMT_TIME)) .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_TIMER_AUTOOFF, "timerAutoOff", ITEMT_TIME)) .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_TIMER_ACTIVE, "timerActive", ITEMT_SWITCH)) + // RGBW2-white + .add(new ShellyChannel(m, CHGR_LIGHTCH, CHANNEL_BRIGHTNESS, "whiteBrightness", ITEMT_DIMMER)) + .add(new ShellyChannel(m, CHGR_LIGHTCH, CHANNEL_TIMER_AUTOON, "timerAutoOn", ITEMT_TIME)) + .add(new ShellyChannel(m, CHGR_LIGHTCH, CHANNEL_TIMER_AUTOOFF, "timerAutoOff", ITEMT_TIME)) + .add(new ShellyChannel(m, CHGR_LIGHTCH, CHANNEL_TIMER_ACTIVE, "timerActive", ITEMT_SWITCH)) + // RGBW2-color + .add(new ShellyChannel(m, CHGR_LIGHT, CHANNEL_LIGHT_POWER, "system:power", ITEMT_SWITCH)) // 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)) @@ -217,7 +227,8 @@ public class ShellyChannelDefinitions { // TRV .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_POSITION, "sensorPosition", ITEMT_DIMMER)) .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_MODE, "controlMode", ITEMT_STRING)) - .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_PROFILE, "controlProfile", ITEMT_NUMBER)) + .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_SCHEDULE, "controlSchedule", ITEMT_SWITCH)) + .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_PROFILE, "controlProfile", ITEMT_STRING)) .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_SETTEMP, "targetTemp", ITEMT_TEMP)) .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_BCONTROL, "boostControl", ITEMT_SWITCH)) .add(new ShellyChannel(m, CHGR_CONTROL, CHANNEL_CONTROL_BTIMER, "boostTimer", ITEMT_TIME)); @@ -294,16 +305,13 @@ public class ShellyChannelDefinitions { * @return ArrayList of channels to be added to the thing */ public static Map createRelayChannels(final Thing thing, final ShellyDeviceProfile profile, - final ShellyStatusRelay relay, int idx) { + final ShellySettingsRelay rstatus, int idx) { Map add = new LinkedHashMap<>(); String group = profile.getControlGroup(idx); if (profile.settings.relays != null) { ShellySettingsRelay rs = profile.settings.relays.get(idx); - ShellyShortStatusRelay rstatus = relay.relays.get(idx); - boolean timer = rs.hasTimer != null || (rstatus != null && rstatus.hasTimer != null); // Dimmer 1/2 have - // has_timer under - // /status + boolean timer = rs.hasTimer != null || rstatus.hasTimer != null; // Dimmer 1/2 have addChannel(thing, add, rs.ison != null, group, CHANNEL_OUTPUT); addChannel(thing, add, rs.name != null, group, CHANNEL_OUTPUT_NAME); addChannel(thing, add, rs.autoOn != null, group, CHANNEL_TIMER_AUTOON); @@ -312,13 +320,13 @@ public class ShellyChannelDefinitions { } // Shelly 1/1PM Addon - if (relay.extTemperature != null) { - addChannel(thing, add, relay.extTemperature.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP1); - addChannel(thing, add, relay.extTemperature.sensor2 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP2); - addChannel(thing, add, relay.extTemperature.sensor3 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP3); + if (profile.settings.extTemperature != null) { + addChannel(thing, add, profile.settings.extTemperature.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP1); + addChannel(thing, add, profile.settings.extTemperature.sensor2 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP2); + addChannel(thing, add, profile.settings.extTemperature.sensor3 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP3); } - if (relay.extHumidity != null) { - addChannel(thing, add, relay.extHumidity.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENDOR_HUMIDITY); + if (profile.settings.extHumidity != null) { + addChannel(thing, add, profile.settings.extHumidity.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENDOR_HUMIDITY); } return add; @@ -350,13 +358,15 @@ public class ShellyChannelDefinitions { if (profile.settings.lights != null) { ShellySettingsRgbwLight light = profile.settings.lights.get(idx); + String whiteGroup = profile.isRGBW2 ? group : CHANNEL_GROUP_WHITE_CONTROL; + // Create power channel in color mode and brightness channel in white mode addChannel(thing, add, profile.inColor, group, CHANNEL_LIGHT_POWER); - addChannel(thing, add, !profile.inColor, group, CHANNEL_BRIGHTNESS); - addChannel(thing, add, light.temp != null, CHANNEL_GROUP_WHITE_CONTROL, CHANNEL_COLOR_TEMP); addChannel(thing, add, light.autoOn != null, group, CHANNEL_TIMER_AUTOON); addChannel(thing, add, light.autoOff != null, group, CHANNEL_TIMER_AUTOOFF); addChannel(thing, add, status.hasTimer != null, group, CHANNEL_TIMER_ACTIVE); + addChannel(thing, add, light.brightness != null, whiteGroup, CHANNEL_BRIGHTNESS); + addChannel(thing, add, light.temp != null, whiteGroup, CHANNEL_COLOR_TEMP); } return add; } @@ -444,11 +454,10 @@ public class ShellyChannelDefinitions { CHANNEL_SENSOR_ILLUM); addChannel(thing, newChannels, sdata.flood != null, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_FLOOD); addChannel(thing, newChannels, sdata.smoke != null, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_FLOOD); - addChannel(thing, newChannels, (profile.settings.externalPower != null) || (sdata.charger != null), CHGR_DEVST, + addChannel(thing, newChannels, profile.settings.externalPower != null || sdata.charger != null, CHGR_DEVST, CHANNEL_DEVST_CHARGER); - addChannel(thing, newChannels, - sdata.motion != null || ((sdata.sensor != null) && (sdata.sensor.motion != null)), CHANNEL_GROUP_SENSOR, - CHANNEL_SENSOR_MOTION); + addChannel(thing, newChannels, sdata.motion != null || (sdata.sensor != null && sdata.sensor.motion != null), + CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_MOTION); if (sdata.sensor != null) { // DW, Sense or Motion addChannel(thing, newChannels, sdata.sensor.state != null, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_STATE); // DW/DW2 addChannel(thing, newChannels, sdata.sensor.motionActive != null, CHANNEL_GROUP_SENSOR, // Motion @@ -482,13 +491,13 @@ public class ShellyChannelDefinitions { // TRV if (profile.isTRV) { - addChannel(thing, newChannels, true, CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_SCHEDULE); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SETTEMP); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_BCONTROL); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_BTIMER); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_POSITION); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_MODE); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_PROFILE); + addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE); addChannel(thing, newChannels, true, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_STATE); // TRV } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java index 9fd0884c0..e04bf160d 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java @@ -87,14 +87,14 @@ public class ShellyUtils { @Nullable T obj = gson.fromJson(json, classOfT); if ((obj == null) && exceptionOnNull) { // new in OH3: fromJson may return null - throw new ShellyApiException(PRE + className + "from JSON: " + json); + throw new ShellyApiException(PRE + className + " from JSON: " + json); } return obj; } catch (JsonSyntaxException e) { throw new ShellyApiException( PRE + className + "from JSON (syntax/format error: " + e.getMessage() + "): " + json, e); } catch (RuntimeException e) { - throw new ShellyApiException(PRE + className + "from JSON: " + json, e); + throw new ShellyApiException(PRE + className + " from JSON: " + json, e); } } } @@ -321,7 +321,7 @@ public class ShellyUtils { } public static String buildControlGroupName(ShellyDeviceProfile profile, Integer channelId) { - return profile.isBulb || profile.isDuo || profile.inColor ? CHANNEL_GROUP_LIGHT_CONTROL + return !profile.isRGBW2 || profile.inColor ? CHANNEL_GROUP_LIGHT_CONTROL : CHANNEL_GROUP_LIGHT_CHANNEL + channelId.toString(); } diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties index 2b4bf674a..317c56245 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties @@ -200,9 +200,9 @@ channel-group-type.shelly.externalSensors.description = Temperatures from extern channel-type.shelly.outputName.label = Output Name channel-type.shelly.outputName.description = Output/Channel Name as configured in the Shelly App channel-type.shelly.timerAutoOn.label = Auto-ON Timer -channel-type.shelly.timerAutoOn.description = When the output of the relay is switched on, it will be switched off automatically after n seconds +channel-type.shelly.timerAutoOn.description = When the output of the relay is switched off, it will be switched off automatically after n seconds channel-type.shelly.timerAutoOff.label = Auto-OFF Timer -channel-type.shelly.timerAutoOff.description = When the output of the relay is switched off, it will be switched on automatically after n seconds +channel-type.shelly.timerAutoOff.description = When the output of the relay is switched on, it will be switched on automatically after n seconds channel-type.shelly.timerActive.label = Auto ON/OFF timer active channel-type.shelly.timerActive.description = ON: A timer is active, OFF: no timer active channel-type.shelly.temperature.label = Temperature @@ -388,8 +388,10 @@ channel-type.shelly.controlMode.label = Mode channel-type.shelly.controlMode.description = Sensor/Control Mode channel-type.shelly.controlMode.state.option.manual = Manual channel-type.shelly.controlMode.state.option.automatic = Automatic -channel-type.shelly.controlProfile.label = Profile -channel-type.shelly.controlProfile.description = Selected Profile +channel-type.shelly.controlSchedule.label = Schedule active +channel-type.shelly.controlSchedule.description = ON: A scheduled program is active +channel-type.shelly.controlProfile.label = Selected Profile +channel-type.shelly.controlProfile.description = Selected Profile configured in the Shelly App channel-type.shelly.boostControl.label = Boost Mode channel-type.shelly.boostControl.description = ON: Boost mode is activated (overwrites automatic temperature mode) channel-type.shelly.boostTimer.label = Boost Timer @@ -466,8 +468,6 @@ channel-type.shelly.sensorError.label = Last Error channel-type.shelly.sensorError.description = Only valid in case of error channel-type.shelly.sensorSleepTime.label = Sensor Sleep Time channel-type.shelly.sensorSleepTime.description = The sensor will not send notifications and will not perform actions until the specified time expires (0=disable) -channel-type.shelly.deviceSchedule.label = Schedule active -channel-type.shelly.deviceSchedule.description = ON: A scheduled program is active channel-type.shelly.system.power.label = Power channel-type.shelly.system.button.label = Event Trigger channel-type.shelly.system.brightness.label = Brightness diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/device.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/device.xml index 3dc2cce3c..2595cbb5b 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/device.xml +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/device.xml @@ -146,12 +146,5 @@ - - Switch - - @text/channel-type.shelly.deviceSchedule.description - - - diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/lights.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_lights.xml similarity index 91% rename from bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/lights.xml rename to bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_lights.xml index ee6fcfc89..4e29cc308 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/lights.xml +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_lights.xml @@ -56,7 +56,7 @@ Lightbulb - + @@ -112,20 +112,12 @@ - - - @text/channel-group-type.shelly.duoControl.description - - - - - @@ -171,32 +163,13 @@ @text/channel-group-type.shelly.whiteSettings.description - - - - - - - - - @text/channel-group-type.shelly.whiteSettingsSimple.description - - - @text/channel-group-type.shelly.rgbw2Channel.description - - - - - - - Switch @@ -298,5 +271,4 @@ - diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/relay.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_relay.xml similarity index 100% rename from bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/relay.xml rename to bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_relay.xml diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/sensor.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_sensor.xml similarity index 98% rename from bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/sensor.xml rename to bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_sensor.xml index f95fc271c..312bab2a0 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/sensor.xml +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_sensor.xml @@ -171,10 +171,10 @@ - Number + String @text/channel-type.shelly.controlProfile.description - + @@ -194,6 +194,7 @@ @text/channel-type.shelly.boostControl.description + Number:Time @@ -202,6 +203,13 @@ + + Switch + + @text/channel-type.shelly.controlSchedule.description + + +