[shelly] Plus 1/1PM Add-On support; fix roller pos on open/close state (#13520)
* Added #13493 Plus 1/1PM addon support; Fixed #13515 pos for roller in open/close state; various null warnings removed; README updated Signed-off-by: Markus Michels <markus7017@gmail.com> * digitalInput, analogInput and voltage added for Add-On; README updated Signed-off-by: Markus Michels <markus7017@gmail.com> * shelly2-roller re-added (wrong assumption that Shelly 2 doesn't support roller mode, because it has no power meter) Signed-off-by: markus7017 <markus7017@gmail.com> Signed-off-by: Markus Michels <markus7017@gmail.com> * Initialization for Californium 2.7.3 fixed (no multicast packets where received) Signed-off-by: Markus Michels <markus7017@gmail.com> * Analogous input support for Plus Addon changed; Allterco made a format change in the beta firmware Signed-off-by: Markus Michels <markus7017@gmail.com> * changes applied Signed-off-by: Markus Michels <markus7017@gmail.com> * README updated; Shelly Plus addon handling adjusted to latest firmware (before was beta) Signed-off-by: Markus Michels <markus7017@gmail.com> * Update bundles/org.openhab.binding.shelly/README.md Signed-off-by: Fabian Wolter <github@fabian-wolter.de> * fix JSON for Shelly1 - ext_switch_enable is a boolean, not an int Signed-off-by: Markus Michels <markus7017@gmail.com> Signed-off-by: Markus Michels <markus7017@gmail.com> Signed-off-by: markus7017 <markus7017@gmail.com> Signed-off-by: Fabian Wolter <github@fabian-wolter.de> Co-authored-by: Fabian Wolter <github@fabian-wolter.de>
This commit is contained in:
parent
2382fadaaa
commit
8f972362c3
@ -27,6 +27,13 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
|
||||
|
||||
## Supported Devices
|
||||
|
||||
The binding supports both hardware generations
|
||||
|
||||
- Generation 1: The original Shelly devices like the Shelly 1, Shelly 2.5, Shelly Flood etc.
|
||||
- Generation 2: The new Plus / Pro series of devices
|
||||
|
||||
The binding provides the same feature set across all devices as good as possible and depending on device specific features.
|
||||
|
||||
### Generation 1
|
||||
|
||||
| thing-type | Model | Vendor ID |
|
||||
@ -35,6 +42,7 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
|
||||
| shelly1l | Shelly 1L Single Relay Switch | SHSW-L |
|
||||
| shelly1pm | Shelly Single Relay Switch with integrated Power Meter | SHSW-PM |
|
||||
| shelly2-relay | Shelly Double Relay Switch in relay mode | SHSW-21 |
|
||||
| shelly2-roller | Shelly2 in Roller Mode | SHSW-21 |
|
||||
| shelly25-relay | Shelly 2.5 in Relay Switch | SHSW-25 |
|
||||
| shelly25-roller | Shelly 2.5 in Roller Mode | SHSW-25 |
|
||||
| shelly4pro | Shelly 4x Relay Switch | SHSW-44 |
|
||||
@ -68,7 +76,7 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
|
||||
| shellytrv | Shelly TRV | SHTRV-01 |
|
||||
| shellydevice | A password protected Shelly device or an unknown type | |
|
||||
|
||||
### Generation 2 Plus series:
|
||||
### Generation 2 Plus series
|
||||
|
||||
| thing-type | Model | Vendor ID |
|
||||
|---------------------|----------------------------------------------------------|----------------|
|
||||
@ -80,7 +88,7 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
|
||||
| shellyplusi4dc | Shelly Plus i4 with 4x DC input | SNSN-0D24X |
|
||||
| shellyplusht | Shelly Plus HT with temperature + humidity sensor | SNSN-0013A |
|
||||
|
||||
### Generation 2 Pro series:
|
||||
### Generation 2 Pro series
|
||||
|
||||
| thing-type | Model | Vendor ID |
|
||||
|---------------------|----------------------------------------------------------|----------------|
|
||||
@ -97,21 +105,32 @@ Also check out the [Shelly Manager](doc/ShellyManager.md), which
|
||||
|
||||
The binding has the following configuration options:
|
||||
|
||||
### Generation 1
|
||||
|
||||
| Parameter |Description |Mandatory|Default |
|
||||
|----------------|------------------------------------------------------------------|---------|------------------------------------------------|
|
||||
|----------------|--------------------------------------------------------------------|---------|------------------------------------------------|
|
||||
| defaultUserId |Default user id for HTTP authentication when not set in the Thing | no |admin |
|
||||
| defaultPassword|Default password for HTTP authentication when not set in the Thing| no |admin |
|
||||
| autoCoIoT |Auto-enable CoIoT events when firmware 1.6+ is enabled. | no |true |
|
||||
| defaultPassword|Default password for HTTP authentication when not set in the Thing | no |admin |
|
||||
| autoCoIoT |Auto-enable CoIoT events when firmware 1.6+ is enabled (Gen1 only). | no |true |
|
||||
|
||||
`defaultUserId` and `defaultPassword:` will be used by the binding if device protection is enabled.
|
||||
However, the Plus/Pro devices have a fixed user id admin`. Nevertheless the binding provide that option to allow a mixed operation of Gen 1 and 2 devices in the same installation having same defaults.
|
||||
|
||||
`Generation 1`: The binding defaults to CoIoT events when firmware 1.6 or newer is detected.
|
||||
CoIoT provides near-realtime updates on device status changes.
|
||||
|
||||
The binding defaults to CoIoT events when firmware 1.6 or newer is detected. CoIoT provides near-realtime updates on device status changes.
|
||||
This mode also overrules event settings in the Thing configuration.
|
||||
|
||||
Disabling this feature allows granular control, which event types will be used. This is also required when the Shelly devices are not located on the same IP subnet (e.g. using a VPN).
|
||||
Disabling this feature allows granular control, which event types will be used.
|
||||
This is also required when the Shelly devices are not located on the same IP subnet (e.g. using a VPN).
|
||||
In this case autoCoIoT should be disabled, CoIoT events will not work, because the underlying CoAP protocol is based on Multicast IP, which usually doesn't passes a VPN or routed network.
|
||||
|
||||
'Generation 2:'
|
||||
|
||||
### Generation 2 (Plus
|
||||
|
||||
## Firmware
|
||||
|
||||
The binding requires firmware version 1.7.0 or newer to enable all features, version 1.9.2 is recommended.
|
||||
The binding requires firmware version 1.8.2 or newer for generation 1 to enable all features, version 1.9.2+ is recommended. Generation 2 devices require 0.10.2 or newer, the Plus HT at least 0.11.0.
|
||||
Some of the features are enabled dynamically or are not available depending on device type and firmware release.
|
||||
The Web UI of the Shelly device displays the current firmware version under Settings:Firmware and shows an update option when a newer version is available.
|
||||
|
||||
@ -134,10 +153,10 @@ The binding uses mDNS to discover the Shelly devices.
|
||||
They periodically announce their presence, which is used by the binding to find them on the local network.
|
||||
Sometimes you need to run the manual discovery multiple times until you see all your devices.
|
||||
|
||||
`Important`:
|
||||
`Important for Generation 1 Devices`:
|
||||
It's recommended to enable CoIoT in the device settings for faster response times (event driven rather than polling).
|
||||
Open the device's Web UI, section "COIOT settings" and select "Enable COCIOT".
|
||||
It's recommended to switch the Shelly devices to CoAP Unicast mode if you have only your openHAB system controlling the device.
|
||||
It's recommended to switch the Shelly devices to CoAP peer mode if you have only your openHAB system controlling the device.
|
||||
This allows routing the CoIoT/CoAP messages across multiple IP subnets without special network setup required.
|
||||
You could use Shelly Manager (doc/ShellyManager.md) to easily do the setup (configuring the openHAB host as CoAP peer address).
|
||||
Keep Multicast mode if you have multiple hosts, which should receive the CoAP updates.
|
||||
@ -170,7 +189,7 @@ Sometimes you need to run the discovery multiple times.
|
||||
|
||||
### Roller Favorites
|
||||
|
||||
Firmware 1.9.2 for Shelly 2.5 in roller mode supports so called favorites for positions.
|
||||
Firmware 1.9.2+ for Shelly 2.5 and 0.11+ for Plus 2PM in roller mode supports so called roller favorites for positions.
|
||||
You could use the Shelly App to setup 4 different positions (percentage) and assign id 1-4.
|
||||
The channel `roller#rollerFav` allows to select those from openHAB and the roller moves to the desired position.
|
||||
In the Thing configuration you could also configure an id when the `roller#control` channel receives UP or DOWN.
|
||||
@ -186,14 +205,14 @@ The binding sets the following Thing status depending on the device status:
|
||||
| UNKNOWN | Indicates that the status is currently unknown, which must not show a problem. Usually the Thing stays in this status when the device is in sleep mode. Once the device is reachable and was initialized the Thing switches to status ONLINE.|
|
||||
| ONLINE | ONLINE indicates that the device can be accessed and is responding properly. Battery powered devices also stay ONLINE when in sleep mode. The binding has an integrated watchdog timer supervising the device, see below. The Thing switches to status OFFLINE when some type of communication error occurs. |
|
||||
| OFFLINE | Communication with the device failed. Check the Thing status in the UI and openHAB's log for an indication of the error. Try restarting OH or deleting and re-discovering the Thing. You could also post to the community thread if the problem persists. |
|
||||
| CONFIG PENDING | CONFIG PENDING description |
|
||||
| ERROR: COMM | ERROR: COMM description |
|
||||
| CONFIG PENDING | The thing has been initialized, but device initialization is in progress or pending (e.g. waiting for device wake-up) |
|
||||
| ERROR: COMM | Communication with the device has reported an error, check detailed status. |
|
||||
|
||||
`Battery powered devices:`
|
||||
If the device is in sleep mode and can't be reached by the binding, the Thing will change into CONFIG_PENDING.
|
||||
Once the device wakes up, the Thing will perform initialization and the state will change to ONLINE.
|
||||
|
||||
The first time a device is discovered and initialized successfully, the binding will be able to perform auto-initialization when OH is restarted. Waking up the device triggers the event URL and/or CoIoT packet, which is processed by the binding and triggers initialization. Once a device is initialized, it is no longer necessary to manually wake it up after an openHAB restart unless you change the battery. In this case press the button and run the discovery again.
|
||||
The first time a device is discovered and initialized successfully, the binding will be able to perform auto-initialization when OH is restarted. Waking up the device triggers the a status report (CoIoT packet for event url for Gen1 and WebSocket call for Gen2), which is processed by the binding and triggers initialization. Once a device is initialized, it is no longer necessary to manually wake it up after an openHAB restart unless you change the battery. In this case press the button and run the discovery again.
|
||||
|
||||
### Device Watchdog
|
||||
|
||||
@ -208,7 +227,7 @@ The binding also monitors that the device is responding at least once within a g
|
||||
The period is computed depending on the device type and configuration:
|
||||
|
||||
- battery powered devices: <sleepPeriod from device config> + 10min, usually 12h+10min=730min
|
||||
- else, if CoIoT is enabled: 3*<update Period from device settings>+10sec, usually3*15+10=45sec
|
||||
- else, if CoIoT or WebSocket is enabled: 3*<update Period from device settings>+10sec, usually3*15+10=45sec
|
||||
- else 2*60+10sec = 130sec
|
||||
|
||||
Once the timer expires the device switches to OFFFLINE and the bindings starts to re-initialize the device periodically.
|
||||
@ -266,7 +285,7 @@ The LED channels are available for the Plug-S with firmware 1.6x and for various
|
||||
|
||||
## Events
|
||||
|
||||
### Action URLs vs. CoIoT
|
||||
### Generation 1: Action URLs vs. CoIoT
|
||||
|
||||
Depending on the firmware release the Shelly devices supports 2 different mechanims to report sensor updates or events.
|
||||
|
||||
@ -299,6 +318,16 @@ If there is no specific reason you should enable CoIoT. Check section Network Se
|
||||
|
||||
Enable the autoCoIoT option in the binding configuration or eventsCoIoT in the Thing configuration to activate CoIoT.
|
||||
|
||||
### Generation 2: WebSockets
|
||||
|
||||
The Plus and Pro series of devices use WebSockets for device communication.
|
||||
Usually the binding establishes a WebSocket connection to the device (http port 80).
|
||||
However, battery powered devices like the Plus HT are not reachable while the device is in sleep mode.
|
||||
For those the binding sets up a so called "Outbound WebSocket" during device initialization.
|
||||
Afterwards the device wakes up and calls the configured URL, which is the processed by the binding.
|
||||
The device UI shows the URL when active.
|
||||
Battery powered devices could only report events to a single host, take care if you have multiple openHAB instances on the same network.
|
||||
|
||||
### Button events
|
||||
|
||||
Various devices signal an event when the physical button is pressed.
|
||||
@ -378,6 +407,7 @@ Depending on the device type and firmware release channels might be not availabl
|
||||
| |temperature2 |Number |yes |Temperature value of external sensor #2 (if connected to temp/hum addon) |
|
||||
| |temperature3 |Number |yes |Temperature value of external sensor #3 (if connected to temp/hum addon) |
|
||||
| |humidity |Number |yes |Humidity in percent (if connected to temp/hum addon) |
|
||||
| |input1 |Contact |yes |Status of the reed contact (OPEN/CLOSE), only with external switch add-on |
|
||||
|
||||
### Shelly 1L (thing-type: shelly1l)
|
||||
|
||||
@ -402,6 +432,7 @@ Depending on the device type and firmware release channels might be not availabl
|
||||
| |temperature2 |Number |yes |Temperature value of external sensor #2 (if connected to temp/hum addon) |
|
||||
| |temperature3 |Number |yes |Temperature value of external sensor #3 (if connected to temp/hum addon) |
|
||||
| |humidity |Number |yes |Humidity in percent (if connected to temp/hum addon) |
|
||||
| |input1 |Contact |yes |Status of the reed contact (OPEN/CLOSE), only with external switch add-on |
|
||||
|
||||
Note: The `meter`for the Shelly 1L is kind of fake.
|
||||
It doesn't have a real power meter, but you could setup an estimated consumption in the Shelly App, e.g. 60W if you have attached a good old light bulb to the output channel.
|
||||
@ -417,12 +448,14 @@ In this case the is no real measurement based on power consumption, but the Shel
|
||||
| |button |Trigger |yes |Event trigger, see section Button Events |
|
||||
|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 Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart)
|
||||
|
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|sensors |temperature1 |Number |yes |Temperature value of external sensor #1 (if connected to temp/hum addon) |
|
||||
| |temperature2 |Number |yes |Temperature value of external sensor #2 (if connected to temp/hum addon) |
|
||||
| |temperature3 |Number |yes |Temperature value of external sensor #3 (if connected to temp/hum addon) |
|
||||
| |humidity |Number |yes |Humidity in percent (if connected to temp/hum addon) |
|
||||
| |input1 |Contact |yes |Status of the reed contact (OPEN/CLOSE), only with external switch add-on |
|
||||
|
||||
### Shelly EM (thing-type: shellyem)
|
||||
|
||||
@ -438,14 +471,14 @@ In this case the is no real measurement based on power consumption, but the Shel
|
||||
| |autoOff |Number |r/w |Relay #1: Sets a timer to turn the device OFF after every ON command; in seconds|
|
||||
| |timerActive |Switch |yes |Relay #1: ON: An auto-on/off timer is active |
|
||||
|meter1 |currentWatts |Number |yes |Current power consumption in Watts |
|
||||
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |returnedKWH |Number |yes |Total returned energy, kwh |
|
||||
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
|
||||
| |voltage |Number |yes |RMS voltage, Volts |
|
||||
| |powerFactor |Number |yes |Power Factor in percent |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|meter2 |currentWatts |Number |yes |Current power consumption in Watts |
|
||||
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |returnedKWH |Number |yes |Total returned energy, kwh |
|
||||
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
|
||||
| |voltage |Number |yes |RMS voltage, Volts |
|
||||
@ -469,7 +502,7 @@ The Thing id is derived from the service name, so that's the reason why the Thin
|
||||
| |autoOff |Number |r/w |Relay #1: Sets a timer to turn the device OFF after every ON command; in seconds|
|
||||
| |timerActive |Switch |yes |Relay #1: ON: An auto-on/off timer is active |
|
||||
|meter1 |currentWatts |Number |yes |Current power consumption in Watts |
|
||||
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |returnedKWH |Number |yes |Total returned energy, kwh |
|
||||
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
|
||||
| |voltage |Number |yes |RMS voltage, Volts |
|
||||
@ -477,7 +510,7 @@ The Thing id is derived from the service name, so that's the reason why the Thin
|
||||
| |powerFactor |Number |yes |Power Factor in percent |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|meter2 |currentWatts |Number |yes |Current power consumption in Watts |
|
||||
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |returnedKWH |Number |yes |Total returned energy, kwh |
|
||||
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
|
||||
| |voltage |Number |yes |RMS voltage, Volts |
|
||||
@ -485,7 +518,7 @@ The Thing id is derived from the service name, so that's the reason why the Thin
|
||||
| |powerFactor |Number |yes |Power Factor in percent |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|meter3 |currentWatts |Number |yes |Current power consumption in Watts |
|
||||
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |returnedKWH |Number |yes |Total returned energy, kwh |
|
||||
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
|
||||
| |voltage |Number |yes |RMS voltage, Volts |
|
||||
@ -514,9 +547,31 @@ The Thing id is derived from the service name, so that's the reason why the Thin
|
||||
| |button |Trigger |yes |Event trigger, see section Button Events |
|
||||
|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 Watts since the device powered up (resets on restart)|
|
||||
| |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 2 - roller mode thing-type: shelly2-roller)
|
||||
|
||||
|Group |Channel |Type |read-only|Description |
|
||||
|----------|-------------|---------|---------|--------------------------------------------------------------------------------------|
|
||||
|roller |control |Rollershutter|r/w |can be open (0%), stop, or close (100%); could also handle ON (open) and OFF (close) |
|
||||
| |input |Switch |yes |ON: Input/Button is powered, see General Notes on Channels |
|
||||
| |event |Trigger |yes |Roller event/trigger with payload ROLLER_OPEN / ROLLER_CLOSE / ROLLER_STOP |
|
||||
| |rollerpos |Number |r/w |Roller position: 100%=open...0%=closed; gets updated when the roller stops, see Notes |
|
||||
| |rollerFav |Number |r/w |Select roller position favorite (1-4, 0=no), see Notes |
|
||||
| |state |String |yes |Roller state: open/close/stop |
|
||||
| |stopReason |String |yes |Last stop reasons: normal, safety_switch or obstacle |
|
||||
| |safety |Switch |yes |Indicates status of the Safety Switch, ON=problem detected, powered off |
|
||||
|meter |currentWatts |Number |yes |Current power consumption in Watts |
|
||||
| |lastPower1 |Number |yes |Accumulated energy consumption in Watts for the full last minute |
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (reset on restart) |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|
||||
*Note: The Roller should be calibrated using the device Web UI or Shelly App, otherwise the position can't be set.*
|
||||
|
||||
The roller positioning calibration has to be performed using the Shelly Web UI or App before the position can be set in percent.
|
||||
Refer to [Smartify Roller Shutters with openHAB and Shelly](doc/UseCaseSmartRoller.md) for more information on roller integration.
|
||||
|
||||
### Shelly 2.5 - relay mode (thing-type:shelly25-relay)
|
||||
|
||||
The Shelly 2.5 includes 2 meters, one for each channel.
|
||||
@ -592,7 +647,7 @@ The Shelly 4Pro provides 4 relays and 4 power meters.
|
||||
| |timerActive |Switch |yes |Relay #1: ON: An auto-on/off timer is active |
|
||||
|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 Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|
||||
|
||||
@ -676,10 +731,10 @@ This information applies to the Shelly Duo-1 as well as the Duo White for the G1
|
||||
| |brightness |Dimmer | |Brightness: 0..100% or 0..100 |
|
||||
|meter |currentWatts |Number |yes |Current power consumption in Watts |
|
||||
| |lastPower1 |Number |yes |Energy consumption in Watts for a round minute, 1 minute ago |
|
||||
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
|
||||
| |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 Vintage (thing-type: shellyvintage)
|
||||
### Shelly Vintage (thing-type: shellyvintage)
|
||||
|
||||
|Group |Channel |Type |read-only|Description |
|
||||
|----------|-------------|---------|---------|-----------------------------------------------------------------------|
|
||||
@ -981,6 +1036,20 @@ You should calibrate the valve using the device Web UI or Shelly App before star
|
||||
| |timerActive |Switch |yes |Relay #1: ON: An auto-on/off timer is active |
|
||||
| |button |Trigger |yes |Event trigger, see section Button Events |
|
||||
|
||||
If the Shelly Add-On is installed:
|
||||
|
||||
|Group |Channel |Type |read-only|Description |
|
||||
|----------|-------------|---------|---------|---------------------------------------------------------------------------------|
|
||||
|sensors |temperature1 |Number |yes |Temperature value of external sensor #1 |
|
||||
| |temperature2 |Number |yes |Temperature value of external sensor #2 |
|
||||
| |temperature3 |Number |yes |Temperature value of external sensor #3 |
|
||||
| |temperature4 |Number |yes |Temperature value of external sensor #4 |
|
||||
| |temperature5 |Number |yes |Temperature value of external sensor #5 |
|
||||
| |humidity |Number |yes |Relative Humidity in percent |
|
||||
| |voltage |Number |yes |Measured voltage |
|
||||
| |analogInput |Number |yes |Percentage of reference voltage (VREF) at analogous input |
|
||||
| |digitalInput |Switch |yes |State of digital input (ON/OFF) |
|
||||
|
||||
### Shelly Plus 1PM (thing-type: shellyplus1pm)
|
||||
|
||||
|Group |Channel |Type |read-only|Description |
|
||||
@ -994,9 +1063,23 @@ You should calibrate the valve using the device Web UI or Shelly App before star
|
||||
| |button |Trigger |yes |Event trigger, see section Button Events |
|
||||
|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 Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|
||||
If the Shelly Add-On is installed:
|
||||
|
||||
|Group |Channel |Type |read-only|Description |
|
||||
|----------|-------------|---------|---------|---------------------------------------------------------------------------------|
|
||||
|sensors |temperature1 |Number |yes |Temperature value of external sensor #1 |
|
||||
| |temperature2 |Number |yes |Temperature value of external sensor #2 |
|
||||
| |temperature3 |Number |yes |Temperature value of external sensor #3 |
|
||||
| |temperature4 |Number |yes |Temperature value of external sensor #4 |
|
||||
| |temperature5 |Number |yes |Temperature value of external sensor #5 |
|
||||
| |humidity |Number |yes |Relative Humidity in percent |
|
||||
| |voltage |Number |yes |Measured voltage |
|
||||
| |analogInput |Number |yes |Percentage of reference voltage (VREF) at analogous input |
|
||||
| |digitalInput |Switch |yes |State of digital input (ON/OFF) |
|
||||
|
||||
### Shelly Plus 2PM - relay mode (thing-type: shellyplus2pm-relay)
|
||||
|
||||
|Group |Channel |Type |read-only|Description |
|
||||
@ -1010,7 +1093,7 @@ You should calibrate the valve using the device Web UI or Shelly App before star
|
||||
| |button |Trigger |yes |Event trigger, see section Button Events |
|
||||
|meter1 |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 Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|relay2 |output |Switch |r/w |Relay #2: Controls the relay's output channel (on/off) |
|
||||
| |outputName |String |yes |Logical name of this relay output as configured in the Shelly App |
|
||||
@ -1021,7 +1104,7 @@ You should calibrate the valve using the device Web UI or Shelly App before star
|
||||
| |button |Trigger |yes |Event trigger, see section Button Events |
|
||||
|meter2 |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 Watts since the device powered up (resets on restart)|
|
||||
| |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 Plus 2PM - roller mode (thing-type: shellyplus2pm-roller)
|
||||
@ -1104,7 +1187,7 @@ Channels lastEvent and eventCount are only available if input type is set to mom
|
||||
| |timerActive |Switch |yes |Relay #1: ON: An auto-on/off timer is active |
|
||||
|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 Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|
||||
|
||||
@ -1148,7 +1231,7 @@ Channels lastEvent and eventCount are only available if input type is set to mom
|
||||
| |button |Trigger |yes |Event trigger, see section Button Events |
|
||||
|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 Watts since the device powered up (resets on restart)|
|
||||
| |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 Pro 2 PM - roller mode (thing-type: shellypro2pm-roller)
|
||||
@ -1164,7 +1247,7 @@ Channels lastEvent and eventCount are only available if input type is set to mom
|
||||
| |event |Trigger |yes |Roller event/trigger with payload ROLLER_OPEN / ROLLER_CLOSE / ROLLER_STOP |
|
||||
|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 Watts since the device powered up (resets on restart)|
|
||||
| |totalKWH |Number |yes |Total energy consumption in kwh since the device powered up (resets on restart) |
|
||||
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|
||||
|
||||
|
||||
|
||||
@ -14,10 +14,7 @@ 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;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
@ -35,23 +32,58 @@ public class ShellyBindingConstants {
|
||||
public static final String BINDING_ID = "shelly";
|
||||
public static final String SYSTEM_ID = "system";
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream
|
||||
.of(THING_TYPE_SHELLY1, THING_TYPE_SHELLY1L, THING_TYPE_SHELLY1PM, THING_TYPE_SHELLYEM,
|
||||
THING_TYPE_SHELLY3EM, THING_TYPE_SHELLY2_RELAY, THING_TYPE_SHELLY25_RELAY,
|
||||
THING_TYPE_SHELLY25_ROLLER, THING_TYPE_SHELLY4PRO, THING_TYPE_SHELLYPLUG, THING_TYPE_SHELLYPLUGS,
|
||||
THING_TYPE_SHELLYPLUGU1, THING_TYPE_SHELLYUNI, THING_TYPE_SHELLYDIMMER, THING_TYPE_SHELLYDIMMER2,
|
||||
THING_TYPE_SHELLYIX3, THING_TYPE_SHELLYBULB, THING_TYPE_SHELLYDUO, THING_TYPE_SHELLYVINTAGE,
|
||||
THING_TYPE_SHELLYDUORGBW, THING_TYPE_SHELLYRGBW2_COLOR, THING_TYPE_SHELLYRGBW2_WHITE,
|
||||
THING_TYPE_SHELLYHT, THING_TYPE_SHELLYTRV, THING_TYPE_SHELLYSENSE, THING_TYPE_SHELLYEYE,
|
||||
THING_TYPE_SHELLYSMOKE, THING_TYPE_SHELLYGAS, THING_TYPE_SHELLYFLOOD, THING_TYPE_SHELLYDOORWIN,
|
||||
THING_TYPE_SHELLYDOORWIN2, THING_TYPE_SHELLYBUTTON1, THING_TYPE_SHELLYBUTTON2,
|
||||
THING_TYPE_SHELLMOTION, THING_TYPE_SHELLMOTION, THING_TYPE_SHELLYPLUS1, THING_TYPE_SHELLYPLUS1PM,
|
||||
THING_TYPE_SHELLYPLUS2PM_RELAY, THING_TYPE_SHELLYPLUS2PM_ROLLER, THING_TYPE_SHELLYPRO1,
|
||||
THING_TYPE_SHELLYPRO1PM, THING_TYPE_SHELLYPRO2_RELAY, THING_TYPE_SHELLYPRO2PM_RELAY,
|
||||
THING_TYPE_SHELLYPRO2PM_ROLLER, THING_TYPE_SHELLYPRO3, THING_TYPE_SHELLYPRO4PM,
|
||||
THING_TYPE_SHELLYPLUSI4, THING_TYPE_SHELLYPLUSI4DC, THING_TYPE_SHELLYPLUSHT,
|
||||
THING_TYPE_SHELLYPLUSPLUGUS, THING_TYPE_SHELLYPROTECTED, THING_TYPE_SHELLYUNKNOWN)
|
||||
.collect(Collectors.toSet()));
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_SHELLY1, //
|
||||
THING_TYPE_SHELLY1L, //
|
||||
THING_TYPE_SHELLY1PM, //
|
||||
THING_TYPE_SHELLYEM, //
|
||||
THING_TYPE_SHELLY3EM, //
|
||||
THING_TYPE_SHELLY2_RELAY, //
|
||||
THING_TYPE_SHELLY2_ROLLER, //
|
||||
THING_TYPE_SHELLY25_RELAY, //
|
||||
THING_TYPE_SHELLY25_ROLLER, //
|
||||
THING_TYPE_SHELLY4PRO, //
|
||||
THING_TYPE_SHELLYPLUG, //
|
||||
THING_TYPE_SHELLYPLUGS, //
|
||||
THING_TYPE_SHELLYPLUGU1, //
|
||||
THING_TYPE_SHELLYUNI, //
|
||||
THING_TYPE_SHELLYDIMMER, //
|
||||
THING_TYPE_SHELLYDIMMER2, //
|
||||
THING_TYPE_SHELLYIX3, //
|
||||
THING_TYPE_SHELLYBULB, //
|
||||
THING_TYPE_SHELLYDUO, //
|
||||
THING_TYPE_SHELLYVINTAGE, //
|
||||
THING_TYPE_SHELLYDUORGBW, //
|
||||
THING_TYPE_SHELLYRGBW2_COLOR, //
|
||||
THING_TYPE_SHELLYRGBW2_WHITE, //
|
||||
THING_TYPE_SHELLYHT, //
|
||||
THING_TYPE_SHELLYTRV, //
|
||||
THING_TYPE_SHELLYSENSE, //
|
||||
THING_TYPE_SHELLYEYE, //
|
||||
THING_TYPE_SHELLYSMOKE, //
|
||||
THING_TYPE_SHELLYGAS, //
|
||||
THING_TYPE_SHELLYFLOOD, //
|
||||
THING_TYPE_SHELLYDOORWIN, //
|
||||
THING_TYPE_SHELLYDOORWIN2, //
|
||||
THING_TYPE_SHELLYBUTTON1, //
|
||||
THING_TYPE_SHELLYBUTTON2, //
|
||||
THING_TYPE_SHELLMOTION, //
|
||||
THING_TYPE_SHELLYPLUS1, //
|
||||
THING_TYPE_SHELLYPLUS1PM, //
|
||||
THING_TYPE_SHELLYPLUS2PM_RELAY, //
|
||||
THING_TYPE_SHELLYPLUS2PM_ROLLER, //
|
||||
THING_TYPE_SHELLYPRO1, //
|
||||
THING_TYPE_SHELLYPRO1PM, //
|
||||
THING_TYPE_SHELLYPRO2_RELAY, //
|
||||
THING_TYPE_SHELLYPRO2PM_RELAY, //
|
||||
THING_TYPE_SHELLYPRO2PM_ROLLER, //
|
||||
THING_TYPE_SHELLYPRO3, //
|
||||
THING_TYPE_SHELLYPRO4PM, //
|
||||
THING_TYPE_SHELLYPLUSI4, //
|
||||
THING_TYPE_SHELLYPLUSI4DC, //
|
||||
THING_TYPE_SHELLYPLUSHT, //
|
||||
THING_TYPE_SHELLYPLUSPLUGUS, //
|
||||
THING_TYPE_SHELLYPROTECTED, //
|
||||
THING_TYPE_SHELLYUNKNOWN);
|
||||
|
||||
// Thing Configuration Properties
|
||||
public static final String CONFIG_DEVICEIP = "deviceIp";
|
||||
@ -149,10 +181,17 @@ public class ShellyBindingConstants {
|
||||
public static final String CHANNEL_CONTROL_PROFILE = "selectedProfile";
|
||||
|
||||
// External sensors for Shelly1/1PM
|
||||
public static final String CHANNEL_ESENDOR_TEMP1 = CHANNEL_SENSOR_TEMP + "1";
|
||||
public static final String CHANNEL_ESENDOR_TEMP2 = CHANNEL_SENSOR_TEMP + "2";
|
||||
public static final String CHANNEL_ESENDOR_TEMP3 = CHANNEL_SENSOR_TEMP + "3";
|
||||
public static final String CHANNEL_ESENDOR_HUMIDITY = CHANNEL_SENSOR_HUM;
|
||||
public static final String CHANNEL_ESENSOR_TEMP1 = CHANNEL_SENSOR_TEMP + "1";
|
||||
public static final String CHANNEL_ESENSOR_TEMP2 = CHANNEL_SENSOR_TEMP + "2";
|
||||
public static final String CHANNEL_ESENSOR_TEMP3 = CHANNEL_SENSOR_TEMP + "3";
|
||||
public static final String CHANNEL_ESENSOR_TEMP4 = CHANNEL_SENSOR_TEMP + "4";
|
||||
public static final String CHANNEL_ESENSOR_TEMP5 = CHANNEL_SENSOR_TEMP + "5";
|
||||
public static final String CHANNEL_ESENSOR_HUMIDITY = CHANNEL_SENSOR_HUM;
|
||||
public static final String CHANNEL_ESENSOR_VOLTAGE = CHANNEL_SENSOR_VOLTAGE;
|
||||
public static final String CHANNEL_ESENSOR_DIGITALINPUT = "digitalInput";;
|
||||
public static final String CHANNEL_ESENSOR_ANALOGINPUT = "analogInput";;
|
||||
public static final String CHANNEL_ESENSOR_INPUT = "input";
|
||||
public static final String CHANNEL_ESENSOR_INPUT1 = CHANNEL_ESENSOR_INPUT + "1";
|
||||
|
||||
public static final String CHANNEL_GROUP_CONTROL = "control";
|
||||
public static final String CHANNEL_SENSE_KEY = "key";
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
*/
|
||||
package org.openhab.binding.shelly.internal.api;
|
||||
|
||||
import static org.openhab.binding.shelly.internal.util.ShellyUtils.getString;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NoRouteToHostException;
|
||||
@ -92,6 +94,10 @@ public class ShellyApiException extends Exception {
|
||||
return message;
|
||||
}
|
||||
|
||||
public boolean isJsonError() {
|
||||
return getString(getMessage()).startsWith("Unable to create object of type");
|
||||
}
|
||||
|
||||
public boolean isApiException() {
|
||||
return getCauseClass() == ShellyApiException.class;
|
||||
}
|
||||
|
||||
@ -337,10 +337,15 @@ public class ShellyDeviceProfile {
|
||||
}
|
||||
|
||||
public String[] getValveProfileList(int valveId) {
|
||||
if (isTRV && settings.thermostats != null && valveId <= settings.thermostats.size()) {
|
||||
if (isTRV && settings.thermostats != null) {
|
||||
int sz = settings.thermostats.size();
|
||||
if (valveId <= sz) {
|
||||
if (settings.thermostats != null) {
|
||||
ShellyThermnostat t = settings.thermostats.get(valveId);
|
||||
return t.profileNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
|
||||
@ -618,10 +618,18 @@ public class Shelly1ApiJsonDTO {
|
||||
public @Nullable ArrayList<ShellySettingsRgbwLight> lights;
|
||||
public @Nullable ArrayList<ShellySettingsEMeter> emeters;
|
||||
public @Nullable ArrayList<ShellyThermnostat> thermostats; // TRV
|
||||
|
||||
@SerializedName("ext_switch_enable")
|
||||
public Boolean externalSwitchEnable;
|
||||
@SerializedName("ext_switch")
|
||||
public ShellyStatusSensor.ShellyExtSwitchSettings extSwitch;
|
||||
@SerializedName("ext_temperature")
|
||||
public ShellyStatusSensor.ShellyExtTemperature extTemperature; // Shelly 1/1PM: sensor values
|
||||
@SerializedName("ext_humidity")
|
||||
public ShellyStatusSensor.ShellyExtHumidity extHumidity; // Shelly 1/1PM: sensor values
|
||||
public ShellyStatusSensor.ShellyExtVoltage extVoltage; // Shelly ´Plus 1/1PM: sensor values
|
||||
public ShellyStatusSensor.ShellyExtAnalogInput extAnalogInput; // Shelly ´Plus 1/1PM: sensor values
|
||||
public ShellyStatusSensor.ShellyExtDigitalInput extDigitalInput; // Shelly ´Plus 1/1PM: state of digital input
|
||||
|
||||
@SerializedName("temperature_units")
|
||||
public String temperatureUnits = "C"; // Either'C'or'F'
|
||||
@ -736,6 +744,11 @@ public class Shelly1ApiJsonDTO {
|
||||
public ShellyStatusSensor.ShellyExtTemperature extTemperature; // Shelly 1/1PM: sensor values
|
||||
@SerializedName("ext_humidity")
|
||||
public ShellyStatusSensor.ShellyExtHumidity extHumidity; // Shelly 1/1PM: sensor values
|
||||
public ShellyStatusSensor.ShellyExtVoltage extVoltage; // Shelly ´Plus 1/1PM: sensor values
|
||||
public ShellyStatusSensor.ShellyExtAnalogInput extAnalogInput; // Shelly ´Plus 1/1PM: sensor values
|
||||
public ShellyStatusSensor.ShellyExtDigitalInput extDigitalInput; // Shelly ´Plus 1/1PM: sensor values
|
||||
@SerializedName("ext_switch")
|
||||
public ShellyStatusSensor.ShellyExtSwitchStatus extSwitch;
|
||||
|
||||
// Internal device temp
|
||||
public ShellySensorTmp tmp = new ShellySensorTmp(); // Shelly 1PM
|
||||
@ -984,6 +997,10 @@ public class Shelly1ApiJsonDTO {
|
||||
public ShellyShortTemp sensor2;
|
||||
@SerializedName("2")
|
||||
public ShellyShortTemp sensor3;
|
||||
@SerializedName("3")
|
||||
public ShellyShortTemp sensor4;
|
||||
@SerializedName("4")
|
||||
public ShellyShortTemp sensor5;
|
||||
}
|
||||
|
||||
public static class ShellyExtHumidity {
|
||||
@ -991,16 +1008,92 @@ public class Shelly1ApiJsonDTO {
|
||||
public Double hum; // Humidity reading of sensor 0, percent
|
||||
}
|
||||
|
||||
// Shelly 1/1PM have up to 3 sensors
|
||||
// for whatever reasons it's not an array, but 3 independent elements
|
||||
public ShellyExtHumidity() {
|
||||
}
|
||||
|
||||
public ShellyExtHumidity(double hum) {
|
||||
sensor1 = new ShellyShortHum();
|
||||
sensor1.hum = hum;
|
||||
}
|
||||
|
||||
@SerializedName("0")
|
||||
public ShellyShortHum sensor1;
|
||||
}
|
||||
|
||||
public static class ShellyExtVoltage {
|
||||
public static class ShellyShortVoltage {
|
||||
public Double voltage;
|
||||
}
|
||||
|
||||
public ShellyExtVoltage() {
|
||||
}
|
||||
|
||||
public ShellyExtVoltage(double voltage) {
|
||||
sensor1 = new ShellyShortVoltage();
|
||||
sensor1.voltage = voltage;
|
||||
}
|
||||
|
||||
@SerializedName("0")
|
||||
public ShellyShortVoltage sensor1;
|
||||
}
|
||||
|
||||
public static class ShellyExtDigitalInput {
|
||||
public static class ShellyShortDigitalInput {
|
||||
public Boolean state;
|
||||
}
|
||||
|
||||
public ShellyExtDigitalInput() {
|
||||
}
|
||||
|
||||
public ShellyExtDigitalInput(boolean state) {
|
||||
sensor1 = new ShellyShortDigitalInput();
|
||||
sensor1.state = state;
|
||||
}
|
||||
|
||||
@SerializedName("0")
|
||||
public ShellyShortDigitalInput sensor1;
|
||||
}
|
||||
|
||||
public static class ShellyExtAnalogInput {
|
||||
public static class ShellyShortAnalogInput {
|
||||
public Double percent;
|
||||
}
|
||||
|
||||
public ShellyExtAnalogInput() {
|
||||
}
|
||||
|
||||
public ShellyExtAnalogInput(double percent) {
|
||||
sensor1 = new ShellyShortAnalogInput();
|
||||
sensor1.percent = percent;
|
||||
}
|
||||
|
||||
@SerializedName("0")
|
||||
public ShellyShortAnalogInput sensor1;
|
||||
}
|
||||
|
||||
public static class ShellyADC {
|
||||
public Double voltage;
|
||||
}
|
||||
|
||||
public static class ShellyExtSwitchSettings {
|
||||
public static class ShellyExtSwitchSettingsInput {
|
||||
@SerializedName("relay_num")
|
||||
public Integer relayNum;
|
||||
}
|
||||
|
||||
@SerializedName("0")
|
||||
public ShellyExtSwitchSettingsInput input0;
|
||||
}
|
||||
|
||||
public static class ShellyExtSwitchStatus {
|
||||
public static class ShellyExtSwitchStatusInput {
|
||||
public Integer input;
|
||||
}
|
||||
|
||||
@SerializedName("0")
|
||||
public ShellyExtSwitchStatusInput input0;
|
||||
}
|
||||
|
||||
public ShellySensorTmp tmp;
|
||||
public ShellySensorHum hum;
|
||||
public ShellySensorLux lux;
|
||||
|
||||
@ -83,9 +83,9 @@ public class Shelly1CoapServer {
|
||||
logger.debug("Initializing CoIoT listener (local IP={}:{})", localIp, port);
|
||||
NetworkConfig nc = NetworkConfig.getStandard();
|
||||
InetAddress localAddr = InetAddress.getByName(localIp);
|
||||
// Join the multicast group on the selected network interface
|
||||
statusConnector = new UdpMulticastConnector.Builder().setLocalAddress(localAddr, port)
|
||||
.addMulticastGroup(CoAP.MULTICAST_IPV4).build(); // bind UDP listener
|
||||
// Join the multicast group on the selected network interface, add UDP listener
|
||||
statusConnector = new UdpMulticastConnector.Builder().setLocalAddress(localAddr, port).setLocalPort(port)
|
||||
.setOutgoingMulticastInterface(localAddr).addMulticastGroup(CoAP.MULTICAST_IPV4).build();
|
||||
statusEndpoint = new CoapEndpoint.Builder().setNetworkConfig(nc).setConnector(statusConnector).build();
|
||||
server = new CoapServer(NetworkConfig.getStandard(), port);
|
||||
server.addEndpoint(statusEndpoint);
|
||||
|
||||
@ -49,6 +49,7 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyShortLig
|
||||
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.api1.Shelly1ApiJsonDTO.ShellyThermnostat;
|
||||
import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
|
||||
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
@ -257,7 +258,7 @@ public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterfa
|
||||
@Override
|
||||
public void setValveMode(int valveId, boolean auto) throws ShellyApiException {
|
||||
String uri = "/settings/thermostat/" + valveId + "?target_t_enabled=" + (auto ? "1" : "0");
|
||||
if (auto) {
|
||||
if (auto && profile.settings.thermostats != null) {
|
||||
uri = uri + "&target_t=" + getDouble(profile.settings.thermostats.get(0).targetTemp.value);
|
||||
}
|
||||
httpRequest(uri); // percentage to open the valve
|
||||
@ -281,9 +282,12 @@ public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterfa
|
||||
|
||||
@Override
|
||||
public void startValveBoost(int valveId, int value) throws ShellyApiException {
|
||||
int minutes = value != -1 ? value : getInteger(profile.settings.thermostats.get(0).boostMinutes);
|
||||
if (profile.settings.thermostats != null) {
|
||||
ShellyThermnostat t = profile.settings.thermostats.get(0);
|
||||
int minutes = value != -1 ? value : getInteger(t.boostMinutes);
|
||||
httpRequest("/thermostat/0?boost_minutes=" + minutes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLedStatus(String ledName, Boolean value) throws ShellyApiException {
|
||||
|
||||
@ -41,6 +41,12 @@ import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettings
|
||||
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.Shelly1ApiJsonDTO.ShellyStatusSensor;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtAnalogInput;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtDigitalInput;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtHumidity;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtTemperature;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtTemperature.ShellyShortTemp;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellyExtVoltage;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellySensorBat;
|
||||
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyStatusSensor.ShellySensorHum;
|
||||
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2AuthRequest;
|
||||
@ -182,8 +188,8 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
updateHumidityStatus(sensorData, result.humidity0);
|
||||
updateTemperatureStatus(sensorData, result.temperature0);
|
||||
updateBatteryStatus(sensorData, result.devicepower0);
|
||||
updateAddonStatus(status, result);
|
||||
updated |= ShellyComponents.updateSensors(getThing(), status);
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
@ -380,6 +386,45 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
return updateChannels ? ShellyComponents.updateRoller((ShellyBaseHandler) getThing(), rs, cs.id) : false;
|
||||
}
|
||||
|
||||
// Addon
|
||||
private void updateAddonStatus(ShellySettingsStatus status, @Nullable Shelly2DeviceStatusResult ds)
|
||||
throws ShellyApiException {
|
||||
if (ds == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ds.temperature100 != null) {
|
||||
if (status.extTemperature == null) {
|
||||
status.extTemperature = new ShellyExtTemperature();
|
||||
}
|
||||
status.extTemperature.sensor1 = updateExtTempSensor(ds.temperature100);
|
||||
status.extTemperature.sensor2 = updateExtTempSensor(ds.temperature101);
|
||||
status.extTemperature.sensor3 = updateExtTempSensor(ds.temperature102);
|
||||
status.extTemperature.sensor4 = updateExtTempSensor(ds.temperature103);
|
||||
status.extTemperature.sensor5 = updateExtTempSensor(ds.temperature104);
|
||||
}
|
||||
if (ds.humidity100 != null) {
|
||||
status.extHumidity = new ShellyExtHumidity(ds.humidity100.rh);
|
||||
}
|
||||
if (ds.voltmeter100 != null) {
|
||||
status.extVoltage = new ShellyExtVoltage(ds.voltmeter100.voltage);
|
||||
}
|
||||
if (ds.input100 != null) {
|
||||
status.extDigitalInput = new ShellyExtDigitalInput(getBool(ds.input100.state));
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable ShellyShortTemp updateExtTempSensor(@Nullable Shelly2DeviceStatusTempId value) {
|
||||
if (value != null) {
|
||||
ShellyShortTemp temp = new ShellyShortTemp();
|
||||
temp.hwID = value.id.toString();
|
||||
temp.tC = value.tC;
|
||||
temp.tF = value.tF;
|
||||
return temp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void updateHumidityStatus(ShellyStatusSensor sdata, @Nullable Shelly2DeviceStatusHumidity value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
@ -458,19 +503,21 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
protected boolean updateInputStatus(ShellySettingsStatus status, Shelly2DeviceStatusResult ds,
|
||||
boolean updateChannels) throws ShellyApiException {
|
||||
boolean updated = false;
|
||||
updated |= addInputStatus(ds.input0, updateChannels);
|
||||
updated |= addInputStatus(ds.input1, updateChannels);
|
||||
updated |= addInputStatus(ds.input2, updateChannels);
|
||||
updated |= addInputStatus(ds.input3, updateChannels);
|
||||
updated |= addInputStatus(status, ds.input0, updateChannels);
|
||||
updated |= addInputStatus(status, ds.input1, updateChannels);
|
||||
updated |= addInputStatus(status, ds.input2, updateChannels);
|
||||
updated |= addInputStatus(status, ds.input3, updateChannels);
|
||||
status.inputs = relayStatus.inputs;
|
||||
return updated;
|
||||
}
|
||||
|
||||
private boolean addInputStatus(@Nullable Shelly2InputStatus is, boolean updateChannels) throws ShellyApiException {
|
||||
private boolean addInputStatus(ShellySettingsStatus status, @Nullable Shelly2InputStatus is, boolean updateChannels)
|
||||
throws ShellyApiException {
|
||||
if (is == null) {
|
||||
return false;
|
||||
}
|
||||
ShellyDeviceProfile profile = getProfile();
|
||||
|
||||
if (is.id == null || is.id > profile.numInputs) {
|
||||
logger.debug("{}: Invalid input id: {}", thingName, is.id);
|
||||
return false;
|
||||
@ -485,6 +532,9 @@ public class Shelly2ApiClient extends ShellyHttpClient {
|
||||
input.event = "";
|
||||
input.eventCount = 0;
|
||||
}
|
||||
if (is.percent != null) { // analogous input
|
||||
status.extAnalogInput = new ShellyExtAnalogInput(getDouble(is.percent));
|
||||
}
|
||||
relayStatus.inputs.set(is.id, input);
|
||||
if (updateChannels) {
|
||||
updated |= updateChannel(group, CHANNEL_INPUT + profile.getInputSuffix(is.id), getOnOff(getBool(is.state)));
|
||||
|
||||
@ -74,6 +74,7 @@ public class Shelly2ApiJsonDTO {
|
||||
// Input types
|
||||
public static final String SHELLY2_INPUTT_SWITCH = "switch";
|
||||
public static final String SHELLY2_INPUTT_BUTTON = "button";
|
||||
public static final String SHELLY2_INPUTT_ANALOG = "analog"; // Shelly Addon: analogous input
|
||||
|
||||
// Switcm modes
|
||||
public static final String SHELLY2_API_MODE_DETACHED = "detached";
|
||||
@ -253,6 +254,8 @@ public class Shelly2ApiJsonDTO {
|
||||
public Boolean invert;
|
||||
@SerializedName("factory_reset")
|
||||
public Boolean factoryReset;
|
||||
@SerializedName("report_thr")
|
||||
public Double reportTreshold; // only for type analog
|
||||
}
|
||||
|
||||
public class Shelly2DevConfigSwitch {
|
||||
@ -413,6 +416,8 @@ public class Shelly2ApiJsonDTO {
|
||||
public class Shelly2InputStatus {
|
||||
public Integer id;
|
||||
public Boolean state;
|
||||
public Double percent; // analog input only
|
||||
public ArrayList<String> errors;// shown only if at least one error is present.
|
||||
}
|
||||
|
||||
public static class Shelly2DeviceStatusResult {
|
||||
@ -456,6 +461,11 @@ public class Shelly2ApiJsonDTO {
|
||||
public Double rh;
|
||||
}
|
||||
|
||||
public class Shelly2DeviceStatusVoltage {
|
||||
public Integer id;
|
||||
public Double voltage;
|
||||
}
|
||||
|
||||
public class Shelly2DeviceStatusTempId extends Shelly2DeviceStatusTemp {
|
||||
public Integer id;
|
||||
}
|
||||
@ -490,6 +500,8 @@ public class Shelly2ApiJsonDTO {
|
||||
public Shelly2InputStatus input2;
|
||||
@SerializedName("input:3")
|
||||
public Shelly2InputStatus input3;
|
||||
@SerializedName("input:100")
|
||||
public Shelly2InputStatus input100; // Digital Input from Add-On
|
||||
|
||||
@SerializedName("switch:0")
|
||||
public Shelly2RelayStatus switch0;
|
||||
@ -503,10 +515,27 @@ public class Shelly2ApiJsonDTO {
|
||||
@SerializedName("cover:0")
|
||||
public Shelly2CoverStatus cover0;
|
||||
|
||||
@SerializedName("humidity:0")
|
||||
public Shelly2DeviceStatusHumidity humidity0;
|
||||
@SerializedName("temperature:0")
|
||||
public Shelly2DeviceStatusTempId temperature0;
|
||||
@SerializedName("temperature:100")
|
||||
public Shelly2DeviceStatusTempId temperature100;
|
||||
@SerializedName("temperature:101")
|
||||
public Shelly2DeviceStatusTempId temperature101;
|
||||
@SerializedName("temperature:102")
|
||||
public Shelly2DeviceStatusTempId temperature102;
|
||||
@SerializedName("temperature:103")
|
||||
public Shelly2DeviceStatusTempId temperature103;
|
||||
@SerializedName("temperature:104")
|
||||
public Shelly2DeviceStatusTempId temperature104;
|
||||
|
||||
@SerializedName("humidity:0")
|
||||
public Shelly2DeviceStatusHumidity humidity0;
|
||||
@SerializedName("humidity:100")
|
||||
public Shelly2DeviceStatusHumidity humidity100;
|
||||
|
||||
@SerializedName("voltmeter:100")
|
||||
public Shelly2DeviceStatusVoltage voltmeter100;
|
||||
|
||||
@SerializedName("devicepower:0")
|
||||
public Shelly2DeviceStatusPower devicepower0;
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant {
|
||||
try {
|
||||
ShellyApiInterface api = gen2 ? new Shelly2ApiRpc(name, config, httpClient)
|
||||
: new Shelly1HttpApi(name, config, httpClient);
|
||||
if (name.contains("plushat")) {
|
||||
if (name.contains("plus1pm")) {
|
||||
int i = 1;
|
||||
}
|
||||
api.initialize();
|
||||
|
||||
@ -104,6 +104,7 @@ public class ShellyThingCreator {
|
||||
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";
|
||||
@ -166,6 +167,8 @@ public class ShellyThingCreator {
|
||||
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,
|
||||
@ -367,7 +370,7 @@ public class ShellyThingCreator {
|
||||
return mode.equals(SHELLY_MODE_RELAY) ? THING_TYPE_SHELLY25_RELAY_STR : THING_TYPE_SHELLY25_ROLLER_STR;
|
||||
}
|
||||
if (name.startsWith(THING_TYPE_SHELLY2_PREFIX)) { // Shelly v2
|
||||
return THING_TYPE_SHELLY2_RELAY_STR;
|
||||
return mode.equals(SHELLY_MODE_RELAY) ? THING_TYPE_SHELLY2_RELAY_STR : THING_TYPE_SHELLY2_ROLLER_STR;
|
||||
}
|
||||
if (name.startsWith(THING_TYPE_SHELLYPLUG_STR)) {
|
||||
// shellyplug-s needs to be mapped to shellyplugs to follow the schema
|
||||
|
||||
@ -187,12 +187,18 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
|
||||
start = initializeThing();
|
||||
} catch (ShellyApiException e) {
|
||||
ShellyApiResult res = e.getApiResult();
|
||||
if (profile.alwaysOn && e.isConnectionError()) {
|
||||
setThingOffline(ThingStatusDetail.COMMUNICATION_ERROR, "offline.status-error-connect",
|
||||
e.toString());
|
||||
}
|
||||
if (isAuthorizationFailed(res)) {
|
||||
String mid = "";
|
||||
if (e.isJsonError()) { // invalid JSON format
|
||||
mid = "offline.status-error-unexpected-error";
|
||||
start = false;
|
||||
} else if (isAuthorizationFailed(res)) {
|
||||
mid = "offline.conf-error-access-denied";
|
||||
start = false;
|
||||
} else if (profile.alwaysOn && e.isConnectionError()) {
|
||||
mid = "offline.status-error-connect";
|
||||
}
|
||||
if (!mid.isEmpty()) {
|
||||
setThingOffline(ThingStatusDetail.COMMUNICATION_ERROR, mid, e.toString());
|
||||
}
|
||||
logger.debug("{}: Unable to initialize: {}, retrying later", thingName, e.toString());
|
||||
} catch (IllegalArgumentException e) {
|
||||
@ -576,14 +582,18 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
|
||||
profile.fwDate);
|
||||
logger.debug("{}: Shelly settings info for {}: {}", thingName, profile.hostname, profile.settingsJson);
|
||||
logger.debug("{}: Device "
|
||||
+ "hasRelays:{} (numRelays={}),isRoller:{} (numRoller={}),isDimmer:{},numMeter={},isEMeter:{})"
|
||||
+ "hasRelays:{} (numRelays={}),isRoller:{} (numRoller={}),isDimmer:{},numMeter={},isEMeter:{}), ext. Switch Add-On: {}"
|
||||
+ ",isSensor:{},isDS:{},hasBattery:{}{},isSense:{},isMotion:{},isLight:{},isBulb:{},isDuo:{},isRGBW2:{},inColor:{}"
|
||||
+ ",alwaysOn:{}, updatePeriod:{}sec", thingName, profile.hasRelays, profile.numRelays, profile.isRoller,
|
||||
profile.numRollers, profile.isDimmer, profile.numMeters, profile.isEMeter, profile.isSensor,
|
||||
profile.isDW, profile.hasBattery,
|
||||
profile.hasBattery ? " (low battery threshold=" + config.lowBattery + "%)" : "", profile.isSense,
|
||||
profile.isMotion, profile.isLight, profile.isBulb, profile.isDuo, profile.isRGBW2, profile.inColor,
|
||||
profile.alwaysOn, profile.updatePeriod);
|
||||
profile.numRollers, profile.isDimmer, profile.numMeters, profile.isEMeter,
|
||||
profile.settings.extSwitch != null ? "installed" : "n/a", profile.isSensor, profile.isDW,
|
||||
profile.hasBattery, profile.hasBattery ? " (low battery threshold=" + config.lowBattery + "%)" : "",
|
||||
profile.isSense, profile.isMotion, profile.isLight, profile.isBulb, profile.isDuo, profile.isRGBW2,
|
||||
profile.inColor, profile.alwaysOn, profile.updatePeriod);
|
||||
if (profile.status.extTemperature != null || profile.status.extHumidity != null
|
||||
|| profile.status.extVoltage != null || profile.status.extAnalogInput != null) {
|
||||
logger.debug("{}: Shelly Add-On detected with at least 1 external sensor", thingName);
|
||||
}
|
||||
}
|
||||
|
||||
private void addStateOptions(ShellyDeviceProfile prf) {
|
||||
|
||||
@ -91,8 +91,13 @@ public class ShellyComponents {
|
||||
|
||||
public static boolean updateRelay(ShellyBaseHandler thingHandler, ShellySettingsStatus status, int id) {
|
||||
ShellyDeviceProfile profile = thingHandler.getProfile();
|
||||
ShellySettingsRelay rsettings = profile.settings.relays.get(id);
|
||||
ShellySettingsRelay relay = status.relays.get(id);
|
||||
ShellySettingsRelay rsettings;
|
||||
if (profile.settings.relays != null) {
|
||||
rsettings = profile.settings.relays.get(id);
|
||||
} else {
|
||||
throw new IllegalArgumentException("No relay settings");
|
||||
}
|
||||
|
||||
boolean updated = false;
|
||||
if (relay.isValid == null || relay.isValid) {
|
||||
@ -105,26 +110,53 @@ public class ShellyComponents {
|
||||
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_OUTPUT, getOnOff(relay.ison));
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_TIMER_ACTIVE, getOnOff(relay.hasTimer));
|
||||
if (status.extSwitch != null) {
|
||||
if (status.extSwitch.input0 != null) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_INPUT1,
|
||||
getInteger(status.extSwitch.input0.input) == 1 ? OpenClosedType.OPEN
|
||||
: OpenClosedType.CLOSED);
|
||||
}
|
||||
}
|
||||
if (status.extTemperature != null) {
|
||||
// Shelly 1/1PM support up to 3 external sensors
|
||||
// for whatever reason those are not represented as an array, but 3 elements
|
||||
if (status.extTemperature.sensor1 != null) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP1,
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_TEMP1,
|
||||
toQuantityType(getDouble(status.extTemperature.sensor1.tC), DIGITS_TEMP, SIUnits.CELSIUS));
|
||||
}
|
||||
if (status.extTemperature.sensor2 != null) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP2,
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_TEMP2,
|
||||
toQuantityType(getDouble(status.extTemperature.sensor2.tC), DIGITS_TEMP, SIUnits.CELSIUS));
|
||||
}
|
||||
if (status.extTemperature.sensor3 != null) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENDOR_TEMP3,
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_TEMP3,
|
||||
toQuantityType(getDouble(status.extTemperature.sensor3.tC), DIGITS_TEMP, SIUnits.CELSIUS));
|
||||
}
|
||||
if (status.extTemperature.sensor4 != null) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_TEMP4,
|
||||
toQuantityType(getDouble(status.extTemperature.sensor4.tC), DIGITS_TEMP, SIUnits.CELSIUS));
|
||||
}
|
||||
if (status.extTemperature.sensor5 != null) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_TEMP5,
|
||||
toQuantityType(getDouble(status.extTemperature.sensor5.tC), DIGITS_TEMP, SIUnits.CELSIUS));
|
||||
}
|
||||
}
|
||||
if ((status.extHumidity != null) && (status.extHumidity.sensor1 != null)) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_HUM,
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_HUMIDITY,
|
||||
toQuantityType(getDouble(status.extHumidity.sensor1.hum), DIGITS_PERCENT, Units.PERCENT));
|
||||
}
|
||||
if ((status.extVoltage != null) && (status.extVoltage.sensor1 != null)) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_VOLTAGE,
|
||||
toQuantityType(getDouble(status.extVoltage.sensor1.voltage), 4, Units.VOLT));
|
||||
}
|
||||
if ((status.extDigitalInput != null) && (status.extDigitalInput.sensor1 != null)) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_DIGITALINPUT,
|
||||
getOnOff(status.extDigitalInput.sensor1.state));
|
||||
}
|
||||
if ((status.extAnalogInput != null) && (status.extAnalogInput.sensor1 != null)) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_ESENSOR_ANALOGINPUT, toQuantityType(
|
||||
getDouble(status.extAnalogInput.sensor1.percent), DIGITS_PERCENT, Units.PERCENT));
|
||||
}
|
||||
|
||||
// Update Auto-ON/OFF timer
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_TIMER_AUTOON,
|
||||
@ -146,16 +178,27 @@ public class ShellyComponents {
|
||||
}
|
||||
|
||||
String state = getString(control.state);
|
||||
if (state.equals(SHELLY_ALWD_ROLLER_TURN_STOP)) {
|
||||
int pos = -1;
|
||||
switch (state) {
|
||||
case SHELLY_ALWD_ROLLER_TURN_OPEN:
|
||||
pos = SHELLY_MAX_ROLLER_POS;
|
||||
break;
|
||||
case SHELLY_ALWD_ROLLER_TURN_CLOSE:
|
||||
pos = SHELLY_MIN_ROLLER_POS;
|
||||
break;
|
||||
case SHELLY_ALWD_ROLLER_TURN_STOP:
|
||||
if (control.currentPos != null) {
|
||||
// only valid in stop state
|
||||
int pos = Math.max(SHELLY_MIN_ROLLER_POS, Math.min(control.currentPos, SHELLY_MAX_ROLLER_POS));
|
||||
pos = Math.max(SHELLY_MIN_ROLLER_POS, Math.min(control.currentPos, SHELLY_MAX_ROLLER_POS));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (pos != -1) {
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_CONTROL,
|
||||
toQuantityType((double) (SHELLY_MAX_ROLLER_POS - pos), Units.PERCENT));
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_POS,
|
||||
toQuantityType((double) pos, Units.PERCENT));
|
||||
}
|
||||
}
|
||||
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_STATE, new StringType(state));
|
||||
updated |= thingHandler.updateChannel(groupName, CHANNEL_ROL_CONTROL_STOPR,
|
||||
@ -382,18 +425,19 @@ public class ShellyComponents {
|
||||
temp = convertToC(temp, getString(sdata.tmp.units));
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_TEMP,
|
||||
toQuantityType(temp.doubleValue(), DIGITS_TEMP, SIUnits.CELSIUS));
|
||||
} else if (status.thermostats != null && profile.settings.thermostats != null) {
|
||||
} else if (status.thermostats != null) {
|
||||
// Shelly TRV
|
||||
ShellyThermnostat t = status.thermostats.get(0);
|
||||
if (profile.settings.thermostats != null) {
|
||||
ShellyThermnostat ps = profile.settings.thermostats.get(0);
|
||||
ShellyThermnostat t = status.thermostats.get(0);
|
||||
int bminutes = getInteger(t.boostMinutes) >= 0 ? getInteger(t.boostMinutes)
|
||||
: getInteger(ps.boostMinutes);
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_BCONTROL,
|
||||
getOnOff(getInteger(t.boostMinutes) > 0));
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_BTIMER,
|
||||
toQuantityType((double) bminutes, DIGITS_NONE, Units.MINUTE));
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_MODE,
|
||||
getStringType(getBool(t.targetTemp.enabled) ? SHELLY_TRV_MODE_AUTO : SHELLY_TRV_MODE_MANUAL));
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_MODE, getStringType(
|
||||
getBool(t.targetTemp.enabled) ? SHELLY_TRV_MODE_AUTO : SHELLY_TRV_MODE_MANUAL));
|
||||
int pid = getBool(t.schedule) ? getInteger(t.profile) : 0;
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE,
|
||||
getOnOff(t.schedule));
|
||||
@ -414,6 +458,7 @@ public class ShellyComponents {
|
||||
getDouble(t.pos) > 0 ? OpenClosedType.OPEN : OpenClosedType.CLOSED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sdata.hum != null) {
|
||||
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_HUM,
|
||||
|
||||
@ -231,10 +231,16 @@ public class ShellyChannelDefinitions {
|
||||
.add(new ShellyChannel(m, CHGR_STATUS, CHANNEL_LAST_UPDATE, "lastUpdate", ITEMT_DATETIME))
|
||||
|
||||
// Addon with external sensors
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP1, "sensorExtTemp", ITEMT_TEMP))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP2, "sensorExtTemp", ITEMT_TEMP))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP3, "sensorExtTemp", ITEMT_TEMP))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENDOR_HUMIDITY, "sensorExtHum", ITEMT_PERCENT))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP1, "sensorExtTemp", ITEMT_TEMP))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP2, "sensorExtTemp", ITEMT_TEMP))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP3, "sensorExtTemp", ITEMT_TEMP))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_HUMIDITY, "sensorExtHum", ITEMT_PERCENT))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_VOLTAGE, "sensorExtVolt", ITEMT_VOLT))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_INPUT1, "sensorContact", ITEMT_CONTACT))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_DIGITALINPUT, "sensorExtDigitalInput",
|
||||
ITEMT_SWITCH))
|
||||
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_ESENSOR_ANALOGINPUT, "sensorExtAnalogInput",
|
||||
ITEMT_PERCENT))
|
||||
|
||||
// Battery
|
||||
.add(new ShellyChannel(m, CHGR_BAT, CHANNEL_SENSOR_BAT_LEVEL, "system:battery-level", ITEMT_PERCENT))
|
||||
@ -337,15 +343,20 @@ public class ShellyChannelDefinitions {
|
||||
addChannel(thing, add, rs.autoOff != null, group, CHANNEL_TIMER_AUTOOFF);
|
||||
}
|
||||
|
||||
// Shelly 1/1PM Addon
|
||||
// Shelly 1/1PM and Plus 1/1PM Addon
|
||||
addChannel(thing, add,
|
||||
profile.settings.extSwitch != null && profile.settings.extSwitch.input0 != null
|
||||
&& idx == getInteger(profile.settings.extSwitch.input0.relayNum),
|
||||
CHGR_SENSOR, CHANNEL_ESENSOR_INPUT + (profile.settings.extSwitch.input0.relayNum + 1));
|
||||
if (profile.status.extTemperature != null) {
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP1);
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor2 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP2);
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor3 != null, CHGR_SENSOR, CHANNEL_ESENDOR_TEMP3);
|
||||
}
|
||||
if (profile.settings.extHumidity != null) {
|
||||
addChannel(thing, add, profile.settings.extHumidity.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENDOR_HUMIDITY);
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor1 != null, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP1);
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor2 != null, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP2);
|
||||
addChannel(thing, add, profile.status.extTemperature.sensor3 != null, CHGR_SENSOR, CHANNEL_ESENSOR_TEMP3);
|
||||
}
|
||||
addChannel(thing, add, profile.status.extHumidity != null, CHGR_SENSOR, CHANNEL_ESENSOR_HUMIDITY);
|
||||
addChannel(thing, add, profile.status.extVoltage != null, CHGR_SENSOR, CHANNEL_ESENSOR_VOLTAGE);
|
||||
addChannel(thing, add, profile.status.extDigitalInput != null, CHGR_SENSOR, CHANNEL_ESENSOR_DIGITALINPUT);
|
||||
addChannel(thing, add, profile.status.extAnalogInput != null, CHGR_SENSOR, CHANNEL_ESENSOR_ANALOGINPUT);
|
||||
|
||||
return add;
|
||||
}
|
||||
@ -534,8 +545,11 @@ public class ShellyChannelDefinitions {
|
||||
|
||||
public ChannelTypeUID getChannelTypeUID(String channelId) {
|
||||
ShellyChannel channelDef = getDefinition(channelId);
|
||||
if (channelDef != null) {
|
||||
return new ChannelTypeUID(BINDING_ID, channelDef.typeId);
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid channelId:" + channelId);
|
||||
}
|
||||
|
||||
private static void addChannel(Thing thing, Map<String, Channel> newChannels, boolean supported, String group,
|
||||
String channelName) throws IllegalArgumentException {
|
||||
|
||||
@ -94,7 +94,8 @@ public class ShellyUtils {
|
||||
throw new ShellyApiException(
|
||||
PRE + className + " from JSON (syntax/format error: " + e.getMessage() + "): " + json, e);
|
||||
} catch (RuntimeException e) {
|
||||
throw new ShellyApiException(PRE + className + " from JSON: " + json, e);
|
||||
throw new ShellyApiException(
|
||||
PRE + className + " from JSON (" + getString(e.getMessage() + "), JSON=" + json), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ channel-group-type.shelly.dimmerChannel.description = A Shelly Dimmer channel
|
||||
channel-group-type.shelly.iXChannel1.label = Input 1
|
||||
channel-group-type.shelly.iXChannel2.label = Input 2
|
||||
channel-group-type.shelly.iXChannel3.label = Input 3
|
||||
channel-group-type.shelly.iXChannel4.label = Input 3
|
||||
channel-group-type.shelly.iXChannel4.label = Input 4
|
||||
channel-group-type.shelly.iXChannel.description = Input Status
|
||||
channel-group-type.shelly.rollerControl.label = Roller Control
|
||||
channel-group-type.shelly.rollerControl.description = Controlling the roller mode
|
||||
@ -232,6 +232,10 @@ channel-type.shelly.temperature2.label = Temperature 2
|
||||
channel-type.shelly.temperature2.description = Temperature of external Sensor #2
|
||||
channel-type.shelly.temperature3.label = Temperature 3
|
||||
channel-type.shelly.temperature3.description = Temperature of external Sensor #3
|
||||
channel-type.shelly.temperature4.label = Temperature 4
|
||||
channel-type.shelly.temperature4.description = Temperature of external Sensor #4
|
||||
channel-type.shelly.temperature5.label = Temperature 5
|
||||
channel-type.shelly.temperature6.description = Temperature of external Sensor #5
|
||||
channel-type.shelly.targetTemp.label = Target Temperature
|
||||
channel-type.shelly.targetTemp.description = Target Temperature in °C to be reached in auto-temperature mode
|
||||
channel-type.shelly.humidity.label = Humidity
|
||||
@ -338,10 +342,6 @@ channel-type.shelly.colorEffectRGBW2.option.2 = Gradual Change
|
||||
channel-type.shelly.colorEffectRGBW2.option.3 = Flash
|
||||
channel-type.shelly.sensorTemp.label = Temperature
|
||||
channel-type.shelly.sensorTemp.description = Temperature from the sensor
|
||||
channel-type.shelly.sensorExtTemp.label = Temperature
|
||||
channel-type.shelly.sensorExtTemp.description = Temperature from the external sensor
|
||||
channel-type.shelly.sensorExtHum.label = Humidity
|
||||
channel-type.shelly.sensorExtHum.description = Relative humidity in percent (0..100%) from external sensor
|
||||
channel-type.shelly.sensorHumidity.label = Humidity
|
||||
channel-type.shelly.sensorHumidity.description = Relative humidity in percent (0..100%)
|
||||
channel-type.shelly.sensorFlood.label = Flood Alarm
|
||||
@ -368,6 +368,16 @@ channel-type.shelly.sensorVibration.label = Vibration
|
||||
channel-type.shelly.sensorVibration.description = Vibration detected when toggled ON
|
||||
channel-type.shelly.sensorMotion.label = Motion
|
||||
channel-type.shelly.sensorMotion.description = Motion detected when toggled ON
|
||||
channel-type.shelly.sensorExtTemp.label = Temperature
|
||||
channel-type.shelly.sensorExtTemp.description = Temperature from the external sensor
|
||||
channel-type.shelly.sensorExtHum.label = Humidity
|
||||
channel-type.shelly.sensorExtHum.description = Relative humidity in percent (0..100%) from external sensor
|
||||
channel-type.shelly.sensorExtVolt.label = Voltage
|
||||
channel-type.shelly.sensorExtVolt.description = Voltage from external sensor
|
||||
channel-type.shelly.sensorExtDigitalInput.label = Digital Input
|
||||
channel-type.shelly.sensorExtDigitalInput.description = State of digital input connected to add-on
|
||||
channel-type.shelly.sensorExtAnalogInput.label = Analog Input
|
||||
channel-type.shelly.sensorExtAnalogInput.description = Percentage of analog input from external sensor
|
||||
channel-type.shelly.motionActive.label = Motion Active
|
||||
channel-type.shelly.motionActive.description = Indicates if motion sensor is active or within sleep time
|
||||
channel-type.shelly.motionTimestamp.label = Last Motion
|
||||
|
||||
@ -104,6 +104,20 @@
|
||||
<config-description-ref uri="thing-type:shelly:relay"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="shelly2-roller">
|
||||
<label>Shelly 2 Roller</label>
|
||||
<description>@text/thing-type.shelly.shelly2-roller.description</description>
|
||||
<category>Rollershutter</category>
|
||||
<channel-groups>
|
||||
<channel-group id="roller" typeId="rollerControl"/>
|
||||
<channel-group id="meter" typeId="meter"/>
|
||||
<channel-group id="device" typeId="deviceStatus"/>
|
||||
</channel-groups>
|
||||
|
||||
<representation-property>serviceName</representation-property>
|
||||
<config-description-ref uri="thing-type:shelly:roller"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="shelly25-relay">
|
||||
<label>Shelly 2.5 Relay</label>
|
||||
<description>@text/thing-type.shelly.shelly25-relay.description</description>
|
||||
|
||||
@ -309,32 +309,6 @@
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorExtTemp">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>@text/channel-type.shelly.sensorExtTemp.label</label>
|
||||
<description>@text/channel-type.shelly.sensorExtTemp.label</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.1f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorExtHum">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>@text/channel-type.shelly.sensorExtHum.label</label>
|
||||
<description>@text/channel-type.shelly.sensorExtHum.description</description>
|
||||
<category>Humidity</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Humidity</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.1f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorHumidity">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>@text/channel-type.shelly.sensorHumidity.label</label>
|
||||
@ -344,7 +318,7 @@
|
||||
<tag>Measurement</tag>
|
||||
<tag>Humidity</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||
<state readOnly="true" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorFlood">
|
||||
@ -487,6 +461,65 @@
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorExtTemp">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>@text/channel-type.shelly.sensorExtTemp.label</label>
|
||||
<description>@text/channel-type.shelly.sensorExtTemp.label</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.1f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorExtHum">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>@text/channel-type.shelly.sensorExtHum.label</label>
|
||||
<description>@text/channel-type.shelly.sensorExtHum.description</description>
|
||||
<category>Humidity</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Humidity</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.1f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorExtVolt">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>@text/channel-type.shelly.sensorExtVolt.label</label>
|
||||
<description>@text/channel-type.shelly.sensorExtVolt.description</description>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Voltage</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.2f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorExtDigitalInput">
|
||||
<item-type>Switch</item-type>
|
||||
<label>@text/channel-type.shelly.sensorExtDigitalInput.label</label>
|
||||
<description>@text/channel-type.shelly.sensorExtDigitalInput.description</description>
|
||||
<category>Status</category>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorExtAnalogInput">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>@text/channel-type.shelly.sensorExtAnalogInput.label</label>
|
||||
<description>@text/channel-type.shelly.sensorExtAnalogInput.description</description>
|
||||
<category>Humidity</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
</tags>
|
||||
<state readOnly="true" pattern="%.0f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorError">
|
||||
<item-type>String</item-type>
|
||||
<label>@text/channel-type.shelly.sensorError.label</label>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user