From 7d9e277a1507a511a43b83c0b17d405c5152d553 Mon Sep 17 00:00:00 2001 From: Ondrej Pecta Date: Thu, 8 Sep 2022 21:18:42 +0200 Subject: [PATCH] [jablotron] Added thermometers support for JA100F alarms (#13361) Signed-off-by: Ondrej Pecta --- .../org.openhab.binding.jablotron/README.md | 4 +- .../handler/JablotronBridgeHandler.java | 26 +++++++++-- .../handler/JablotronJa100FHandler.java | 42 ++++++++++++++++++ .../ja100f/JablotronGetThermoDevicesData.java | 43 +++++++++++++++++++ .../JablotronGetThermoDevicesResponse.java | 31 +++++++++++++ .../internal/model/ja100f/JablotronState.java | 12 ++++++ .../model/ja100f/JablotronThermoDevice.java | 40 +++++++++++++++++ 7 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesData.java create mode 100644 bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesResponse.java create mode 100644 bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronThermoDevice.java diff --git a/bundles/org.openhab.binding.jablotron/README.md b/bundles/org.openhab.binding.jablotron/README.md index 977e1de4ce2..26f699a59c3 100644 --- a/bundles/org.openhab.binding.jablotron/README.md +++ b/bundles/org.openhab.binding.jablotron/README.md @@ -56,11 +56,11 @@ Binding itself doesn't require specific configuration. | JA-100 | thermostat_%nr% | Number:Temperature | the thermostat %nr% value | | JA-100F | sec-%nr% | String | the section %nr% status/control | | JA-100F | pg-%nr% | Switch | the PG switch %nr% status/control | +| JA-100F | thm-%nr% | Number:Temperature | the thermometer %nr% value | The state, pgm, thermometer, thermostat, sec and pg channels for the JA-100/JA-100F alarms are dynamically created according to your configuration. -* The sections are represented by String channels (with possible values "set", "unset", "partialSet" for JA-100 and -possible values "ARM", "PARTIAL_ARM" and "DISARM" for JA100-F) +* The sections are represented by String channels (with possible values "set", "unset", "partialSet" for JA-100 and possible values "ARM", "PARTIAL_ARM" and "DISARM" for JA100-F) ## Full Example diff --git a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronBridgeHandler.java b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronBridgeHandler.java index 9facea5068f..07c524aeeee 100644 --- a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronBridgeHandler.java +++ b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronBridgeHandler.java @@ -41,6 +41,7 @@ import org.openhab.binding.jablotron.internal.model.JablotronHistoryDataEvent; import org.openhab.binding.jablotron.internal.model.JablotronLoginResponse; import org.openhab.binding.jablotron.internal.model.ja100f.JablotronGetPGResponse; import org.openhab.binding.jablotron.internal.model.ja100f.JablotronGetSectionsResponse; +import org.openhab.binding.jablotron.internal.model.ja100f.JablotronGetThermoDevicesResponse; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -334,12 +335,30 @@ public class JablotronBridgeHandler extends BaseBridgeHandler { return null; } - String urlParameters = "{\"connect-device\":false,\"list-type\":\"FULL\",\"service-id\":" - + handler.thingConfig.getServiceId() + ",\"service-states\":true}"; + String urlParameters = getCommonUrlParameters(handler.thingConfig.getServiceId()); return sendJsonMessage(url, urlParameters, JablotronGetPGResponse.class); } + private String getCommonUrlParameters(String serviceId) { + return "{\"connect-device\":false,\"list-type\":\"FULL\",\"service-id\":" + serviceId + + ",\"service-states\":true}"; + } + + protected @Nullable JablotronGetThermoDevicesResponse sendGetThermometers(Thing th, String alarm) { + String url = JABLOTRON_API_URL + alarm + "/thermoDevicesGet.json"; + JablotronAlarmHandler handler = (JablotronAlarmHandler) th.getHandler(); + + if (handler == null) { + logger.debug("Thing handler is null"); + return null; + } + + String urlParameters = getCommonUrlParameters(handler.thingConfig.getServiceId()); + + return sendJsonMessage(url, urlParameters, JablotronGetThermoDevicesResponse.class); + } + protected @Nullable JablotronGetSectionsResponse sendGetSections(Thing th, String alarm) { String url = JABLOTRON_API_URL + alarm + "/sectionsGet.json"; JablotronAlarmHandler handler = (JablotronAlarmHandler) th.getHandler(); @@ -349,8 +368,7 @@ public class JablotronBridgeHandler extends BaseBridgeHandler { return null; } - String urlParameters = "{\"connect-device\":false,\"list-type\":\"FULL\",\"service-id\":" - + handler.thingConfig.getServiceId() + ",\"service-states\":true}"; + String urlParameters = getCommonUrlParameters(handler.thingConfig.getServiceId()); return sendJsonMessage(url, urlParameters, JablotronGetSectionsResponse.class); } diff --git a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronJa100FHandler.java b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronJa100FHandler.java index 5b520e646a8..f16b138cb6d 100644 --- a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronJa100FHandler.java +++ b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/handler/JablotronJa100FHandler.java @@ -22,11 +22,15 @@ import org.openhab.binding.jablotron.internal.model.JablotronHistoryDataEvent; import org.openhab.binding.jablotron.internal.model.JablotronServiceDetailSegment; import org.openhab.binding.jablotron.internal.model.ja100f.JablotronGetPGResponse; import org.openhab.binding.jablotron.internal.model.ja100f.JablotronGetSectionsResponse; +import org.openhab.binding.jablotron.internal.model.ja100f.JablotronGetThermoDevicesResponse; import org.openhab.binding.jablotron.internal.model.ja100f.JablotronSection; import org.openhab.binding.jablotron.internal.model.ja100f.JablotronState; +import org.openhab.binding.jablotron.internal.model.ja100f.JablotronThermoDevice; import org.openhab.core.cache.ExpiringCache; import org.openhab.core.library.types.OnOffType; +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.Channel; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -141,6 +145,15 @@ public class JablotronJa100FHandler extends JablotronAlarmHandler { updateThing(thingBuilder.build()); } + private void createThermoChannel(String name, String label) { + ChannelTypeUID alarmStatus = new ChannelTypeUID(BINDING_ID, "temperature"); + ThingBuilder thingBuilder = editThing(); + Channel channel = ChannelBuilder.create(new ChannelUID(thing.getUID(), name), "Number").withLabel(label) + .withType(alarmStatus).build(); + thingBuilder.withChannel(channel); + updateThing(thingBuilder.build()); + } + private @Nullable JablotronGetSectionsResponse sendGetSections() { JablotronBridgeHandler handler = getBridgeHandler(); if (handler != null) { @@ -177,6 +190,13 @@ public class JablotronJa100FHandler extends JablotronAlarmHandler { updateSectionState(resp.getData().getStates()); } + // thermo devices + JablotronGetThermoDevicesResponse respThermo = handler.sendGetThermometers(getThing(), alarmName); + if (respThermo != null) { + createThermoDeviceChannels(respThermo.getData().getThermoDevices()); + updateThermoState(respThermo.getData().getStates()); + } + // update events List events = sendGetEventHistory(); if (events != null && !events.isEmpty()) { @@ -213,6 +233,18 @@ public class JablotronJa100FHandler extends JablotronAlarmHandler { } } + private void createThermoDeviceChannels(List thermoDevices) { + for (JablotronThermoDevice device : thermoDevices) { + String id = device.getObjectDeviceId().toLowerCase(); + logger.trace("object device id: {} with name: {}", id, device.getName()); + Channel channel = getThing().getChannel(id); + if (channel == null) { + logger.debug("Creating a new channel: {}", id); + createThermoChannel(id, device.getName()); + } + } + } + private void updateSectionState(String section, List states) { for (JablotronState state : states) { String id = state.getCloudComponentId(); @@ -230,6 +262,14 @@ public class JablotronJa100FHandler extends JablotronAlarmHandler { } } + private void updateThermoState(List states) { + for (JablotronState state : states) { + logger.debug("updating thermo state: {}", state.getObjectDeviceId()); + String id = state.getObjectDeviceId(); + updateSection(id, state); + } + } + private void updateSection(String id, JablotronState state) { logger.debug("component id: {} with state: {}", id, state.getState()); State newState; @@ -238,6 +278,8 @@ public class JablotronJa100FHandler extends JablotronAlarmHandler { newState = new StringType(state.getState()); } else if (id.startsWith("PG-")) { newState = "ON".equals(state.getState()) ? OnOffType.ON : OnOffType.OFF; + } else if (id.startsWith("THM-")) { + newState = new QuantityType<>(state.getTemperature(), SIUnits.CELSIUS); } else { logger.debug("unknown component id: {}", id); return; diff --git a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesData.java b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesData.java new file mode 100644 index 00000000000..18c436d23a1 --- /dev/null +++ b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesData.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2010-2022 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.jablotron.internal.model.ja100f; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link JablotronGetThermoDevicesData} class defines the data object for the + * getThermoDevices response + * + * @author Ondrej Pecta - Initial contribution + */ +@NonNullByDefault +public class JablotronGetThermoDevicesData { + + List states = new ArrayList<>(); + + @SerializedName(value = "thermo-devices") + List thermoDevices = new ArrayList<>(); + + public List getStates() { + return states; + } + + public List getThermoDevices() { + return thermoDevices; + } +} diff --git a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesResponse.java b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesResponse.java new file mode 100644 index 00000000000..ff08d0cdb5a --- /dev/null +++ b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronGetThermoDevicesResponse.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2010-2022 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.jablotron.internal.model.ja100f; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link JablotronGetThermoDevicesResponse} class defines the response object for the + * getThermometers call + * + * @author Ondrej Pecta - Initial contribution + */ +@NonNullByDefault +public class JablotronGetThermoDevicesResponse { + + JablotronGetThermoDevicesData data = new JablotronGetThermoDevicesData(); + + public JablotronGetThermoDevicesData getData() { + return data; + } +} diff --git a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronState.java b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronState.java index 6972d6426d9..f9f76a62d3d 100644 --- a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronState.java +++ b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronState.java @@ -28,7 +28,11 @@ public class JablotronState { @SerializedName(value = "cloud-component-id", alternate = "component-id") String cloudComponentId = ""; + @SerializedName(value = "object-device-id") + String objectDeviceId = ""; + String state = ""; + float temperature = 0; public String getCloudComponentId() { return cloudComponentId; @@ -37,4 +41,12 @@ public class JablotronState { public String getState() { return state; } + + public float getTemperature() { + return temperature; + } + + public String getObjectDeviceId() { + return objectDeviceId; + } } diff --git a/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronThermoDevice.java b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronThermoDevice.java new file mode 100644 index 00000000000..17af16229f8 --- /dev/null +++ b/bundles/org.openhab.binding.jablotron/src/main/java/org/openhab/binding/jablotron/internal/model/ja100f/JablotronThermoDevice.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2010-2022 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.jablotron.internal.model.ja100f; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link JablotronThermoDevice} class defines the thermal device object + * for the getThermoDevices response + * + * @author Ondrej Pecta - Initial contribution + */ +@NonNullByDefault +public class JablotronThermoDevice { + + @SerializedName(value = "object-device-id") + String objectDeviceId = ""; + + String name = ""; + + public String getObjectDeviceId() { + return objectDeviceId; + } + + public String getName() { + return name; + } +}