From 2a7391bc4b19ac183d4b8ac351f2218b3be22e0e Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Fri, 1 Nov 2024 22:01:55 +0100 Subject: [PATCH 1/5] [ism8] Add channel types for heat pumps Extend add-on to support new information provided by lates ISM firmware versions 1.80 and 1.90. * Add channel type power-r used by CHA device * Add channel type activeenergy-r used by solar module * Add channel type value1ucount-r and value2ucount-r used for device information * Extend channel type volumetricflow-r to data type used by solar module * i18n * Rework documentation Signed-off-by: Holger Friedrich --- bundles/org.openhab.binding.ism8/README.md | 88 ++++++----- .../binding/ism8/server/DataPointFactory.java | 9 ++ .../ism8/server/DataPointIntegerValue.java | 69 +++++++++ .../ism8/server/DataPointLongValue.java | 8 + .../binding/ism8/server/DataPointValue.java | 8 + .../resources/OH-INF/i18n/ism8.properties | 138 +++++++++++++----- .../resources/OH-INF/thing/thing-types.xml | 76 ++++++++++ 7 files changed, 317 insertions(+), 79 deletions(-) create mode 100644 bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointIntegerValue.java diff --git a/bundles/org.openhab.binding.ism8/README.md b/bundles/org.openhab.binding.ism8/README.md index 1d6eb60393b91..d62dadac2910c 100644 --- a/bundles/org.openhab.binding.ism8/README.md +++ b/bundles/org.openhab.binding.ism8/README.md @@ -1,18 +1,21 @@ # Ism8 Binding -_This binding can receive values of the Wolf heating system._ +_This binding can receive measurements from a Wolf heating system._ The ISM8 card can be placed into the Wolf heating system. -The card is usually used in combination with an object server, where the object server does forward those messages into the KNX bus system. -In case there is no need to handle the heating system values directly in the KNX system you can use this binding to monitor and control your heating system without the need to buy an object server. -The system works in a way that the ISM8 connects to a partner and sends from time to time an update. The frequency depends on the change of the values. +The card is usually used in combination with an object server, where the object server forwards those messages into the KNX bus system. +If there is no need to handle the heating system values directly in the KNX system, you can use this binding to monitor and control your heating system without the need to buy an object server. +The system works in such a way that the ISM8 connects to a partner and sends, from time to time, an update. The frequency depends on the change in values. This binding is listening to those messages. -After the first connection there is an active command send to the ISM8 in order to receive all available data points. -The manual of the ISM8 can be downloaded from the supplier () +After the first connection, there is an active command sent to the ISM8 in order to receive all available data points. +The manual for the ISM8 can be downloaded here: () + +Note that there are different firmware versions of the ISM8 module. +Some data points are not available with older firmware versions. ## Supported Things -_This binding does only support one Thing - the Ism8-Device._ +_This binding does only support one Thing - the ISM8-Device._ ## Discovery @@ -20,18 +23,19 @@ _Auto-discovery is not supported._ ## Thing Configuration -The intention was to have a generic ISM8 binding in order to offer the full flexibilty for the different heating systems. -For this reason you need to create a Thing configuration, where basically only the port is required next to the channel configuration. +The intention was to have a generic ISM8 binding in order to offer full flexibility for the different heating systems. +For this reason, you need to create a Thing configuration, where basically only the port is required next to the channel configuration. (`Thing ism8:device:heater "Wolf Heizung" [portNumber=12004]`) + ## Channels -You can use any channel supported by the ISM8 as data point. Please have a look at the official manual from Wolf. -Within this document you'll find a table containing all supported data points. -The available data points are depending on your heating system configuration. -The ISM8 does currently support 4 different devices at the same moment of time (e.g. CGB-2, CWL Excellent, Solar, ...). +You can use any channel supported by the ISM8 as a data point. Please take a look at the official manual from Wolf. +Within this document, you'll find a table containing all supported data points. +Depending on your heating system configuration, different data points are available. +The ISM8 does currently support 4 different devices at the same moment of time (e.g., CHA, CGB-2, CWL Excellent, Solar, etc.). -Once you have an overview of your heating system set you can start to create the channels accordingly. +Once you have an overview of your heating system, you can start to create the channels accordingly. Each channel should be created in the following way: | Type | Name | Description | Configuration | @@ -49,28 +53,34 @@ Description: Configuration: - id=1 - Please enter here the ID of the data point you'd like to map to this channel. -A list of the available IDs are available within the Wolf manual. -The supported IDs are depending on the firmware version of the ISM8 and the connected systems. -- type="1.001" - Please enter here the knx type of the data point. +A list of the available IDs is available within the Wolf manual. + +Depending on the firmware version of the ISM8 and the connected systems, the supported IDs differ. +- type="1.001" - Please enter here the KNX type of the data point. You can find the data type in the Wolf ISM8 document as well. - write=true - This parameter defines if the channel is bidirectional, but the parameter is optional and by default false. -Note: -Not all available types of the ISM8 interface are fully supported, but this can be extended. -For the moment the following data types are implemented: - -| Channel type | Datapoint type | Item type | R/W | KNX-type's | -|----------------|--------------------------------|---------------------------|-----|----------------------------| -| switch-rw | Digital DataPoint | Switch | R/W | 1.001, 1.002, 1.003, 1.009 | -| switch-r | Digital Readonly DataPoint | Switch | R | 1.001, 1.002, 1.003, 1.009 | -| percentage-rw | Percentage DataPoint | Number:Dimensionless | R/W | 5.001 | -| percentage-r | Percentage Readonly DataPoint | Number:Dimensionless | R | 5.001 | -| temperature-rw | Temperature DataPoint | Number:Temperature | R/W | 9.001,9.002 | -| temperature-r | Temperature Readonly DataPoint | Number:Temperature | R | 9.002,9.002 | -| pressure-r | Pressure Readonly DataPoint | Number:Pressure | R | 9.006 | -| flowrate-r | Flowrate Readonly DataPoint | Number:VolumetricFlowRate | R | 13.002 | -| mode-rw | Mode DataPoint | Number:Dimensionless | R/W | 20.102, 20.103, 20.105 | -| mode-r | Mode Readonly DataPoint | Number:Dimensionless | R | 20.102, 20.103, 20.105 | +> Note: +Not all available data types of the ISM8 interface are fully supported. +For the moment, the following data types are implemented: + +| Channel type | Datapoint type | Item type | R/W | KNX-type's | +|----------------|------------------------------------------|---------------------------|-----|----------------------------| +| switch-rw | Digital DataPoint | Switch | R/W | 1.001, 1.002, 1.003, 1.009 | +| switch-r | Digital Readonly DataPoint | Switch | R | 1.001, 1.002, 1.003, 1.009 | +| percentage-rw | Percentage DataPoint | Number:Dimensionless | R/W | 5.001 | +| percentage-r | Percentage Readonly DataPoint | Number:Dimensionless | R | 5.001 | +| value1ucount-r | Value 2-byte Unsigned Readonly DataPoint | Number:Dimensionless | R | 5.010 | +| value2ucount-r | Value 2-byte Unsigned Readonly DataPoint | Number:Dimensionless | R | 7.001 | +| temperature-rw | Temperature DataPoint | Number:Temperature | R/W | 9.001,9.002 | +| temperature-r | Temperature Readonly DataPoint | Number:Temperature | R | 9.002,9.002 | +| pressure-r | Pressure Readonly DataPoint | Number:Pressure | R | 9.006 | +| flowrate-r | Flowrate Readonly DataPoint | Number:VolumetricFlowRate | R | 9.025, 13.002 | +| activeenergy-r | Active Energy Readonly DataPoint | Number:Energy | R | 13.010, 13.013 | +| mode-rw | Mode DataPoint | Number:Dimensionless | R/W | 20.102, 20.103, 20.105 | +| mode-r | Mode Readonly DataPoint | Number:Dimensionless | R | 20.102, 20.103, 20.105 | + +Date and Time types used by for CWL Excellent and CWL2 are currently not supported by the ISM8 add-on. ## Full Example @@ -80,28 +90,28 @@ For the moment the following data types are implemented: Thing ism8:device:heater "Wolf Heizung" [portNumber=12004] { Type switch-r : DpId001 "Störung Heizgerät" [id=1, type="1.001"] - Type number-r : DpId002 "Betriebsart" [id=2, type="20.105"] + Type mode-r : DpId002 "Betriebsart" [id=2, type="20.105"] Type percentage-r : DpId003 "Brennerleistung" [id=3, type="5.001"] Type temperature-r : DpId004 "Kesseltemperatur" [id=4, type="9.001"] Type temperature-r : DpId006 "Rücklauftemperatur" [id=6, type="9.001"] Type temperature-r : DpId007 "Warmwassertemperatur" [id=7, type="9.001"] Type temperature-r : DpId008 "Außentemperatur" [id=8, type="9.001"] Type switch-r : DpId009 "Status Flamme" [id=9, type="1.001"] - Type temperature-r : DpId013 "Anlagendruck" [id=13, type="9.006"] + Type pressure-r : DpId013 "Anlagendruck" [id=13, type="9.006"] Type switch-r : DpId053 "Störung Systemmodul" [id=53, type="1.001"] Type temperature-r : DpId054 "Außentemperatur Systemmodul" [id=54, type="9.001"] Type temperature-rw : DpId056 "Sollwert Warmwasser" [id=56, type="9.001"] Type mode-rw : DpId057 "Betriebsart Heizkreis" [id=57, type="20.102"] Type mode-rw : DpId058 "Betriebsart Warmwasser" [id=58, type="20.103"] Type temperature-rw : DpId065 "Sollwertverschiebung" [id=65, type="9.002"] - Type switch-rw : DpId148 "CML Störung" [id=148, type="1.001"] + Type switch-rw : DpId148 "CWL Störung" [id=148, type="1.001"] Type mode-rw : DpId149 "CWL Betriebsart" [id=149, type="20.102"] Type percentage-r : DpId163 "CWL Lüftungsstufe" [id=163, type="5.001"] Type temperature-r : DpId164 "CWL Ablufttemperatur" [id=164, type="9.001"] Type temperature-r : DpId165 "CWL Zulufttemperatur" [id=165, type="9.001"] Type flowrate-r : DpId166 "CWL Luftdurchsatz Zuluft" [id=166, type="13.002"] Type flowrate-r : DpId167 "CWL Luftdurchsatz Abluft" [id=167, type="13.002"] - Type switch-r : DpId192 "CML Filterwarnung" [id=192, type="1.001"] + Type switch-r : DpId192 "CWL Filterwarnung" [id=192, type="1.001"] } ``` @@ -123,14 +133,14 @@ Number ISM_HeizungSollwertWarmwasser "Sollwert Warmwasser [%.1f °C]" Number ISM_HeizungBetriebsartHeizkreis "Betriebsart Heizkreis" { channel="ism8:device:heater:DpId057" } Number ISM_HeizungBetriebsartWarmwasser "Betriebsart Warmwasser" { channel="ism8:device:heater:DpId058" } Number ISM_HeizungSollwertverschiebung "Sollwertverschiebung [%.1f °C]" { channel="ism8:device:heater:DpId065" } -Switch ISM_LueftungStoerung "CML Störung" { channel="ism8:device:heater:DpId148" } +Switch ISM_LueftungStoerung "CWL Störung" { channel="ism8:device:heater:DpId148" } Number ISM_LueftungBetriebsart "CWL Betriebsart" { channel="ism8:device:heater:DpId149" } Number ISM_LueftungLueftungsstufe "CWL Lüftungsstufe [%.1f %%]" { channel="ism8:device:heater:DpId163" } Number ISM_LueftungAblufttemperatur "CWL Ablufttemperatur [%.1f °C]" { channel="ism8:device:heater:DpId164" } Number ISM_LueftungZulufttemperatur "CWL Zulufttemperatur [%.1f °C]" { channel="ism8:device:heater:DpId165" } Number ISM_LueftungLuftdurchsatzZuluft "CWL Luftdurchsatz Zuluft [%.1f m³/h]" { channel="ism8:device:heater:DpId166" } Number ISM_LueftungLuftdurchsatzAbluft "CWL Luftdurchsatz Abluft [%.1f m³/h]" { channel="ism8:device:heater:DpId167" } -Switch ISM_LueftungFilterwarnung "CML Filterwarnung" { channel="ism8:device:heater:DpId192" } +Switch ISM_LueftungFilterwarnung "CWL Filterwarnung" { channel="ism8:device:heater:DpId192" } ``` ### demo.sitemap diff --git a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointFactory.java b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointFactory.java index a61f1ff05b0ed..36733374b3683 100644 --- a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointFactory.java +++ b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointFactory.java @@ -19,6 +19,7 @@ * The {@link DataPointFactory} creates the data points depending on the types * * @author Hans-Reiner Hoffmann - Initial contribution + * @author Holger Friedrich - Extend to new data types (fw 1.80 and 1.90) */ @NonNullByDefault public class DataPointFactory { @@ -40,14 +41,22 @@ public static IDataPoint createDataPoint(int id, String knxType, String descript case "5.001": dataPoint = new DataPointScaling(id, knxType, description); break; + case "7.001": + dataPoint = new DataPointIntegerValue(id, knxType, description); + break; case "9.001": case "9.002": case "9.006": + case "9.024": + case "9.025": dataPoint = new DataPointValue(id, knxType, description); break; + // TODO 10.001 (Time, CWL) + // TODO 11.001 (Date, CWL) case "13.002": dataPoint = new DataPointLongValue(id, knxType, description); break; + case "5.010": case "20.102": case "20.103": case "20.105": diff --git a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointIntegerValue.java b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointIntegerValue.java new file mode 100644 index 0000000000000..f12d7c8390734 --- /dev/null +++ b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointIntegerValue.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2010-2024 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.ism8.server; + +import java.nio.ByteBuffer; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link DataPointIntegerValue} is the data points for integer values + * + * @author Holger Friedrich - Initial contribution + */ +@NonNullByDefault +public class DataPointIntegerValue extends DataPointBase<@Nullable Integer> { + private final Logger logger = LoggerFactory.getLogger(DataPointIntegerValue.class); + + public DataPointIntegerValue(int id, String knxDataType, String description) { + super(id, knxDataType, description); + } + + @Override + public String getValueText() { + Object val = this.getValue(); + return val != null ? val.toString() : "0"; + } + + @Override + public void processData(byte[] data) { + if (this.checkProcessData(data)) { + if (data[3] != 2 && data.length <= 5) { + logger.debug("DataPoint-ProcessData: Data size wrong for this type({}/1).", data[3]); + return; + } + int rawValue = Byte.toUnsignedInt(data[4]) * 0x100 + Byte.toUnsignedInt(data[5]); + this.setValue(rawValue); + } + } + + @Override + protected byte[] convertWriteValue(Object value) { + ByteBuffer data = ByteBuffer.allocate(2); + int intVal; + try { + intVal = Integer.parseInt(value.toString()); + } catch (NumberFormatException e) { + intVal = 0; + } + + int val = intVal; + data.put((byte) (val & 0xFF)); + val = (val & 0xFF) / 256; + data.put((byte) (val & 0xFF)); + return data.array(); + } +} diff --git a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointLongValue.java b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointLongValue.java index 18e9f8dc4ef62..b12479619f70a 100644 --- a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointLongValue.java +++ b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointLongValue.java @@ -38,6 +38,14 @@ public DataPointLongValue(int id, String knxDataType, String description) { this.setUnit(Units.CUBICMETRE_PER_HOUR); this.factor = 0.0001f; this.outputFormat = "%.1f"; + } else if ("13.010".equals(knxDataType)) { + this.setUnit(Units.WATT_HOUR); + this.factor = 1.0f; + this.outputFormat = "%.1f"; + } else if ("13.013".equals(knxDataType)) { + this.setUnit(Units.WATT_HOUR); + this.factor = 1000.0f; + this.outputFormat = "%.1f"; } else { this.setUnit(Units.ONE); this.factor = 1.0f; diff --git a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java index fbb5f5b5d0b75..2528d5c2ae7ce 100644 --- a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java +++ b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java @@ -47,6 +47,14 @@ public DataPointValue(int id, String knxDataType, String description) { this.setUnit(Units.BAR); this.factor = 0.0000001f; this.outputFormat = "%.2f"; + } else if ("9.024".equals(knxDataType)) { + this.setUnit(Units.WATT); + this.factor = 0.01f; + this.outputFormat = "%.2f"; + } else if ("9.025".equals(knxDataType)) { + this.setUnit(Units.LITRE_PER_MINUTE); + this.factor = 0.01f * 60.0f; + this.outputFormat = "%.2f"; } } diff --git a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties index 99778eeead9d5..9b45d4198c2e5 100644 --- a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties +++ b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties @@ -15,46 +15,104 @@ thing-type.config.ism8.device.portNumber.description = Port number of the object # channel types -channel-type.ism8.number-readonly.label = Value Readonly DataPoint -channel-type.ism8.number.label = Value DataPoint -channel-type.ism8.switch-readonly.label = Digital Readonly DataPoint -channel-type.ism8.switch.label = Digital DataPoint +channel-type.ism8.activeenergy-r.label = Active Energy Readonly DataPoint +channel-type.ism8.flowrate-r.label = Flowrate Readonly DataPoint +channel-type.ism8.mode-r.label = Mode Readonly DataPoint +channel-type.ism8.mode-rw.label = Mode DataPoint +channel-type.ism8.percentage-r.label = Percentage Readonly DataPoint +channel-type.ism8.percentage-rw.label = Percentage DataPoint +channel-type.ism8.power-r.label = Power Readonly DataPoint +channel-type.ism8.pressure-r.label = Pressure Readonly DataPoint +channel-type.ism8.switch-r.label = Digital Readonly DataPoint +channel-type.ism8.switch-rw.label = Digital DataPoint +channel-type.ism8.temperature-r.label = Temperature Readonly DataPoint +channel-type.ism8.temperature-rw.label = Temperature DataPoint +channel-type.ism8.value1ucount-r.label = Value 1-byte Unsigned Readonly DataPoint +channel-type.ism8.value2ucount-r.label = Value 2-byte Unsigned Readonly DataPoint # channel types config -channel-type.config.ism8.number-readonly.id.label = DP ID -channel-type.config.ism8.number-readonly.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. -channel-type.config.ism8.number-readonly.type.label = Type -channel-type.config.ism8.number-readonly.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) -channel-type.config.ism8.number-readonly.type.option.5.001 = DPT_Scaling -channel-type.config.ism8.number-readonly.type.option.9.001 = DPT_Value_Temp -channel-type.config.ism8.number-readonly.type.option.9.002 = DPT_Value_Tempd -channel-type.config.ism8.number-readonly.type.option.9.006 = DPT_Value_Pres -channel-type.config.ism8.number-readonly.type.option.13.002 = DPT_FlowRate -channel-type.config.ism8.number-readonly.type.option.20.102 = DPT_HVACMode -channel-type.config.ism8.number-readonly.type.option.20.103 = DPT_DHWMode -channel-type.config.ism8.number-readonly.type.option.20.105 = DPT_HVACContrMode -channel-type.config.ism8.number.id.label = DP ID -channel-type.config.ism8.number.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. -channel-type.config.ism8.number.type.label = Type -channel-type.config.ism8.number.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) -channel-type.config.ism8.number.type.option.9.001 = DPT_Value_Temp -channel-type.config.ism8.number.type.option.20.102 = DPT_HVACMode -channel-type.config.ism8.number.type.option.20.103 = DPT_DHWMode -channel-type.config.ism8.number.type.option.20.105 = DPT_HVACContrMode -channel-type.config.ism8.switch-readonly.id.label = DP ID -channel-type.config.ism8.switch-readonly.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. -channel-type.config.ism8.switch-readonly.type.label = Type -channel-type.config.ism8.switch-readonly.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Switch / 1.001) -channel-type.config.ism8.switch-readonly.type.option.1.001 = DPT_Switch -channel-type.config.ism8.switch-readonly.type.option.1.002 = DPT_Bool -channel-type.config.ism8.switch-readonly.type.option.1.003 = DPT_Enable -channel-type.config.ism8.switch-readonly.type.option.1.009 = DPT_OpenClose -channel-type.config.ism8.switch.id.label = DP ID -channel-type.config.ism8.switch.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. -channel-type.config.ism8.switch.type.label = Type -channel-type.config.ism8.switch.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Switch / 1.001) -channel-type.config.ism8.switch.type.option.1.001 = DPT_Switch -channel-type.config.ism8.switch.type.option.1.002 = DPT_Bool -channel-type.config.ism8.switch.type.option.1.003 = DPT_Enable -channel-type.config.ism8.switch.type.option.1.009 = DPT_OpenClose +channel-type.config.ism8.activeenergy-r.id.label = DP ID +channel-type.config.ism8.activeenergy-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.activeenergy-r.type.label = Type +channel-type.config.ism8.activeenergy-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.activeenergy-r.type.option.13.010 = DPT_ActiveEnergy +channel-type.config.ism8.activeenergy-r.type.option.13.013 = DPT_ActiveEnergy_kWh +channel-type.config.ism8.flowrate-r.id.label = DP ID +channel-type.config.ism8.flowrate-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.flowrate-r.type.label = Type +channel-type.config.ism8.flowrate-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.flowrate-r.type.option.9.025 = DPT_Power +channel-type.config.ism8.flowrate-r.type.option.13.002 = DPT_FlowRate +channel-type.config.ism8.mode-r.id.label = DP ID +channel-type.config.ism8.mode-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.mode-r.type.label = Type +channel-type.config.ism8.mode-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.mode-r.type.option.20.102 = DPT_HVACMode +channel-type.config.ism8.mode-r.type.option.20.103 = DPT_DHWMode +channel-type.config.ism8.mode-r.type.option.20.105 = DPT_HVACContrMode +channel-type.config.ism8.mode-rw.id.label = DP ID +channel-type.config.ism8.mode-rw.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.mode-rw.type.label = Type +channel-type.config.ism8.mode-rw.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.mode-rw.type.option.20.102 = DPT_HVACMode +channel-type.config.ism8.mode-rw.type.option.20.103 = DPT_DHWMode +channel-type.config.ism8.mode-rw.type.option.20.105 = DPT_HVACContrMode +channel-type.config.ism8.percentage-r.id.label = DP ID +channel-type.config.ism8.percentage-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.percentage-r.type.label = Type +channel-type.config.ism8.percentage-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.percentage-r.type.option.5.001 = DPT_Scaling +channel-type.config.ism8.percentage-rw.id.label = DP ID +channel-type.config.ism8.percentage-rw.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.percentage-rw.type.label = Type +channel-type.config.ism8.percentage-rw.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.percentage-rw.type.option.5.001 = DPT_Scaling +channel-type.config.ism8.power-r.id.label = DP ID +channel-type.config.ism8.power-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.power-r.type.label = Type +channel-type.config.ism8.power-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.power-r.type.option.9.024 = DPT_Power +channel-type.config.ism8.pressure-r.id.label = DP ID +channel-type.config.ism8.pressure-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.pressure-r.type.label = Type +channel-type.config.ism8.pressure-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.pressure-r.type.option.9.006 = DPT_Value_Pres +channel-type.config.ism8.switch-r.id.label = DP ID +channel-type.config.ism8.switch-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.switch-r.type.label = Type +channel-type.config.ism8.switch-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Switch / 1.001) +channel-type.config.ism8.switch-r.type.option.1.001 = DPT_Switch +channel-type.config.ism8.switch-r.type.option.1.002 = DPT_Bool +channel-type.config.ism8.switch-r.type.option.1.003 = DPT_Enable +channel-type.config.ism8.switch-r.type.option.1.009 = DPT_OpenClose +channel-type.config.ism8.switch-rw.id.label = DP ID +channel-type.config.ism8.switch-rw.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.switch-rw.type.label = Type +channel-type.config.ism8.switch-rw.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Switch / 1.001) +channel-type.config.ism8.switch-rw.type.option.1.001 = DPT_Switch +channel-type.config.ism8.switch-rw.type.option.1.002 = DPT_Bool +channel-type.config.ism8.switch-rw.type.option.1.003 = DPT_Enable +channel-type.config.ism8.switch-rw.type.option.1.009 = DPT_OpenClose +channel-type.config.ism8.temperature-r.id.label = DP ID +channel-type.config.ism8.temperature-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.temperature-r.type.label = Type +channel-type.config.ism8.temperature-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.temperature-r.type.option.9.001 = DPT_Value_Temp +channel-type.config.ism8.temperature-r.type.option.9.002 = DPT_Value_Tempd +channel-type.config.ism8.temperature-rw.id.label = DP ID +channel-type.config.ism8.temperature-rw.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.temperature-rw.type.label = Type +channel-type.config.ism8.temperature-rw.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.temperature-rw.type.option.9.001 = DPT_Value_Temp +channel-type.config.ism8.temperature-rw.type.option.9.002 = DPT_Value_Tempd +channel-type.config.ism8.value1ucount-r.id.label = DP ID +channel-type.config.ism8.value1ucount-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.value1ucount-r.type.label = Type +channel-type.config.ism8.value1ucount-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.value1ucount-r.type.option.5.010 = DPT_Value_1_Ucount +channel-type.config.ism8.value2ucount-r.id.label = DP ID +channel-type.config.ism8.value2ucount-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.value2ucount-r.type.label = Type +channel-type.config.ism8.value2ucount-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.value2ucount-r.type.option.7.001 = DPT_Value_2_Ucount diff --git a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml index e21c8946d5ccb..d889c0ab23c70 100644 --- a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml @@ -98,6 +98,42 @@ + + Number:Dimensionless + + + + + Put the number of the DataPoint ID to be mapped from the heating sytem. + + + + Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) + + + + + + + + + Number:Dimensionless + + + + + Put the number of the DataPoint ID to be mapped from the heating sytem. + + + + Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) + + + + + + + Number:Temperature @@ -157,6 +193,25 @@ + + Number:Power + + + + + + Put the number of the DataPoint ID to be mapped from the heating sytem. + + + + Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) + + + + + + + Number:VolumetricFlowRate @@ -170,12 +225,33 @@ Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) + + + Number:Energy + + + + + + Put the number of the DataPoint ID to be mapped from the heating sytem. + + + + Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) + + + + + + + + Number:Dimensionless From 3a0da57511515dccca0d42f465a16568e7683903 Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sat, 2 Nov 2024 12:04:42 +0100 Subject: [PATCH 2/5] reviewer suggestions Signed-off-by: Holger Friedrich --- bundles/org.openhab.binding.ism8/README.md | 29 +++++++++---------- .../resources/OH-INF/i18n/ism8.properties | 19 +++++------- .../resources/OH-INF/thing/thing-types.xml | 21 ++------------ 3 files changed, 23 insertions(+), 46 deletions(-) diff --git a/bundles/org.openhab.binding.ism8/README.md b/bundles/org.openhab.binding.ism8/README.md index d62dadac2910c..9a9f47618dc76 100644 --- a/bundles/org.openhab.binding.ism8/README.md +++ b/bundles/org.openhab.binding.ism8/README.md @@ -64,21 +64,20 @@ You can find the data type in the Wolf ISM8 document as well. Not all available data types of the ISM8 interface are fully supported. For the moment, the following data types are implemented: -| Channel type | Datapoint type | Item type | R/W | KNX-type's | -|----------------|------------------------------------------|---------------------------|-----|----------------------------| -| switch-rw | Digital DataPoint | Switch | R/W | 1.001, 1.002, 1.003, 1.009 | -| switch-r | Digital Readonly DataPoint | Switch | R | 1.001, 1.002, 1.003, 1.009 | -| percentage-rw | Percentage DataPoint | Number:Dimensionless | R/W | 5.001 | -| percentage-r | Percentage Readonly DataPoint | Number:Dimensionless | R | 5.001 | -| value1ucount-r | Value 2-byte Unsigned Readonly DataPoint | Number:Dimensionless | R | 5.010 | -| value2ucount-r | Value 2-byte Unsigned Readonly DataPoint | Number:Dimensionless | R | 7.001 | -| temperature-rw | Temperature DataPoint | Number:Temperature | R/W | 9.001,9.002 | -| temperature-r | Temperature Readonly DataPoint | Number:Temperature | R | 9.002,9.002 | -| pressure-r | Pressure Readonly DataPoint | Number:Pressure | R | 9.006 | -| flowrate-r | Flowrate Readonly DataPoint | Number:VolumetricFlowRate | R | 9.025, 13.002 | -| activeenergy-r | Active Energy Readonly DataPoint | Number:Energy | R | 13.010, 13.013 | -| mode-rw | Mode DataPoint | Number:Dimensionless | R/W | 20.102, 20.103, 20.105 | -| mode-r | Mode Readonly DataPoint | Number:Dimensionless | R | 20.102, 20.103, 20.105 | +| Channel type | Datapoint type | Item type | R/W | KNX-type's | +|-----------------|------------------------------------------|---------------------------|-----|----------------------------| +| switch-rw | Digital DataPoint | Switch | R/W | 1.001, 1.002, 1.003, 1.009 | +| switch-r | Digital Readonly DataPoint | Switch | R | 1.001, 1.002, 1.003, 1.009 | +| percentage-rw | Percentage DataPoint | Number:Dimensionless | R/W | 5.001 | +| percentage-r | Percentage Readonly DataPoint | Number:Dimensionless | R | 5.001 | +| number-r | Numeric Readonly DataPoint | Number:Dimensionless | R | 5.010, 7.001 | +| temperature-rw | Temperature DataPoint | Number:Temperature | R/W | 9.001,9.002 | +| temperature-r | Temperature Readonly DataPoint | Number:Temperature | R | 9.002,9.002 | +| pressure-r | Pressure Readonly DataPoint | Number:Pressure | R | 9.006 | +| flowrate-r | Flowrate Readonly DataPoint | Number:VolumetricFlowRate | R | 9.025, 13.002 | +| active-energy-r | Active Energy Readonly DataPoint | Number:Energy | R | 13.010, 13.013 | +| mode-rw | Mode DataPoint | Number:Dimensionless | R/W | 20.102, 20.103, 20.105 | +| mode-r | Mode Readonly DataPoint | Number:Dimensionless | R | 20.102, 20.103, 20.105 | Date and Time types used by for CWL Excellent and CWL2 are currently not supported by the ISM8 add-on. diff --git a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties index 9b45d4198c2e5..c4506df4fd82e 100644 --- a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties +++ b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties @@ -19,6 +19,7 @@ channel-type.ism8.activeenergy-r.label = Active Energy Readonly DataPoint channel-type.ism8.flowrate-r.label = Flowrate Readonly DataPoint channel-type.ism8.mode-r.label = Mode Readonly DataPoint channel-type.ism8.mode-rw.label = Mode DataPoint +channel-type.ism8.number-r.label = Numeric Readonly DataPoint channel-type.ism8.percentage-r.label = Percentage Readonly DataPoint channel-type.ism8.percentage-rw.label = Percentage DataPoint channel-type.ism8.power-r.label = Power Readonly DataPoint @@ -27,8 +28,6 @@ channel-type.ism8.switch-r.label = Digital Readonly DataPoint channel-type.ism8.switch-rw.label = Digital DataPoint channel-type.ism8.temperature-r.label = Temperature Readonly DataPoint channel-type.ism8.temperature-rw.label = Temperature DataPoint -channel-type.ism8.value1ucount-r.label = Value 1-byte Unsigned Readonly DataPoint -channel-type.ism8.value2ucount-r.label = Value 2-byte Unsigned Readonly DataPoint # channel types config @@ -58,6 +57,12 @@ channel-type.config.ism8.mode-rw.type.description = Put the KNX-type of the Data channel-type.config.ism8.mode-rw.type.option.20.102 = DPT_HVACMode channel-type.config.ism8.mode-rw.type.option.20.103 = DPT_DHWMode channel-type.config.ism8.mode-rw.type.option.20.105 = DPT_HVACContrMode +channel-type.config.ism8.number-r.id.label = DP ID +channel-type.config.ism8.number-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.number-r.type.label = Type +channel-type.config.ism8.number-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.number-r.type.option.5.010 = DPT_Value_1_Ucount +channel-type.config.ism8.number-r.type.option.7.001 = DPT_Value_2_Ucount channel-type.config.ism8.percentage-r.id.label = DP ID channel-type.config.ism8.percentage-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. channel-type.config.ism8.percentage-r.type.label = Type @@ -106,13 +111,3 @@ channel-type.config.ism8.temperature-rw.type.label = Type channel-type.config.ism8.temperature-rw.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) channel-type.config.ism8.temperature-rw.type.option.9.001 = DPT_Value_Temp channel-type.config.ism8.temperature-rw.type.option.9.002 = DPT_Value_Tempd -channel-type.config.ism8.value1ucount-r.id.label = DP ID -channel-type.config.ism8.value1ucount-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. -channel-type.config.ism8.value1ucount-r.type.label = Type -channel-type.config.ism8.value1ucount-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) -channel-type.config.ism8.value1ucount-r.type.option.5.010 = DPT_Value_1_Ucount -channel-type.config.ism8.value2ucount-r.id.label = DP ID -channel-type.config.ism8.value2ucount-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. -channel-type.config.ism8.value2ucount-r.type.label = Type -channel-type.config.ism8.value2ucount-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) -channel-type.config.ism8.value2ucount-r.type.option.7.001 = DPT_Value_2_Ucount diff --git a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml index d889c0ab23c70..2e8fdd4b28ee6 100644 --- a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml @@ -98,9 +98,9 @@ - + Number:Dimensionless - + @@ -111,23 +111,6 @@ Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) - - - - - - - Number:Dimensionless - - - - - Put the number of the DataPoint ID to be mapped from the heating sytem. - - - - Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) - From 12ffae22e8369c5856013fde57ee5d4650bf1d4f Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sat, 2 Nov 2024 12:07:11 +0100 Subject: [PATCH 3/5] reviewer suggestions Signed-off-by: Holger Friedrich --- .../src/main/resources/OH-INF/i18n/ism8.properties | 14 +++++++------- .../main/resources/OH-INF/thing/thing-types.xml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties index c4506df4fd82e..828e2388c868b 100644 --- a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties +++ b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/i18n/ism8.properties @@ -15,7 +15,7 @@ thing-type.config.ism8.device.portNumber.description = Port number of the object # channel types -channel-type.ism8.activeenergy-r.label = Active Energy Readonly DataPoint +channel-type.ism8.active-energy-r.label = Active Energy Readonly DataPoint channel-type.ism8.flowrate-r.label = Flowrate Readonly DataPoint channel-type.ism8.mode-r.label = Mode Readonly DataPoint channel-type.ism8.mode-rw.label = Mode DataPoint @@ -31,12 +31,12 @@ channel-type.ism8.temperature-rw.label = Temperature DataPoint # channel types config -channel-type.config.ism8.activeenergy-r.id.label = DP ID -channel-type.config.ism8.activeenergy-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. -channel-type.config.ism8.activeenergy-r.type.label = Type -channel-type.config.ism8.activeenergy-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) -channel-type.config.ism8.activeenergy-r.type.option.13.010 = DPT_ActiveEnergy -channel-type.config.ism8.activeenergy-r.type.option.13.013 = DPT_ActiveEnergy_kWh +channel-type.config.ism8.active-energy-r.id.label = DP ID +channel-type.config.ism8.active-energy-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. +channel-type.config.ism8.active-energy-r.type.label = Type +channel-type.config.ism8.active-energy-r.type.description = Put the KNX-type of the DataPoint (e.g. DPT_Value_Temp / 9.001) +channel-type.config.ism8.active-energy-r.type.option.13.010 = DPT_ActiveEnergy +channel-type.config.ism8.active-energy-r.type.option.13.013 = DPT_ActiveEnergy_kWh channel-type.config.ism8.flowrate-r.id.label = DP ID channel-type.config.ism8.flowrate-r.id.description = Put the number of the DataPoint ID to be mapped from the heating sytem. channel-type.config.ism8.flowrate-r.type.label = Type diff --git a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml index 2e8fdd4b28ee6..80fa732d36088 100644 --- a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml @@ -215,7 +215,7 @@ - + Number:Energy From 89d8aca0cf7433df1230bfb63591139e97bdb791 Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sun, 3 Nov 2024 12:17:39 +0100 Subject: [PATCH 4/5] Add tests, fix implementation Signed-off-by: Holger Friedrich --- .../ism8/internal/util/Ism8DomainMap.java | 10 + .../binding/ism8/server/DataPointValue.java | 4 +- .../ism8/internal/util/Ism8DomainMapTest.java | 221 +++++++++++++++++- 3 files changed, 225 insertions(+), 10 deletions(-) diff --git a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/internal/util/Ism8DomainMap.java b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/internal/util/Ism8DomainMap.java index bf5144abf05e4..4ecb42d491dfe 100644 --- a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/internal/util/Ism8DomainMap.java +++ b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/internal/util/Ism8DomainMap.java @@ -17,6 +17,8 @@ import javax.measure.Unit; import javax.measure.quantity.Dimensionless; +import javax.measure.quantity.Energy; +import javax.measure.quantity.Power; import javax.measure.quantity.Pressure; import javax.measure.quantity.Temperature; @@ -57,8 +59,14 @@ public static State toOpenHABState(IDataPoint dataPoint) { return new QuantityType((Double) value, Units.KELVIN); } else if (Units.CUBICMETRE_PER_HOUR.equals(unit)) { return new QuantityType((Double) value, Units.CUBICMETRE_PER_HOUR); + } else if (Units.LITRE_PER_MINUTE.equals(unit)) { + return new QuantityType((Double) value, Units.LITRE_PER_MINUTE); } else if (Units.BAR.equals(unit)) { return new QuantityType((Double) value, Units.BAR); + } else if (Units.WATT.equals(unit)) { + return new QuantityType((Double) value, Units.WATT); + } else if (Units.WATT_HOUR.equals(unit)) { + return new QuantityType((Double) value, Units.WATT_HOUR); } else if (Units.PERCENT.equals(unit)) { return new QuantityType((Double) value, Units.PERCENT); } else if (Units.ONE.equals(unit)) { @@ -67,6 +75,8 @@ public static State toOpenHABState(IDataPoint dataPoint) { return OnOffType.from((boolean) value); } else if (value instanceof Byte) { return new QuantityType((byte) value, Units.ONE); + } else if (value instanceof Integer) { + return new QuantityType((int) value, Units.ONE); } LOGGER.debug("Failed to map DataPoint id: {} val: {}, to UoM state. Performing fallback.", dataPoint.getId(), diff --git a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java index 2528d5c2ae7ce..d9b67157a1777 100644 --- a/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java +++ b/bundles/org.openhab.binding.ism8/src/main/java/org/openhab/binding/ism8/server/DataPointValue.java @@ -49,11 +49,11 @@ public DataPointValue(int id, String knxDataType, String description) { this.outputFormat = "%.2f"; } else if ("9.024".equals(knxDataType)) { this.setUnit(Units.WATT); - this.factor = 0.01f; + this.factor = 0.01f * 1000.0f; this.outputFormat = "%.2f"; } else if ("9.025".equals(knxDataType)) { this.setUnit(Units.LITRE_PER_MINUTE); - this.factor = 0.01f * 60.0f; + this.factor = 0.01f / 60.0f; this.outputFormat = "%.2f"; } } diff --git a/bundles/org.openhab.binding.ism8/src/test/java/org/openhab/binding/ism8/internal/util/Ism8DomainMapTest.java b/bundles/org.openhab.binding.ism8/src/test/java/org/openhab/binding/ism8/internal/util/Ism8DomainMapTest.java index 05ca48ca1b62b..311831d3d2615 100644 --- a/bundles/org.openhab.binding.ism8/src/test/java/org/openhab/binding/ism8/internal/util/Ism8DomainMapTest.java +++ b/bundles/org.openhab.binding.ism8/src/test/java/org/openhab/binding/ism8/internal/util/Ism8DomainMapTest.java @@ -15,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import javax.measure.quantity.Dimensionless; -import javax.measure.quantity.Temperature; +import javax.measure.quantity.Pressure; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.jupiter.api.BeforeEach; @@ -24,6 +24,8 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.openhab.binding.ism8.server.DataPointBool; import org.openhab.binding.ism8.server.DataPointByteValue; +import org.openhab.binding.ism8.server.DataPointIntegerValue; +import org.openhab.binding.ism8.server.DataPointLongValue; import org.openhab.binding.ism8.server.DataPointScaling; import org.openhab.binding.ism8.server.DataPointValue; import org.openhab.binding.ism8.server.IDataPoint; @@ -35,6 +37,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.openhab.core.util.HexUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -44,6 +48,7 @@ @ExtendWith(MockitoExtension.class) @NonNullByDefault public class Ism8DomainMapTest { + private static final Logger LOGGER = LoggerFactory.getLogger(Ism8DomainMap.class); @BeforeEach public void initialize() { @@ -105,29 +110,229 @@ public void mapDataPointScalingToMessage() { assertEquals("0620F080001504000000F0C1000300010003000121", HexUtils.bytesToHex(result)); } + @Test + public void mapDataPointBoolToOHState() { + { + // arrange + IDataPoint dataPoint = new DataPointBool(1, "1.001", "Datapoint_1.001"); + dataPoint.processData(HexUtils.hexToBytes("0001030200")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(OnOffType.from(false), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointBool(1, "1.001", "Datapoint_1.001"); + dataPoint.processData(HexUtils.hexToBytes("0001030201")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(OnOffType.from(true), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointBool(1, "1.002", "Datapoint_1.002"); + dataPoint.processData(HexUtils.hexToBytes("0001030201")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(OnOffType.from(true), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointBool(1, "1.003", "Datapoint_1.003"); + dataPoint.processData(HexUtils.hexToBytes("0001030201")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(OnOffType.from(true), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointBool(1, "1.009", "Datapoint_1.009"); + dataPoint.processData(HexUtils.hexToBytes("0001030201")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(OnOffType.from(true), result); + // TODO: check if OpenClosedType is appropriate + // assertEquals(OpenClosedType.valueOf("OPEN"), result); + } + } + @Test public void mapDataPointValueToOHState() { + { + // arrange + IDataPoint dataPoint = new DataPointValue(4, "9.001", "Datapoint_9.001"); + dataPoint.processData(HexUtils.hexToBytes("000403020FE9")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(new QuantityType<>("40.49999909475446 °C"), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointValue(4, "9.002", "Datapoint_9.002"); + dataPoint.processData(HexUtils.hexToBytes("000403020FE9")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(new QuantityType<>("40.49999909475446 K"), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointValue(4, "9.006", "Datapoint_9.006"); + dataPoint.processData(HexUtils.hexToBytes("000403020FE9")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + // original unit is Pa, will be bar in OH -> divide by 10000, i.e. expect 0.0004049999909475446 bar + // text ctor cannot be used, as it will result in scientific notation ..E-4, + // double ctor returns a slightly different number caused by internal representation + assertEquals(new QuantityType(0.00040500000473286946, Units.BAR), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointValue(4, "9.024", "Datapoint_9.024"); + dataPoint.processData(HexUtils.hexToBytes("000403020FE9")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + // original unit is kW + assertEquals(new QuantityType<>("40500 W"), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointValue(4, "9.025", "Datapoint_9.025"); + dataPoint.processData(HexUtils.hexToBytes("000403020FE9")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + // original unit is l/h, i.e. divide by 60 to get l/min + assertEquals(new QuantityType<>("0.6749999927706085 l/min"), result); + } + } + + @Test + public void mapDataPointByteValueToOHState() { // arrange - IDataPoint dataPoint = new DataPointValue(4, "9.001", "Datapoint_9.001"); - dataPoint.processData(HexUtils.hexToBytes("000403020FE9")); + IDataPoint dataPoint = new DataPointByteValue(5, "5.010", "Datapoint_5.010"); + dataPoint.processData(HexUtils.hexToBytes("0005030243")); // act State result = Ism8DomainMap.toOpenHABState(dataPoint); // assert - assertEquals(new QuantityType(40.49999909475446, SIUnits.CELSIUS), result); + assertEquals(new QuantityType(0x43, Units.ONE), result); } @Test - public void mapDataPointLongToOHState() { + public void mapDataPointIntegerValueToOHState() { // arrange - IDataPoint dataPoint = new DataPointByteValue(2, "20.102", "Datapoint_20.102"); - dataPoint.processData(HexUtils.hexToBytes("0002030101")); + IDataPoint dataPoint = new DataPointIntegerValue(7, "7.001", "Datapoint_7.001"); + dataPoint.processData(HexUtils.hexToBytes("000703024321")); // act State result = Ism8DomainMap.toOpenHABState(dataPoint); // assert - assertEquals(new QuantityType(1, Units.ONE), result); + assertEquals(new QuantityType(0x4321, Units.ONE), result); + } + + @Test + public void mapDataPointLongValueToOHState() { + { + // arrange + IDataPoint dataPoint = new DataPointLongValue(13, "13.002", "Datapoint_13.002"); + dataPoint.processData(HexUtils.hexToBytes("000D03027FFFFFFF")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + // value encoded above is max value 2147483647, scaling for 13.002 is 0.0001, unit m^3/h + // -> expected is 214748.3647 m^3/h + assertEquals(new QuantityType<>("214748.359275 m³/h"), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointLongValue(13, "13.010", "Datapoint_13.010"); + dataPoint.processData(HexUtils.hexToBytes("000D03027FFFFFFF")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + // value encoded above is max value 2147483647 + assertEquals(new QuantityType<>("2147483647 Wh"), result); + } + { + // arrange + IDataPoint dataPoint = new DataPointLongValue(13, "13.013", "Datapoint_13.013"); + dataPoint.processData(HexUtils.hexToBytes("000D03027FFFFFFF")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + // value encoded above is max value 2147483647 + assertEquals(new QuantityType<>("2147483647 kWh"), result); + } + } + + @Test + public void mapDataPointLongToOHState() { + { // arrange + IDataPoint dataPoint = new DataPointByteValue(20, "20.102", "Datapoint_20.102"); + dataPoint.processData(HexUtils.hexToBytes("0014030101")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(new QuantityType(1, Units.ONE), result); + } + { // arrange + IDataPoint dataPoint = new DataPointByteValue(20, "20.103", "Datapoint_20.103"); + dataPoint.processData(HexUtils.hexToBytes("0014030101")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(new QuantityType(1, Units.ONE), result); + } + { // arrange + IDataPoint dataPoint = new DataPointByteValue(20, "20.105", "Datapoint_20.105"); + dataPoint.processData(HexUtils.hexToBytes("0014030101")); + + // act + State result = Ism8DomainMap.toOpenHABState(dataPoint); + + // assert + assertEquals(new QuantityType(1, Units.ONE), result); + } } } From e8ba5d12bfc1ea81e4e2e25f1314b627effbb230 Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sun, 3 Nov 2024 23:14:22 +0100 Subject: [PATCH 5/5] Mark channel number-r readonly Signed-off-by: Holger Friedrich --- .../src/main/resources/OH-INF/thing/thing-types.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml index 80fa732d36088..cb7d5b8603cfc 100644 --- a/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.ism8/src/main/resources/OH-INF/thing/thing-types.xml @@ -101,6 +101,7 @@ Number:Dimensionless +