This PR is just to reduce the delta before I create the PR for Plus/Pro (#13176)

support. In general Gen1 and Gen2 devices have a total different API so
I spliced the API code in version/gen 1 and 2. This means restructuring
the classes (e.h. api+coap became api+api1+api2) and therefor dummy
changes in the code, e.g. import statements. This creates a lot of
overhead and separating those "dummy changes" simplifies merging the
actual PR.

Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
Markus Michels
2022-07-29 19:48:10 +02:00
committed by GitHub
parent d5b657c6fd
commit 8aa88bc3d9
34 changed files with 869 additions and 478 deletions

View File

@@ -12,6 +12,8 @@
*/
package org.openhab.binding.shelly.internal;
import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
@@ -33,174 +35,6 @@ public class ShellyBindingConstants {
public static final String BINDING_ID = "shelly";
public static final String SYSTEM_ID = "system";
// Type names
public static final String THING_TYPE_SHELLY1_STR = "shelly1";
public static final String THING_TYPE_SHELLY1L_STR = "shelly1l";
public static final String THING_TYPE_SHELLY1PM_STR = "shelly1pm";
public static final String THING_TYPE_SHELLYEM_STR = "shellyem";
public static final String THING_TYPE_SHELLY3EM_STR = "shellyem3"; // bad: misspelled product name, it's 3EM
public static final String THING_TYPE_SHELLY2_PREFIX = "shellyswitch";
public static final String THING_TYPE_SHELLY2_RELAY_STR = "shelly2-relay";
public static final String THING_TYPE_SHELLY2_ROLLER_STR = "shelly2-roller";
public static final String THING_TYPE_SHELLY25_PREFIX = "shellyswitch25";
public static final String THING_TYPE_SHELLY25_RELAY_STR = "shelly25-relay";
public static final String THING_TYPE_SHELLY25_ROLLER_STR = "shelly25-roller";
public static final String THING_TYPE_SHELLY4PRO_STR = "shelly4pro";
public static final String THING_TYPE_SHELLYPLUG_STR = "shellyplug";
public static final String THING_TYPE_SHELLYPLUGS_STR = "shellyplugs";
public static final String THING_TYPE_SHELLYPLUGU1_STR = "shellyplugu1"; // Shely Plug US
public static final String THING_TYPE_SHELLYDIMMER_STR = "shellydimmer";
public static final String THING_TYPE_SHELLYDIMMER2_STR = "shellydimmer2";
public static final String THING_TYPE_SHELLYIX3_STR = "shellyix3";
public static final String THING_TYPE_SHELLYBULB_STR = "shellybulb";
public static final String THING_TYPE_SHELLYDUO_STR = "shellybulbduo";
public static final String THING_TYPE_SHELLYVINTAGE_STR = "shellyvintage";
public static final String THING_TYPE_SHELLYRGBW2_PREFIX = "shellyrgbw2";
public static final String THING_TYPE_SHELLYRGBW2_COLOR_STR = THING_TYPE_SHELLYRGBW2_PREFIX + "-color";
public static final String THING_TYPE_SHELLYRGBW2_WHITE_STR = THING_TYPE_SHELLYRGBW2_PREFIX + "-white";
public static final String THING_TYPE_SHELLYDUORGBW_STR = "shellycolorbulb";
public static final String THING_TYPE_SHELLYHT_STR = "shellyht";
public static final String THING_TYPE_SHELLYSMOKE_STR = "shellysmoke";
public static final String THING_TYPE_SHELLYGAS_STR = "shellygas";
public static final String THING_TYPE_SHELLYFLOOD_STR = "shellyflood";
public static final String THING_TYPE_SHELLYDOORWIN_STR = "shellydw";
public static final String THING_TYPE_SHELLYDOORWIN2_STR = "shellydw2";
public static final String THING_TYPE_SHELLYEYE_STR = "shellyseye";
public static final String THING_TYPE_SHELLYSENSE_STR = "shellysense";
public static final String THING_TYPE_SHELLYTRV_STR = "shellytrv";
public static final String THING_TYPE_SHELLYMOTION_STR = "shellymotion";
public static final String THING_TYPE_SHELLYMOTION2_STR = "shellymotion2";
public static final String THING_TYPE_SHELLYBUTTON1_STR = "shellybutton1";
public static final String THING_TYPE_SHELLYBUTTON2_STR = "shellybutton2";
public static final String THING_TYPE_SHELLYUNI_STR = "shellyuni";
// Shelly Plus Seriens
public static final String THING_TYPE_SHELLYPLUS1_STR = "shellyplus1";
public static final String THING_TYPE_SHELLYPLUS1PM_STR = "shellyplus1pm";
public static final String THING_TYPE_SHELLYPLUS2PM_RELAY_STR = "shellyplus2pm-relay";
public static final String THING_TYPE_SHELLYPLUS2PM_ROLLER_STR = "shellyplus2pm-roller";
public static final String THING_TYPE_SHELLYPLUSI4_STR = "shellyplusi4";
public static final String THING_TYPE_SHELLYPLUSHT_STR = "shellyplusht";
public static final String THING_TYPE_SHELLYPLUSPLUGUS_STR = "shellyplusplugus";
// Shelly Pro Series
public static final String THING_TYPE_SHELLYPRO1_STR = "shellypro1";
public static final String THING_TYPE_SHELLYPRO1PM_STR = "shellypro1pm";
public static final String THING_TYPE_SHELLYPRO2_RELAY_STR = "shellypro2-relay";
public static final String THING_TYPE_SHELLYPRO2_ROLLER_STR = "shellypro2-roller";
public static final String THING_TYPE_SHELLYPRO2PM_RELAY_STR = "shellypro2pm-relay";
public static final String THING_TYPE_SHELLYPRO2PM_ROLLER_STR = "shellypro2pm-roller";
public static final String THING_TYPE_SHELLYPRO4PM_STR = "shellypro4pm";
public static final String THING_TYPE_SHELLYPROTECTED_STR = "shellydevice";
public static final String THING_TYPE_SHELLYUNKNOWN_STR = "shellyunknown";
// Device Types
public static final String SHELLYDT_1 = "SHSW-1";
public static final String SHELLYDT_1PM = "SHSW-PM";
public static final String SHELLYDT_1L = "SHSW-L";
public static final String SHELLYDT_SHPLG = "SHPLG-1";
public static final String SHELLYDT_SHPLG_S = "SHPLG-S";
public static final String SHELLYDT_SHPLG_U1 = "SHPLG-U1";
public static final String SHELLYDT_SHELLY2 = "SHSW-21";
public static final String SHELLYDT_SHELLY25 = "SHSW-25";
public static final String SHELLYDT_SHPRO = "SHSW-44";
public static final String SHELLYDT_EM = "SHEM";
public static final String SHELLYDT_3EM = "SHEM-3";
public static final String SHELLYDT_HT = "SHHT-1";
public static final String SHELLYDT_DW = "SHDW-1";
public static final String SHELLYDT_DW2 = "SHDW-2";
public static final String SHELLYDT_SENSE = "SHSEN-1";
public static final String SHELLYDT_MOTION = "SHMOS-01";
public static final String SHELLYDT_MOTION2 = "SHMOS-02";
public static final String SHELLYDT_GAS = "SHGS-1";
public static final String SHELLYDT_DIMMER = "SHDM-1";
public static final String SHELLYDT_DIMMER2 = "SHDM-2";
public static final String SHELLYDT_IX3 = "SHIX3-1";
public static final String SHELLYDT_BULB = "SHBLB-1";
public static final String SHELLYDT_DUO = "SHBDUO-1";
public static final String SHELLYDT_DUORGBW = "SHCB-1";
public static final String SHELLYDT_VINTAGE = "SHVIN-1";
public static final String SHELLYDT_RGBW2 = "SHRGBW2";
public static final String SHELLYDT_BUTTON1 = "SHBTN-1";
public static final String SHELLYDT_BUTTON2 = "SHBTN-2";
public static final String SHELLYDT_UNI = "SHUNI-1";
public static final String SHELLYDT_TRV = "SHTRV-01";
// Shelly Plus Series
public static final String SHELLYDT_PLUS1 = "SNSW-001X16EU";
public static final String SHELLYDT_PLUS1PM = "SNSW-001P16EU";
public static final String SHELLYDT_PLUS2PM_RELAY = "SNSW-002P16EU-relay";
public static final String SHELLYDT_PLUS2PM_ROLLER = "SNSW-002P16EU-roller";
public static final String SHELLYDT_PLUSPLUGUS = "SNPL-00116US";
public static final String SHELLYDT_PLUSI4 = "SNSN-0024X";
public static final String SHELLYDT_PLUSHT = "SNSN-0013A";
// Shelly Pro Series
public static final String SHELLYDT_PRO1 = "SPSW-001XE16EU";
public static final String SHELLYDT_PRO1PM = "SPSW-001PE16EU";
public static final String SHELLYDT_PRO2_RELAY = "SPSW-002XE16EU-relay";
public static final String SHELLYDT_PRO2_ROLLER = "SPSW-002XE16EU-roller";
public static final String SHELLYDT_PRO2PM_RELAY = "SPSW-002PE16EU-relay";
public static final String SHELLYDT_PRO2PM_ROLLER = "SPSW-002PE16EU-roller";
public static final String SHELLYDT_PRO4PM = "SPSW-004PE16EU";
// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_SHELLY1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1_STR);
public static final ThingTypeUID THING_TYPE_SHELLY1L = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1L_STR);
public static final ThingTypeUID THING_TYPE_SHELLY1PM = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1PM_STR);
public static final ThingTypeUID THING_TYPE_SHELLYEM = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYEM_STR);
public static final ThingTypeUID THING_TYPE_SHELLY3EM = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY3EM_STR);
public static final ThingTypeUID THING_TYPE_SHELLY2_RELAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY2_RELAY_STR);
public static final ThingTypeUID THING_TYPE_SHELLY2_ROLLER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY2_ROLLER_STR);
public static final ThingTypeUID THING_TYPE_SHELLY25_RELAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY25_RELAY_STR);
public static final ThingTypeUID THING_TYPE_SHELLY25_ROLLER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY25_ROLLER_STR);
public static final ThingTypeUID THING_TYPE_SHELLY4PRO = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY4PRO_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUG = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPLUG_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUGS = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPLUGS_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUGU1 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUGU1_STR);
public static final ThingTypeUID THING_TYPE_SHELLYUNI = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYUNI_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDIMMER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDIMMER_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDIMMER2 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDIMMER2_STR);
public static final ThingTypeUID THING_TYPE_SHELLYIX3 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYIX3_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBULB = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYBULB_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDUO = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYDUO_STR);
public static final ThingTypeUID THING_TYPE_SHELLYVINTAGE = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYVINTAGE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDUORGBW = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDUORGBW_STR);
public static final ThingTypeUID THING_TYPE_SHELLYHT = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYHT_STR);
public static final ThingTypeUID THING_TYPE_SHELLYSENSE = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYSENSE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYSMOKE = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYSMOKE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYGAS = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYGAS_STR);
public static final ThingTypeUID THING_TYPE_SHELLYFLOOD = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYFLOOD_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDOORWIN = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDOORWIN_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDOORWIN2 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDOORWIN2_STR);
public static final ThingTypeUID THING_TYPE_SHELLYTRV = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYTRV_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBUTTON1 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBUTTON1_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBUTTON2 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBUTTON2_STR);
public static final ThingTypeUID THING_TYPE_SHELLYEYE = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYEYE_STR);
public static final ThingTypeUID THING_TYPE_SHELLMOTION = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYMOTION_STR);
public static final ThingTypeUID THING_TYPE_SHELLYRGBW2_COLOR = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYRGBW2_COLOR_STR);
public static final ThingTypeUID THING_TYPE_SHELLYRGBW2_WHITE = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYRGBW2_WHITE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPROTECTED = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPROTECTED_STR);
public static final ThingTypeUID THING_TYPE_SHELLYUNKNOWN = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYUNKNOWN_STR);
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
.unmodifiableSet(Stream.of(THING_TYPE_SHELLY1, THING_TYPE_SHELLY1L, THING_TYPE_SHELLY1PM,
THING_TYPE_SHELLYEM, THING_TYPE_SHELLY3EM, THING_TYPE_SHELLY2_RELAY, THING_TYPE_SHELLY2_ROLLER,

View File

@@ -12,7 +12,7 @@
*/
package org.openhab.binding.shelly.internal;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import java.util.HashMap;
import java.util.Map;
@@ -21,7 +21,7 @@ import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.shelly.internal.coap.ShellyCoapServer;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapServer;
import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyBaseHandler;
import org.openhab.binding.shelly.internal.handler.ShellyLightHandler;
@@ -62,7 +62,7 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory {
private final Logger logger = LoggerFactory.getLogger(ShellyHandlerFactory.class);
private final HttpClient httpClient;
private final ShellyTranslationProvider messages;
private final ShellyCoapServer coapServer;
private final Shelly1CoapServer coapServer;
private final ShellyThingTable thingTable;
private ShellyBindingConfiguration bindingConfig = new ShellyBindingConfiguration();
@@ -81,7 +81,6 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory {
@Reference ShellyTranslationProvider translationProvider, @Reference ShellyThingTable thingTable,
@Reference HttpClientFactory httpClientFactory, ComponentContext componentContext,
Map<String, Object> configProperties) {
logger.debug("Activate Shelly HandlerFactory");
super.activate(componentContext);
messages = translationProvider;
// Save bindingConfig & pass it to all registered listeners
@@ -103,10 +102,7 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory {
logger.debug("Using OH HTTP port {}", httpPort);
this.thingTable = thingTable;
this.coapServer = new ShellyCoapServer();
// Promote Shelly Manager usage
logger.info("{}", messages.get("status.managerstarted", localIP, httpPort));
this.coapServer = new Shelly1CoapServer();
}
@Override

View File

@@ -15,15 +15,15 @@ package org.openhab.binding.shelly.internal.api;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyControlRoller;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyOtaCheckResult;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsDevice;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsLogin;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyShortLightStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusLight;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusSensor;
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.ShellySettingsDevice;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsLogin;
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.ShellyStatusLight;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusRelay;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
/**
@@ -47,11 +47,11 @@ public interface ShellyApiInterface {
public void setSleepTime(int value) throws ShellyApiException;
public ShellyStatusRelay getRelayStatus(Integer relayIndex) throws ShellyApiException;
public ShellyStatusRelay getRelayStatus(int relayIndex) throws ShellyApiException;
public void setRelayTurn(int id, String turnMode) throws ShellyApiException;
public ShellyControlRoller getRollerStatus(int rollerIndex) throws ShellyApiException;
public ShellyRollerStatus getRollerStatus(int rollerIndex) throws ShellyApiException;
public void setRollerTurn(int relayIndex, String turnMode) throws ShellyApiException;

View File

@@ -13,7 +13,7 @@
package org.openhab.binding.shelly.internal.api;
import static org.eclipse.jetty.http.HttpStatus.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@@ -33,6 +33,7 @@ public class ShellyApiResult {
public String response = "";
public int httpCode = -1;
public String httpReason = "";
public String authResponse = "";
public ShellyApiResult() {
}

View File

@@ -13,7 +13,8 @@
package org.openhab.binding.shelly.internal.api;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.HashMap;
@@ -23,12 +24,12 @@ import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsDimmer;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsGlobal;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsInput;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsRgbwLight;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDimmer;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsGlobal;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsInput;
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.util.ShellyVersionDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,6 +64,7 @@ public class ShellyDeviceProfile {
public boolean discoverable = true;
public boolean auth = false;
public boolean alwaysOn = true;
public boolean isGen2 = false;
public String hwRev = "";
public String hwBatchId = "";
@@ -93,7 +95,7 @@ public class ShellyDeviceProfile {
public boolean isHT = false; // true for H&T
public boolean isDW = false; // true for Door Window sensor
public boolean isButton = false; // true for a Shelly Button 1
public boolean isIX3 = false; // true for a Shelly IX
public boolean isIX = false; // true for a Shelly IX
public boolean isTRV = false; // true for a Shelly TRV
public int minTemp = 0; // Bulb/Duo: Min Light Temp
@@ -202,11 +204,12 @@ public class ShellyDeviceProfile {
boolean isSmoke = thingType.equals(THING_TYPE_SHELLYSMOKE_STR);
boolean isGas = thingType.equals(THING_TYPE_SHELLYGAS_STR);
boolean isUNI = thingType.equals(THING_TYPE_SHELLYUNI_STR);
isHT = thingType.equals(THING_TYPE_SHELLYHT_STR);
isHT = thingType.equals(THING_TYPE_SHELLYHT_STR) || thingType.equals(THING_TYPE_SHELLYPLUSHT_STR);
isDW = thingType.equals(THING_TYPE_SHELLYDOORWIN_STR) || thingType.equals(THING_TYPE_SHELLYDOORWIN2_STR);
isMotion = thingType.startsWith(THING_TYPE_SHELLYMOTION_STR);
isSense = thingType.equals(THING_TYPE_SHELLYSENSE_STR);
isIX3 = thingType.equals(THING_TYPE_SHELLYIX3_STR);
isIX = thingType.equals(THING_TYPE_SHELLYIX3_STR) || thingType.equals(THING_TYPE_SHELLYPLUSI4_STR)
|| thingType.equals(THING_TYPE_SHELLYPLUSI4DC_STR);
isButton = thingType.equals(THING_TYPE_SHELLYBUTTON1_STR) || thingType.equals(THING_TYPE_SHELLYBUTTON2_STR);
isSensor = isHT || isFlood || isDW || isSmoke || isGas || isButton || isUNI || isMotion || isSense || isTRV;
hasBattery = isHT || isFlood || isDW || isSmoke || isButton || isMotion || isTRV;
@@ -261,7 +264,7 @@ public class ShellyDeviceProfile {
int idx = i + 1; // group names are 1-based
if (isRGBW2) {
return CHANNEL_GROUP_LIGHT_CONTROL;
} else if (isIX3) {
} else if (isIX) {
return CHANNEL_GROUP_STATUS + idx;
} else if (isButton) {
return CHANNEL_GROUP_STATUS;
@@ -275,7 +278,7 @@ public class ShellyDeviceProfile {
public String getInputSuffix(int i) {
int idx = i + 1; // channel names are 1-based
if (isRGBW2 || isIX3) {
if (isRGBW2 || isIX) {
return ""; // RGBW2 has only 1 channel
} else if (isRoller || isDimmer) {
// Roller has 2 relays, but it will be mapped to 1 roller with 2 inputs
@@ -294,7 +297,7 @@ public class ShellyDeviceProfile {
String btnType = "";
if (isButton) {
return true;
} else if (isIX3 && settings.inputs != null && idx < settings.inputs.size()) {
} else if (isIX && settings.inputs != null && idx < settings.inputs.size()) {
ShellySettingsInput input = settings.inputs.get(idx);
btnType = getString(input.btnType);
} else if (isDimmer) {

View File

@@ -0,0 +1,245 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.api;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.SHELLY_API_TIMEOUT_MS;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
/**
* {@link ShellyHttpClient} implements basic HTTP access
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public class ShellyHttpClient {
private final Logger logger = LoggerFactory.getLogger(ShellyHttpClient.class);
public static final String HTTP_HEADER_AUTH = "Authorization";
public static final String HTTP_AUTH_TYPE_BASIC = "Basic";
public static final String CONTENT_TYPE_JSON = "application/json; charset=UTF-8";
public static final String CONTENT_TYPE_FORM_URLENC = "application/x-www-form-urlencoded";
protected final HttpClient httpClient;
protected ShellyThingConfiguration config = new ShellyThingConfiguration();
protected String thingName;
protected final Gson gson = new Gson();
protected int timeoutErrors = 0;
protected int timeoutsRecovered = 0;
private ShellyDeviceProfile profile;
public ShellyHttpClient(String thingName, ShellyThingInterface thing) {
this(thingName, thing.getThingConfig(), thing.getHttpClient());
this.profile = thing.getProfile();
profile.initFromThingType(thingName);
}
public ShellyHttpClient(String thingName, ShellyThingConfiguration config, HttpClient httpClient) {
profile = new ShellyDeviceProfile();
this.thingName = thingName;
setConfig(thingName, config);
this.httpClient = httpClient;
}
public void initialize() throws ShellyApiException {
}
public void setConfig(String thingName, ShellyThingConfiguration config) {
this.thingName = thingName;
this.config = config;
}
/**
* Submit GET request and return response, check for invalid responses
*
* @param uri: URI (e.g. "/settings")
*/
public <T> T callApi(String uri, Class<T> classOfT) throws ShellyApiException {
String json = httpRequest(uri);
return fromJson(gson, json, classOfT);
}
public <T> T postApi(String uri, String data, Class<T> classOfT) throws ShellyApiException {
String json = httpPost(uri, data);
return fromJson(gson, json, classOfT);
}
protected String httpRequest(String uri) throws ShellyApiException {
ShellyApiResult apiResult = new ShellyApiResult();
int retries = 3;
boolean timeout = false;
while (retries > 0) {
try {
apiResult = innerRequest(HttpMethod.GET, uri, "");
if (timeout) {
logger.debug("{}: API timeout #{}/{} recovered ({})", thingName, timeoutErrors, timeoutsRecovered,
apiResult.getUrl());
timeoutsRecovered++;
}
return apiResult.response; // successful
} catch (ShellyApiException e) {
if ((!e.isTimeout() && !apiResult.isHttpServerError()) && !apiResult.isNotFound() || profile.hasBattery
|| (retries == 0)) {
// Sensor in sleep mode or API exception for non-battery device or retry counter expired
throw e; // non-timeout exception
}
timeout = true;
retries--;
timeoutErrors++; // count the retries
logger.debug("{}: API Timeout, retry #{} ({})", thingName, timeoutErrors, e.toString());
}
}
throw new ShellyApiException("API Timeout or inconsistent result"); // successful
}
public String httpPost(String uri, String data) throws ShellyApiException {
return innerRequest(HttpMethod.POST, uri, data).response;
}
private ShellyApiResult innerRequest(HttpMethod method, String uri, String data) throws ShellyApiException {
Request request = null;
String url = "http://" + config.deviceIp + uri;
ShellyApiResult apiResult = new ShellyApiResult(method.toString(), url);
try {
request = httpClient.newRequest(url).method(method.toString()).timeout(SHELLY_API_TIMEOUT_MS,
TimeUnit.MILLISECONDS);
if (!config.password.isEmpty() && !getString(data).contains("\"auth\":{")) {
String value = config.userId + ":" + config.password;
request.header(HTTP_HEADER_AUTH,
HTTP_AUTH_TYPE_BASIC + " " + Base64.getEncoder().encodeToString(value.getBytes()));
}
fillPostData(request, data);
logger.trace("{}: HTTP {} for {} {}", thingName, method, url, data);
// Do request and get response
ContentResponse contentResponse = request.send();
apiResult = new ShellyApiResult(contentResponse);
apiResult.httpCode = contentResponse.getStatus();
String response = contentResponse.getContentAsString().replace("\t", "").replace("\r\n", "").trim();
logger.trace("{}: HTTP Response {}: {}", thingName, contentResponse.getStatus(), response);
HttpFields headers = contentResponse.getHeaders();
String auth = headers.get(HttpHeader.WWW_AUTHENTICATE);
if (!getString(auth).isEmpty()) {
apiResult.authResponse = auth;
}
// validate response, API errors are reported as Json
if (apiResult.httpCode != HttpStatus.OK_200) {
throw new ShellyApiException(apiResult);
}
if (response.isEmpty() || !response.startsWith("{") && !response.startsWith("[") && !url.contains("/debug/")
&& !url.contains("/sta_cache_reset")) {
throw new ShellyApiException("Unexpected response: " + response);
}
} catch (ExecutionException | InterruptedException | TimeoutException | IllegalArgumentException e) {
ShellyApiException ex = new ShellyApiException(apiResult, e);
if (!ex.isTimeout()) { // will be handled by the caller
logger.trace("{}: API call returned exception", thingName, ex);
}
throw ex;
}
return apiResult;
}
/**
* Fill in POST data, set http headers
*
* @param request HTTP request structure
* @param data POST data, might be empty
*/
private void fillPostData(Request request, String data) {
boolean json = data.startsWith("{") || data.contains("\": {");
String type = json ? CONTENT_TYPE_JSON : CONTENT_TYPE_FORM_URLENC;
request.header(HttpHeader.CONTENT_TYPE, type);
if (!data.isEmpty()) {
StringContentProvider postData;
postData = new StringContentProvider(type, data, StandardCharsets.UTF_8);
request.content(postData);
request.header(HttpHeader.CONTENT_LENGTH, Long.toString(postData.getLength()));
}
}
/**
* Format POST body depending on content type (JSON or form encoded)
*
* @param dataMap Field list
* @param json true=JSON format, false=form encoded
* @return formatted body
*/
public static String buildPostData(Map<String, String> dataMap, boolean json) {
String data = "";
for (Map.Entry<String, String> e : dataMap.entrySet()) {
data = data + (data.isEmpty() ? "" : json ? ", " : "&");
if (!json) {
data = data + e.getKey() + "=" + e.getValue();
} else {
data = data + "\"" + e.getKey() + "\" : \"" + e.getValue() + "\"";
}
}
return json ? "{ " + data + " }" : data;
}
public String getControlUriPrefix(Integer id) {
String uri = "";
if (profile.isLight || profile.isDimmer) {
if (profile.isDuo || profile.isDimmer) {
// Duo + Dimmer
uri = SHELLY_URL_CONTROL_LIGHT;
} else {
// Bulb + RGBW2
uri = "/" + (profile.inColor ? SHELLY_MODE_COLOR : SHELLY_MODE_WHITE);
}
} else {
// Roller, Relay
uri = SHELLY_URL_CONTROL_RELEAY;
}
uri = uri + "/" + id;
return uri;
}
public int getTimeoutErrors() {
return timeoutErrors;
}
public int getTimeoutsRecovered() {
return timeoutsRecovered;
}
}

View File

@@ -10,22 +10,22 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.api;
package org.openhab.binding.shelly.internal.api1;
import java.util.ArrayList;
import java.util.List;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusSensor.ShellyMotionSettings;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyMotionSettings;
import org.openhab.core.thing.CommonTriggerEvents;
import com.google.gson.annotations.SerializedName;
/**
* The {@link ShellyApiJsonDTO} is used for the JSon/GSon mapping
* The {@link Shelly1ApiJsonDTO} is used for the JSon/GSon mapping
*
* @author Markus Michels - Initial contribution
*/
public class ShellyApiJsonDTO {
public class Shelly1ApiJsonDTO {
public static final String SHELLY_NULL_URL = "null";
public static final String SHELLY_URL_DEVINFO = "/shelly";
public static final String SHELLY_URL_STATUS = "/status";
@@ -264,6 +264,7 @@ public class ShellyApiJsonDTO {
public String hostname;
public String fw;
public Boolean auth;
public Integer gen;
@SerializedName("coiot") // Shelly Motion Multicast Endpoint
public String coiot;
@@ -495,6 +496,7 @@ public class ShellyApiJsonDTO {
public String name;
public Boolean ison; // true: output is ON
public Integer brightness;
public Integer temp;
public Integer transition;
@SerializedName("default_state")
public String defaultState;
@@ -728,7 +730,7 @@ public class ShellyApiJsonDTO {
public ArrayList<ShellySettingsEMeter> emeters;
// Internal device temp
public ShellyStatusSensor.ShellySensorTmp tmp; // Shelly 1PM
public ShellySensorTmp tmp; // Shelly 1PM
public Double temperature = SHELLY_API_INVTEMP; // Shelly 2.5
public Boolean overtemperature;
@@ -818,7 +820,7 @@ public class ShellyApiJsonDTO {
public ShellyStatusSensor.ShellyExtHumidity extHumidity; // Shelly 1/1PM: sensor values
public Double temperature; // device temp acc. on the selected temp unit
public ShellyStatusSensor.ShellySensorTmp tmp;
public ShellySensorTmp tmp;
}
public static class ShellyStatusDimmer {
@@ -827,14 +829,14 @@ public class ShellyApiJsonDTO {
public ArrayList<ShellyShortLightStatus> lights; // relay status
public ArrayList<ShellySettingsMeter> meters; // current meter value
public ShellyStatusSensor.ShellySensorTmp tmp;
public ShellySensorTmp tmp;
public Boolean overtemperature;
public Boolean loaderror;
public Boolean overload;
}
public static class ShellyControlRoller {
public static class ShellyRollerStatus {
public String name; // FW 1.8: Symbolic name is configurable
@SerializedName("roller_pos")
@@ -900,17 +902,17 @@ public class ShellyApiJsonDTO {
public Integer boostMinutes;
}
public static class ShellySensorTmp {
public Double value; // Temperature in configured unites
public String units; // 'C' or 'F'
public Double tC; // temperature in deg C
public Double tF; // temperature in deg F
@SerializedName("is_valid")
public Boolean isValid; // whether the internal sensor is operating properly
}
public static class ShellyStatusSensor {
// https://shelly-api-docs.shelly.cloud/#h-amp-t-settings
public static class ShellySensorTmp {
public Double value; // Temperature in configured unites
public String units; // 'C' or 'F'
public Double tC; // temperature in deg C
public Double tF; // temperature in deg F
@SerializedName("is_valid")
public Boolean isValid; // whether the internal sensor is operating properly
}
public static class ShellySensorHum {
public Double value; // relative humidity in %
}

View File

@@ -10,26 +10,26 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.handler.ShellyColorUtils;
import org.openhab.core.types.State;
/**
* The {@link ShellyCoapListener} describes the listening interface to process Coap responses
* The {@link Shelly1CoapListener} describes the listening interface to process Coap responses
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public interface ShellyCoIoTInterface {
public interface Shelly1CoIoTInterface {
public int getVersion();
public CoIotDescrSen fixDescription(@Nullable CoIotDescrSen sen, Map<String, CoIotDescrBlk> blkMap);

View File

@@ -10,10 +10,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.List;
@@ -23,9 +23,9 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.shelly.internal.api.ShellyApiInterface;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.handler.ShellyColorUtils;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
import org.openhab.core.library.types.OnOffType;
@@ -41,13 +41,13 @@ import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
/**
* The {@link ShellyCoIoTProtocol} implements common functions for the CoIoT implementations
* The {@link Shelly1CoIoTProtocol} implements common functions for the CoIoT implementations
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public class ShellyCoIoTProtocol {
private final Logger logger = LoggerFactory.getLogger(ShellyCoIoTProtocol.class);
public class Shelly1CoIoTProtocol {
private final Logger logger = LoggerFactory.getLogger(Shelly1CoIoTProtocol.class);
protected final String thingName;
protected final ShellyThingInterface thingHandler;
protected final ShellyDeviceProfile profile;
@@ -63,7 +63,7 @@ public class ShellyCoIoTProtocol {
protected String[] inputEvent = { "", "", "", "", "", "", "", "" };
protected String lastWakeup = "";
public ShellyCoIoTProtocol(String thingName, ShellyThingInterface thingHandler, Map<String, CoIotDescrBlk> blkMap,
public Shelly1CoIoTProtocol(String thingName, ShellyThingInterface thingHandler, Map<String, CoIotDescrBlk> blkMap,
Map<String, CoIotDescrSen> sensorMap) {
this.thingName = thingName;
this.thingHandler = thingHandler;

View File

@@ -10,10 +10,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.List;
@@ -21,9 +21,9 @@ import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.handler.ShellyColorUtils;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
import org.openhab.core.library.types.OnOffType;
@@ -35,22 +35,22 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link ShellyCoIoTVersion1} implements the parsing for CoIoT version 1
* The {@link Shelly1CoIoTVersion1} implements the parsing for CoIoT version 1
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public class ShellyCoIoTVersion1 extends ShellyCoIoTProtocol implements ShellyCoIoTInterface {
private final Logger logger = LoggerFactory.getLogger(ShellyCoIoTVersion1.class);
public class Shelly1CoIoTVersion1 extends Shelly1CoIoTProtocol implements Shelly1CoIoTInterface {
private final Logger logger = LoggerFactory.getLogger(Shelly1CoIoTVersion1.class);
public ShellyCoIoTVersion1(String thingName, ShellyThingInterface thingHandler, Map<String, CoIotDescrBlk> blkMap,
public Shelly1CoIoTVersion1(String thingName, ShellyThingInterface thingHandler, Map<String, CoIotDescrBlk> blkMap,
Map<String, CoIotDescrSen> sensorMap) {
super(thingName, thingHandler, blkMap, sensorMap);
}
@Override
public int getVersion() {
return ShellyCoapJSonDTO.COIOT_VERSION_1;
return Shelly1CoapJSonDTO.COIOT_VERSION_1;
}
/**

View File

@@ -11,14 +11,14 @@
* SPDX-License-Identifier: EPL-2.0
*/
/**
* The {@link ShellyCoIoTVersion1} implements the parsing for CoIoT version 1
* The {@link Shelly1CoIoTVersion1} implements the parsing for CoIoT version 1
*
* @author Markus Michels - Initial contribution
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.List;
@@ -26,9 +26,9 @@ import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.handler.ShellyColorUtils;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
import org.openhab.core.library.types.OnOffType;
@@ -41,22 +41,22 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link ShellyCoIoTVersion1} implements the parsing for CoIoT version 2
* The {@link Shelly1CoIoTVersion1} implements the parsing for CoIoT version 2
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public class ShellyCoIoTVersion2 extends ShellyCoIoTProtocol implements ShellyCoIoTInterface {
private final Logger logger = LoggerFactory.getLogger(ShellyCoIoTVersion2.class);
public class Shelly1CoIoTVersion2 extends Shelly1CoIoTProtocol implements Shelly1CoIoTInterface {
private final Logger logger = LoggerFactory.getLogger(Shelly1CoIoTVersion2.class);
public ShellyCoIoTVersion2(String thingName, ShellyThingInterface thingHandler, Map<String, CoIotDescrBlk> blkMap,
public Shelly1CoIoTVersion2(String thingName, ShellyThingInterface thingHandler, Map<String, CoIotDescrBlk> blkMap,
Map<String, CoIotDescrSen> sensorMap) {
super(thingName, thingHandler, blkMap, sensorMap);
}
@Override
public int getVersion() {
return ShellyCoapJSonDTO.COIOT_VERSION_2;
return Shelly1CoapJSonDTO.COIOT_VERSION_2;
}
/**

View File

@@ -10,10 +10,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.net.SocketException;
@@ -38,13 +38,13 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiInterface;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDevDescrTypeAdapter;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotDevDescription;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotGenericSensorList;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.CoIotSensorTypeAdapter;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrBlk;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDescrSen;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDevDescrTypeAdapter;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotDevDescription;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotGenericSensorList;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotSensor;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.CoIotSensorTypeAdapter;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyColorUtils;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
@@ -58,15 +58,15 @@ import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
/**
* The {@link ShellyCoapHandler} handles the CoIoT/CoAP registration and events.
* The {@link Shelly1CoapHandler} handles the CoIoT/CoAP registration and events.
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public class ShellyCoapHandler implements ShellyCoapListener {
public class Shelly1CoapHandler implements Shelly1CoapListener {
private static final byte[] EMPTY_BYTE = new byte[0];
private final Logger logger = LoggerFactory.getLogger(ShellyCoapHandler.class);
private final Logger logger = LoggerFactory.getLogger(Shelly1CoapHandler.class);
private final ShellyThingInterface thingHandler;
private ShellyThingConfiguration config = new ShellyThingConfiguration();
private final GsonBuilder gsonBuilder = new GsonBuilder();
@@ -74,10 +74,10 @@ public class ShellyCoapHandler implements ShellyCoapListener {
private String thingName;
private boolean coiotBound = false;
private ShellyCoIoTInterface coiot;
private Shelly1CoIoTInterface coiot;
private int coiotVers = -1;
private final ShellyCoapServer coapServer;
private final Shelly1CoapServer coapServer;
private @Nullable CoapClient statusClient;
private Request reqDescription = new Request(Code.GET, Type.CON);
private Request reqStatus = new Request(Code.GET, Type.CON);
@@ -93,13 +93,13 @@ public class ShellyCoapHandler implements ShellyCoapListener {
private ShellyDeviceProfile profile;
private ShellyApiInterface api;
public ShellyCoapHandler(ShellyThingInterface thingHandler, ShellyCoapServer coapServer) {
public Shelly1CoapHandler(ShellyThingInterface thingHandler, Shelly1CoapServer coapServer) {
this.thingHandler = thingHandler;
this.thingName = thingHandler.getThingName();
this.profile = thingHandler.getProfile();
this.api = thingHandler.getApi();
this.coapServer = coapServer;
this.coiot = new ShellyCoIoTVersion2(thingName, thingHandler, blkMap, sensorMap); // Default: V2
this.coiot = new Shelly1CoIoTVersion2(thingName, thingHandler, blkMap, sensorMap); // Default: V2
gsonBuilder.registerTypeAdapter(CoIotDevDescription.class, new CoIotDevDescrTypeAdapter());
gsonBuilder.registerTypeAdapter(CoIotGenericSensorList.class, new CoIotSensorTypeAdapter());
@@ -240,9 +240,9 @@ public class ShellyCoapHandler implements ShellyCoapListener {
thingHandler.updateProperties(PROPERTY_COAP_VERSION, sVersion);
logger.debug("{}: CoIoT Version {} detected", thingName, iVersion);
if (iVersion == COIOT_VERSION_1) {
coiot = new ShellyCoIoTVersion1(thingName, thingHandler, blkMap, sensorMap);
coiot = new Shelly1CoIoTVersion1(thingName, thingHandler, blkMap, sensorMap);
} else if (iVersion == COIOT_VERSION_2) {
coiot = new ShellyCoIoTVersion2(thingName, thingHandler, blkMap, sensorMap);
coiot = new Shelly1CoIoTVersion2(thingName, thingHandler, blkMap, sensorMap);
} else {
logger.warn("{}: Unsupported CoAP version detected: {}", thingName, sVersion);
return;

View File

@@ -10,7 +10,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import java.io.IOException;
import java.util.ArrayList;
@@ -23,11 +23,11 @@ import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
/**
* The {@link ShellyCoapJSonDTO} helps the CoIoT Json into Java objects
* The {@link Shelly1CoapJSonDTO} helps the CoIoT Json into Java objects
*
* @author Markus Michels - Initial contribution
*/
public class ShellyCoapJSonDTO {
public class Shelly1CoapJSonDTO {
// Coap
public static final int COIOT_VERSION_1 = 1;
public static final int COIOT_VERSION_2 = 2;

View File

@@ -10,18 +10,18 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import org.eclipse.californium.core.coap.Response;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* The {@link ShellyCoapListener} describes the listening interface to process Coap responses
* The {@link Shelly1CoapListener} describes the listening interface to process Coap responses
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public interface ShellyCoapListener {
public interface Shelly1CoapListener {
public void processResponse(@Nullable Response response);
}

View File

@@ -10,9 +10,9 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.coap;
package org.openhab.binding.shelly.internal.api1;
import static org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO.COIOT_PORT;
import static org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO.COIOT_PORT;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -38,24 +38,24 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link ShellyCoapServer} implements the UDP listener and status event processor (for /cit/s messages)
* The {@link Shelly1CoapServer} implements the UDP listener and status event processor (for /cit/s messages)
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public class ShellyCoapServer {
private final Logger logger = LoggerFactory.getLogger(ShellyCoapServer.class);
public class Shelly1CoapServer {
private final Logger logger = LoggerFactory.getLogger(Shelly1CoapServer.class);
boolean started = false;
private CoapEndpoint statusEndpoint = new CoapEndpoint.Builder().build();
private @Nullable UdpMulticastConnector statusConnector;
private CoapServer server = new CoapServer(NetworkConfig.getStandard(), COIOT_PORT);
private final Set<ShellyCoapListener> coapListeners = ConcurrentHashMap.newKeySet();
private final Set<Shelly1CoapListener> coapListeners = ConcurrentHashMap.newKeySet();
protected class ShellyStatusListener extends CoapResource {
private ShellyCoapServer listener;
private Shelly1CoapServer listener;
public ShellyStatusListener(String uri, ShellyCoapServer listener) {
public ShellyStatusListener(String uri, Shelly1CoapServer listener) {
super(uri, true);
getAttributes().setTitle("ShellyCoapListener");
this.listener = listener;
@@ -78,7 +78,7 @@ public class ShellyCoapServer {
}
}
public synchronized void start(String localIp, int port, ShellyCoapListener listener)
public synchronized void start(String localIp, int port, Shelly1CoapListener listener)
throws UnknownHostException, SocketException {
if (!started) {
logger.debug("Initializing CoIoT listener (local IP={}:{})", localIp, port);
@@ -125,7 +125,7 @@ public class ShellyCoapServer {
/**
* Cancel pending requests and shutdown the client
*/
public void stop(ShellyCoapListener listener) {
public void stop(Shelly1CoapListener listener) {
coapListeners.remove(listener);
if (coapListeners.isEmpty()) {
stop();

View File

@@ -10,10 +10,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.shelly.internal.api;
package org.openhab.binding.shelly.internal.api1;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.nio.charset.StandardCharsets;
@@ -31,61 +31,59 @@ import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyControlRoller;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyOtaCheckResult;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySendKeyList;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySenseKeyCode;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsDevice;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsLight;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsLogin;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsUpdate;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyShortLightStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusLight;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusSensor;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiInterface;
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.ShellySendKeyList;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySenseKeyCode;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDevice;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsLight;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsLogin;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsUpdate;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortLightStatus;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusLight;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusRelay;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
import org.openhab.core.library.unit.ImperialUnits;
import org.openhab.core.library.unit.SIUnits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
/**
* {@link ShellyHttpApi} wraps the Shelly REST API and provides various low level function to access the device api (not
* {@link Shelly1HttpApi} wraps the Shelly REST API and provides various low level function to access the device api
* (not
* cloud api).
*
* @author Markus Michels - Initial contribution
*/
@NonNullByDefault
public class ShellyHttpApi implements ShellyApiInterface {
public static final String HTTP_HEADER_AUTH = "Authorization";
public static final String HTTP_AUTH_TYPE_BASIC = "Basic";
public static final String CONTENT_TYPE_JSON = "application/json; charset=UTF-8";
public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterface {
private final Logger logger = LoggerFactory.getLogger(Shelly1HttpApi.class);
private final ShellyDeviceProfile profile;
private final Logger logger = LoggerFactory.getLogger(ShellyHttpApi.class);
private final HttpClient httpClient;
private ShellyThingConfiguration config = new ShellyThingConfiguration();
private String thingName;
private final Gson gson = new Gson();
private int timeoutErrors = 0;
private int timeoutsRecovered = 0;
private ShellyDeviceProfile profile = new ShellyDeviceProfile();
public ShellyHttpApi(String thingName, ShellyThingConfiguration config, HttpClient httpClient) {
this.httpClient = httpClient;
this.thingName = thingName;
setConfig(thingName, config);
profile.initFromThingType(thingName);
public Shelly1HttpApi(String thingName, ShellyThingInterface thing) {
super(thingName, thing);
profile = thing.getProfile();
}
@Override
public void setConfig(String thingName, ShellyThingConfiguration config) {
this.thingName = thingName;
this.config = config;
/**
* Simple initialization - called by discovery handler
*
* @param thingName Symbolic thing name
* @param config Thing Configuration
* @param httpClient HTTP Client to be passed to ShellyHttpClient
*/
public Shelly1HttpApi(String thingName, ShellyThingConfiguration config, HttpClient httpClient) {
super(thingName, config, httpClient);
this.profile = new ShellyDeviceProfile();
}
@Override
@@ -112,7 +110,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
*/
@Override
public ShellyDeviceProfile getDeviceProfile(String thingType) throws ShellyApiException {
String json = request(SHELLY_URL_SETTINGS);
String json = httpRequest(SHELLY_URL_SETTINGS);
if (json.contains("\"type\":\"SHDM-")) {
logger.trace("{}: Detected a Shelly Dimmer: fix Json (replace lights[] tag with dimmers[]", thingName);
json = fixDimmerJson(json);
@@ -151,7 +149,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
public ShellySettingsStatus getStatus() throws ShellyApiException {
String json = "";
try {
json = request(SHELLY_URL_STATUS);
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,"));
@@ -164,8 +162,8 @@ public class ShellyHttpApi implements ShellyApiInterface {
}
@Override
public ShellyStatusRelay getRelayStatus(Integer relayIndex) throws ShellyApiException {
return callApi(SHELLY_URL_STATUS_RELEAY + "/" + relayIndex.toString(), ShellyStatusRelay.class);
public ShellyStatusRelay getRelayStatus(int relayIndex) throws ShellyApiException {
return callApi(SHELLY_URL_STATUS_RELEAY + "/" + relayIndex, ShellyStatusRelay.class);
}
@Override
@@ -183,27 +181,23 @@ public class ShellyHttpApi implements ShellyApiInterface {
@Override
public void setBrightness(int id, int brightness, boolean autoOn) throws ShellyApiException {
String turn = autoOn ? SHELLY_LIGHT_TURN + "=" + SHELLY_API_ON + "&" : "";
request(getControlUriPrefix(id) + "?" + turn + "brightness=" + brightness);
httpRequest(getControlUriPrefix(id) + "?" + turn + "brightness=" + brightness);
}
@Override
public ShellyControlRoller getRollerStatus(int idx) throws ShellyApiException {
String uri = SHELLY_URL_CONTROL_ROLLER + "/" + idx + "/pos";
return callApi(uri, ShellyControlRoller.class);
public ShellyRollerStatus getRollerStatus(int rollerIndex) throws ShellyApiException {
String uri = SHELLY_URL_CONTROL_ROLLER + "/" + rollerIndex + "/pos";
return callApi(uri, ShellyRollerStatus.class);
}
@Override
public void setRollerTurn(int idx, String turnMode) throws ShellyApiException {
request(SHELLY_URL_CONTROL_ROLLER + "/" + idx + "?go=" + turnMode);
public void setRollerTurn(int relayIndex, String turnMode) throws ShellyApiException {
httpRequest(SHELLY_URL_CONTROL_ROLLER + "/" + relayIndex + "?go=" + turnMode);
}
@Override
public void setRollerPos(int id, int position) throws ShellyApiException {
request(SHELLY_URL_CONTROL_ROLLER + "/" + id + "?go=to_pos&roller_pos=" + position);
}
public void setRollerTimer(int idx, int timer) throws ShellyApiException {
request(SHELLY_URL_CONTROL_ROLLER + "/" + idx + "?timer=" + timer);
public void setRollerPos(int relayIndex, int position) throws ShellyApiException {
httpRequest(SHELLY_URL_CONTROL_ROLLER + "/" + relayIndex + "?go=to_pos&roller_pos=" + position);
}
@Override
@@ -239,12 +233,12 @@ public class ShellyHttpApi implements ShellyApiInterface {
type = SHELLY_CLASS_LIGHT;
}
String uri = SHELLY_URL_SETTINGS + "/" + type + "/" + index + "?" + timerName + "=" + value;
request(uri);
httpRequest(uri);
}
@Override
public void setSleepTime(int value) throws ShellyApiException {
request(SHELLY_URL_SETTINGS + "?sleep_time=" + value);
httpRequest(SHELLY_URL_SETTINGS + "?sleep_time=" + value);
}
@Override
@@ -258,7 +252,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
if (auto) {
uri = uri + "&target_t=" + getDouble(profile.settings.thermostats.get(0).targetTemp.value);
}
request(uri); // percentage to open the valve
httpRequest(uri); // percentage to open the valve
}
@Override
@@ -280,12 +274,12 @@ public class ShellyHttpApi implements ShellyApiInterface {
@Override
public void startValveBoost(int valveId, int value) throws ShellyApiException {
int minutes = value != -1 ? value : getInteger(profile.settings.thermostats.get(0).boostMinutes);
request("/thermostat/" + valveId + "?boost_minutes=" + minutes);
httpRequest("/thermostat/0?boost_minutes=" + minutes);
}
@Override
public void setLedStatus(String ledName, Boolean value) throws ShellyApiException {
request(SHELLY_URL_SETTINGS + "?" + ledName + "=" + (value ? SHELLY_API_TRUE : SHELLY_API_FALSE));
httpRequest(SHELLY_URL_SETTINGS + "?" + ledName + "=" + (value ? SHELLY_API_TRUE : SHELLY_API_FALSE));
}
public ShellySettingsLight getLightSettings() throws ShellyApiException {
@@ -298,7 +292,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
}
public void setLightSetting(String parm, String value) throws ShellyApiException {
request(SHELLY_URL_SETTINGS + "?" + parm + "=" + value);
httpRequest(SHELLY_URL_SETTINGS + "?" + parm + "=" + value);
}
@Override
@@ -396,7 +390,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
public void setLightParm(int lightIndex, String parm, String value) throws ShellyApiException {
// Bulb, RGW2: /<color mode>/<light id>?parm?value
// Dimmer: /light/<light id>?parm=value
request(getControlUriPrefix(lightIndex) + "?" + parm + "=" + value);
httpRequest(getControlUriPrefix(lightIndex) + "?" + parm + "=" + value);
}
@Override
@@ -410,7 +404,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
url = url + key + "=" + parameters.get(key);
i++;
}
request(url);
httpRequest(url);
}
/**
@@ -422,7 +416,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
* @throws ShellyApiException
*/
public Map<String, String> getIRCodeList() throws ShellyApiException {
String result = request(SHELLY_URL_LIST_IR);
String result = httpRequest(SHELLY_URL_LIST_IR);
// take pragmatic approach to make the returned JSon into named arrays for Gson parsing
String keyList = substringAfter(result, "[");
keyList = substringBeforeLast(keyList, "]");
@@ -468,11 +462,11 @@ public class ShellyHttpApi implements ShellyApiInterface {
} else if (type.equals(SHELLY_IR_CODET_PRONTO_HEX)) {
url = url + "&" + SHELLY_IR_CODET_PRONTO_HEX + "=" + keyCode;
}
request(url);
httpRequest(url);
}
public void setSenseSetting(String setting, String value) throws ShellyApiException {
request(SHELLY_URL_SETTINGS + "?" + setting + "=" + value);
httpRequest(SHELLY_URL_SETTINGS + "?" + setting + "=" + value);
}
/**
@@ -500,7 +494,8 @@ public class ShellyHttpApi implements ShellyApiInterface {
private void setDimmerEvents() throws ShellyApiException {
if (profile.settings.dimmers != null) {
for (int i = 0; i < profile.settings.dimmers.size(); i++) {
int sz = profile.settings.dimmers.size();
for (int i = 0; i < sz; i++) {
setEventUrls(i);
}
} else if (profile.isLight) {
@@ -574,7 +569,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
if (!profile.settingsJson.contains(testUrl)) {
// Current Action URL is != new URL
logger.debug("{}: Set new url for event type {}: {}", thingName, eventType, newUrl);
request(SHELLY_URL_SETTINGS + "?" + mkEventUrl(eventType) + "=" + urlEncode(newUrl));
httpRequest(SHELLY_URL_SETTINGS + "?" + mkEventUrl(eventType) + "=" + urlEncode(newUrl));
}
}
}
@@ -597,8 +592,8 @@ public class ShellyHttpApi implements ShellyApiInterface {
if (!profile.settingsJson.contains(test)) {
// Current Action URL is != new URL
logger.debug("{}: Set URL for type {} to {}", thingName, eventType, newUrl);
request(SHELLY_URL_SETTINGS + "/" + deviceClass + "/" + index + "?" + mkEventUrl(eventType) + "="
+ urlEncode(newUrl));
httpRequest(SHELLY_URL_SETTINGS + "/" + deviceClass + "/" + index + "?" + mkEventUrl(eventType)
+ "=" + urlEncode(newUrl));
}
}
}
@@ -613,6 +608,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
*
* @param uri: URI (e.g. "/settings")
*/
@Override
public <T> T callApi(String uri, Class<T> classOfT) throws ShellyApiException {
String json = request(uri);
return fromJson(gson, json, classOfT);
@@ -687,6 +683,7 @@ public class ShellyHttpApi implements ShellyApiInterface {
return apiResult;
}
@Override
public String getControlUriPrefix(Integer id) {
String uri = "";
if (profile.isLight || profile.isDimmer) {

View File

@@ -29,7 +29,7 @@ import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiResult;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api.ShellyHttpApi;
import org.openhab.binding.shelly.internal.api1.Shelly1HttpApi;
import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyBaseHandler;
@@ -140,7 +140,7 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant {
config.password = bindingConfig.defaultPassword;
try {
ShellyHttpApi api = new ShellyHttpApi(name, config, httpClient);
Shelly1HttpApi api = new Shelly1HttpApi(name, config, httpClient);
profile = api.getDeviceProfile(thingType);
logger.debug("{}: Shelly settings : {}", name, profile.settingsJson);

View File

@@ -12,8 +12,8 @@
*/
package org.openhab.binding.shelly.internal.discovery;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.BINDING_ID;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.LinkedHashMap;
@@ -30,6 +30,219 @@ import org.openhab.core.thing.ThingUID;
*/
@NonNullByDefault
public class ShellyThingCreator {
// Device Types
public static final String SHELLYDT_1 = "SHSW-1";
public static final String SHELLYDT_1PM = "SHSW-PM";
public static final String SHELLYDT_1L = "SHSW-L";
public static final String SHELLYDT_SHPLG = "SHPLG-1";
public static final String SHELLYDT_SHPLG_S = "SHPLG-S";
public static final String SHELLYDT_SHPLG_U1 = "SHPLG-U1";
public static final String SHELLYDT_SHELLY2 = "SHSW-21";
public static final String SHELLYDT_SHELLY25 = "SHSW-25";
public static final String SHELLYDT_SHPRO = "SHSW-44";
public static final String SHELLYDT_EM = "SHEM";
public static final String SHELLYDT_3EM = "SHEM-3";
public static final String SHELLYDT_HT = "SHHT-1";
public static final String SHELLYDT_DW = "SHDW-1";
public static final String SHELLYDT_DW2 = "SHDW-2";
public static final String SHELLYDT_SENSE = "SHSEN-1";
public static final String SHELLYDT_MOTION = "SHMOS-01";
public static final String SHELLYDT_MOTION2 = "SHMOS-02";
public static final String SHELLYDT_GAS = "SHGS-1";
public static final String SHELLYDT_DIMMER = "SHDM-1";
public static final String SHELLYDT_DIMMER2 = "SHDM-2";
public static final String SHELLYDT_IX3 = "SHIX3-1";
public static final String SHELLYDT_BULB = "SHBLB-1";
public static final String SHELLYDT_DUO = "SHBDUO-1";
public static final String SHELLYDT_DUORGBW = "SHCB-1";
public static final String SHELLYDT_VINTAGE = "SHVIN-1";
public static final String SHELLYDT_RGBW2 = "SHRGBW2";
public static final String SHELLYDT_BUTTON1 = "SHBTN-1";
public static final String SHELLYDT_BUTTON2 = "SHBTN-2";
public static final String SHELLYDT_UNI = "SHUNI-1";
public static final String SHELLYDT_TRV = "SHTRV-01";
// Shelly Plus Series
public static final String SHELLYDT_PLUS1 = "SNSW-001X16EU";
public static final String SHELLYDT_PLUS1PM = "SNSW-001P16EU";
public static final String SHELLYDT_PLUS1UL = "SNSW-001X15UL";
public static final String SHELLYDT_PLUS1PMUL = "SNSW-001P15UL";
public static final String SHELLYDT_PLUS2PM_RELAY = "SNSW-002P16EU-relay";
public static final String SHELLYDT_PLUS2PM_ROLLER = "SNSW-002P16EU-roller";
public static final String SHELLYDT_PLUSPLUGUS = "SNPL-00116US";
public static final String SHELLYDT_PLUSI4 = "SNSN-0024X";
public static final String SHELLYDT_PLUSI4DC = "SNSN-0D24X";
public static final String SHELLYDT_PLUSHT = "SNSN-0013A";
// Shelly Pro Series
public static final String SHELLYDT_PRO1 = "SPSW-001XE16EU";
public static final String SHELLYDT_PRO1_2 = "SPSW-101XE16EU";
public static final String SHELLYDT_PRO1PM = "SPSW-001PE16EU";
public static final String SHELLYDT_PRO1PM_ = "SPSW-201PE16EU";
public static final String SHELLYDT_PRO1PM_2 = "SPSW-101PE16EU";
public static final String SHELLYDT_PRO2_RELAY = "SPSW-002XE16EU-relay";
public static final String SHELLYDT_PRO2_ROLLER = "SPSW-002XE16EU-roller";
public static final String SHELLYDT_PRO2_RELAY_2 = "SPSW-102XE16EU-relay";
public static final String SHELLYDT_PRO2_ROLLER_2 = "SPSW-102XE16EU-roller";
public static final String SHELLYDT_PRO2PM_RELAY = "SPSW-002PE16EU-relay";
public static final String SHELLYDT_PRO2PM_ROLLER = "SPSW-002PE16EU-roller";
public static final String SHELLYDT_PRO2PM_RELAY_2 = "SPSW-002PE16EU-relay";
public static final String SHELLYDT_PRO2PM_ROLLER_2 = "SPSW-002PE16EU-roller";
public static final String SHELLYDT_PRO3 = "SPSW-003XE16EU";
public static final String SHELLYDT_PRO4PM = "SPSW-004PE16EU";
public static final String SHELLYDT_PRO4PM_2 = "SPSW-104PE16EU";
// Thing names
public static final String THING_TYPE_SHELLY1_STR = "shelly1";
public static final String THING_TYPE_SHELLY1L_STR = "shelly1l";
public static final String THING_TYPE_SHELLY1PM_STR = "shelly1pm";
public static final String THING_TYPE_SHELLYEM_STR = "shellyem";
public static final String THING_TYPE_SHELLY3EM_STR = "shellyem3"; // bad: misspelled product name, it's 3EM
public static final String THING_TYPE_SHELLY2_PREFIX = "shellyswitch";
public static final String THING_TYPE_SHELLY2_RELAY_STR = "shelly2-relay";
public static final String THING_TYPE_SHELLY2_ROLLER_STR = "shelly2-roller";
public static final String THING_TYPE_SHELLY25_PREFIX = "shellyswitch25";
public static final String THING_TYPE_SHELLY25_RELAY_STR = "shelly25-relay";
public static final String THING_TYPE_SHELLY25_ROLLER_STR = "shelly25-roller";
public static final String THING_TYPE_SHELLY4PRO_STR = "shelly4pro";
public static final String THING_TYPE_SHELLYPLUG_STR = "shellyplug";
public static final String THING_TYPE_SHELLYPLUGS_STR = "shellyplugs";
public static final String THING_TYPE_SHELLYPLUGU1_STR = "shellyplugu1"; // Shely Plug US
public static final String THING_TYPE_SHELLYDIMMER_STR = "shellydimmer";
public static final String THING_TYPE_SHELLYDIMMER2_STR = "shellydimmer2";
public static final String THING_TYPE_SHELLYIX3_STR = "shellyix3";
public static final String THING_TYPE_SHELLYBULB_STR = "shellybulb";
public static final String THING_TYPE_SHELLYDUO_STR = "shellybulbduo";
public static final String THING_TYPE_SHELLYVINTAGE_STR = "shellyvintage";
public static final String THING_TYPE_SHELLYRGBW2_PREFIX = "shellyrgbw2";
public static final String THING_TYPE_SHELLYRGBW2_COLOR_STR = THING_TYPE_SHELLYRGBW2_PREFIX + "-color";
public static final String THING_TYPE_SHELLYRGBW2_WHITE_STR = THING_TYPE_SHELLYRGBW2_PREFIX + "-white";
public static final String THING_TYPE_SHELLYDUORGBW_STR = "shellycolorbulb";
public static final String THING_TYPE_SHELLYHT_STR = "shellyht";
public static final String THING_TYPE_SHELLYSMOKE_STR = "shellysmoke";
public static final String THING_TYPE_SHELLYGAS_STR = "shellygas";
public static final String THING_TYPE_SHELLYFLOOD_STR = "shellyflood";
public static final String THING_TYPE_SHELLYDOORWIN_STR = "shellydw";
public static final String THING_TYPE_SHELLYDOORWIN2_STR = "shellydw2";
public static final String THING_TYPE_SHELLYEYE_STR = "shellyseye";
public static final String THING_TYPE_SHELLYSENSE_STR = "shellysense";
public static final String THING_TYPE_SHELLYTRV_STR = "shellytrv";
public static final String THING_TYPE_SHELLYMOTION_STR = "shellymotion";
public static final String THING_TYPE_SHELLYMOTION2_STR = "shellymotion2";
public static final String THING_TYPE_SHELLYBUTTON1_STR = "shellybutton1";
public static final String THING_TYPE_SHELLYBUTTON2_STR = "shellybutton2";
public static final String THING_TYPE_SHELLYUNI_STR = "shellyuni";
// Shelly Plus Seriens
public static final String THING_TYPE_SHELLYPLUS1_STR = "shellyplus1";
public static final String THING_TYPE_SHELLYPLUS1PM_STR = "shellyplus1pm";
public static final String THING_TYPE_SHELLYPLUS2PM_RELAY_STR = "shellyplus2pm-relay";
public static final String THING_TYPE_SHELLYPLUS2PM_ROLLER_STR = "shellyplus2pm-roller";
public static final String THING_TYPE_SHELLYPLUSI4_STR = "shellyplusi4";
public static final String THING_TYPE_SHELLYPLUSI4DC_STR = "shellyplusi4dc";
public static final String THING_TYPE_SHELLYPLUSHT_STR = "shellyplusht";
public static final String THING_TYPE_SHELLYPLUSPLUGUS_STR = "shellyplusplugus";
// Shelly Pro Series
public static final String THING_TYPE_SHELLYPRO1_STR = "shellypro1";
public static final String THING_TYPE_SHELLYPRO1PM_STR = "shellypro1pm";
public static final String THING_TYPE_SHELLYPRO2_RELAY_STR = "shellypro2-relay";
public static final String THING_TYPE_SHELLYPRO2_ROLLER_STR = "shellypro2-roller";
public static final String THING_TYPE_SHELLYPRO2PM_RELAY_STR = "shellypro2pm-relay";
public static final String THING_TYPE_SHELLYPRO2PM_ROLLER_STR = "shellypro2pm-roller";
public static final String THING_TYPE_SHELLYPRO3_STR = "shellypro3";
public static final String THING_TYPE_SHELLYPRO4PM_STR = "shellypro4pm";
public static final String THING_TYPE_SHELLYPROTECTED_STR = "shellydevice";
public static final String THING_TYPE_SHELLYUNKNOWN_STR = "shellyunknown";
// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_SHELLY1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1_STR);
public static final ThingTypeUID THING_TYPE_SHELLY1L = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1L_STR);
public static final ThingTypeUID THING_TYPE_SHELLY1PM = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY1PM_STR);
public static final ThingTypeUID THING_TYPE_SHELLYEM = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYEM_STR);
public static final ThingTypeUID THING_TYPE_SHELLY3EM = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY3EM_STR);
public static final ThingTypeUID THING_TYPE_SHELLY2_RELAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY2_RELAY_STR);
public static final ThingTypeUID THING_TYPE_SHELLY2_ROLLER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY2_ROLLER_STR);
public static final ThingTypeUID THING_TYPE_SHELLY25_RELAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY25_RELAY_STR);
public static final ThingTypeUID THING_TYPE_SHELLY25_ROLLER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLY25_ROLLER_STR);
public static final ThingTypeUID THING_TYPE_SHELLY4PRO = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLY4PRO_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUG = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPLUG_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUGS = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPLUGS_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUGU1 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUGU1_STR);
public static final ThingTypeUID THING_TYPE_SHELLYUNI = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYUNI_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDIMMER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDIMMER_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDIMMER2 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDIMMER2_STR);
public static final ThingTypeUID THING_TYPE_SHELLYIX3 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYIX3_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBULB = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYBULB_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDUO = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYDUO_STR);
public static final ThingTypeUID THING_TYPE_SHELLYVINTAGE = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYVINTAGE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDUORGBW = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDUORGBW_STR);
public static final ThingTypeUID THING_TYPE_SHELLYHT = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYHT_STR);
public static final ThingTypeUID THING_TYPE_SHELLYSENSE = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYSENSE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYSMOKE = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYSMOKE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYGAS = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYGAS_STR);
public static final ThingTypeUID THING_TYPE_SHELLYFLOOD = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYFLOOD_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDOORWIN = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDOORWIN_STR);
public static final ThingTypeUID THING_TYPE_SHELLYDOORWIN2 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYDOORWIN2_STR);
public static final ThingTypeUID THING_TYPE_SHELLYTRV = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYTRV_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBUTTON1 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBUTTON1_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBUTTON2 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBUTTON2_STR);
public static final ThingTypeUID THING_TYPE_SHELLYEYE = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYEYE_STR);
public static final ThingTypeUID THING_TYPE_SHELLMOTION = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYMOTION_STR);
public static final ThingTypeUID THING_TYPE_SHELLYRGBW2_COLOR = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYRGBW2_COLOR_STR);
public static final ThingTypeUID THING_TYPE_SHELLYRGBW2_WHITE = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYRGBW2_WHITE_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPROTECTED = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPROTECTED_STR);
public static final ThingTypeUID THING_TYPE_SHELLYUNKNOWN = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYUNKNOWN_STR);
// Shelly Plus/Pro
public static final ThingTypeUID THING_TYPE_SHELLYPLUS1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPLUS1_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUS1PM = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUS1PM_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUS2PM_RELAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUS2PM_RELAY_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUS2PM_ROLLER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUS2PM_ROLLER_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUSI4 = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUSI4_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUSI4DC = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUSI4DC_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUSHT = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUSHT_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPLUSPLUGUS = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPLUSPLUGUS_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO1 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPRO1_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO1PM = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO1PM_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO2_RELAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO2_RELAY_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO2_ROLLER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO2_ROLLER_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO2PM_RELAY = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO2PM_RELAY_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO2PM_ROLLER = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO2PM_ROLLER_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO3 = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPRO3_STR);
public static final ThingTypeUID THING_TYPE_SHELLYPRO4PM = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYPRO4PM_STR);
private static final Map<String, String> THING_TYPE_MAPPING = new LinkedHashMap<>();
static {
// mapping by device type id
@@ -57,6 +270,35 @@ public class ShellyThingCreator {
THING_TYPE_MAPPING.put(SHELLYDT_TRV, THING_TYPE_SHELLYTRV_STR);
THING_TYPE_MAPPING.put(SHELLYDT_MOTION, THING_TYPE_SHELLYMOTION_STR);
// Plus Series
THING_TYPE_MAPPING.put(SHELLYDT_PLUS1, THING_TYPE_SHELLYPLUS1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUS1PM, THING_TYPE_SHELLYPLUS1PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUS1UL, THING_TYPE_SHELLYPLUS1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUS1PMUL, THING_TYPE_SHELLYPLUS1PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUS2PM_RELAY, THING_TYPE_SHELLYPLUS2PM_RELAY_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUS2PM_ROLLER, THING_TYPE_SHELLYPLUS2PM_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUSPLUGUS, THING_TYPE_SHELLYPLUSPLUGUS_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUSI4DC, THING_TYPE_SHELLYPLUSI4DC_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUSI4, THING_TYPE_SHELLYPLUSI4_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PLUSHT, THING_TYPE_SHELLYPLUSHT_STR);
// Pro Series
THING_TYPE_MAPPING.put(SHELLYDT_PRO1, THING_TYPE_SHELLYPRO1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO1_2, THING_TYPE_SHELLYPRO1_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO1PM, THING_TYPE_SHELLYPRO1PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO1PM_2, THING_TYPE_SHELLYPRO1PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2_RELAY, THING_TYPE_SHELLYPRO2_RELAY_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2_RELAY_2, THING_TYPE_SHELLYPRO2_RELAY_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2_ROLLER, THING_TYPE_SHELLYPRO2_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2_ROLLER_2, THING_TYPE_SHELLYPRO2_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2PM_RELAY, THING_TYPE_SHELLYPRO2PM_RELAY_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2PM_RELAY_2, THING_TYPE_SHELLYPRO2PM_RELAY_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2PM_ROLLER, THING_TYPE_SHELLYPRO2PM_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO2PM_ROLLER_2, THING_TYPE_SHELLYPRO2PM_ROLLER_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO3, THING_TYPE_SHELLYPRO3_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO4PM, THING_TYPE_SHELLYPRO4PM_STR);
THING_TYPE_MAPPING.put(SHELLYDT_PRO4PM_2, THING_TYPE_SHELLYPRO4PM_STR);
// mapping by thing type
THING_TYPE_MAPPING.put(THING_TYPE_SHELLY1_STR, THING_TYPE_SHELLY1_STR);
THING_TYPE_MAPPING.put(THING_TYPE_SHELLY1PM_STR, THING_TYPE_SHELLY1PM_STR);

View File

@@ -13,7 +13,8 @@
package org.openhab.binding.shelly.internal.handler;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import static org.openhab.binding.shelly.internal.handler.ShellyComponents.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import static org.openhab.core.thing.Thing.*;
@@ -31,17 +32,17 @@ import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiInterface;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyInputState;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyOtaCheckResult;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsDevice;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiResult;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api.ShellyHttpApi;
import org.openhab.binding.shelly.internal.coap.ShellyCoapHandler;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO;
import org.openhab.binding.shelly.internal.coap.ShellyCoapServer;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyInputState;
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.Shelly1CoapHandler;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapServer;
import org.openhab.binding.shelly.internal.api1.Shelly1HttpApi;
import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.discovery.ShellyThingCreator;
@@ -84,11 +85,13 @@ public class ShellyBaseHandler extends BaseThingHandler
public String thingType = "";
protected final ShellyApiInterface api;
private final HttpClient httpClient;
protected 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 ShellyCoapHandler coap;
private final Shelly1CoapHandler coap;
public boolean autoCoIoT = false;
public final ShellyTranslationProvider messages;
@@ -124,7 +127,7 @@ public class ShellyBaseHandler extends BaseThingHandler
* @param httpPort from httpService
*/
public ShellyBaseHandler(final Thing thing, final ShellyTranslationProvider translationProvider,
final ShellyBindingConfiguration bindingConfig, final ShellyCoapServer coapServer, final String localIP,
final ShellyBindingConfiguration bindingConfig, final Shelly1CoapServer coapServer, final String localIP,
int httpPort, final HttpClient httpClient) {
super(thing);
@@ -135,11 +138,12 @@ public class ShellyBaseHandler extends BaseThingHandler
this.bindingConfig = bindingConfig;
this.config = getConfigAs(ShellyThingConfiguration.class);
this.httpClient = httpClient;
this.localIP = localIP;
this.localPort = String.valueOf(httpPort);
this.api = new ShellyHttpApi(thingName, config, httpClient);
this.api = new Shelly1HttpApi(thingName, config, httpClient);
coap = new ShellyCoapHandler(this, coapServer);
coap = new Shelly1CoapHandler(this, coapServer);
}
@Override
@@ -196,6 +200,11 @@ public class ShellyBaseHandler extends BaseThingHandler
return config;
}
@Override
public HttpClient getHttpClient() {
return httpClient;
}
/**
* This routine is called every time the Thing configuration has been changed
*/
@@ -274,7 +283,7 @@ public class ShellyBaseHandler extends BaseThingHandler
if (config.eventsCoIoT && (tmpPrf.settings.coiot != null) && (tmpPrf.settings.coiot.enabled != null)) {
String devpeer = getString(tmpPrf.settings.coiot.peer);
String ourpeer = config.localIp + ":" + ShellyCoapJSonDTO.COIOT_PORT;
String ourpeer = config.localIp + ":" + Shelly1CoapJSonDTO.COIOT_PORT;
if (!tmpPrf.settings.coiot.enabled || (profile.isMotion && devpeer.isEmpty())) {
try {
api.setCoIoTPeer(ourpeer);
@@ -749,7 +758,7 @@ public class ShellyBaseHandler extends BaseThingHandler
if (isButton) {
triggerButton(group, idx, mapButtonEvent(event));
channel = CHANNEL_BUTTON_TRIGGER + profile.getInputSuffix(idx);
payload = ShellyApiJsonDTO.mapButtonEvent(event);
payload = Shelly1ApiJsonDTO.mapButtonEvent(event);
} else {
logger.debug("{}: Relay button is not in memontary or detached mode, ignore SHORT/LONGPUSH",
thingName);

View File

@@ -12,7 +12,7 @@
*/
package org.openhab.binding.shelly.internal.handler;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import java.math.BigDecimal;

View File

@@ -13,19 +13,19 @@
package org.openhab.binding.shelly.internal.handler;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
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.ShellyApiJsonDTO.ShellySettingsEMeter;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsMeter;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusSensor;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusSensor.ShellyADC;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyThermnostat;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
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.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyADC;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyThermnostat;
import org.openhab.binding.shelly.internal.provider.ShellyChannelDefinitions;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;

View File

@@ -13,7 +13,7 @@
package org.openhab.binding.shelly.internal.handler;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.Map;
@@ -22,13 +22,13 @@ import java.util.TreeMap;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsRgbwLight;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyShortLightStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusLight;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusLightChannel;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.coap.ShellyCoapServer;
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.ShellyStatusLight;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusLightChannel;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapServer;
import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration;
import org.openhab.binding.shelly.internal.provider.ShellyChannelDefinitions;
import org.openhab.binding.shelly.internal.provider.ShellyTranslationProvider;
@@ -66,7 +66,7 @@ public class ShellyLightHandler extends ShellyBaseHandler {
* @param httpPort port of the openHAB HTTP API
*/
public ShellyLightHandler(final Thing thing, final ShellyTranslationProvider translationProvider,
final ShellyBindingConfiguration bindingConfig, final ShellyCoapServer coapServer, final String localIP,
final ShellyBindingConfiguration bindingConfig, final Shelly1CoapServer coapServer, final String localIP,
int httpPort, final HttpClient httpClient) {
super(thing, translationProvider, bindingConfig, coapServer, localIP, httpPort, httpClient);
channelColors = new TreeMap<>();

View File

@@ -14,7 +14,7 @@ package org.openhab.binding.shelly.internal.handler;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.shelly.internal.coap.ShellyCoapServer;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapServer;
import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration;
import org.openhab.binding.shelly.internal.provider.ShellyTranslationProvider;
import org.openhab.core.thing.Thing;
@@ -36,7 +36,7 @@ public class ShellyProtectedHandler extends ShellyBaseHandler {
* @param httpPort port of the openHAB HTTP API
*/
public ShellyProtectedHandler(final Thing thing, final ShellyTranslationProvider translationProvider,
final ShellyBindingConfiguration bindingConfig, final ShellyCoapServer coapServer, final String localIP,
final ShellyBindingConfiguration bindingConfig, final Shelly1CoapServer coapServer, final String localIP,
int httpPort, final HttpClient httpClient) {
super(thing, translationProvider, bindingConfig, coapServer, localIP, httpPort, httpClient);
}

View File

@@ -13,22 +13,22 @@
package org.openhab.binding.shelly.internal.handler;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyControlRoller;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsDimmer;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsRoller;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyShortLightStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyShortStatusRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusRelay;
import org.openhab.binding.shelly.internal.coap.ShellyCoapServer;
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;
import org.openhab.binding.shelly.internal.provider.ShellyTranslationProvider;
@@ -69,7 +69,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
* @param httpPort port of the openHAB HTTP API
*/
public ShellyRelayHandler(final Thing thing, final ShellyTranslationProvider translationProvider,
final ShellyBindingConfiguration bindingConfig, final ShellyCoapServer coapServer, final String localIP,
final ShellyBindingConfiguration bindingConfig, final Shelly1CoapServer coapServer, final String localIP,
int httpPort, final HttpClient httpClient) {
super(thing, translationProvider, bindingConfig, coapServer, localIP, httpPort, httpClient);
}
@@ -222,7 +222,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
int position = -1;
if ((command instanceof UpDownType) || (command instanceof OnOffType)) {
ShellyControlRoller rstatus = api.getRollerStatus(index);
ShellyRollerStatus rstatus = api.getRollerStatus(index);
if (!getString(rstatus.state).isEmpty() && !getString(rstatus.state).equals(SHELLY_ALWD_ROLLER_TURN_STOP)) {
if ((command == UpDownType.UP && getString(rstatus.state).equals(SHELLY_ALWD_ROLLER_TURN_OPEN))
@@ -317,7 +317,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
}
}
private void createRollerChannels(ShellyControlRoller roller) {
private void createRollerChannels(ShellyRollerStatus roller) {
if (!areChannelsCreated()) {
updateChannelDefinitions(ShellyChannelDefinitions.createRollerChannels(getThing(), roller));
}
@@ -406,7 +406,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
for (ShellySettingsRoller roller : status.rollers) {
if (roller.isValid) {
ShellyControlRoller control = api.getRollerStatus(i);
ShellyRollerStatus control = api.getRollerStatus(i);
Integer relayIndex = i + 1;
String groupName = profile.numRollers > 1 ? CHANNEL_GROUP_ROL_CONTROL + relayIndex.toString()
: CHANNEL_GROUP_ROL_CONTROL;
@@ -456,7 +456,7 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
// the same structure as lights[] from Bulb,RGBW2 and Duo. The tag gets replaced by dimmers[] so that Gson
// maps to a different structure (ShellyShortLight).
Gson gson = new Gson();
ShellySettingsStatus dstatus = fromJson(gson, ShellyApiJsonDTO.fixDimmerJson(orgStatus.json),
ShellySettingsStatus dstatus = fromJson(gson, Shelly1ApiJsonDTO.fixDimmerJson(orgStatus.json),
ShellySettingsStatus.class);
logger.trace("{}: Updating {} dimmers(s)", thingName, dstatus.dimmers.size());

View File

@@ -17,10 +17,11 @@ import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiInterface;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
@@ -81,6 +82,8 @@ public interface ShellyThingInterface {
public ShellyThingConfiguration getThingConfig();
public HttpClient getHttpClient();
public String getProperty(String key);
public void updateProperties(String key, String value);

View File

@@ -13,7 +13,7 @@
package org.openhab.binding.shelly.internal.manager;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.PROPERTY_SERVICE_NAME;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.SHELLY_COIOT_MCAST;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.SHELLY_COIOT_MCAST;
import static org.openhab.binding.shelly.internal.manager.ShellyManagerConstants.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
@@ -27,11 +27,11 @@ import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.shelly.internal.ShellyHandlerFactory;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiInterface;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyOtaCheckResult;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsLogin;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api.ShellyHttpApi;
import org.openhab.binding.shelly.internal.coap.ShellyCoapJSonDTO;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyOtaCheckResult;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsLogin;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapJSonDTO;
import org.openhab.binding.shelly.internal.api1.Shelly1HttpApi;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyManagerInterface;
import org.openhab.binding.shelly.internal.provider.ShellyTranslationProvider;
@@ -83,7 +83,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage {
ShellyThingConfiguration config = getThingConfig(th, properties);
ShellyDeviceProfile profile = th.getProfile();
ShellyApiInterface api = th.getApi();
new ShellyHttpApi(uid, config, httpClient);
new Shelly1HttpApi(uid, config, httpClient);
int refreshTimer = 0;
switch (action) {
@@ -139,7 +139,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage {
String peer = getString(profile.settings.coiot.peer);
boolean mcast = peer.isEmpty() || SHELLY_COIOT_MCAST.equalsIgnoreCase(peer);
String newPeer = mcast ? localIp + ":" + ShellyCoapJSonDTO.COIOT_PORT : SHELLY_COIOT_MCAST;
String newPeer = mcast ? localIp + ":" + Shelly1CoapJSonDTO.COIOT_PORT : SHELLY_COIOT_MCAST;
String displayPeer = mcast ? newPeer : "Multicast";
if (profile.isMotion && action.equalsIgnoreCase(ACTION_SETCOIOT_MCAST)) {

View File

@@ -33,9 +33,9 @@ import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.shelly.internal.ShellyHandlerFactory;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsUpdate;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api.ShellyHttpApi;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsUpdate;
import org.openhab.binding.shelly.internal.api1.Shelly1HttpApi;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyManagerInterface;
import org.openhab.binding.shelly.internal.provider.ShellyTranslationProvider;
@@ -122,7 +122,7 @@ public class ShellyManagerOtaPage extends ShellyManagerPage {
new Thread(() -> { // schedule asynchronous reboot
try {
ShellyHttpApi api = new ShellyHttpApi(uid, config, httpClient);
Shelly1HttpApi api = new Shelly1HttpApi(uid, config, httpClient);
ShellySettingsUpdate result = api.firmwareUpdate(updateUrl);
String status = getString(result.status);
logger.info("{}: {}", th.getThingName(), getMessage("fwupdate.initiated", status));

View File

@@ -13,6 +13,7 @@
package org.openhab.binding.shelly.internal.manager;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import static org.openhab.binding.shelly.internal.manager.ShellyManagerConstants.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import static org.openhab.core.thing.Thing.*;
@@ -44,7 +45,7 @@ import org.openhab.binding.shelly.internal.ShellyHandlerFactory;
import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyApiResult;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api.ShellyHttpApi;
import org.openhab.binding.shelly.internal.api.ShellyHttpClient;
import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration;
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyDeviceStats;
@@ -491,7 +492,7 @@ public class ShellyManagerPage {
try {
Request request = httpClient.newRequest(url).method(method).timeout(SHELLY_API_TIMEOUT_MS,
TimeUnit.MILLISECONDS);
request.header(HttpHeader.ACCEPT, ShellyHttpApi.CONTENT_TYPE_JSON);
request.header(HttpHeader.ACCEPT, ShellyHttpClient.CONTENT_TYPE_JSON);
logger.trace("{}: HTTP {} {}", LOG_PREFIX, method, url);
ContentResponse contentResponse = request.send();
apiResult = new ShellyApiResult(contentResponse);

View File

@@ -72,14 +72,14 @@ public class ShellyManagerServlet extends HttpServlet {
className = substringAfterLast(getClass().toString(), ".");
this.httpService = httpService;
String localIp = getString(networkAddressService.getPrimaryIpv4HostAddress());
int localPort = HttpServiceUtil.getHttpServicePort(componentContext.getBundleContext());
Integer localPort = HttpServiceUtil.getHttpServicePort(componentContext.getBundleContext());
this.manager = new ShellyManager(configurationAdmin, translationProvider,
httpClientFactory.getCommonHttpClient(), localIp, localPort, handlerFactory);
try {
httpService.registerServlet(SERVLET_URI, this, null, httpService.createDefaultHttpContext());
// Promote Shelly Manager usage
logger.info("{}", translationProvider.get("status.managerstarted", localIp, localPort + ""));
logger.info("{}", translationProvider.get("status.managerstarted", localIp, localPort.toString()));
} catch (NamespaceException | ServletException | IllegalArgumentException e) {
logger.warn("{}: Unable to initialize bindingConfig", className, e);
}

View File

@@ -13,7 +13,7 @@
package org.openhab.binding.shelly.internal.provider;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.SHELLY_API_INVTEMP;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.SHELLY_API_INVTEMP;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.HashMap;
@@ -27,21 +27,21 @@ import javax.measure.Unit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyControlRoller;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyInputState;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsDimmer;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsEMeter;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsGlobal;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsMeter;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsRgbwLight;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellySettingsStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyShortLightStatus;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyShortStatusRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusLightChannel;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusRelay;
import org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.ShellyStatusSensor;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyInputState;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyRollerStatus;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDimmer;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsEMeter;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsGlobal;
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.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;
import org.openhab.core.thing.ChannelUID;
@@ -262,7 +262,7 @@ public class ShellyChannelDefinitions {
addChannel(thing, add, profile.settings.name != null, CHGR_DEVST, CHANNEL_DEVST_NAME);
if (!profile.isSensor && !profile.isIX3 && getDouble(status.temperature) != SHELLY_API_INVTEMP) {
if (!profile.isSensor && !profile.isIX && getDouble(status.temperature) != SHELLY_API_INVTEMP) {
// Only some devices report the internal device temp
addChannel(thing, add, status.tmp != null || status.temperature != null, CHGR_DEVST, CHANNEL_DEVST_ITEMP);
}
@@ -298,15 +298,18 @@ public class ShellyChannelDefinitions {
Map<String, Channel> add = new LinkedHashMap<>();
String group = profile.getControlGroup(idx);
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
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);
addChannel(thing, add, rs.autoOff != null, group, CHANNEL_TIMER_AUTOOFF);
addChannel(thing, add, timer, group, CHANNEL_TIMER_ACTIVE);
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
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);
addChannel(thing, add, rs.autoOff != null, group, CHANNEL_TIMER_AUTOOFF);
addChannel(thing, add, timer, group, CHANNEL_TIMER_ACTIVE);
}
// Shelly 1/1PM Addon
if (relay.extTemperature != null) {
@@ -329,12 +332,14 @@ public class ShellyChannelDefinitions {
// Shelly Dimmer has an additional brightness channel
addChannel(thing, add, profile.isDimmer, group, CHANNEL_BRIGHTNESS);
ShellySettingsDimmer ds = profile.settings.dimmers.get(idx);
addChannel(thing, add, ds.autoOn != null, group, CHANNEL_TIMER_AUTOON);
addChannel(thing, add, ds.autoOff != null, group, CHANNEL_TIMER_AUTOOFF);
if (profile.settings.dimmers != null) {
ShellySettingsDimmer ds = profile.settings.dimmers.get(idx);
addChannel(thing, add, ds.autoOn != null, group, CHANNEL_TIMER_AUTOON);
addChannel(thing, add, ds.autoOff != null, group, CHANNEL_TIMER_AUTOOFF);
ShellyShortLightStatus dss = dstatus.dimmers.get(idx);
addChannel(thing, add, dss != null && dss.hasTimer != null, group, CHANNEL_TIMER_ACTIVE);
ShellyShortLightStatus dss = dstatus.dimmers.get(idx);
addChannel(thing, add, dss != null && dss.hasTimer != null, group, CHANNEL_TIMER_ACTIVE);
}
return add;
}
@@ -343,13 +348,16 @@ public class ShellyChannelDefinitions {
Map<String, Channel> add = new LinkedHashMap<>();
String group = profile.getControlGroup(idx);
ShellySettingsRgbwLight light = profile.settings.lights.get(idx);
// The is no brightness channel in color mode, so we need a power channel
addChannel(thing, add, profile.inColor, group, CHANNEL_LIGHT_POWER);
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);
if (profile.settings.lights != null) {
ShellySettingsRgbwLight light = profile.settings.lights.get(idx);
// 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);
}
return add;
}
@@ -379,7 +387,7 @@ public class ShellyChannelDefinitions {
return add;
}
public static Map<String, Channel> createRollerChannels(Thing thing, final ShellyControlRoller roller) {
public static Map<String, Channel> createRollerChannels(Thing thing, final ShellyRollerStatus roller) {
Map<String, Channel> add = new LinkedHashMap<>();
addChannel(thing, add, true, CHGR_ROLLER, CHANNEL_ROL_CONTROL_CONTROL);
addChannel(thing, add, true, CHGR_ROLLER, CHANNEL_ROL_CONTROL_STATE);

View File

@@ -19,6 +19,8 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDateTime;
@@ -351,4 +353,26 @@ public class ShellyUtils {
public static char lastChar(String s) {
return s.length() > 1 ? s.charAt(s.length() - 1) : '*';
}
public static String sha256(String string) throws ShellyApiException {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
final byte[] hashbytes = digest.digest(string.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hashbytes);
} catch (NoSuchAlgorithmException e) {
throw new ShellyApiException("SHA256 can't be initialzed", e);
}
}
public static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder(2 * bytes.length);
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xff & bytes[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
}

View File

@@ -17,6 +17,7 @@
<default>admin</default>
<label>@text/binding.shelly.config.defaultPassword.label</label>
<description>@text/binding.shelly.config.defaultPassword.description</description>
<context>password</context>
</parameter>
<parameter name="localIP" type="text">
<label>@text/binding.shelly.config.localIP.label</label>

View File

@@ -86,6 +86,23 @@ thing-type.shelly.shellygas.description = Shelly Gas (Gas Sensor - Gas Leak Dete
thing-type.shelly.shellytrv.description = Shelly TRV (Radiator value, battery powered)
thing-type.shelly.shellyix3.description = Shelly ix3 (Activation Device with 3 inputs)
# Plus/Pro devices
thing-type.shelly.shellyplus1.description = Shelly Plus 1 (Single Relay Switch)
thing-type.shelly.shellyplus1pm.description = Shelly Plus 1PM - Single Relay Switch with Power Meter
thing-type.shelly.shellyplus2-relay.description = Shelly Plus 2PM - Dual Relay Switch with Power Meter
thing-type.shelly.shellyplus2pm-roller.description = Shelly Plus 2PM - Roller Control with Power Meter
thing-type.shelly.shellyplusht.description = Shelly Plus HT - Humidity and Temperature sensor with display
thing-type.shelly.shellyplusi4.description = Shelly Plus i4 - 4xInput Device
thing-type.shelly.shellyplusi4dc.description = Shelly Plus i4DC - 4xDC Input Device
thing-type.shelly.shellypro1.description = Shelly Pro 1 - Single Relay Switch
thing-type.shelly.shellypro1pm.description = Shelly Pro 1PM - Single Relay Switch with Power Meter
thing-type.shelly.shellypro2-relay.description = Shelly Pro 2 - Dual Relay Switch
thing-type.shelly.shellypro2-roller.description = Shelly Pro 2 - Roller Control
thing-type.shelly.shellypro2pm-relay.description= Shelly Pro 2PM - Dual Relay Switch with Power Meter
thing-type.shelly.shellypro2pm-roller.description = Shelly Pro 2PM - Roller Control with Power Meter
thing-type.shelly.shellypro3.description = Shelly Pro 3 - 3xRelay Switch
thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch with Power Meter
# thing config - shellydevice
thing-type.config.shelly.deviceIp.label = IP Address
thing-type.config.shelly.deviceIp.description = IP Address of the Shelly device
@@ -247,7 +264,7 @@ channel-type.shelly.meterAccuReturned.description = Accumulated Returned Power i
channel-type.shelly.meterReactive.label = Reactive Energy
channel-type.shelly.meterReactive.description = Instantaneous reactive power in Watts (W)
channel-type.shelly.lastPower1.label = Last Power
channel-type.shelly.lastPower1.description = Rounded power consumption during last minute
channel-type.shelly.lastPower1.description = Last power consumption #1 - one rounded minute
channel-type.shelly.meterTotal.label = Total Energy Consumption
channel-type.shelly.meterTotal.description = Total energy consumption in kW/h since the device powered up (resets on restart)
channel-type.shelly.meterReturned.label = Total Returned Energy