diff --git a/bundles/org.openhab.binding.shelly/README.md b/bundles/org.openhab.binding.shelly/README.md index 1f686d63a..e4d3ffa5b 100644 --- a/bundles/org.openhab.binding.shelly/README.md +++ b/bundles/org.openhab.binding.shelly/README.md @@ -27,6 +27,8 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which ## Supported Devices +### Generation 1: + | thing-type | Model | Vendor ID | |--------------------|--------------------------------------------------------|-----------| | shelly1 | Shelly 1 Single Relay Switch | SHSW-1 | @@ -745,22 +747,28 @@ Using the Thing configuration option `brightnessAutoOn` you could decide if the `true`: Brightness will be set and device output is powered = light turns on with the new brightness `false`: Brightness will be set, but output stays unchanged so light will not be switched on when it's currently off. -### Shelly RGBW2 in White Mode (thing-type: shellyrgbw2-color) +### Shelly RGBW2 in Color Mode (thing-type: shellyrgbw2-color) |Group |Channel |Type |read-only|Description | |----------|-------------|---------|---------|-----------------------------------------------------------------------| |control |power |Switch |r/w |Switch light ON/OFF | -| |input |Switch |yes |State of Input | -| |autoOn |Number |r/w |Sets a timer to turn the device ON after every OFF; in sec | -| |autoOff |Number |r/w |Sets a timer to turn the device OFF after every ON: in sec | +| |autoOn |Number |r/w |Sets a timer to turn the device ON after every OFF command; in seconds| +| |autoOff |Number |r/w |Sets a timer to turn the device OFF after every ON command; in seconds| | |timerActive |Switch |yes |ON: An auto-on/off timer is active | -|color | | | |Color settings: only valid in COLOR mode | -| |hsb |HSB |r/w |Represents the color picker (HSBType), control r/g/b, but not white | -|meter |currentWatts |Number |yes |Current power consumption in Watts (all channels) | - -Please note that the settings of channel group color are only valid in color mode and vice versa for white mode. -The current firmware doesn't support the timestamp report for the meters. -The binding emulates this by using the system time on every update. +|color |hsb |HSB |r/w |Represents the color picker (HSBType), control r/g/b, bight not white | +| |full |String |r/w |Set Red / Green / Blue / Yellow / White mode and switch mode | +| | | |r/w |Valid settings: "red", "green", "blue", "yellow", "white" or "r,g,b,w" | +| |red |Dimmer |r/w |Red brightness: 0..100% or 0..255 (control only the red channel) | +| |green |Dimmer |r/w |Green brightness: 0..100% or 0..255 (control only the green channel) | +| |blue |Dimmer |r/w |Blue brightness: 0..100% or 0..255 (control only the blue channel) | +| |white |Dimmer |r/w |White brightness: 0..100% or 0..255 (control only the white channel) | +| |gain |Dimmer |r/w |Gain setting: 0..100% or 0..100 | +| |effect |Number |r/w |Puts the light into effect mode: 0..3) | +| | | | |0=No effect, 1=Meteor Shower, 2=Gradual Change, 3=Flash | +|meter |currentWatts |Number |yes |Current power consumption in Watts | +| |lastPower1 |Number |yes |Energy consumption for a round minute, 1 minute ago | +| |totalKWH |Number |yes |Total energy consumption in kWh since the device powered up (resets on restart)| +| |lastUpdate |DateTime |yes |Timestamp of the last measurement | ### Shelly RGBW2 in White Mode (thing-type: shellyrgbw2-white) diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java index e9efbaffe..2c0e00f10 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java @@ -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 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, diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java index 4f5bb53a7..a2cab8c4f 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java @@ -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 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 diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java index a7238a8b7..e267de7e8 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiInterface.java @@ -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; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiResult.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiResult.java index d900ba557..1f26e5065 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiResult.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiResult.java @@ -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() { } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java index 774fc88ed..2d576a27e 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java @@ -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) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpClient.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpClient.java new file mode 100644 index 000000000..1bc9a8fb7 --- /dev/null +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpClient.java @@ -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 callApi(String uri, Class classOfT) throws ShellyApiException { + String json = httpRequest(uri); + return fromJson(gson, json, classOfT); + } + + public T postApi(String uri, String data, Class 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 dataMap, boolean json) { + String data = ""; + for (Map.Entry 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; + } +} diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiJsonDTO.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1ApiJsonDTO.java similarity index 98% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiJsonDTO.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1ApiJsonDTO.java index 39158923a..4cf98d396 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiJsonDTO.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1ApiJsonDTO.java @@ -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 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 lights; // relay status public ArrayList 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 % } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTInterface.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTInterface.java similarity index 72% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTInterface.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTInterface.java index 158f50d4e..0be1585e6 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTInterface.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTInterface.java @@ -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 blkMap); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTProtocol.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTProtocol.java similarity index 96% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTProtocol.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTProtocol.java index ce5124189..f54461675 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTProtocol.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTProtocol.java @@ -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 blkMap, + public Shelly1CoIoTProtocol(String thingName, ShellyThingInterface thingHandler, Map blkMap, Map sensorMap) { this.thingName = thingName; this.thingHandler = thingHandler; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion1.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion1.java similarity index 95% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion1.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion1.java index 9412162c7..9eb440a88 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion1.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion1.java @@ -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 blkMap, + public Shelly1CoIoTVersion1(String thingName, ShellyThingInterface thingHandler, Map blkMap, Map sensorMap) { super(thingName, thingHandler, blkMap, sensorMap); } @Override public int getVersion() { - return ShellyCoapJSonDTO.COIOT_VERSION_1; + return Shelly1CoapJSonDTO.COIOT_VERSION_1; } /** diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion2.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java similarity index 96% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion2.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java index efbe077fc..432ff3878 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion2.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java @@ -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 blkMap, + public Shelly1CoIoTVersion2(String thingName, ShellyThingInterface thingHandler, Map blkMap, Map sensorMap) { super(thingName, thingHandler, blkMap, sensorMap); } @Override public int getVersion() { - return ShellyCoapJSonDTO.COIOT_VERSION_2; + return Shelly1CoapJSonDTO.COIOT_VERSION_2; } /** diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapHandler.java similarity index 95% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapHandler.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapHandler.java index 9b466c9b0..bd0889b16 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapHandler.java @@ -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; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapJSonDTO.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapJSonDTO.java similarity index 98% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapJSonDTO.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapJSonDTO.java index af9834c1c..3529bbbcd 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapJSonDTO.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapJSonDTO.java @@ -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; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapListener.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapListener.java similarity index 78% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapListener.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapListener.java index 5900580f5..2b71b58b6 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapListener.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapListener.java @@ -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); } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapServer.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapServer.java similarity index 89% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapServer.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapServer.java index b7c525b67..527aa2421 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapServer.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapServer.java @@ -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 coapListeners = ConcurrentHashMap.newKeySet(); + private final Set 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(); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpApi.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java similarity index 85% rename from bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpApi.java rename to bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java index 38cb916d0..9c6b8b7f2 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpApi.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java @@ -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: //?parm?value // Dimmer: /light/?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 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 callApi(String uri, Class 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) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java index c185d34d9..cf38e9ed8 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java @@ -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); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyThingCreator.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyThingCreator.java index 924d6b847..61b5b437e 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyThingCreator.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyThingCreator.java @@ -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 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); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java index f0a4ddd75..4c8e0d370 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java @@ -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); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyColorUtils.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyColorUtils.java index 80851e5c2..d424edbd6 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyColorUtils.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyColorUtils.java @@ -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; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java index 9d68b0b91..34f94f9ff 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java @@ -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; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java index 54f722cb7..ea506aa0a 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java @@ -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<>(); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyProtectedHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyProtectedHandler.java index c3f5ea008..f941638c5 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyProtectedHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyProtectedHandler.java @@ -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); } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java index 8fbe6210e..34fbb7c9a 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyRelayHandler.java @@ -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()); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyThingInterface.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyThingInterface.java index 37a43c780..0adb1f040 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyThingInterface.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyThingInterface.java @@ -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); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java index e13df68b4..4c3e14c09 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java @@ -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)) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java index 46949809b..ab498d967 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java @@ -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)); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java index 0d17c0918..a1fad7dc3 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java @@ -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); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java index 2ac54c81e..932046f44 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java @@ -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); } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java index 53f6c8550..670d953a5 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java @@ -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 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 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 createRollerChannels(Thing thing, final ShellyControlRoller roller) { + public static Map createRollerChannels(Thing thing, final ShellyRollerStatus roller) { Map add = new LinkedHashMap<>(); addChannel(thing, add, true, CHGR_ROLLER, CHANNEL_ROL_CONTROL_CONTROL); addChannel(thing, add, true, CHGR_ROLLER, CHANNEL_ROL_CONTROL_STATE); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java index dd7b1ea92..9fd0884c0 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java @@ -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(); + } } diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/binding/binding.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/binding/binding.xml index 0ddaebe5c..9553e75e8 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/binding/binding.xml +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/binding/binding.xml @@ -17,6 +17,7 @@ admin @text/binding.shelly.config.defaultPassword.description + password diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties index 9e1d48a37..2b4bf674a 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties @@ -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