[shelly] Minor bugfixes from hardening (#13200)
* Minor bugfixes from hardening Signed-off-by: Markus Michels <markus7017@gmail.com> * review changes applied Signed-off-by: Markus Michels <markus7017@gmail.com> * controlProfile is type String Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
parent
22f7dfe309
commit
0d73ed8150
@ -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)
|
||||
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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<String, Object> 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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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.)
|
||||
|
||||
@ -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<ShellySettingsRelay> relays;
|
||||
public ArrayList<ShellySettingsRoller> rollers;
|
||||
public ArrayList<ShellySettingsDimmer> dimmers;
|
||||
public ArrayList<ShellySettingsRgbwLight> lights;
|
||||
public ArrayList<ShellySettingsEMeter> emeters;
|
||||
public ArrayList<ShellySettingsInput> inputs; // ix3
|
||||
public ArrayList<ShellyThermnostat> 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<ShellySettingsRelay> relays;
|
||||
public @Nullable ArrayList<ShellySettingsInput> inputs; // ix3
|
||||
public @Nullable ArrayList<ShellySettingsDimmer> dimmers;
|
||||
public @Nullable ArrayList<ShellySettingsRoller> rollers;
|
||||
public @Nullable ArrayList<ShellySettingsRgbwLight> lights;
|
||||
public @Nullable ArrayList<ShellySettingsEMeter> emeters;
|
||||
public @Nullable ArrayList<ShellyThermnostat> 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<ShellySettingsRelay> relays;
|
||||
public Double voltage; // Shelly 2.5
|
||||
|
||||
public ArrayList<ShellySettingsRoller> rollers;
|
||||
public Integer input; // RGBW2 has no JSON array
|
||||
public ArrayList<ShellyInputState> inputs;
|
||||
public ArrayList<ShellySettingsLight> lights;
|
||||
public ArrayList<ShellySettingsRelay> relays;
|
||||
public ArrayList<ShellyRollerStatus> rollers;
|
||||
public ArrayList<ShellyShortLightStatus> dimmers;
|
||||
public ArrayList<ShellyInputState> inputs;
|
||||
public ArrayList<ShellySettingsMeter> meters;
|
||||
public ArrayList<ShellySettingsEMeter> 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<ShellyThermnostat> thermostats;
|
||||
|
||||
public ShellySettingsUpdate update;
|
||||
public ShellySettingsUpdate update = new ShellySettingsUpdate();
|
||||
|
||||
@SerializedName("ram_total")
|
||||
public Long ramTotal;
|
||||
@SerializedName("ram_free")
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -212,11 +212,11 @@ public class ShellyManagerPage {
|
||||
ShellyDeviceStats stats = th.getStats();
|
||||
properties.putAll(stats.asProperties());
|
||||
|
||||
for (Map.Entry<String, Object> p : thing.getConfiguration().getProperties().entrySet()) {
|
||||
for (Map.Entry<String, @Nullable Object> 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<Channel> of channels to be added to the thing
|
||||
*/
|
||||
public static Map<String, Channel> createRelayChannels(final Thing thing, final ShellyDeviceProfile profile,
|
||||
final ShellyStatusRelay relay, int idx) {
|
||||
final ShellySettingsRelay rstatus, int idx) {
|
||||
Map<String, Channel> 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
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -146,12 +146,5 @@
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="deviceSchedule" advanced="true">
|
||||
<item-type>Switch</item-type>
|
||||
<label>@text/channel-type.shelly.deviceSchedule.label</label>
|
||||
<description>@text/channel-type.shelly.deviceSchedule.description</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
<category>Lightbulb</category>
|
||||
<channel-groups>
|
||||
<channel-group id="control" typeId="duoControl"/>
|
||||
<channel-group id="white" typeId="whiteSettingsSimple"/>
|
||||
<channel-group id="white" typeId="whiteSettings"/>
|
||||
<channel-group id="meter" typeId="meter"/>
|
||||
<channel-group id="device" typeId="deviceStatus"/>
|
||||
</channel-groups>
|
||||
@ -112,20 +112,12 @@
|
||||
<channels>
|
||||
<channel id="power" typeId="system.power"/>
|
||||
<channel id="mode" typeId="colorMode"/>
|
||||
<channel id="autoOn" typeId="timerAutoOn"/>
|
||||
<channel id="autoOff" typeId="timerAutoOff"/>
|
||||
<channel id="timerActive" typeId="timerActive"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="duoControl">
|
||||
<label>@text/channel-group-type.shelly.duoControl.label</label>
|
||||
<description>@text/channel-group-type.shelly.duoControl.description</description>
|
||||
<channels>
|
||||
<channel id="autoOn" typeId="timerAutoOn"/>
|
||||
<channel id="autoOff" typeId="timerAutoOff"/>
|
||||
<channel id="timerActive" typeId="timerActive"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="rgbw2ColorControl">
|
||||
@ -171,32 +163,13 @@
|
||||
<channel-group-type id="whiteSettings">
|
||||
<label>@text/channel-group-type.shelly.whiteSettings.label</label>
|
||||
<description>@text/channel-group-type.shelly.whiteSettings.description</description>
|
||||
<channels>
|
||||
<channel id="brightness" typeId="whiteBrightness"/>
|
||||
<channel id="temperature" typeId="whiteTemp"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="whiteSettingsSimple">
|
||||
<label>@text/channel-group-type.shelly.whiteSettingsSimple.label</label>
|
||||
<description>@text/channel-group-type.shelly.whiteSettingsSimple.description</description>
|
||||
<channels>
|
||||
<channel id="brightness" typeId="whiteBrightness"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="rgbw2Channel">
|
||||
<label>@text/channel-group-type.shelly.rgbw2Channel.label</label>
|
||||
<description>@text/channel-group-type.shelly.rgbw2Channel.description</description>
|
||||
<channels>
|
||||
<channel id="autoOn" typeId="timerAutoOn"/>
|
||||
<channel id="autoOff" typeId="timerAutoOff"/>
|
||||
<channel id="timerActive" typeId="timerActive"/>
|
||||
<channel id="brightness" typeId="whiteBrightness"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
|
||||
<channel-type id="colorMode">
|
||||
<item-type>Switch</item-type>
|
||||
<label>@text/channel-type.shelly.colorMode.label</label>
|
||||
@ -298,5 +271,4 @@
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@ -171,10 +171,10 @@
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="controlProfile">
|
||||
<item-type>Number</item-type>
|
||||
<item-type>String</item-type>
|
||||
<label>@text/channel-type.shelly.controlProfile.label</label>
|
||||
<description>@text/channel-type.shelly.controlProfile.description</description>
|
||||
<state min="0" max="5" step="1" readOnly="false"></state>
|
||||
<state readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="targetTemp">
|
||||
@ -194,6 +194,7 @@
|
||||
<label>@text/channel-type.shelly.boostControl.label</label>
|
||||
<description>@text/channel-type.shelly.boostControl.description</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="boostTimer">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>@text/channel-type.shelly.boostTimer.label</label>
|
||||
@ -202,6 +203,13 @@
|
||||
<state min="0" step="1" pattern="%.0f %unit%" readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="controlSchedule" advanced="true">
|
||||
<item-type>Switch</item-type>
|
||||
<label>@text/channel-type.shelly.controlSchedule.label</label>
|
||||
<description>@text/channel-type.shelly.controlSchedule.description</description>
|
||||
<state readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
|
||||
<channel-group-type id="sensorData">
|
||||
<label>@text/channel-group-type.shelly.sensorData.label</label>
|
||||
Loading…
x
Reference in New Issue
Block a user