From: Markus Michels Date: Thu, 4 Aug 2022 06:42:29 +0000 (+0200) Subject: [shelly] Minor bugfixes from hardening (#13200) X-Git-Url: https://git.basschouten.com/?a=commitdiff_plain;h=0d73ed8150b4b1caf376f613a1a9c5ece4368abc;p=openhab-addons.git [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 --- diff --git a/bundles/org.openhab.binding.shelly/README.md b/bundles/org.openhab.binding.shelly/README.md index e4d3ffa5bd..6de414e9d1 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 2c0e00f10a..7179eed182 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 a2cab8c4fc..2ec06f0325 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 e267de7e82..12e99f08ae 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 2d576a27ec..8b0965ea37 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 4cf98d3962..ed3257bff7 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 432ff38783..cd84004b29 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 9c6b8b7f27..af5d754776 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 4c8e0d3705..025c8f53e3 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) { + 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); - break; + } 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 34f94f9ff0..b226667549 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 ea506aa0a1..6a19443383 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 34fbb7c9a7..174817a999 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 a1fad7dc33..0efd3276b0 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 670d953a5e..51a0141eca 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 9fd0884c0a..e04bf160d5 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 2b4bf674a6..317c562455 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 3dc2cce3ca..2595cbb5b2 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/lights.xml deleted file mode 100644 index ee6fcfc895..0000000000 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/lights.xml +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - @text/thing-type.shelly.shellybulb.description - Lightbulb - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellybulbduo.description - Lightbulb - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellycolorbulb.description - ColorLight - - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyvintage.description - Lightbulb - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyrgbw2-color.description - ColorLight - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyrgbw2-white.description - Lightbulb - - - - - - - - - - - - - - - - - - - serviceName - - - - - - @text/channel-group-type.shelly.bulbControl.description - - - - - - - - - - - - @text/channel-group-type.shelly.duoControl.description - - - - - - - - - - @text/channel-group-type.shelly.rgbw2ColorControl.description - - - - - @text/channel-group-type.shelly.rgbw2WhiteControl.description - - - - - @text/channel-group-type.shelly.colorSettingsBulb.description - - - - - - - - - - - - - - - @text/channel-group-type.shelly.colorSettingsRGBW2.description - - - - - - - - - - - - - - - @text/channel-group-type.shelly.whiteSettings.description - - - - - - - - - @text/channel-group-type.shelly.whiteSettingsSimple.description - - - - - - - - @text/channel-group-type.shelly.rgbw2Channel.description - - - - - - - - - - - Switch - - @text/channel-type.shelly.colorMode.description - - - - String - - @text/channel-type.shelly.colorFull.description - - - - - - - - - - - - - Dimmer - - @text/channel-type.shelly.colorRed.description - - - - - Dimmer - - @text/channel-type.shelly.colorGreen.description - - - - - Dimmer - - @text/channel-type.shelly.colorBlue.description - - - - - Dimmer - - @text/channel-type.shelly.colorWhite.description - - - - - Dimmer - - @text/channel-type.shelly.colorGain.description - - - - - Dimmer - - @text/channel-type.shelly.whiteTemp.description - - - - - Dimmer - - @text/channel-type.shelly.whiteBrightness.description - DimmableLight - - - - - Number - - @text/channel-type.shelly.colorEffectBulb.description - - - - - - - - - - - - - - - Number - - @text/channel-type.shelly.colorEffectRGBW2.description - - - - - - - - - - - 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/relay.xml deleted file mode 100644 index 1d37aa1627..0000000000 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/relay.xml +++ /dev/null @@ -1,632 +0,0 @@ - - - - - - @text/thing-type.shelly.shelly1.description - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shelly1l.description - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shelly1pm.description - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyem.description - - - - - - - - - - - - serviceName - - - - - - - @text/thing-type.shelly.shellyem3.description - - - - - - - - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shelly2-relay.description - - - - - - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shelly2-roller.description - Rollershutter - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shelly25-relay.description - - - - - - - - - - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shelly25-roller.description - Rollershutter - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shelly4pro.description - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyplug.description - PowerOutlet - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyplugs.description - PowerOutlet - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyplugu1.description - PowerOutlet - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyuni.description - - - - - - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellydimmer.description - DimmableLight - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellydimmer2.description - DimmableLight - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyix3.description - - - - - - - - - - - - - - serviceName - - - - - - @text/channel-group-type.shelly.relayChannel.description - - - - - @text/channel-group-type.shelly.relayChannel.description - - - - - @text/channel-group-type.shelly.dimmerChannel.description - - - - - @text/channel-group-type.shelly.ix3Channel.description - - - - - @text/channel-group-type.shelly.rollerControl.description - - - - - @text/channel-group-type.shelly.meter.description - - - - - @text/channel-group-type.shelly.externalSensors.description - - - - String - - @text/channel-type.shelly.outputName.description - - - - - - Number:Time - - @text/channel-type.shelly.timerAutoOn.description - Time - - - - - Number:Time - - @text/channel-type.shelly.timerAutoOff.description - Time - - - - - Switch - - @text/channel-type.shelly.timerActive.description - Status - - - - - - Rollershutter - - @text/channel-type.shelly.rollerShutter.description - Blinds - - - - Dimmer - - @text/channel-type.shelly.rollerPosition.description - - Measurement - Level - - - - - - Number - - @text/channel-type.shelly.rollerFavorite.description - - - - - String - - @text/channel-type.shelly.rollerState.description - Status - - - - - - - - - - - String - - @text/channel-type.shelly.rollerStop.description - - - - - - - - - - - String - - @text/channel-type.shelly.rollerDirection.description - - - - - - - - - - - Switch - - @text/channel-type.shelly.rollerSafety.description - - - - - - Switch - - @text/channel-type.shelly.inputState.description - - - - - - Switch - - @text/channel-type.shelly.inputState1.description - - - - - - Switch - - @text/channel-type.shelly.inputState2.description - - - - - - Dimmer - - @text/channel-type.shelly.dimmerBrightness.description - DimmableLight - - - - Number:Power - - @text/channel-type.shelly.meterWatts.description - Energy - - Measurement - Current - - - - - - - Number:Power - - @text/channel-type.shelly.meterAccuWatts.description - Energy - - - - - - Number:Power - - @text/channel-type.shelly.meterAccuTotal.description - Energy - - - - - - Number:Power - - @text/channel-type.shelly.meterAccuReturned.description - Energy - - - - - - Number:Power - - @text/channel-type.shelly.meterReactive.description - - - - - - Number:Energy - - @text/channel-type.shelly.lastPower1.description - Energy - - - - - - Number:Energy - - @text/channel-type.shelly.meterTotal.description - Energy - - - - - - Number:Energy - - @text/channel-type.shelly.meterReturned.description - Energy - - - - - - Number:ElectricPotential - - @text/channel-type.shelly.meterVoltage.description - - Measurement - Voltage - - - - - - - Number:ElectricPotential - - @text/channel-type.shelly.meterCurrent.description - Energy - - Measurement - Power - - - - - - - Number - - @text/channel-type.shelly.meterPowerFactor.description - - - - - - DateTime - - @text/channel-type.shelly.timestamp.description - Time - - Timestamp - - - - - - - Switch - - @text/channel-type.shelly.ledStatusDisable.description - - - - Switch - - @text/channel-type.shelly.ledPowerDisable.description - - - - DateTime - - @text/channel-type.shelly.lastUpdate.description - Time - - Timestamp - - - - - - - trigger - - @text/channel-type.shelly.eventTrigger.description - - - - - - - - - - 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/sensor.xml deleted file mode 100644 index f95fc271ce..0000000000 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/sensor.xml +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - @text/thing-type.shelly.shellyht.description - Sensor - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellysmoke.description - SmokeDetector - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellygas.description - Sensor - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellyflood.description - Sensor - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellydw.description - Sensor - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellydw2.description - Sensor - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellysense.description - - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellybutton1.description - WallSwitch - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellybutton2.description - WallSwitch - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellymotion.description - MotionDetector - - - - - - - serviceName - - - - - - @text/thing-type.shelly.shellytrv.description - RadiatorControl - - - - - - - - serviceName - - - - - String - - @text/channel-type.shelly.controlMode.description - - - - - - - - - - Number - - @text/channel-type.shelly.controlProfile.description - - - - - Number:Temperature - - @text/channel-type.shelly.targetTemp.description - Heating - - Setpoint - Temperature - - - - - - Switch - - @text/channel-type.shelly.boostControl.description - - - Number:Time - - @text/channel-type.shelly.boostTimer.description - Time - - - - - - - @text/channel-group-type.shelly.sensorData.description - - - - - @text/channel-group-type.shelly.batteryStatus.description - BatteryLevel - - - - - @text/channel-group-type.shelly.control.description - - - - - @text/channel-group-type.shelly.buttonState.description - - - - Contact - - @text/channel-type.shelly.sensorContact.description - - - - - - - - - - String - - @text/channel-type.shelly.sensorState.description - - - - - - - - - - - - String - - @text/channel-type.shelly.alarmState.description - - - - - - - - - - - - - String - - @text/channel-type.shelly.lastEvent.description - - - - - - - - - - - - - - Number - - @text/channel-type.shelly.eventCount.description - - - - - - Number:Temperature - - @text/channel-type.shelly.sensorTemp.description - Temperature - - Measurement - Temperature - - - - - - - Number:Temperature - - @text/channel-type.shelly.sensorExtTemp.label - Temperature - - Measurement - Temperature - - - - - - - Number:Dimensionless - - @text/channel-type.shelly.sensorExtHum.description - Humidity - - Measurement - Humidity - - - - - - - Number:Dimensionless - - @text/channel-type.shelly.sensorHumidity.description - Humidity - - Measurement - Humidity - - - - - - Switch - - @text/channel-type.shelly.sensorFlood.description - Water - - - - - - Switch - - @text/channel-type.shelly.sensorSmoke.description - Smoke - - - - - - Number:Illuminance - - @text/channel-type.shelly.sensorLux.description - - - - - - String - - @text/channel-type.shelly.sensorIllumination.description - - - - - - - - - - - - DateTime - - @text/channel-type.shelly.motionTimestamp.description - Time - - Timestamp - - - - - - - Switch - - channel-type.shelly.motionActive.description - Contact - - - - - - Switch - - @text/channel-type.shelly.sensorMotion.description - Motion - - Status - Presence - - - - - - - Switch - - @text/channel-type.shelly.sensorVibration.description - Flow - - - - - - Number:Angle - - @text/channel-type.shelly.sensorTilt.description - Tilt - - - - - - Number:Dimensionless - - @text/channel-type.shelly.sensorPPM.description - Gas - - Measurement - Gas - - - - - - - Number:ElectricPotential - - @text/channel-type.shelly.sensorADC.description - - - - - - Dimmer - - @text/channel-type.shelly.sensorPosition.description - RadiatorControl - - - - - String - - @text/channel-type.shelly.sensorValve.description - Pressure - - - - - - - - - - - - - - - - String - - @text/channel-type.shelly.sensorError.description - - - - - - Number:Time - - @text/channel-type.shelly.sensorSleepTime.description - - - - - String - - @text/channel-type.shelly.senseKey.description - - - diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_lights.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_lights.xml new file mode 100644 index 0000000000..4e29cc3087 --- /dev/null +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_lights.xml @@ -0,0 +1,274 @@ + + + + + + @text/thing-type.shelly.shellybulb.description + Lightbulb + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellybulbduo.description + Lightbulb + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellycolorbulb.description + ColorLight + + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyvintage.description + Lightbulb + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyrgbw2-color.description + ColorLight + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyrgbw2-white.description + Lightbulb + + + + + + + + + + + + + + + + + + + serviceName + + + + + + @text/channel-group-type.shelly.bulbControl.description + + + + + + + + + @text/channel-group-type.shelly.duoControl.description + + + + + @text/channel-group-type.shelly.rgbw2ColorControl.description + + + + + @text/channel-group-type.shelly.rgbw2WhiteControl.description + + + + + @text/channel-group-type.shelly.colorSettingsBulb.description + + + + + + + + + + + + + + + @text/channel-group-type.shelly.colorSettingsRGBW2.description + + + + + + + + + + + + + + + @text/channel-group-type.shelly.whiteSettings.description + + + + + @text/channel-group-type.shelly.rgbw2Channel.description + + + + Switch + + @text/channel-type.shelly.colorMode.description + + + + String + + @text/channel-type.shelly.colorFull.description + + + + + + + + + + + + + Dimmer + + @text/channel-type.shelly.colorRed.description + + + + + Dimmer + + @text/channel-type.shelly.colorGreen.description + + + + + Dimmer + + @text/channel-type.shelly.colorBlue.description + + + + + Dimmer + + @text/channel-type.shelly.colorWhite.description + + + + + Dimmer + + @text/channel-type.shelly.colorGain.description + + + + + Dimmer + + @text/channel-type.shelly.whiteTemp.description + + + + + Dimmer + + @text/channel-type.shelly.whiteBrightness.description + DimmableLight + + + + + Number + + @text/channel-type.shelly.colorEffectBulb.description + + + + + + + + + + + + + + + Number + + @text/channel-type.shelly.colorEffectRGBW2.description + + + + + + + + + + diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_relay.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_relay.xml new file mode 100644 index 0000000000..1d37aa1627 --- /dev/null +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_relay.xml @@ -0,0 +1,632 @@ + + + + + + @text/thing-type.shelly.shelly1.description + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shelly1l.description + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shelly1pm.description + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyem.description + + + + + + + + + + + + serviceName + + + + + + + @text/thing-type.shelly.shellyem3.description + + + + + + + + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shelly2-relay.description + + + + + + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shelly2-roller.description + Rollershutter + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shelly25-relay.description + + + + + + + + + + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shelly25-roller.description + Rollershutter + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shelly4pro.description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyplug.description + PowerOutlet + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyplugs.description + PowerOutlet + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyplugu1.description + PowerOutlet + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyuni.description + + + + + + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellydimmer.description + DimmableLight + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellydimmer2.description + DimmableLight + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyix3.description + + + + + + + + + + + + + + serviceName + + + + + + @text/channel-group-type.shelly.relayChannel.description + + + + + @text/channel-group-type.shelly.relayChannel.description + + + + + @text/channel-group-type.shelly.dimmerChannel.description + + + + + @text/channel-group-type.shelly.ix3Channel.description + + + + + @text/channel-group-type.shelly.rollerControl.description + + + + + @text/channel-group-type.shelly.meter.description + + + + + @text/channel-group-type.shelly.externalSensors.description + + + + String + + @text/channel-type.shelly.outputName.description + + + + + + Number:Time + + @text/channel-type.shelly.timerAutoOn.description + Time + + + + + Number:Time + + @text/channel-type.shelly.timerAutoOff.description + Time + + + + + Switch + + @text/channel-type.shelly.timerActive.description + Status + + + + + + Rollershutter + + @text/channel-type.shelly.rollerShutter.description + Blinds + + + + Dimmer + + @text/channel-type.shelly.rollerPosition.description + + Measurement + Level + + + + + + Number + + @text/channel-type.shelly.rollerFavorite.description + + + + + String + + @text/channel-type.shelly.rollerState.description + Status + + + + + + + + + + + String + + @text/channel-type.shelly.rollerStop.description + + + + + + + + + + + String + + @text/channel-type.shelly.rollerDirection.description + + + + + + + + + + + Switch + + @text/channel-type.shelly.rollerSafety.description + + + + + + Switch + + @text/channel-type.shelly.inputState.description + + + + + + Switch + + @text/channel-type.shelly.inputState1.description + + + + + + Switch + + @text/channel-type.shelly.inputState2.description + + + + + + Dimmer + + @text/channel-type.shelly.dimmerBrightness.description + DimmableLight + + + + Number:Power + + @text/channel-type.shelly.meterWatts.description + Energy + + Measurement + Current + + + + + + + Number:Power + + @text/channel-type.shelly.meterAccuWatts.description + Energy + + + + + + Number:Power + + @text/channel-type.shelly.meterAccuTotal.description + Energy + + + + + + Number:Power + + @text/channel-type.shelly.meterAccuReturned.description + Energy + + + + + + Number:Power + + @text/channel-type.shelly.meterReactive.description + + + + + + Number:Energy + + @text/channel-type.shelly.lastPower1.description + Energy + + + + + + Number:Energy + + @text/channel-type.shelly.meterTotal.description + Energy + + + + + + Number:Energy + + @text/channel-type.shelly.meterReturned.description + Energy + + + + + + Number:ElectricPotential + + @text/channel-type.shelly.meterVoltage.description + + Measurement + Voltage + + + + + + + Number:ElectricPotential + + @text/channel-type.shelly.meterCurrent.description + Energy + + Measurement + Power + + + + + + + Number + + @text/channel-type.shelly.meterPowerFactor.description + + + + + + DateTime + + @text/channel-type.shelly.timestamp.description + Time + + Timestamp + + + + + + + Switch + + @text/channel-type.shelly.ledStatusDisable.description + + + + Switch + + @text/channel-type.shelly.ledPowerDisable.description + + + + DateTime + + @text/channel-type.shelly.lastUpdate.description + Time + + Timestamp + + + + + + + trigger + + @text/channel-type.shelly.eventTrigger.description + + + + + + + + + + diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_sensor.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_sensor.xml new file mode 100644 index 0000000000..312bab2a08 --- /dev/null +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/thing/shellyGen1_sensor.xml @@ -0,0 +1,512 @@ + + + + + + @text/thing-type.shelly.shellyht.description + Sensor + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellysmoke.description + SmokeDetector + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellygas.description + Sensor + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellyflood.description + Sensor + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellydw.description + Sensor + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellydw2.description + Sensor + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellysense.description + + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellybutton1.description + WallSwitch + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellybutton2.description + WallSwitch + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellymotion.description + MotionDetector + + + + + + + serviceName + + + + + + @text/thing-type.shelly.shellytrv.description + RadiatorControl + + + + + + + + serviceName + + + + + String + + @text/channel-type.shelly.controlMode.description + + + + + + + + + + String + + @text/channel-type.shelly.controlProfile.description + + + + + Number:Temperature + + @text/channel-type.shelly.targetTemp.description + Heating + + Setpoint + Temperature + + + + + + Switch + + @text/channel-type.shelly.boostControl.description + + + + Number:Time + + @text/channel-type.shelly.boostTimer.description + Time + + + + + Switch + + @text/channel-type.shelly.controlSchedule.description + + + + + + + @text/channel-group-type.shelly.sensorData.description + + + + + @text/channel-group-type.shelly.batteryStatus.description + BatteryLevel + + + + + @text/channel-group-type.shelly.control.description + + + + + @text/channel-group-type.shelly.buttonState.description + + + + Contact + + @text/channel-type.shelly.sensorContact.description + + + + + + + + + + String + + @text/channel-type.shelly.sensorState.description + + + + + + + + + + + + String + + @text/channel-type.shelly.alarmState.description + + + + + + + + + + + + + String + + @text/channel-type.shelly.lastEvent.description + + + + + + + + + + + + + + Number + + @text/channel-type.shelly.eventCount.description + + + + + + Number:Temperature + + @text/channel-type.shelly.sensorTemp.description + Temperature + + Measurement + Temperature + + + + + + + Number:Temperature + + @text/channel-type.shelly.sensorExtTemp.label + Temperature + + Measurement + Temperature + + + + + + + Number:Dimensionless + + @text/channel-type.shelly.sensorExtHum.description + Humidity + + Measurement + Humidity + + + + + + + Number:Dimensionless + + @text/channel-type.shelly.sensorHumidity.description + Humidity + + Measurement + Humidity + + + + + + Switch + + @text/channel-type.shelly.sensorFlood.description + Water + + + + + + Switch + + @text/channel-type.shelly.sensorSmoke.description + Smoke + + + + + + Number:Illuminance + + @text/channel-type.shelly.sensorLux.description + + + + + + String + + @text/channel-type.shelly.sensorIllumination.description + + + + + + + + + + + + DateTime + + @text/channel-type.shelly.motionTimestamp.description + Time + + Timestamp + + + + + + + Switch + + channel-type.shelly.motionActive.description + Contact + + + + + + Switch + + @text/channel-type.shelly.sensorMotion.description + Motion + + Status + Presence + + + + + + + Switch + + @text/channel-type.shelly.sensorVibration.description + Flow + + + + + + Number:Angle + + @text/channel-type.shelly.sensorTilt.description + Tilt + + + + + + Number:Dimensionless + + @text/channel-type.shelly.sensorPPM.description + Gas + + Measurement + Gas + + + + + + + Number:ElectricPotential + + @text/channel-type.shelly.sensorADC.description + + + + + + Dimmer + + @text/channel-type.shelly.sensorPosition.description + RadiatorControl + + + + + String + + @text/channel-type.shelly.sensorValve.description + Pressure + + + + + + + + + + + + + + + + String + + @text/channel-type.shelly.sensorError.description + + + + + + Number:Time + + @text/channel-type.shelly.sensorSleepTime.description + + + + + String + + @text/channel-type.shelly.senseKey.description + + +