]> git.basschouten.com Git - openhab-addons.git/commitdiff
[openwebnet] add support for Thermoregulation (standalone thermostat and sensors...
authorConte Andrea <andrea@conte.com>
Sat, 5 Jun 2021 17:26:52 +0000 (19:26 +0200)
committerGitHub <noreply@github.com>
Sat, 5 Jun 2021 17:26:52 +0000 (19:26 +0200)
Signed-off-by: Conte Andrea <andrea@conte.com>
Signed-off-by: Massimo Valla <mvcode00@gmail.com>
Co-authored-by: Massimo Valla <mvcode00@gmail.com>
12 files changed:
bundles/org.openhab.binding.openwebnet/README.md
bundles/org.openhab.binding.openwebnet/pom.xml
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/OpenWebNetBindingConstants.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/handler/OpenWebNetBridgeHandler.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/handler/OpenWebNetThermoregulationHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/handler/OpenWebNetThingHandler.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetHandlerFactory.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/discovery/OpenWebNetDeviceDiscoveryService.java
bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusTempSensor.xml [new file with mode: 0644]
bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermostat.xml [new file with mode: 0644]
bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/channels.xml
bundles/org.openhab.binding.openwebnet/src/test/java/org/openhab/binding/openwebnet/handler/OwnIdTest.java

index 72b91fdb0f18d8ec1c59fb3c2f06a74eb147264c..7b2ab4585a33008a337159546309387262674d5b 100644 (file)
@@ -37,20 +37,21 @@ The following Things and OpenWebNet `WHOs` are supported:
 
 ### For BUS/SCS
 
-| Category             | WHO          | Thing Type IDs                               | Description                                                    | Status           |
-| -------------------- | :----------: | :------------------------------------------: | -------------------------------------------------------------- | ---------------- |
-| Gateway Management   | `13`        | `bus_gateway`                            | Any IP gateway supporting OpenWebNet protocol should work (e.g. F454 / MyHOMEServer1 / MH202 / F455 / MH200N, ...) | Successfully tested: F454, MyHOMEServer1, MyHOME_Screen10, F455, F452, F453AV, MH201, MH202, MH200N. Some connection stability issues/gateway resets reported with MH202 |
-| Lighting             | `1`         | `bus_on_off_switch`, `bus_dimmer`   | BUS switches and dimmers                                       | Successfully tested: F411/2, F411/4, F411U2, F422, F429. Some discovery issues reported with F429 (DALI Dimmers)  |
-| Automation           | `2`         | `bus_automation`                        | BUS roller shutters, with position feedback and auto-calibration | Successfully tested: LN4672M2  |
-| Energy Management    | `18`         | `bus_energy_meter`           | Energy Management  | Successfully tested: F520, F521 |
+| Category             | WHO          | Thing Type IDs                      | Description                                                      | Status           |
+| -------------------- | :----------: | :---------------------------------: | ---------------------------------------------------------------- | ---------------- |
+| Gateway Management   | `13`         | `bus_gateway`                       | Any IP gateway supporting OpenWebNet protocol should work (e.g. F454 / MyHOMEServer1 / MH202 / F455 / MH200N, ...) | Successfully tested: F454, MyHOMEServer1, MyHOME_Screen10, F455, F452, F453AV, MH201, MH202, MH200N. Some connection stability issues/gateway resets reported with MH202 |
+| Lighting             | `1`          | `bus_on_off_switch`, `bus_dimmer`   | BUS switches and dimmers                                         | Successfully tested: F411/2, F411/4, F411U2, F422, F429. Some discovery issues reported with F429 (DALI Dimmers)  |
+| Automation           | `2`          | `bus_automation`                    | BUS roller shutters, with position feedback and auto-calibration | Successfully tested: LN4672M2  |
+| Temperature Control  | `4`          | `bus_thermostat`, `bus_temp_sensor` | Zones room thermostats (stand-alone) and external wireless temperature sensors. Please note that Central Unit configurations (4 or 99 zones) are not yet supported. See [Channels - Thermo](#thermo-channels) for more details. | Successfully tested: H/LN4691; external sensors: L/N/NT4577 + 3455 |
+| Energy Management    | `18`         | `bus_energy_meter`                  | Energy Management                                                | Successfully tested: F520, F521 |
 
 ### For ZigBee (Radio)
 
 | Category             | WHO    | Thing Type IDs                    | Description                                                           | Status                               |
 | -------------------- | :----: | :-------------------------------: | :-------------------------------------------------------------------: | ------------------------------------ |
-| Gateway Management   | `13`  | `zb_gateway`                  | ZigBee USB Gateway (models: BTI-3578 / LG 088328)                      | Tested: BTI-3578 and LG 088328       |
-| Lighting             | `1`   | `zb_dimmer`, `zb_on_off_switch`, `zb_on_off_switch2u` | ZigBee dimmers, switches and 2-unit switches      | Tested: BTI-4591, BTI-3584, BTI-4585 |
-| Automation           | `2`   | `zb_automation`               | ZigBee roller shutters                                                |                                       |
+| Gateway Management   | `13`   | `zb_gateway`                      | ZigBee USB Gateway (models: BTI-3578 / LG 088328)                     | Tested: BTI-3578 and LG 088328       |
+| Lighting             | `1`    | `zb_dimmer`, `zb_on_off_switch`, `zb_on_off_switch2u` | ZigBee dimmers, switches and 2-unit switches      | Tested: BTI-4591, BTI-3584, BTI-4585 |
+| Automation           | `2`    | `zb_automation`                   | ZigBee roller shutters                                                |                                      |
 
 ## Discovery
 
@@ -121,18 +122,36 @@ For any manually added device, you must configure:
 - the `where` config parameter (`OpenWebNet Device Address`):
   - example for BUS/SCS device with WHERE address Point to Point `A=2 PL=4` --> `where="24"`
   - example for BUS/SCS device with WHERE address Point to Point `A=03 PL=11` on local bus --> `where="0311#4#01"`
+  - example for BUS/SCS thermo Zones: `Zone=1` --> `where="1"`; external sensor `5` --> `where="500"`
   - example for ZigBee devices: `where=765432101#9`. The ID of the device (ADDR part) is usually written in hexadecimal on the device itself, for example `ID 0074CBB1`: convert to decimal (`7654321`) and add `01#9` at the end to obtain `where=765432101#9`. For 2-unit switch devices (`zb_on_off_switch2u`), last part should be `00#9`.
 
-## Channels
+## Channels 
+
+### Lighting, Automation and Power meter channels
+
+| Channel Type ID (channel ID)             | Applies to Thing Type IDs                                     | Item Type     | Description                                           | Read/Write |
+| ---------------------------------------- | ------------------------------------------------------------- | ------------- | ----------------------------------------------------- | :--------: |
+| `switch` or `switch_01`/`02` for ZigBee  | `bus_on_off_switch`, `zb_on_off_switch`, `zb_on_off_switch2u` | Switch        | To switch the device `ON` and `OFF`                   |    R/W     |
+| `brightness`                             | `bus_dimmer`, `zb_dimmer`                                     | Dimmer        | To adjust the brightness value (Percent, `ON`, `OFF`) |    R/W     |
+| `shutter`                                | `bus_automation`                                              | Rollershutter | To activate roller shutters (`UP`, `DOWN`, `STOP`, Percent - [see Shutter position](#shutter-position)) |    R/W     |
+| `power`                                  | `bus_energy_meter`                                            | Number:Power  | The current active power usage from Energy Meter      |     R      |
+
+### Thermo channels
+
+Currently only stand-alone thermostats are supported (like  [LN4691](https://catalogo.bticino.it/BTI-LN4691-IT)) and the specific thing `bus_thermostat` was created to manage them.
+
+| Channel Type ID (channel ID) | Applies to Thing Type IDs           | Item Type          | Description                                       | Read/Write | Advanced |
+| ---------------------------- | ----------------------------------- | ------------------ | ------------------------------------------------- | :--------: | :------: |
+| `temperature`                | `bus_thermostat`, `bus_temp_sensor` | Number:Temperature | The zone currently sensed temperature       | R          | N        |
+| `setpointTemperature`        | `bus_thermostat`                    | Number:Temperature | The zone setpoint temperature           | R/W        | N        |
+| `function`                   | `bus_thermostat`                    | String             | The zone set thermo function: `COOLING`, `HEATING` or `GENERIC` (heating + cooling)  | R/W | N |
+| `mode`                       | `bus_thermostat`                    | String             | The zone set mode: `MANUAL`, `PROTECTION`, `OFF`  | R/W        | N        |
+| `speedFanCoil`               | `bus_thermostat`                    | String             | The zone fancoil speed: `AUTO`, `SPEED_1`, `SPEED_2`, `SPEED_3`    | R/W | N |
+| `actuator`                   | `bus_thermostat`                    | String             | The zone actuator(s) status: `OFF`, `ON`, `OPENED`, `CLOSED` , `STOP`, `OFF_FAN_COIL`, `ON_SPEED_1`, `ON_SPEED_2`, `ON_SPEED_3`, `OFF_SPEED_1`, `OFF_SPEED_2`, `OFF_SPEED_3` | R | Y |
+| `heatingValve`               | `bus_thermostat`                    | String             | The zone heating valve(s) status: `OFF`, `ON`, `OPENED`, `CLOSED` , `STOP`, `OFF_FAN_COIL`, `ON_SPEED_1`, `ON_SPEED_2`, `ON_SPEED_3`, `OFF_SPEED_1`, `OFF_SPEED_2`, `OFF_SPEED_3` | R | Y |
+| `conditioningValve`          | `bus_thermostat`                    | String             | The zone conditioning valve(s) status: `OFF`, `ON`, `OPENED`, `CLOSED` , `STOP`, `OFF_FAN_COIL`, `ON_SPEED_1`, `ON_SPEED_2`, `ON_SPEED_3`, `OFF_SPEED_1`, `OFF_SPEED_2`, `OFF_SPEED_3`  | R | Y |
 
-Devices support some of the following channels:
 
-| Channel Type ID (channel ID)                   | Item Type     | Description                                             | Read/Write |
-|------------------------------------------------|---------------|---------------------------------------------------------|:----------:|
-| `switch` or `switch_01`/`02` for ZigBee | Switch        | To switch the device `ON` and `OFF`                   |    R/W     |
-| `brightness`                               | Dimmer        | To adjust the brightness value (Percent, `ON`, `OFF`) |    R/W     |
-| `shutter`                                   | Rollershutter | To activate roller shutters (`UP`, `DOWN`, `STOP`, Percent - [see Shutter position](#shutter-position)) |    R/W     |
-| `power`                  | Number:Power        | The current active power usage from Energy Meter       |     R      |
 ### Notes on channels
 
 #### `shutter` position
@@ -154,11 +173,13 @@ BUS gateway and things configuration:
 
 ```xtend
 Bridge openwebnet:bus_gateway:mybridge "MyHOMEServer1" [ host="192.168.1.35", passwd="abcde", port=20000, discoveryByActivation=false ] {
-      bus_on_off_switch        LR_switch        "Living Room Light"     [ where="51" ]
-      bus_dimmer               LR_dimmer        "Living Room Dimmer"    [ where="0311#4#01" ]
-      bus_automation           LR_shutter       "Living Room Shutter"   [ where="93", shutterRun="10050"]
-      bus_energy_meter         CENTRAL_Ta       "Energy Meter Ta"       [ where="51" ]
-      bus_energy_meter         CENTRAL_Tb       "Energy Meter Tb"       [ where="52" ]
+      bus_on_off_switch        LR_switch        "Living Room Light"      [ where="51" ]
+      bus_dimmer               LR_dimmer        "Living Room Dimmer"     [ where="0311#4#01" ]
+      bus_automation           LR_shutter       "Living Room Shutter"    [ where="93", shutterRun="10050"]      
+      bus_energy_meter         CENTRAL_Ta       "Energy Meter Ta"        [ where="51" ]        
+      bus_energy_meter         CENTRAL_Tb       "Energy Meter Tb"        [ where="52" ]           
+      bus_thermostat           LR_thermostat    "Living Room Thermostat" [ where="2"]
+      bus_temp_sensor          EXT_tempsensor   "External Temperature"   [ where="500"]
 }
 ```
 
@@ -178,11 +199,18 @@ Bridge openwebnet:zb_gateway:myZBgateway  [ serialPort="COM3" ] {
 Example items linked to BUS devices:
 
 ```xtend
-Switch          iLR_switch          "Light"                             <light>          (gLivingRoom)                [ "Lighting" ]  { channel="openwebnet:bus_on_off_switch:mybridge:LR_switch:switch" }
-Dimmer          iLR_dimmer          "Dimmer [%.0f %%]"                  <DimmableLight>  (gLivingRoom)                [ "Lighting" ]  { channel="openwebnet:bus_dimmer:mybridge:LR_dimmer:brightness" }
-Rollershutter   iLR_shutter         "Shutter [%.0f %%]"                 <rollershutter>  (gShutters, gLivingRoom)     [ "Blinds"   ]  { channel="openwebnet:bus_automation:mybridge:LR_shutter:shutter" }
-Number:Power    iCENTRAL_Ta         "Power [%.0f %unit%]"               <energy>         { channel="openwebnet:bus_energy_meter:mybridge:CENTRAL_Ta:power" }
-Number:Power    iCENTRAL_Tb         "Power [%.0f %unit%]"               <energy>         { channel="openwebnet:bus_energy_meter:mybridge:CENTRAL_Tb:power" }
+Switch              iLR_switch                  "Light"                  <light>          (gLivingRoom)                [ "Lighting" ]  { channel="openwebnet:bus_on_off_switch:mybridge:LR_switch:switch" }
+Dimmer              iLR_dimmer                  "Dimmer [%.0f %%]"       <DimmableLight>  (gLivingRoom)                [ "Lighting" ]  { channel="openwebnet:bus_dimmer:mybridge:LR_dimmer:brightness" }
+Rollershutter       iLR_shutter                 "Shutter [%.0f %%]"      <rollershutter>  (gShutters, gLivingRoom)     [ "Blinds"   ]  { channel="openwebnet:bus_automation:mybridge:LR_shutter:shutter" }
+Number:Power        iCENTRAL_Ta                 "Power [%.0f %unit%]"    <energy>                                                      { channel="openwebnet:bus_energy_meter:mybridge:CENTRAL_Ta:power" }
+Number:Power        iCENTRAL_Tb                 "Power [%.0f %unit%]"    <energy>                                                      { channel="openwebnet:bus_energy_meter:mybridge:CENTRAL_Tb:power" }
+Number:Temperature  iLR_thermostat_temp         "Temperature"                             (gLivingRoom)                                { channel="openwebnet:bus_thermostat:mybridge:LR_thermostat:temperature" }
+Number:Temperature  iLR_thermostat_set          "SetPoint Temperature"                    (gLivingRoom)                                { channel="openwebnet:bus_thermostat:mybridge:LR_thermostat:setpointTemperature" }
+String              iLR_thermostat_setFanSpeed  "FanSpeed"                                (gLivingRoom)                                { channel="openwebnet:bus_thermostat:mybridge:LR_thermostat:speedFanCoil" }
+String              iLR_thermostat_setMode      "Mode"                                    (gLivingRoom)                                { channel="openwebnet:bus_thermostat:mybridge:LR_thermostat:mode" }
+String              iLR_thermostat_setFunc      "Function"                                (gLivingRoom)                                { channel="openwebnet:bus_thermostat:mybridge:LR_thermostat:function" }
+Number:Temperature  iEXT_temp                   "Temperature [%.1f °C]"  <temperature>    (gExternal)                                  { channel="openwebnet:bus_temp_sensor:mybridge:EXT_tempsensor:temperature" }
+
 
 ```
 
@@ -212,6 +240,15 @@ sitemap openwebnet label="OpenWebNet Binding Example Sitemap"
           Default item=iCENTRAL_Ta label="General"      icon="energy" valuecolor=[>3000="red"]
           Default item=iCENTRAL_Tb label="Ground Floor" icon="energy" valuecolor=[>3000="red"]
     }
+
+    Frame label="Thermoregulation"
+    {
+          Default   item=iLR_thermostat_temp        label="Temperature" icon="fire" valuecolor=[<20="red"] 
+          Setpoint  item=iLR_thermostat_set         label="Setpoint [%.1f °C]" step=0.5 minValue=15 maxValue=30
+          Selection item=iLR_thermostat_setFanSpeed label="Fan Speed" icon="fan" mappings=[AUTO="AUTO", SPEED_1="Low", SPEED_2="Medium", SPEED_3="High"]
+          Switch    item=iLR_thermostat_setMode     label="Mode" icon="settings"
+          Selection item=iLR_thermostat_setFunc     label="Function" icon="heating" mappings=[HEATING="Heating", COOLING="Cooling", GENERIC="Heating/Cooling"]
+    }
 }
 ```
 
index 9b703d9762b6de556406d33777ba39c4930eb8dc..caefdc9197160874dbd7f1d2a805fb95dcfda134 100644 (file)
@@ -23,7 +23,7 @@
     <dependency>
       <groupId>io.github.openwebnet4j</groupId>
       <artifactId>openwebnet4j</artifactId>
-      <version>0.4.1</version>
+      <version>0.5.2</version>
       <scope>compile</scope>
     </dependency>
 
index 33fa4def8a9e5b161c390c936d5c796d30e60bfc..42c369ec0e9782c604265c9c5c7906d9b71a4416 100644 (file)
@@ -12,7 +12,6 @@
  */
 package org.openhab.binding.openwebnet;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
@@ -26,7 +25,8 @@ import org.openhab.core.thing.ThingTypeUID;
  * The {@link OpenWebNetBindingConstants} class defines common constants, which are used across the whole binding.
  *
  * @author Massimo Valla - Initial contribution
- * @author Andrea Conte - Energy management
+ * @author Andrea Conte - Energy management, Thermoregulation
+ * @author Gilberto Cocchi - Thermoregulation
  */
 
 @NonNullByDefault
@@ -55,6 +55,10 @@ public class OpenWebNetBindingConstants {
     public static final String THING_LABEL_BUS_AUTOMATION = "Automation";
     public static final ThingTypeUID THING_TYPE_BUS_ENERGY_METER = new ThingTypeUID(BINDING_ID, "bus_energy_meter");
     public static final String THING_LABEL_BUS_ENERGY_METER = "Energy Meter";
+    public static final ThingTypeUID THING_TYPE_BUS_TEMP_SENSOR = new ThingTypeUID(BINDING_ID, "bus_temp_sensor");
+    public static final String THING_LABEL_BUS_TEMP_SENSOR = "Temperature Sensor";
+    public static final ThingTypeUID THING_TYPE_BUS_THERMOSTAT = new ThingTypeUID(BINDING_ID, "bus_thermostat");
+    public static final String THING_LABEL_BUS_THERMOSTAT = "Thermostat (stand-alone)";
 
     // ZIGBEE
     public static final ThingTypeUID THING_TYPE_ZB_ON_OFF_SWITCH = new ThingTypeUID(BINDING_ID, "zb_on_off_switch");
@@ -69,28 +73,31 @@ public class OpenWebNetBindingConstants {
 
     // #SUPPORTED THINGS SETS
     // ## Generic
-    public static final Set<ThingTypeUID> GENERIC_SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_GENERIC_DEVICE));
+    public static final Set<ThingTypeUID> GENERIC_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_GENERIC_DEVICE);
     // ## Lighting
-    public static final Set<ThingTypeUID> LIGHTING_SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_ZB_ON_OFF_SWITCH, THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS, THING_TYPE_ZB_DIMMER,
-                    THING_TYPE_BUS_ON_OFF_SWITCH, THING_TYPE_BUS_DIMMER));
+    public static final Set<ThingTypeUID> LIGHTING_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_ZB_ON_OFF_SWITCH,
+            THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS, THING_TYPE_ZB_DIMMER, THING_TYPE_BUS_ON_OFF_SWITCH,
+            THING_TYPE_BUS_DIMMER);
     // ## Automation
-    public static final Set<ThingTypeUID> AUTOMATION_SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_ZB_AUTOMATION, THING_TYPE_BUS_AUTOMATION));
+    public static final Set<ThingTypeUID> AUTOMATION_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_ZB_AUTOMATION,
+            THING_TYPE_BUS_AUTOMATION);
+
+    // ## Thermoregulation
+    public static final Set<ThingTypeUID> THERMOREGULATION_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BUS_THERMOSTAT,
+            THING_TYPE_BUS_TEMP_SENSOR);
 
     // ## Energy Management
-    public static final Set<ThingTypeUID> ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_BUS_ENERGY_METER));
+    public static final Set<ThingTypeUID> ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BUS_ENERGY_METER);
 
     // ## Groups
     public static final Set<ThingTypeUID> DEVICE_SUPPORTED_THING_TYPES = Stream
             .of(LIGHTING_SUPPORTED_THING_TYPES, AUTOMATION_SUPPORTED_THING_TYPES,
-                    ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES, GENERIC_SUPPORTED_THING_TYPES)
+                    THERMOREGULATION_SUPPORTED_THING_TYPES, ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES,
+                    GENERIC_SUPPORTED_THING_TYPES)
             .flatMap(Collection::stream).collect(Collectors.toCollection(HashSet::new));
 
-    public static final Set<ThingTypeUID> BRIDGE_SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_ZB_GATEWAY, THING_TYPE_BUS_GATEWAY));
+    public static final Set<ThingTypeUID> BRIDGE_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_ZB_GATEWAY,
+            THING_TYPE_BUS_GATEWAY);
 
     public static final Set<ThingTypeUID> ALL_SUPPORTED_THING_TYPES = Stream
             .of(DEVICE_SUPPORTED_THING_TYPES, BRIDGE_SUPPORTED_THING_TYPES).flatMap(Collection::stream)
@@ -106,6 +113,16 @@ public class OpenWebNetBindingConstants {
     // automation
     public static final String CHANNEL_SHUTTER = "shutter";
 
+    // thermo
+    public static final String CHANNEL_TEMPERATURE = "temperature";
+    public static final String CHANNEL_FUNCTION = "function";
+    public static final String CHANNEL_TEMP_SETPOINT = "setpointTemperature";
+    public static final String CHANNEL_MODE = "mode";
+    public static final String CHANNEL_FAN_SPEED = "speedFanCoil";
+    public static final String CHANNEL_CONDITIONING_VALVE = "conditioningValve";
+    public static final String CHANNEL_HEATING_VALVE = "heatingValve";
+    public static final String CHANNEL_ACTUATOR = "actuator";
+
     // energy management
     public static final String CHANNEL_POWER = "power";
 
index 5b0dfb104c635f3ee40a680caaa0753d1e623af3..b73d3e98c7fb67c175c1934780a28ec037254e76 100644 (file)
@@ -53,6 +53,7 @@ import org.openwebnet4j.message.FrameException;
 import org.openwebnet4j.message.GatewayMgmt;
 import org.openwebnet4j.message.Lighting;
 import org.openwebnet4j.message.OpenMessage;
+import org.openwebnet4j.message.Thermoregulation;
 import org.openwebnet4j.message.What;
 import org.openwebnet4j.message.Where;
 import org.openwebnet4j.message.WhereZigBee;
@@ -64,7 +65,8 @@ import org.slf4j.LoggerFactory;
  * The {@link OpenWebNetBridgeHandler} is responsible for handling communication with gateways and handling events.
  *
  * @author Massimo Valla - Initial contribution
- * @author Andrea Conte - Energy management
+ * @author Andrea Conte - Energy management, Thermoregulation
+ * @author Gilberto Cocchi - Thermoregulation
  */
 @NonNullByDefault
 public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implements GatewayListener {
@@ -304,11 +306,9 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
             logger.warn("discoverByActivation: null OpenWebNetDeviceDiscoveryService, ignoring msg={}", baseMsg);
             return;
         }
-        if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement) { // we
-                                                                                                                   // support
-                                                                                                                   // these
-                                                                                                                   // types
-                                                                                                                   // only
+        // we support these types only
+        if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement
+                || baseMsg instanceof Thermoregulation) {
             BaseOpenMessage bmsg = baseMsg;
             if (baseMsg instanceof Lighting) {
                 What what = baseMsg.getWhat();
@@ -418,7 +418,8 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
 
         BaseOpenMessage baseMsg = (BaseOpenMessage) msg;
         // let's try to get the Thing associated with this message...
-        if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement) {
+        if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement
+                || baseMsg instanceof Thermoregulation) {
             String ownId = ownIdFromMessage(baseMsg);
             logger.debug("ownIdFromMessage({}) --> {}", baseMsg, ownId);
             OpenWebNetThingHandler deviceHandler = registeredDevices.get(ownId);
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/handler/OpenWebNetThermoregulationHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/handler/OpenWebNetThermoregulationHandler.java
new file mode 100644 (file)
index 0000000..01a16d3
--- /dev/null
@@ -0,0 +1,337 @@
+/**
+ * Copyright (c) 2010-2021 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.openwebnet.handler;
+
+import static org.openhab.binding.openwebnet.OpenWebNetBindingConstants.*;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.openwebnet.OpenWebNetBindingConstants;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusInfo;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.UnDefType;
+import org.openwebnet4j.communication.OWNException;
+import org.openwebnet4j.message.BaseOpenMessage;
+import org.openwebnet4j.message.FrameException;
+import org.openwebnet4j.message.MalformedFrameException;
+import org.openwebnet4j.message.Thermoregulation;
+import org.openwebnet4j.message.Where;
+import org.openwebnet4j.message.WhereThermo;
+import org.openwebnet4j.message.Who;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link OpenWebNetThermoregulationHandler} is responsible for handling commands/messages for a Thermoregulation
+ * OpenWebNet device. It extends the abstract {@link OpenWebNetThingHandler}.
+ *
+ * @author Massimo Valla - Initial contribution
+ * @author Andrea Conte - Thermoregulation
+ * @author Gilberto Cocchi - Thermoregulation
+ */
+@NonNullByDefault
+public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
+
+    private final Logger logger = LoggerFactory.getLogger(OpenWebNetThermoregulationHandler.class);
+
+    public final static Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.THERMOREGULATION_SUPPORTED_THING_TYPES;
+
+    private boolean isTempSensor = false; // is the device a sensor or thermostat?
+
+    private double currentSetPointTemp = 11.5d; // 11.5 is the default setTemp used in MyHomeUP mobile app
+
+    private Thermoregulation.Function currentFunction = Thermoregulation.Function.GENERIC;
+
+    public OpenWebNetThermoregulationHandler(Thing thing) {
+        super(thing);
+    }
+
+    @Override
+    public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
+        super.bridgeStatusChanged(bridgeStatusInfo);
+        // when the bridge is ONLINE request for thing states (temp, setTemp, fanSpeed...)
+        if (bridgeStatusInfo.getStatus().equals(ThingStatus.ONLINE)) {
+            refreshDevice(false);
+        }
+    }
+
+    @Override
+    protected void handleChannelCommand(ChannelUID channel, Command command) {
+        switch (channel.getId()) {
+            case CHANNEL_TEMP_SETPOINT:
+                handleSetpoint(command);
+                break;
+            case CHANNEL_FUNCTION:
+                handleFunction(command);
+                break;
+            case CHANNEL_MODE:
+                handleMode(command);
+                break;
+            case CHANNEL_FAN_SPEED:
+                handleSetFanSpeed(command);
+                break;
+            default: {
+                logger.warn("handleChannelCommand() Unsupported ChannelUID {}", channel.getId());
+            }
+        }
+    }
+
+    @Override
+    protected void requestChannelState(ChannelUID channel) {
+        refreshDevice(false);
+    }
+
+    @Override
+    protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
+        WhereThermo wt = new WhereThermo(wStr);
+        if (wt.isProbe()) {
+            isTempSensor = true;
+        }
+        return wt;
+    }
+
+    @Override
+    protected String ownIdPrefix() {
+        return Who.THERMOREGULATION.value().toString();
+    }
+
+    private void handleSetFanSpeed(Command command) {
+        if (command instanceof StringType) {
+            Where w = deviceWhere;
+            if (w != null) {
+                try {
+                    Thermoregulation.FanCoilSpeed speed = Thermoregulation.FanCoilSpeed.valueOf(command.toString());
+                    send(Thermoregulation.requestWriteFanCoilSpeed(w.value(), speed));
+                } catch (OWNException e) {
+                    logger.warn("handleSetFanSpeed() {}", e.getMessage());
+                } catch (IllegalArgumentException e) {
+                    logger.warn("handleSetFanSpeed() Unsupported command {} for thing {}", command,
+                            getThing().getUID());
+                    return;
+                }
+            }
+        } else {
+            logger.warn("handleSetFanSpeed() Unsupported command {} for thing {}", command, getThing().getUID());
+        }
+    }
+
+    private void handleSetpoint(Command command) {
+        if (command instanceof QuantityType || command instanceof DecimalType) {
+            Where w = deviceWhere;
+            if (w != null) {
+                double newTemp = 0;
+                if (command instanceof QuantityType) {
+                    QuantityType<?> tempCelsius = ((QuantityType<?>) command).toUnit(SIUnits.CELSIUS);
+                    if (tempCelsius != null) {
+                        newTemp = tempCelsius.doubleValue();
+                    }
+                } else {
+                    newTemp = ((DecimalType) command).doubleValue();
+                }
+                try {
+                    send(Thermoregulation.requestWriteSetpointTemperature(w.value(), newTemp, currentFunction));
+                } catch (MalformedFrameException | OWNException e) {
+                    logger.warn("handleSetpoint() {}", e.getMessage());
+                }
+            }
+        } else {
+            logger.warn("handleSetpoint() Unsupported command {} for thing {}", command, getThing().getUID());
+        }
+    }
+
+    private void handleMode(Command command) {
+        if (command instanceof StringType) {
+            Where w = deviceWhere;
+            if (w != null) {
+                try {
+                    Thermoregulation.OperationMode mode = Thermoregulation.OperationMode.valueOf(command.toString());
+                    send(Thermoregulation.requestWriteMode(w.value(), mode, currentFunction, currentSetPointTemp));
+                } catch (OWNException e) {
+                    logger.warn("handleMode() {}", e.getMessage());
+                } catch (IllegalArgumentException e) {
+                    logger.warn("handleMode() Unsupported command {} for thing {}", command, getThing().getUID());
+                    return;
+                }
+            }
+        } else {
+            logger.warn("handleMode() Unsupported command {} for thing {}", command, getThing().getUID());
+        }
+    }
+
+    private void handleFunction(Command command) {
+        if (command instanceof StringType) {
+            Where w = deviceWhere;
+            if (w != null) {
+                try {
+                    Thermoregulation.Function function = Thermoregulation.Function.valueOf(command.toString());
+                    send(Thermoregulation.requestWriteFunction(w.value(), function));
+                } catch (OWNException e) {
+                    logger.warn("handleFunction() {}", e.getMessage());
+                } catch (IllegalArgumentException e) {
+                    logger.warn("handleFunction() Unsupported command {} for thing {}", command, getThing().getUID());
+                    return;
+                }
+            }
+        } else {
+            logger.warn("handleFunction() Unsupported command {} for thing {}", command, getThing().getUID());
+        }
+    }
+
+    @Override
+    protected void handleMessage(BaseOpenMessage msg) {
+        super.handleMessage(msg);
+        if (msg.isCommand()) {
+            updateModeAndFunction((Thermoregulation) msg);
+        } else {
+            if (msg.getDim() == null) {
+                return;
+            }
+            if (msg.getDim() == Thermoregulation.DimThermo.TEMPERATURE
+                    || msg.getDim() == Thermoregulation.DimThermo.PROBE_TEMPERATURE) {
+                updateTemperature((Thermoregulation) msg);
+            } else if (msg.getDim() == Thermoregulation.DimThermo.TEMP_SETPOINT
+                    || msg.getDim() == Thermoregulation.DimThermo.COMPLETE_PROBE_STATUS) {
+                updateSetpoint((Thermoregulation) msg);
+            } else if (msg.getDim() == Thermoregulation.DimThermo.VALVES_STATUS) {
+                updateValveStatus((Thermoregulation) msg);
+            } else if (msg.getDim() == Thermoregulation.DimThermo.ACTUATOR_STATUS) {
+                updateActuatorStatus((Thermoregulation) msg);
+            } else if (msg.getDim() == Thermoregulation.DimThermo.FAN_COIL_SPEED) {
+                updateFanCoilSpeed((Thermoregulation) msg);
+            } else {
+                logger.debug("handleMessage() Ignoring unsupported DIM {} for thing {}. Frame={}", msg.getDim(),
+                        getThing().getUID(), msg);
+            }
+        }
+    }
+
+    private void updateModeAndFunction(Thermoregulation tmsg) {
+        if (tmsg.getWhat() == null) {
+            logger.debug("updateModeAndFunction() Could not parse Mode or Function from {} (what is null)",
+                    tmsg.getFrameValue());
+            return;
+        }
+
+        Thermoregulation.WhatThermo w = Thermoregulation.WhatThermo.fromValue(tmsg.getWhat().value());
+
+        if (w.mode() == null) {
+            logger.debug("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue());
+            return;
+        }
+        if (w.function() == null) {
+            logger.debug("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue());
+            return;
+        }
+
+        Thermoregulation.OperationMode mode = w.mode();
+        Thermoregulation.Function function = w.function();
+
+        if (w == Thermoregulation.WhatThermo.HEATING) {
+            function = Thermoregulation.Function.HEATING;
+        } else if (w == Thermoregulation.WhatThermo.CONDITIONING) {
+            function = Thermoregulation.Function.COOLING;
+        }
+
+        updateState(CHANNEL_MODE, new StringType(mode.toString()));
+        updateState(CHANNEL_FUNCTION, new StringType(function.toString()));
+
+        // store current function
+        currentFunction = function;
+    }
+
+    private void updateTemperature(Thermoregulation tmsg) {
+        try {
+            double temp = Thermoregulation.parseTemperature(tmsg);
+            updateState(CHANNEL_TEMPERATURE, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS));
+        } catch (FrameException e) {
+            logger.warn("updateTemperature() FrameException on frame {}: {}", tmsg, e.getMessage());
+            updateState(CHANNEL_TEMPERATURE, UnDefType.UNDEF);
+        }
+    }
+
+    private void updateSetpoint(Thermoregulation tmsg) {
+        try {
+            double temp = Thermoregulation.parseTemperature(tmsg);
+            updateState(CHANNEL_TEMP_SETPOINT, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS));
+            currentSetPointTemp = temp;
+        } catch (FrameException e) {
+            logger.warn("updateSetpoint() FrameException on frame {}: {}", tmsg, e.getMessage());
+            updateState(CHANNEL_TEMP_SETPOINT, UnDefType.UNDEF);
+        }
+    }
+
+    private void updateFanCoilSpeed(Thermoregulation tmsg) {
+        try {
+            Thermoregulation.FanCoilSpeed speed = Thermoregulation.parseFanCoilSpeed(tmsg);
+            updateState(CHANNEL_FAN_SPEED, new StringType(speed.toString()));
+        } catch (FrameException e) {
+            logger.warn("updateFanCoilSpeed() FrameException on frame {}: {}", tmsg, e.getMessage());
+            updateState(CHANNEL_FAN_SPEED, UnDefType.UNDEF);
+        }
+    }
+
+    private void updateValveStatus(Thermoregulation tmsg) {
+        try {
+            Thermoregulation.ValveOrActuatorStatus cv = Thermoregulation.parseValveStatus(tmsg,
+                    Thermoregulation.WhatThermo.CONDITIONING);
+            updateState(CHANNEL_CONDITIONING_VALVE, new StringType(cv.toString()));
+
+            Thermoregulation.ValveOrActuatorStatus hv = Thermoregulation.parseValveStatus(tmsg,
+                    Thermoregulation.WhatThermo.HEATING);
+            updateState(CHANNEL_HEATING_VALVE, new StringType(hv.toString()));
+        } catch (FrameException e) {
+            logger.warn("updateValveStatus() FrameException on frame {}: {}", tmsg, e.getMessage());
+            updateState(CHANNEL_CONDITIONING_VALVE, UnDefType.UNDEF);
+            updateState(CHANNEL_HEATING_VALVE, UnDefType.UNDEF);
+        }
+    }
+
+    private void updateActuatorStatus(Thermoregulation tmsg) {
+        try {
+            Thermoregulation.ValveOrActuatorStatus hv = Thermoregulation.parseActuatorStatus(tmsg);
+            updateState(CHANNEL_ACTUATOR, new StringType(hv.toString()));
+        } catch (FrameException e) {
+            logger.warn("updateActuatorStatus() FrameException on frame {}: {}", tmsg, e.getMessage());
+            updateState(CHANNEL_ACTUATOR, UnDefType.UNDEF);
+        }
+    }
+
+    @Override
+    protected void refreshDevice(boolean refreshAll) {
+        if (deviceWhere != null) {
+            String w = deviceWhere.value();
+            try {
+                send(Thermoregulation.requestTemperature(w));
+                if (!this.isTempSensor) {
+                    // for bus_thermostat request also other single channels updates
+                    send(Thermoregulation.requestSetPointTemperature(w));
+                    send(Thermoregulation.requestFanCoilSpeed(w));
+                    send(Thermoregulation.requestMode(w));
+                    send(Thermoregulation.requestValveStatus(w));
+                    send(Thermoregulation.requestActuatorStatus(w));
+                }
+            } catch (OWNException e) {
+                logger.warn("refreshDevice() where='{}' returned OWNException {}", w, e.getMessage());
+            }
+        }
+    }
+}
index 03d94a71db48e76b7ae7f4f6c0aa72d88c9c8689..1ff15ef96cc6c8f1ccc7d7a8b11b87e09c2da840 100644 (file)
@@ -18,8 +18,12 @@ import java.util.Map;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+import javax.measure.Quantity;
+import javax.measure.Unit;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.library.types.QuantityType;
 import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
@@ -28,6 +32,8 @@ import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.binding.BaseThingHandler;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
 import org.openwebnet4j.OpenGateway;
 import org.openwebnet4j.communication.OWNException;
 import org.openwebnet4j.communication.Response;
@@ -221,6 +227,17 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
         super.dispose();
     }
 
+    /**
+     * Helper method to return a Quantity from a Number value or UnDefType.NULL if value is null
+     *
+     * @param value to be used
+     * @param unit to be used
+     * @return Quantity
+     */
+    protected <U extends Quantity<U>> State getAsQuantityTypeOrNull(@Nullable Number value, Unit<U> unit) {
+        return value == null ? UnDefType.NULL : new QuantityType<>(value, unit);
+    }
+
     /**
      * Returns a prefix String for ownId specific for each handler. To be implemented by sub-classes.
      *
index 8e1058f6a130415a1fde5cda860e93e09fd60a41..0d4205d36c7f7b6ce6b34f1b26836256d8361742 100644 (file)
@@ -21,6 +21,7 @@ import org.openhab.binding.openwebnet.handler.OpenWebNetBridgeHandler;
 import org.openhab.binding.openwebnet.handler.OpenWebNetEnergyHandler;
 import org.openhab.binding.openwebnet.handler.OpenWebNetGenericHandler;
 import org.openhab.binding.openwebnet.handler.OpenWebNetLightingHandler;
+import org.openhab.binding.openwebnet.handler.OpenWebNetThermoregulationHandler;
 import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingTypeUID;
@@ -35,7 +36,8 @@ import org.slf4j.LoggerFactory;
  * The {@link OpenWebNetHandlerFactory} is responsible for creating thing handlers.
  *
  * @author Massimo Valla - Initial contribution
- * @author Andrea Conte - Energy management
+ * @author Andrea Conte - Energy management, Thermoregulation
+ * @author Gilberto Cocchi - Thermoregulation
  */
 @NonNullByDefault
 @Component(configurationPid = "binding.openwebnet", service = ThingHandlerFactory.class)
@@ -65,6 +67,9 @@ public class OpenWebNetHandlerFactory extends BaseThingHandlerFactory {
         } else if (OpenWebNetEnergyHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
             logger.debug("creating NEW ENERGY Handler");
             return new OpenWebNetEnergyHandler(thing);
+        } else if (OpenWebNetThermoregulationHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
+            logger.debug("creating NEW THERMO Handler");
+            return new OpenWebNetThermoregulationHandler(thing);
         }
         logger.warn("ThingType {} is not supported by this binding", thing.getThingTypeUID());
         return null;
index 1dc4420c4f783595d7935a2ff8f533a3decf1100..df53544edbbe3911b08ff78bda6908b1dad93afc 100644 (file)
@@ -41,7 +41,8 @@ import org.slf4j.LoggerFactory;
  * bridge/gateway
  *
  * @author Massimo Valla - Initial contribution
- * @author Andrea Conte - Energy management
+ * @author Andrea Conte - Energy management, Thermoregulation
+ * @author Gilberto Cocchi - Thermoregulation
  */
 @NonNullByDefault
 public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
@@ -130,14 +131,28 @@ public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
                 deviceWho = Who.AUTOMATION;
                 break;
             }
-
+            case SCS_TEMP_SENSOR: {
+                thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_TEMP_SENSOR;
+                thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_TEMP_SENSOR;
+                deviceWho = Who.THERMOREGULATION;
+                break;
+            }
+            case SCS_THERMOSTAT: {
+                thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_THERMOSTAT;
+                thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_THERMOSTAT;
+                deviceWho = Who.THERMOREGULATION;
+                break;
+            }
+            case SCS_THERMO_CENTRAL_UNIT: {
+                logger.warn("newDiscoveryResult() deviceType={} is not supported yet (WHERE={})", deviceType, where);
+                break;
+            }
             case SCS_ENERGY_METER: {
                 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_ENERGY_METER;
                 thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_ENERGY_METER;
                 deviceWho = Who.ENERGY_MANAGEMENT;
                 break;
             }
-
             default:
                 logger.warn("Device type {} is not supported, default to GENERIC device (WHERE={})", deviceType, where);
                 if (where instanceof WhereZigBee) {
@@ -161,7 +176,7 @@ public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
 
         DiscoveryResult discoveryResult = null;
 
-        String whereConfig = where.value();
+        String whereConfig = bridgeHandler.normalizeWhere(where);
         if (where instanceof WhereZigBee && WhereZigBee.UNIT_02.equals(((WhereZigBee) where).getUnit())) {
             logger.debug("UNIT=02 found (WHERE={}) -> will remove previous result if exists", where);
             thingRemoved(thingUID); // remove previously discovered thing
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusTempSensor.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusTempSensor.xml
new file mode 100644 (file)
index 0000000..2770dc0
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="openwebnet"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <!-- Thing for BUS Temperature Sensor -->
+       <thing-type id="bus_temp_sensor">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bus_gateway"/>
+               </supported-bridge-type-refs>
+               <label>Temperature Sensor</label>
+               <description>A OpenWebNet BUS/SCS temperature sensor. BTicino models: L/N/NT4577 etc.</description>
+
+               <channels>
+                       <channel id="temperature" typeId="temperature"/>
+               </channels>
+
+               <properties>
+                       <property name="vendor">BTicino/Legrand</property>
+                       <property name="model">BTI-L/N/NT4577 etc.</property>
+                       <property name="ownDeviceType">---</property>
+               </properties>
+
+               <representation-property>ownId</representation-property>
+
+               <config-description>
+                       <parameter name="where" type="text" required="true">
+                               <label>OpenWebNet Device Address</label>
+                               <description>Example: Zone 2 --> where=2. For external sensors: sensor 5 --> where=500</description>
+                       </parameter>
+               </config-description>
+
+       </thing-type>
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermostat.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermostat.xml
new file mode 100644 (file)
index 0000000..0b90519
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="openwebnet"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <!-- Thing for BUS Thermostat (BTicino xxx/xxx/...) -->
+       <thing-type id="bus_thermostat">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bus_gateway"/>
+               </supported-bridge-type-refs>
+
+               <label>Thermostat (stand-alone)</label>
+               <description>A OpenWebNet BUS/SCS zone stand-alone thermostat. BTicino models: LN4691.</description>
+
+               <channels>
+                       <!-- read only -->
+                       <channel id="temperature" typeId="temperature"/>
+                       <channel id="conditioningValve" typeId="conditioningValve"/>
+                       <channel id="heatingValve" typeId="heatingValve"/>
+                       <channel id="actuator" typeId="actuator"/>
+                       <!-- read/write -->
+                       <channel id="setpointTemperature" typeId="setpointTemperature"/>
+                       <channel id="function" typeId="function"/>
+                       <channel id="mode" typeId="mode"/>
+                       <channel id="speedFanCoil" typeId="speedFanCoil"/>
+               </channels>
+
+               <properties>
+                       <property name="vendor">BTicino/Legrand</property>
+                       <property name="model">BTI-LN4691</property>
+                       <property name="ownDeviceType">410/420/430</property>
+               </properties>
+
+               <representation-property>ownId</representation-property>
+
+               <config-description>
+                       <parameter name="where" type="text" required="true">
+                               <label>OpenWebNet Device Address</label>
+                               <description>Example: Zone 2 --> where=2.</description>
+                       </parameter>
+               </config-description>
+
+       </thing-type>
+</thing:thing-descriptions>
index 612739564ed0a234aa1801d202aa232383a9beec..fa04e3d36c036babb924afdad8c0d3fbc1ac7283 100644 (file)
@@ -29,7 +29,7 @@
        <!-- Shutter Channel -->
        <channel-type id="shutter">
                <item-type>Rollershutter</item-type>
-               <label>Roller shutter</label>
+               <label>Roller Shutter</label>
                <description>Control the roller shutter position</description>
                <category>Blinds</category>
                <tags>
                </tags>
        </channel-type>
 
+       <!-- Thermo channels -->
+       <channel-type id="temperature">
+               <item-type>Number:Temperature</item-type>
+               <label>Temperature</label>
+               <description>Current temperature (read only)</description>
+               <category>Temperature</category>
+               <tags>
+                       <tag>CurrentTemperature</tag>
+               </tags>
+               <state readOnly="true" pattern="%.1f %unit%"/>
+       </channel-type>
+
+       <channel-type id="function">
+               <item-type>String</item-type>
+               <label>Thermo Function</label>
+               <description>Thermo function of the thermostat (read/write)</description>
+               <state>
+                       <options>
+                               <option value="HEATING">Heating</option>
+                               <option value="COOLING">Cooling</option>
+                               <option value="GENERIC">Generic</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="setpointTemperature">
+               <item-type>Number:Temperature</item-type>
+               <label>Setpoint Temperature</label>
+               <description>Setpoint temperature (read/write)</description>
+               <category>Temperature</category>
+               <tags>
+                       <tag>TargetTemperature</tag>
+               </tags>
+               <state pattern="%.1f %unit%" step="0.5"/>
+       </channel-type>
+
+       <channel-type id="mode">
+               <item-type>String</item-type>
+               <label>Mode</label>
+               <description>Set mode of the thermostat (read/write)</description>
+               <state>
+                       <options>
+                               <option value="MANUAL">Manual</option>
+                               <option value="PROTECTION">Protection</option>
+                               <option value="OFF">Off</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="speedFanCoil">
+               <item-type>String</item-type>
+               <label>Set Fan Speed</label>
+               <description>Set speed of the Fan Coil (read/write)</description>
+               <state>
+                       <options>
+                               <option value="AUTO">Auto</option>
+                               <option value="SPEED_1">Fan speed 1</option>
+                               <option value="SPEED_2">Fan speed 2</option>
+                               <option value="SPEED_3">Fan speed 3</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="conditioningValve" advanced="true">
+               <item-type>String</item-type>
+               <label>Conditioning Valve</label>
+               <description>Conditioning Valve status (read only)</description>
+               <state readOnly="true">
+                       <options>
+                               <option value="OFF">OFF</option>
+                               <option value="ON">ON</option>
+                               <option value="OPENED">Opened</option>
+                               <option value="CLOSED">Closed</option>
+                               <option value="STOP">Stop</option>
+                               <option value="OFF_FAN_COIL">OFF Fan Coil</option>
+                               <option value="ON_SPEED_1">ON speed 1</option>
+                               <option value="ON_SPEED_2">ON speed 2</option>
+                               <option value="ON_SPEED_3">ON speed 3</option>
+                               <option value="OFF_SPEED_1">OFF speed 1</option>
+                               <option value="OFF_SPEED_2">OFF speed 2</option>
+                               <option value="OFF_SPEED_3">OFF speed 3</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="heatingValve" advanced="true">
+               <item-type>String</item-type>
+               <label>Heating Valve</label>
+               <description>Heating Valve status (read only)</description>
+               <state readOnly="true">
+                       <options>
+                               <option value="OFF">OFF</option>
+                               <option value="ON">ON</option>
+                               <option value="OPENED">Opened</option>
+                               <option value="CLOSED">Closed</option>
+                               <option value="STOP">Stop</option>
+                               <option value="OFF_FAN_COIL">OFF Fan Coil</option>
+                               <option value="ON_SPEED_1">ON speed 1</option>
+                               <option value="ON_SPEED_2">ON speed 2</option>
+                               <option value="ON_SPEED_3">ON speed 3</option>
+                               <option value="OFF_SPEED_1">OFF speed 1</option>
+                               <option value="OFF_SPEED_2">OFF speed 2</option>
+                               <option value="OFF_SPEED_3">OFF speed 3</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="actuator" advanced="true">
+               <item-type>String</item-type>
+               <label>Actuator Status</label>
+               <description>Actuator status (read only)</description>
+               <state readOnly="true">
+                       <options>
+                               <option value="OFF">OFF</option>
+                               <option value="ON">ON</option>
+                               <option value="OPENED">Opened</option>
+                               <option value="CLOSED">Closed</option>
+                               <option value="STOP">Stop</option>
+                               <option value="OFF_FAN_COIL">OFF Fan Coil</option>
+                               <option value="ON_SPEED_1">ON speed 1</option>
+                               <option value="ON_SPEED_2">ON speed 2</option>
+                               <option value="ON_SPEED_3">ON speed 3</option>
+                               <option value="OFF_SPEED_1">OFF speed 1</option>
+                               <option value="OFF_SPEED_2">OFF speed 2</option>
+                               <option value="OFF_SPEED_3">OFF speed 3</option>
+                       </options>
+               </state>
+       </channel-type>
+
        <!-- Energy channels -->
        <channel-type id="power">
                <item-type>Number:Power</item-type>
index 992e6f10c2c9476d83e82c1e662d9ec6cdf8c00b..ce8910e12da43e9a2cfab313d30bfa42799110cd 100644 (file)
@@ -24,6 +24,7 @@ import org.openwebnet4j.message.FrameException;
 import org.openwebnet4j.message.Where;
 import org.openwebnet4j.message.WhereEnergyManagement;
 import org.openwebnet4j.message.WhereLightAutom;
+import org.openwebnet4j.message.WhereThermo;
 import org.openwebnet4j.message.WhereZigBee;
 import org.openwebnet4j.message.Who;
 import org.slf4j.Logger;
@@ -55,11 +56,12 @@ public class OwnIdTest {
      * BUS Local Bus        25#4#01         25h4h01             1.25h4h01       25h4h01
      * BUS Autom            93              93                  2.93            93
      * BUS Thermo           #1 or 1         1                   4.1             1
+     * BUS Thermo actuator  1#2             1                   4.1             1
      * BUS TempSensor       500             500                 4.500           500
      * BUS Energy           51              51                  18.51           51
-     * BUS CEN              51              51                  15.51           51
-     * BUS CEN+             212             212                 25.212          212
-     * BUS DryContact       399             399                 25.399          399
+     * -INACTIVE- BUS CEN              51              51                  15.51           51
+     * -INACTIVE- BUS CEN+             212             212                 25.212          212
+     * -INACTIVE- BUS DryContact       399             399                 25.399          399
      *
      */
 // @formatter:on
@@ -71,10 +73,11 @@ public class OwnIdTest {
         zb_switch_2u_2(new WhereZigBee("789301202#9"), Who.fromValue(1), "*1*1*789301202#9##", "789301200h9", "1.789301200h9", "789301200h9"),
         bus_switch(new WhereLightAutom("51"), Who.fromValue(1), "*1*1*51##", "51", "1.51", "51"),
         bus_localbus(new WhereLightAutom("25#4#01"), Who.fromValue(1), "*1*1*25#4#01##", "25h4h01", "1.25h4h01", "25h4h01"),
-        //bus_thermo_zone(new WhereThermo("1"), Who.fromValue(4),"*#4*1*0*0020##" , "1", "4.1", "1"),
-        //bus_thermo_zone_act(new WhereThermo("2#1"), Who.fromValue(4),"*#4*2#1*20*0##" ,"2", "4.2", "2"),
-        //bus_thermo_via_cu(new WhereThermo("#1"), Who.fromValue(4),"*#4*#1*0*0020##" ,"1", "4.1", "1"),
-        // bus_tempSensor("500", "4", "500", "4.500", "500"),
+        bus_autom(new WhereLightAutom("93"), Who.fromValue(2), "*2*0*93##", "93", "2.93", "93"),
+        bus_thermo_via_cu(new WhereThermo("#1"), Who.fromValue(4),"*#4*#1*0*0020##" ,"1", "4.1", "1"),
+        bus_thermo(new WhereThermo("1"), Who.fromValue(4),"*#4*1*0*0020##" , "1", "4.1", "1"),
+        bus_thermo_act(new WhereThermo("1#2"), Who.fromValue(4),"*#4*1#2*20*0##" ,"1", "4.1", "1"),
+        bus_tempSensor(new WhereThermo("500"), Who.fromValue(4), "*#4*500*15*1*0020*0001##", "500", "4.500", "500"),
         bus_energy(new WhereEnergyManagement("51"), Who.fromValue(18), "*#18*51*113##", "51", "18.51", "51");
 
         // @formatter:on