From d8e5a57de9d55521ab32abc5e69626d1518d9213 Mon Sep 17 00:00:00 2001 From: CSchlipp Date: Tue, 19 Jan 2021 00:58:20 +0100 Subject: [PATCH] [WlanThermo] Add support for new ESP32-powered devices [V3.x] (#9579) * Add support for ESP32 devices * Add Unit Tests Ensure Gson objects are NonNull Generify Handlers Generify Utils Signed-off-by: Christian Schlipp --- .../internal/WlanThermoBindingConstants.java | 34 +- ...tion.java => WlanThermoConfiguration.java} | 4 +- .../internal/WlanThermoException.java | 41 ++ .../WlanThermoExtendedConfiguration.java | 51 ++ .../internal/WlanThermoHandler.java | 189 +++++++ .../internal/WlanThermoHandlerFactory.java | 14 +- .../internal/WlanThermoInputException.java | 35 ++ .../internal/WlanThermoMiniHandler.java | 152 ------ .../internal/WlanThermoNanoConfiguration.java | 101 ---- .../internal/WlanThermoNanoHandler.java | 205 -------- .../WlanThermoUnknownChannelException.java | 40 ++ .../wlanthermo/internal/WlanThermoUtil.java | 53 ++ .../esp32/WlanThermoEsp32CommandHandler.java | 299 +++++++++++ .../api/esp32/WlanThermoEsp32Handler.java | 124 +++++ .../api/esp32/WlanThermoEsp32Util.java | 74 +++ .../internal/api/esp32/dto/data/Channel.java | 136 +++++ .../internal/api/esp32/dto/data/Data.java | 61 +++ .../api/esp32/dto/data/Pitmaster.java | 50 ++ .../internal/api/esp32/dto/data/Pm.java | 114 +++++ .../internal/api/esp32/dto/data/System.java | 92 ++++ .../internal/api/esp32/dto/settings/Api.java | 37 ++ .../api/esp32/dto/settings/Device.java | 114 +++++ .../api/esp32/dto/settings/Display.java | 48 ++ .../internal/api/esp32/dto/settings/Ext.java | 94 ++++ .../api/esp32/dto/settings/Features.java | 48 ++ .../internal/api/esp32/dto/settings/Iot.java | 147 ++++++ .../api/esp32/dto/settings/Notes.java | 50 ++ .../internal/api/esp32/dto/settings/Pid.java | 180 +++++++ .../api/esp32/dto/settings/Sensor.java | 59 +++ .../api/esp32/dto/settings/Settings.java | 149 ++++++ .../api/esp32/dto/settings/System.java | 136 +++++ .../mini/WlanThermoMiniCommandHandler.java | 165 +++++++ .../api/mini/WlanThermoMiniHandler.java | 85 ++++ .../UtilMini.java => WlanThermoMiniUtil.java} | 12 +- .../builtin/WlanThermoMiniCommandHandler.java | 164 ------- .../api/mini/{ => dto}/builtin/App.java | 2 +- .../api/mini/{ => dto}/builtin/Channel.java | 2 +- .../api/mini/{ => dto}/builtin/Data.java | 2 +- .../api/mini/{ => dto}/builtin/Pit.java | 2 +- .../nano/WlanThermoNanoCommandHandler.java | 261 ---------- .../nano/WlanThermoNanoV1CommandHandler.java | 282 +++++++++++ .../api/nano/WlanThermoNanoV1Handler.java | 106 ++++ ...tilNano.java => WlanThermoNanoV1Util.java} | 24 +- .../api/nano/{ => dto}/data/Channel.java | 2 +- .../api/nano/{ => dto}/data/Data.java | 2 +- .../api/nano/{ => dto}/data/Pitmaster.java | 2 +- .../internal/api/nano/{ => dto}/data/Pm.java | 2 +- .../api/nano/{ => dto}/data/System.java | 2 +- .../api/nano/{ => dto}/settings/Api.java | 2 +- .../api/nano/{ => dto}/settings/Device.java | 2 +- .../api/nano/{ => dto}/settings/Ext.java | 2 +- .../api/nano/{ => dto}/settings/Iot.java | 2 +- .../api/nano/{ => dto}/settings/Notes.java | 2 +- .../api/nano/{ => dto}/settings/Pid.java | 2 +- .../api/nano/{ => dto}/settings/Settings.java | 2 +- .../api/nano/{ => dto}/settings/System.java | 2 +- .../thing/channel-group-types-esp32.xml | 51 ++ .../OH-INF/thing/channel-group-types-mini.xml | 47 ++ .../OH-INF/thing/channel-group-types-nano.xml | 52 ++ .../resources/OH-INF/thing/channel-types.xml | 259 ++++++++++ .../OH-INF/thing/thing-types-esp32.xml | 151 ++++++ .../OH-INF/thing/thing-types-mini.xml | 79 +++ .../OH-INF/thing/thing-types-nano.xml | 74 +++ .../resources/OH-INF/thing/thing-types.xml | 463 ------------------ .../WlanThermoEsp32CommandHandlerTest.java | 224 +++++++++ .../WlanThermoMiniCommandHandlerTest.java | 160 ++++++ .../WlanThermoNanoV1CommandHandlerTest.java | 207 ++++++++ .../src/test/resources/esp32/data.json | 151 ++++++ .../src/test/resources/esp32/settings.json | 229 +++++++++ .../src/test/resources/mini/app.json | 121 +++++ .../src/test/resources/nanov1/data.json | 109 +++++ .../src/test/resources/nanov1/settings.json | 117 +++++ 72 files changed, 5155 insertions(+), 1403 deletions(-) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/{WlanThermoMiniConfiguration.java => WlanThermoConfiguration.java} (91%) create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoException.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoExtendedConfiguration.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandler.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoInputException.java delete mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniHandler.java delete mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoConfiguration.java delete mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoHandler.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUnknownChannelException.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUtil.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandler.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Handler.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Util.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Channel.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Data.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pitmaster.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pm.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/System.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Api.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Device.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Display.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Ext.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Features.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Iot.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Notes.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Pid.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Sensor.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Settings.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/System.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandler.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniHandler.java rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/{builtin/UtilMini.java => WlanThermoMiniUtil.java} (86%) delete mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/WlanThermoMiniCommandHandler.java rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/{ => dto}/builtin/App.java (98%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/{ => dto}/builtin/Channel.java (98%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/{ => dto}/builtin/Data.java (98%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/{ => dto}/builtin/Pit.java (98%) delete mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoCommandHandler.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandler.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Handler.java rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{UtilNano.java => WlanThermoNanoV1Util.java} (74%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/data/Channel.java (98%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/data/Data.java (97%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/data/Pitmaster.java (96%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/data/Pm.java (98%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/data/System.java (97%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/Api.java (91%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/Device.java (94%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/Ext.java (94%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/Iot.java (95%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/Notes.java (92%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/Pid.java (95%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/Settings.java (95%) rename bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/{ => dto}/settings/System.java (95%) create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-esp32.xml create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-mini.xml create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-nano.xml create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-types.xml create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-esp32.xml create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-mini.xml create mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-nano.xml delete mode 100644 bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types.xml create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandlerTest.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandlerTest.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandlerTest.java create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/data.json create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/settings.json create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/resources/mini/app.json create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/data.json create mode 100644 bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/settings.json diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoBindingConstants.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoBindingConstants.java index 92c6a00fd..0fa5a2465 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoBindingConstants.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoBindingConstants.java @@ -13,6 +13,7 @@ package org.openhab.binding.wlanthermo.internal; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.library.types.DecimalType; import org.openhab.core.thing.ThingTypeUID; /** @@ -27,11 +28,17 @@ public class WlanThermoBindingConstants { private static final String BINDING_ID = "wlanthermo"; // List of all Thing Type UIDs - public static final ThingTypeUID THING_TYPE_WLANTHERMO_NANO = new ThingTypeUID(BINDING_ID, "nano"); + public static final ThingTypeUID THING_TYPE_WLANTHERMO_NANO_V1 = new ThingTypeUID(BINDING_ID, "nano"); public static final ThingTypeUID THING_TYPE_WLANTHERMO_MINI = new ThingTypeUID(BINDING_ID, "mini"); + public static final ThingTypeUID THING_TYPE_WLANTHERMO_ESP32 = new ThingTypeUID(BINDING_ID, "esp32"); - // ThreadPool - public static final String WLANTHERMO_THREAD_POOL = "wlanthermo"; + // Properties + public static final String PROPERTY_MODEL = "model"; + public static final String PROPERTY_SERIAL = "serial"; + public static final String PROPERTY_ESP32_BT_ENABLED = "esp32_bt_enabled"; + public static final String PROPERTY_ESP32_PM_ENABLED = "esp32_pm_enabled"; + public static final String PROPERTY_ESP32_TEMP_CHANNELS = "esp32_temp_channels"; + public static final String PROPERTY_ESP32_PM_CHANNELS = "esp32_pm_channels"; // List of all Channel ids // System Channels @@ -43,16 +50,7 @@ public class WlanThermoBindingConstants { public static final String SYSTEM_CPU_LOAD = "cpu_load"; public static final String SYSTEM_CPU_TEMP = "cpu_temp"; - public static final String CHANNEL0 = "channel0"; - public static final String CHANNEL1 = "channel1"; - public static final String CHANNEL2 = "channel2"; - public static final String CHANNEL3 = "channel3"; - public static final String CHANNEL4 = "channel4"; - public static final String CHANNEL5 = "channel5"; - public static final String CHANNEL6 = "channel6"; - public static final String CHANNEL7 = "channel7"; - public static final String CHANNEL8 = "channel8"; - public static final String CHANNEL9 = "channel9"; + public static final String CHANNEL_PREFIX = "channel"; public static final String CHANNEL_NAME = "name"; public static final String CHANNEL_TYP = "typ"; @@ -67,6 +65,9 @@ public class WlanThermoBindingConstants { public static final String CHANNEL_COLOR = "color"; public static final String CHANNEL_COLOR_NAME = "color_name"; + public static final String CHANNEL_PITMASTER_PREFIX = "pit"; + public static final String CHANNEL_PITMASTER_1 = "pit1"; + public static final String CHANNEL_PITMASTER_2 = "pit2"; public static final String CHANNEL_PITMASTER_ENABLED = "enabled"; // Mini public static final String CHANNEL_PITMASTER_CURRENT = "current"; // Mini public static final String CHANNEL_PITMASTER_SETPOINT = "setpoint"; // Mini+Nano @@ -76,7 +77,12 @@ public class WlanThermoBindingConstants { public static final String CHANNEL_PITMASTER_STATE = "state"; // Nano public static final String CHANNEL_PITMASTER_PIDPROFILE = "pid_id"; // Nano - public static final String TRIGGER_ALARM_OFF = "OFF"; + public static final String TRIGGER_NONE = ""; public static final String TRIGGER_ALARM_MIN = "MIN"; public static final String TRIGGER_ALARM_MAX = "MAX"; + + public static final DecimalType SIGNAL_STRENGTH_4 = new DecimalType(4); + public static final DecimalType SIGNAL_STRENGTH_3 = new DecimalType(3); + public static final DecimalType SIGNAL_STRENGTH_2 = new DecimalType(2); + public static final DecimalType SIGNAL_STRENGTH_1 = new DecimalType(1); } diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniConfiguration.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoConfiguration.java similarity index 91% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniConfiguration.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoConfiguration.java index f62571d43..41508eb54 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniConfiguration.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoConfiguration.java @@ -18,12 +18,12 @@ import java.net.URISyntaxException; import org.eclipse.jdt.annotation.NonNullByDefault; /** - * The {@link WlanThermoMiniConfiguration} class contains fields mapping thing configuration parameters. + * The {@link WlanThermoConfiguration} class contains fields mapping thing configuration parameters. * * @author Christian Schlipp - Initial contribution */ @NonNullByDefault -public class WlanThermoMiniConfiguration { +public class WlanThermoConfiguration { /** * IP Address of WlanThermo. diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoException.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoException.java new file mode 100644 index 000000000..f334838e2 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoException.java @@ -0,0 +1,41 @@ +/** + * 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.wlanthermo.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link WlanThermoException} is thrown if an exception in WlanThermoBinding occurs. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoException extends Exception { + + static final long serialVersionUID = 1L; + + public WlanThermoException(String reason) { + super(reason, null); + } + + public WlanThermoException(String message, Throwable cause) { + super(message, cause); + } + + public WlanThermoException(Throwable cause) { + super(cause); + } + + public WlanThermoException() { + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoExtendedConfiguration.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoExtendedConfiguration.java new file mode 100644 index 000000000..c78d34188 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoExtendedConfiguration.java @@ -0,0 +1,51 @@ +/** + * 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.wlanthermo.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link WlanThermoExtendedConfiguration} class contains fields mapping thing configuration parameters. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoExtendedConfiguration extends WlanThermoConfiguration { + + /** + * Username of WlanThermo user. + */ + private String username = ""; + + /** + * Password of WlanThermo user. + */ + + private String password = ""; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandler.java new file mode 100644 index 000000000..3a8bacc56 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandler.java @@ -0,0 +1,189 @@ +/** + * 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.wlanthermo.internal; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.Authentication; +import org.eclipse.jetty.client.api.AuthenticationStore; +import org.eclipse.jetty.client.util.DigestAuthentication; +import org.eclipse.jetty.client.util.StringContentProvider; +import org.openhab.core.thing.*; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +/** + * The {@link WlanThermoHandler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public abstract class WlanThermoHandler extends BaseThingHandler { + + private final boolean extendedConfig; + protected WlanThermoConfiguration config = new WlanThermoConfiguration(); + protected final HttpClient httpClient; + protected final Logger logger = LoggerFactory.getLogger(WlanThermoHandler.class); + protected final Gson gson = new Gson(); + protected @Nullable ScheduledFuture pollingScheduler; + + public WlanThermoHandler(Thing thing, HttpClient httpClient, boolean extendedConfig) { + super(thing); + this.httpClient = httpClient; + this.extendedConfig = extendedConfig; + } + + @Override + public void initialize() { + updateStatus(ThingStatus.UNKNOWN); + try { + if (extendedConfig) { + config = getConfigAs(WlanThermoExtendedConfiguration.class); + WlanThermoExtendedConfiguration extendedConfig = (WlanThermoExtendedConfiguration) config; + if (extendedConfig.getUsername().isEmpty() && !extendedConfig.getPassword().isEmpty()) { + AuthenticationStore authStore = httpClient.getAuthenticationStore(); + authStore.addAuthentication(new DigestAuthentication(config.getUri(), Authentication.ANY_REALM, + extendedConfig.getUsername(), extendedConfig.getPassword())); + } + } else { + config = getConfigAs(WlanThermoConfiguration.class); + } + pollingScheduler = scheduler.scheduleWithFixedDelay(this::checkConnectionAndUpdate, 0, + config.getPollingInterval(), TimeUnit.SECONDS); + } catch (URISyntaxException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "Failed to initialize WlanThermo: " + e.getMessage()); + } + } + + @Override + public void dispose() { + ScheduledFuture oldScheduler = pollingScheduler; + if (oldScheduler != null) { + boolean stopped = oldScheduler.cancel(true); + logger.debug("Stopped polling: {}", stopped); + } + pollingScheduler = null; + } + + protected void checkConnectionAndUpdate() { + if (this.thing.getStatus() != ThingStatus.ONLINE) { + try { + if (httpClient.GET(config.getUri()).getStatus() == 200) { + updateStatus(ThingStatus.ONLINE); + // rerun immediately to update state + checkConnectionAndUpdate(); + } else { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "WlanThermo not found under given address."); + } + } catch (URISyntaxException | ExecutionException | TimeoutException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "Could not connect to WlanThermo at " + config.getIpAddress() + ": " + e.getMessage()); + } catch (InterruptedException e) { + logger.debug("Connection check interrupted. {}", e.getMessage()); + } + } else { + pull(); + } + } + + protected boolean doPost(String endpoint, String json) throws InterruptedException { + try { + URI uri = config.getUri(endpoint); + int status = httpClient.POST(uri).content(new StringContentProvider(json), "application/json") + .timeout(5, TimeUnit.SECONDS).send().getStatus(); + if (status == 401) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "No or wrong login credentials provided. Please configure username/password for write access to WlanThermo!"); + return false; + } else if (status != 200) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "Failed to update channel on device, Statuscode " + status + " on URI " + uri.toString()); + logger.debug("Payload sent: {}", json); + // Still continue to try next channel + return true; + } else { + updateStatus(ThingStatus.ONLINE); + return true; + } + } catch (TimeoutException | ExecutionException | URISyntaxException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "Failed to update channel on device: " + e.getMessage()); + return false; + } + } + + protected T doGet(String endpoint, Class object) throws InterruptedException, WlanThermoException { + try { + String json = httpClient.GET(config.getUri(endpoint)).getContentAsString(); + logger.debug("Received at {}: {}", endpoint, json); + return requireNonNull(gson.fromJson(json, object)); + } catch (URISyntaxException | ExecutionException | TimeoutException | WlanThermoException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "Update failed: " + e.getMessage()); + for (Channel channel : thing.getChannels()) { + updateState(channel.getUID(), UnDefType.UNDEF); + } + throw new WlanThermoException(e); + } + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + if (command instanceof RefreshType) { + try { + State s = getState(channelUID); + updateState(channelUID, s); + } catch (WlanThermoException e) { + logger.debug("Could not handle command of type {} for channel {}!", + command.getClass().toGenericString(), channelUID.getId()); + } + } else { + if (setState(channelUID, command) && thing.getStatus() == ThingStatus.ONLINE) { + logger.debug("Data updated, pushing changes"); + scheduler.execute(this::push); + } else { + logger.debug("Could not handle command of type {} for channel {}!", + command.getClass().toGenericString(), channelUID.getId()); + } + } + } + + protected abstract void push(); + + protected abstract void pull(); + + protected abstract State getState(ChannelUID channelUID) + throws WlanThermoInputException, WlanThermoUnknownChannelException; + + protected abstract boolean setState(ChannelUID channelUID, Command command); +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandlerFactory.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandlerFactory.java index c84195ddb..da0d991a3 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandlerFactory.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandlerFactory.java @@ -19,6 +19,9 @@ import java.util.Set; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.client.HttpClient; +import org.openhab.binding.wlanthermo.internal.api.esp32.WlanThermoEsp32Handler; +import org.openhab.binding.wlanthermo.internal.api.mini.WlanThermoMiniHandler; +import org.openhab.binding.wlanthermo.internal.api.nano.WlanThermoNanoV1Handler; import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; @@ -40,8 +43,9 @@ import org.osgi.service.component.annotations.Reference; public class WlanThermoHandlerFactory extends BaseThingHandlerFactory { private static final Set SUPPORTED_THING_TYPES_UIDS = new HashSet( - Arrays.asList(WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO, - WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI)); + Arrays.asList(WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO_V1, + WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI, + WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_ESP32)); private final HttpClient httpClient; @Activate @@ -58,10 +62,12 @@ public class WlanThermoHandlerFactory extends BaseThingHandlerFactory { protected @Nullable ThingHandler createHandler(Thing thing) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); - if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO.equals(thingTypeUID)) { - return new WlanThermoNanoHandler(thing, httpClient); + if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO_V1.equals(thingTypeUID)) { + return new WlanThermoNanoV1Handler(thing, httpClient); } else if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI.equals(thingTypeUID)) { return new WlanThermoMiniHandler(thing, httpClient); + } else if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_ESP32.equals(thingTypeUID)) { + return new WlanThermoEsp32Handler(thing, httpClient); } return null; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoInputException.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoInputException.java new file mode 100644 index 000000000..3955a3fb3 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoInputException.java @@ -0,0 +1,35 @@ +/** + * 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.wlanthermo.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link WlanThermoInputException} is thrown if input is invalid or null + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoInputException extends WlanThermoException { + + static final long serialVersionUID = 1L; + public static final String INVALID_INPUT_EXCEPTION = "Input Data is invalid!"; + + public WlanThermoInputException() { + super(INVALID_INPUT_EXCEPTION); + } + + public WlanThermoInputException(Throwable cause) { + super(INVALID_INPUT_EXCEPTION, cause); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniHandler.java deleted file mode 100644 index eb0c3893e..000000000 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniHandler.java +++ /dev/null @@ -1,152 +0,0 @@ -/** - * 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.wlanthermo.internal; - -import java.net.URISyntaxException; -import java.util.Objects; -import java.util.concurrent.*; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; -import org.openhab.binding.wlanthermo.internal.api.mini.builtin.App; -import org.openhab.binding.wlanthermo.internal.api.mini.builtin.WlanThermoMiniCommandHandler; -import org.openhab.core.common.ThreadPoolManager; -import org.openhab.core.thing.*; -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.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.gson.Gson; - -/** - * The {@link WlanThermoMiniHandler} is responsible for handling commands, which are - * sent to one of the channels. - * - * @author Christian Schlipp - Initial contribution - */ -@NonNullByDefault -public class WlanThermoMiniHandler extends BaseThingHandler { - - private final Logger logger = LoggerFactory.getLogger(WlanThermoMiniHandler.class); - private final WlanThermoMiniCommandHandler wlanThermoMiniCommandHandler = new WlanThermoMiniCommandHandler(); - - private WlanThermoMiniConfiguration config = new WlanThermoMiniConfiguration(); - private final HttpClient httpClient; - private @Nullable ScheduledFuture pollingScheduler; - private final ScheduledExecutorService scheduler = ThreadPoolManager - .getScheduledPool(WlanThermoBindingConstants.WLANTHERMO_THREAD_POOL); - private final Gson gson = new Gson(); - private App app = new App(); - - public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) { - super(thing); - this.httpClient = httpClient; - } - - @Override - public void initialize() { - logger.debug("Start initializing WlanThermo Mini!"); - config = getConfigAs(WlanThermoMiniConfiguration.class); - - updateStatus(ThingStatus.UNKNOWN); - scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS); - - logger.debug("Finished initializing WlanThermo Mini!"); - } - - private void checkConnection() { - try { - if (httpClient.GET(config.getUri("/app.php")).getStatus() == 200) { - updateStatus(ThingStatus.ONLINE); - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - oldScheduler.cancel(false); - } - pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(), - TimeUnit.SECONDS); - } else { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, - "WlanThermo not found under given address."); - } - } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) { - logger.debug("Failed to connect.", e); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, - "Could not connect to WlanThermo at " + config.getIpAddress()); - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - oldScheduler.cancel(false); - } - pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS); - } - } - - @Override - public void handleCommand(ChannelUID channelUID, Command command) { - if (command instanceof RefreshType) { - State s = wlanThermoMiniCommandHandler.getState(channelUID, app); - if (s != null) - updateState(channelUID, s); - } - // Mini is read only! - } - - private void update() { - try { - // Update objects with data from device - String json = httpClient.GET(config.getUri("/app.php")).getContentAsString(); - app = Objects.requireNonNull(gson.fromJson(json, App.class)); - logger.debug("Received at /app.php: {}", json); - - // Update channels - for (Channel channel : thing.getChannels()) { - State state = wlanThermoMiniCommandHandler.getState(channel.getUID(), app); - if (state != null) { - updateState(channel.getUID(), state); - } else { - String trigger = wlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app); - if (trigger != null) { - triggerChannel(channel.getUID(), trigger); - } - } - - } - - } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) { - logger.debug("Update failed, checking connection", e); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Update failed, reconnecting..."); - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - oldScheduler.cancel(false); - } - for (Channel channel : thing.getChannels()) { - updateState(channel.getUID(), UnDefType.UNDEF); - } - checkConnection(); - } - } - - @Override - public void dispose() { - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - boolean stopped = oldScheduler.cancel(true); - logger.debug("Stopped polling: {}", stopped); - } - pollingScheduler = null; - } -} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoConfiguration.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoConfiguration.java deleted file mode 100644 index 378b5b6d4..000000000 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoConfiguration.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * 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.wlanthermo.internal; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link WlanThermoNanoConfiguration} class contains fields mapping thing configuration parameters. - * - * @author Christian Schlipp - Initial contribution - */ -@NonNullByDefault -public class WlanThermoNanoConfiguration { - - /** - * IP Address of WlanThermo. - */ - private String ipAddress = ""; - - /** - * Username of WlanThermo user. - */ - private @Nullable String username; - - /** - * Password of WlanThermo user. - */ - - private @Nullable String password; - - /** - * Polling interval - */ - private int pollingInterval = 10; - - public String getIpAddress() { - return ipAddress; - } - - public URI getUri(String path) throws URISyntaxException { - String uri = ipAddress; - if (!uri.startsWith("http://")) { - uri = "http://" + uri; - } - - if (!path.startsWith("/") && !uri.endsWith("/")) { - uri = uri + "/"; - } - uri = uri + path; - - return new URI(uri); - } - - public URI getUri() throws URISyntaxException { - return getUri(""); - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - @Nullable - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - @Nullable - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public int getPollingInterval() { - return pollingInterval; - } - - public void setPollingInterval(int pollingInterval) { - this.pollingInterval = pollingInterval; - } -} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoHandler.java deleted file mode 100644 index 0b44d3e6e..000000000 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoHandler.java +++ /dev/null @@ -1,205 +0,0 @@ -/** - * 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.wlanthermo.internal; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Objects; -import java.util.concurrent.*; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.Authentication; -import org.eclipse.jetty.client.api.AuthenticationStore; -import org.eclipse.jetty.client.util.DigestAuthentication; -import org.eclipse.jetty.client.util.StringContentProvider; -import org.openhab.binding.wlanthermo.internal.api.nano.WlanThermoNanoCommandHandler; -import org.openhab.binding.wlanthermo.internal.api.nano.data.Data; -import org.openhab.binding.wlanthermo.internal.api.nano.settings.Settings; -import org.openhab.core.common.ThreadPoolManager; -import org.openhab.core.thing.*; -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.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.gson.Gson; - -/** - * The {@link WlanThermoNanoHandler} is responsible for handling commands, which are - * sent to one of the channels. - * - * @author Christian Schlipp - Initial contribution - */ -@NonNullByDefault -public class WlanThermoNanoHandler extends BaseThingHandler { - - private final Logger logger = LoggerFactory.getLogger(WlanThermoNanoHandler.class); - - private WlanThermoNanoConfiguration config = new WlanThermoNanoConfiguration(); - private WlanThermoNanoCommandHandler wlanThermoNanoCommandHandler = new WlanThermoNanoCommandHandler(); - private final HttpClient httpClient; - private @Nullable ScheduledFuture pollingScheduler; - private final ScheduledExecutorService scheduler = ThreadPoolManager - .getScheduledPool(WlanThermoBindingConstants.WLANTHERMO_THREAD_POOL); - private final Gson gson = new Gson(); - private Data data = new Data(); - private Settings settings = new Settings(); - - public WlanThermoNanoHandler(Thing thing, HttpClient httpClient) { - super(thing); - this.httpClient = httpClient; - } - - @Override - public void initialize() { - logger.debug("Start initializing WlanThermo Nano!"); - config = getConfigAs(WlanThermoNanoConfiguration.class); - - updateStatus(ThingStatus.UNKNOWN); - try { - if (config.getUsername() != null && !config.getUsername().isEmpty() && config.getPassword() != null - && !config.getPassword().isEmpty()) { - AuthenticationStore authStore = httpClient.getAuthenticationStore(); - authStore.addAuthentication(new DigestAuthentication(config.getUri(), Authentication.ANY_REALM, - config.getUsername(), config.getPassword())); - } - scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS); - - logger.debug("Finished initializing WlanThermo Nano!"); - } catch (URISyntaxException e) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, - "Failed to initialize WlanThermo Nano!"); - logger.debug("Failed to initialize WlanThermo Nano!", e); - } - } - - private void checkConnection() { - try { - if (httpClient.GET(config.getUri()).getStatus() == 200) { - updateStatus(ThingStatus.ONLINE); - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - oldScheduler.cancel(false); - } - pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(), - TimeUnit.SECONDS); - } else { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, - "WlanThermo not found under given address."); - } - } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) { - logger.debug("Failed to connect.", e); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, - "Could not connect to WlanThermo at " + config.getIpAddress()); - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - oldScheduler.cancel(false); - } - pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS); - } - } - - @Override - public void handleCommand(ChannelUID channelUID, Command command) { - if (command instanceof RefreshType) { - State s = wlanThermoNanoCommandHandler.getState(channelUID, data, settings); - if (s != null) - updateState(channelUID, s); - } else { - if (wlanThermoNanoCommandHandler.setState(channelUID, command, data)) { - logger.debug("Data updated, pushing changes"); - push(); - } else { - logger.debug("Could not handle command of type {} for channel {}!", - command.getClass().toGenericString(), channelUID.getId()); - } - } - } - - private void update() { - try { - // Update objects with data from device - String json = httpClient.GET(config.getUri("/data")).getContentAsString(); - data = Objects.requireNonNull(gson.fromJson(json, Data.class)); - logger.debug("Received at /data: {}", json); - json = httpClient.GET(config.getUri("/settings")).getContentAsString(); - settings = Objects.requireNonNull(gson.fromJson(json, Settings.class)); - logger.debug("Received at /settings: {}", json); - - // Update channels - for (Channel channel : thing.getChannels()) { - State state = wlanThermoNanoCommandHandler.getState(channel.getUID(), data, settings); - if (state != null) { - updateState(channel.getUID(), state); - } else { - // if we could not obtain a state, try trigger instead - String trigger = wlanThermoNanoCommandHandler.getTrigger(channel.getUID(), data); - if (trigger != null) { - triggerChannel(channel.getUID(), trigger); - } - } - } - } catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) { - logger.debug("Update failed, checking connection", e); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Update failed, reconnecting..."); - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - oldScheduler.cancel(false); - } - for (Channel channel : thing.getChannels()) { - updateState(channel.getUID(), UnDefType.UNDEF); - } - checkConnection(); - } - } - - private void push() { - data.getChannel().forEach(c -> { - try { - String json = gson.toJson(c); - logger.debug("Pushing: {}", json); - URI uri = config.getUri("/setchannels"); - int status = httpClient.POST(uri).content(new StringContentProvider(json), "application/json") - .timeout(5, TimeUnit.SECONDS).send().getStatus(); - if (status == 401) { - updateStatus(ThingStatus.ONLINE, ThingStatusDetail.COMMUNICATION_ERROR, - "No or wrong login credentials provided. Please configure username/password for write access to WlanThermo!"); - } else if (status != 200) { - updateStatus(ThingStatus.ONLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Failed to update channel " - + c.getName() + " on device, Statuscode " + status + " on URI " + uri.toString()); - } else { - updateStatus(ThingStatus.ONLINE); - } - } catch (InterruptedException | TimeoutException | ExecutionException | URISyntaxException e) { - updateStatus(ThingStatus.ONLINE, ThingStatusDetail.COMMUNICATION_ERROR, - "Failed to update channel " + c.getName() + " on device!"); - logger.debug("Failed to update channel {} on device", c.getName(), e); - } - }); - } - - @Override - public void dispose() { - ScheduledFuture oldScheduler = pollingScheduler; - if (oldScheduler != null) { - boolean stopped = oldScheduler.cancel(true); - logger.debug("Stopped polling: {}", stopped); - } - pollingScheduler = null; - } -} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUnknownChannelException.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUnknownChannelException.java new file mode 100644 index 000000000..ca0153613 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUnknownChannelException.java @@ -0,0 +1,40 @@ +/** + * 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.wlanthermo.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.thing.ChannelUID; + +/** + * The {@link WlanThermoUnknownChannelException} is thrown if a channel or trigger is unknown + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoUnknownChannelException extends WlanThermoException { + + static final long serialVersionUID = 1L; + public static final String UNKNOWN_CHANNEL_EXCEPTION = "Channel or Trigger unknown!"; + + public WlanThermoUnknownChannelException() { + super(UNKNOWN_CHANNEL_EXCEPTION); + } + + public WlanThermoUnknownChannelException(ChannelUID channelUID) { + super(UNKNOWN_CHANNEL_EXCEPTION + "ChannelUID: " + channelUID.toString()); + } + + public WlanThermoUnknownChannelException(ChannelUID channelUID, Throwable cause) { + super(UNKNOWN_CHANNEL_EXCEPTION + "ChannelUID: " + channelUID.toString(), cause); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUtil.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUtil.java new file mode 100644 index 000000000..d6ff83750 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUtil.java @@ -0,0 +1,53 @@ +/** + * 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.wlanthermo.internal; + +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.library.types.HSBType; + +/** + * The {@link WlanThermoUtil} class provides conversion functions for the WlanThermo + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoUtil { + + public static String toColorName(String colorHex, Map colorMappings, String defaultColorName) { + if (!colorHex.startsWith("#")) { + colorHex = "#" + colorHex; + } + + for (Map.Entry entry : colorMappings.entrySet()) { + if (entry.getValue().equalsIgnoreCase(colorHex)) { + return entry.getKey(); + } + } + + return defaultColorName; + } + + public static String toHex(HSBType hsb) { + return "#" + String.format("%02X", hsb.getRed().intValue()) + String.format("%02X", hsb.getGreen().intValue()) + + String.format("%02X", hsb.getBlue().intValue()); + } + + public static T requireNonNull(@Nullable T obj) throws WlanThermoInputException { + if (obj == null) + throw new WlanThermoInputException(); + return obj; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandler.java new file mode 100644 index 000000000..cf72a89eb --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandler.java @@ -0,0 +1,299 @@ +/** + * 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.wlanthermo.internal.api.esp32; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*; +import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull; + +import java.awt.Color; +import java.math.BigInteger; +import java.util.List; + +import javax.measure.Unit; +import javax.measure.quantity.Temperature; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.wlanthermo.internal.WlanThermoInputException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUtil; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Channel; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Data; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Pm; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.System; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings.Settings; +import org.openhab.core.library.types.*; +import org.openhab.core.library.unit.ImperialUnits; +import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.library.unit.Units; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +/** + * The {@link WlanThermoEsp32CommandHandler} is responsible for mapping the Commands to the respective data fields + * of the API. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoEsp32CommandHandler { + + public static State getState(ChannelUID channelUID, Data data, Settings settings) + throws WlanThermoUnknownChannelException, WlanThermoInputException { + + String groupId = requireNonNull(channelUID.getGroupId()); + System system = data.getSystem(); + Unit unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS; + + List channelList = data.getChannel(); + if (SYSTEM.equals(groupId)) { + switch (channelUID.getIdWithoutGroup()) { + case SYSTEM_SOC: + if (system.getSoc() != null) { + return new DecimalType(system.getSoc()); + } else { + return UnDefType.UNDEF; + } + case SYSTEM_CHARGE: + if (system.getCharge() != null) { + return OnOffType.from(system.getCharge()); + } else { + return UnDefType.UNDEF; + } + case SYSTEM_RSSI_SIGNALSTRENGTH: + int dbm = system.getRssi(); + if (dbm >= -80) { + return SIGNAL_STRENGTH_4; + } else if (dbm >= -95) { + return SIGNAL_STRENGTH_3; + } else if (dbm >= -105) { + return SIGNAL_STRENGTH_2; + } else { + return SIGNAL_STRENGTH_1; + } + case SYSTEM_RSSI: + return new QuantityType<>(system.getRssi(), Units.DECIBEL_MILLIWATTS); + } + } else if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1; + if (channelList != null && channelList.size() > 0 && channelId < channelList.size()) { + Channel channel = channelList.get(channelId); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_NAME: + return new StringType(channel.getName()); + case CHANNEL_TYP: + return new StringType(settings.getSensors().get(channel.getTyp()).getName()); + case CHANNEL_TEMP: + return channel.getTemp() == 999.0 ? UnDefType.UNDEF + : new QuantityType<>(channel.getTemp(), unit); + case CHANNEL_MIN: + return new QuantityType<>(channel.getMin(), unit); + case CHANNEL_MAX: + return new QuantityType<>(channel.getMax(), unit); + case CHANNEL_ALARM_DEVICE: + return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(1)); + case CHANNEL_ALARM_PUSH: + return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(0)); + case CHANNEL_ALARM_OPENHAB_HIGH: + if (channel.getTemp() != 999 && channel.getTemp() > channel.getMax()) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + case CHANNEL_ALARM_OPENHAB_LOW: + if (channel.getTemp() != 999 && channel.getTemp() < channel.getMin()) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + case CHANNEL_COLOR: + String color = channel.getColor(); + if (color != null && !color.isEmpty()) { + Color c = Color.decode(color); + return HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue()); + } else { + return UnDefType.UNDEF; + } + case CHANNEL_COLOR_NAME: + String colorHex = channel.getColor(); + if (colorHex != null && !colorHex.isEmpty()) { + return new StringType(WlanThermoEsp32Util.toColorName(colorHex)); + } else { + return UnDefType.UNDEF; + } + } + } + } else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PITMASTER_PREFIX.length())) - 1; + if (settings.getFeatures().getPitmaster() && data.getPitmaster() != null + && data.getPitmaster().getPm() != null && data.getPitmaster().getPm().size() > channelId) { + Pm pm = data.getPitmaster().getPm().get(channelId); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_PITMASTER_CHANNEL_ID: + return new DecimalType(pm.getChannel()); + case CHANNEL_PITMASTER_PIDPROFILE: + return new DecimalType(pm.getPid()); + case CHANNEL_PITMASTER_DUTY_CYCLE: + return new DecimalType(pm.getValue()); + case CHANNEL_PITMASTER_SETPOINT: + return new QuantityType<>(pm.getSet(), unit); + case CHANNEL_PITMASTER_STATE: + return new StringType(pm.getTyp()); + } + } else { + return UnDefType.UNDEF; + } + } + throw new WlanThermoUnknownChannelException(channelUID); + } + + public static boolean setState(ChannelUID channelUID, Command command, Data data, Settings settings) { + String groupId; + try { + groupId = requireNonNull(channelUID.getGroupId()); + } catch (WlanThermoInputException ignore) { + return false; + } + + List channelList = data.getChannel(); + System system = data.getSystem(); + Unit unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS; + + if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1; + if (channelList.size() > 0 && channelId < channelList.size()) { + Channel channel = channelList.get(channelId); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_NAME: + if (command instanceof StringType) { + channel.setName(command.toFullString()); + return true; + } + return false; + case CHANNEL_MIN: + if (command instanceof QuantityType) { + try { + channel.setMin(requireNonNull(((QuantityType) command).toUnit(unit)).doubleValue()); + return true; + } catch (WlanThermoInputException ignore) { + return false; + } + } + return false; + case CHANNEL_MAX: + if (command instanceof QuantityType) { + try { + channel.setMax(requireNonNull(((QuantityType) command).toUnit(unit)).doubleValue()); + return true; + } catch (WlanThermoInputException ignore) { + return false; + } + } + return false; + case CHANNEL_ALARM_DEVICE: + if (command instanceof OnOffType) { + BigInteger value; + if (command == OnOffType.ON) { + value = BigInteger.valueOf(channel.getAlarm()).setBit(1); + } else { + value = BigInteger.valueOf(channel.getAlarm()).clearBit(1); + } + channel.setAlarm(value.intValue()); + return true; + } + return false; + case CHANNEL_ALARM_PUSH: + if (command instanceof OnOffType) { + BigInteger value; + if (command == OnOffType.ON) { + value = BigInteger.valueOf(channel.getAlarm()).setBit(0); + } else { + value = BigInteger.valueOf(channel.getAlarm()).clearBit(0); + } + channel.setAlarm(value.intValue()); + return true; + } + return false; + case CHANNEL_COLOR_NAME: + if (command instanceof StringType) { + channel.setColor(WlanThermoEsp32Util.toHex(((StringType) command).toString())); + return true; + } + return false; + case CHANNEL_COLOR: + if (command instanceof HSBType) { + channel.setColor(WlanThermoUtil.toHex((HSBType) command)); + return true; + } + return false; + } + } + } else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PITMASTER_PREFIX.length())) - 1; + if (settings.getFeatures().getPitmaster() && data.getPitmaster() != null + && data.getPitmaster().getPm() != null && data.getPitmaster().getPm().size() > channelId) { + Pm pm = data.getPitmaster().getPm().get(channelId); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_PITMASTER_CHANNEL_ID: + pm.setChannel(((DecimalType) command).intValue()); + return true; + case CHANNEL_PITMASTER_PIDPROFILE: + pm.setPid(((DecimalType) command).intValue()); + return true; + case CHANNEL_PITMASTER_SETPOINT: + try { + pm.setSet(requireNonNull(((QuantityType) command).toUnit(unit)).doubleValue()); + return true; + } catch (WlanThermoInputException ignore) { + return false; + } + case CHANNEL_PITMASTER_STATE: + String state = ((StringType) command).toString(); + if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual") + || state.equalsIgnoreCase("auto")) { + pm.setTyp(state); + return true; + } + return false; + } + } + } + return false; + } + + public static String getTrigger(ChannelUID channelUID, Data data) + throws WlanThermoUnknownChannelException, WlanThermoInputException { + String groupId = requireNonNull(channelUID.getGroupId()); + List channelList = data.getChannel(); + + if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1; + if (channelList.size() > 0 && channelId < channelList.size()) { + Channel channel = channelList.get(channelId); + if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) { + if (channel.getTemp() != 999) { + if (channel.getTemp() > channel.getMax()) { + return TRIGGER_ALARM_MAX; + } else if (channel.getTemp() < channel.getMin()) { + return TRIGGER_ALARM_MIN; + } else { + return TRIGGER_NONE; + } + } + } + } + } + throw new WlanThermoUnknownChannelException(channelUID); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Handler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Handler.java new file mode 100644 index 000000000..b42c882c0 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Handler.java @@ -0,0 +1,124 @@ +/** + * 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.wlanthermo.internal.api.esp32; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE; + +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.client.HttpClient; +import org.openhab.binding.wlanthermo.internal.*; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Data; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings.Settings; +import org.openhab.core.thing.*; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; + +/** + * The {@link WlanThermoEsp32Handler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoEsp32Handler extends WlanThermoHandler { + + private Data data = new Data(); + private Settings settings = new Settings(); + + public WlanThermoEsp32Handler(Thing thing, HttpClient httpClient) { + super(thing, httpClient, true); + } + + @Override + protected State getState(ChannelUID channelUID) throws WlanThermoInputException, WlanThermoUnknownChannelException { + return WlanThermoEsp32CommandHandler.getState(channelUID, data, settings); + } + + @Override + protected boolean setState(ChannelUID channelUID, Command command) { + return WlanThermoEsp32CommandHandler.setState(channelUID, command, data, settings); + } + + @Override + protected void push() { + // Push update for sensor channels + for (org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Channel c : data.getChannel()) { + try { + String json = gson.toJson(c); + if (!doPost("/setchannels", json)) { + break; + } + } catch (InterruptedException e) { + logger.debug("Push interrupted. {}", e.getMessage()); + return; + } + } + + // push update for pitmaster channels + try { + String json = gson.toJson(data.getPitmaster().getPm()); + doPost("/setpitmaster", json); + } catch (InterruptedException e) { + logger.debug("Push interrupted. {}", e.getMessage()); + } + } + + @Override + protected void pull() { + try { + // Update objects with data from device + data = doGet("/data", Data.class); + settings = doGet("/settings", Settings.class); + + // Update Channels if required + Map properties = editProperties(); + Boolean pmEnabled = settings.getFeatures().getBluetooth(); + int pmChannels = pmEnabled ? data.getPitmaster().getPm().size() : 0; + int tempChannels = data.getChannel().size(); + + // Update properties + properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_MODEL, settings.getDevice().getDevice()); + properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_SERIAL, settings.getDevice().getSerial()); + properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_ESP32_BT_ENABLED, + settings.getFeatures().getBluetooth().toString()); + properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_ESP32_PM_ENABLED, pmEnabled.toString()); + properties.put(WlanThermoBindingConstants.PROPERTY_ESP32_TEMP_CHANNELS, String.valueOf(tempChannels)); + properties.put(WlanThermoBindingConstants.PROPERTY_ESP32_PM_CHANNELS, String.valueOf(pmChannels)); + updateProperties(properties); + + // Update channel state + for (Channel channel : thing.getChannels()) { + try { + State state = WlanThermoEsp32CommandHandler.getState(channel.getUID(), data, settings); + updateState(channel.getUID(), state); + } catch (WlanThermoUnknownChannelException e) { + // if we could not obtain a state, try trigger instead + try { + String trigger = WlanThermoEsp32CommandHandler.getTrigger(channel.getUID(), data); + if (!trigger.equals(TRIGGER_NONE)) { + triggerChannel(channel.getUID(), trigger); + } + } catch (WlanThermoUnknownChannelException e1) { + logger.debug("{}", e.getMessage()); + } + } + } + } catch (WlanThermoException ignore) { + // Nothing more to do + } catch (InterruptedException e) { + logger.debug("Update interrupted. {}", e.getMessage()); + } + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Util.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Util.java new file mode 100644 index 000000000..cef43ae8d --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Util.java @@ -0,0 +1,74 @@ +/** + * 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.wlanthermo.internal.api.esp32; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.wlanthermo.internal.WlanThermoUtil; + +/** + * The {@link WlanThermoEsp32Util} class provides conversion functions for the WlanThermo Nano V3 + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoEsp32Util extends WlanThermoUtil { + + private static final Map COLOR_MAPPINGS = createColorMap(); + private static final String DEFAULT_HEX = "#FFFFFF"; + private static final String DEFAULT_COLORNAME = "undefined"; + + private WlanThermoEsp32Util() { + // hidden + } + + private static Map createColorMap() { + HashMap map = new HashMap<>(); + map.put("yellow", "#FFFF00"); + map.put("dark yellow", "#FFC002"); + map.put("green", "#00FF00"); + map.put("white", "#FFFFFF"); + map.put("pink", "#FF1DC4"); + map.put("orange", "#E46C0A"); + map.put("olive", "#C3D69B"); + map.put("light blue", "#0FE6F1"); + map.put("blue", "#0000FF"); + map.put("dark green", "#03A923"); + map.put("brown", "#C84B32"); + map.put("light brown", "#FF9B69"); + map.put("dark blue", "#5082BE"); + map.put("light pink", "#FFB1D0"); + map.put("light green", "#A6EF03"); + map.put("dark pink", "#D42A6B"); + map.put("beige", "#FFDA8F"); + map.put("azure", "#00B0F0"); + map.put("dark olive", "#948A54"); + return map; + } + + /** + * Convert WlanThermo Color Name to Hex + * + * @param colorName the WlanThermo color name + * @return The color as Hex String + */ + public static String toHex(String colorName) { + return COLOR_MAPPINGS.getOrDefault(colorName, DEFAULT_HEX); + } + + public static String toColorName(String colorHex) { + return toColorName(colorHex, COLOR_MAPPINGS, DEFAULT_COLORNAME); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Channel.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Channel.java new file mode 100644 index 000000000..330191845 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Channel.java @@ -0,0 +1,136 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.data; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Channel { + + @SerializedName("number") + @Expose + private Integer number; + @SerializedName("name") + @Expose + private String name; + @SerializedName("typ") + @Expose + private Integer typ; + @SerializedName("temp") + @Expose + private Double temp; + @SerializedName("min") + @Expose + private Double min; + @SerializedName("max") + @Expose + private Double max; + @SerializedName("alarm") + @Expose + private Integer alarm; + @SerializedName("color") + @Expose + private String color; + @SerializedName("fixed") + @Expose + private Boolean fixed; + @SerializedName("connected") + @Expose + private Boolean connected; + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getTyp() { + return typ; + } + + public void setTyp(Integer typ) { + this.typ = typ; + } + + public Double getTemp() { + return temp; + } + + public void setTemp(Double temp) { + this.temp = temp; + } + + public Double getMin() { + return min; + } + + public void setMin(Double min) { + this.min = min; + } + + public Double getMax() { + return max; + } + + public void setMax(Double max) { + this.max = max; + } + + public Integer getAlarm() { + return alarm; + } + + public void setAlarm(Integer alarm) { + this.alarm = alarm; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public Boolean getFixed() { + return fixed; + } + + public void setFixed(Boolean fixed) { + this.fixed = fixed; + } + + public Boolean getConnected() { + return connected; + } + + public void setConnected(Boolean connected) { + this.connected = connected; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Data.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Data.java new file mode 100644 index 000000000..470d8801a --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Data.java @@ -0,0 +1,61 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.data; + +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Data { + + @SerializedName("system") + @Expose + private System system; + @SerializedName("channel") + @Expose + private List channel = null; + @SerializedName("pitmaster") + @Expose + private Pitmaster pitmaster; + + public System getSystem() { + return system; + } + + public void setSystem(System system) { + this.system = system; + } + + public List getChannel() { + return channel; + } + + public void setChannel(List channel) { + this.channel = channel; + } + + public Pitmaster getPitmaster() { + return pitmaster; + } + + public void setPitmaster(Pitmaster pitmaster) { + this.pitmaster = pitmaster; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pitmaster.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pitmaster.java new file mode 100644 index 000000000..3d6f54200 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pitmaster.java @@ -0,0 +1,50 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.data; + +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Pitmaster { + + @SerializedName("type") + @Expose + private List type = null; + @SerializedName("pm") + @Expose + private List pm = null; + + public List getType() { + return type; + } + + public void setType(List type) { + this.type = type; + } + + public List getPm() { + return pm; + } + + public void setPm(List pm) { + this.pm = pm; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pm.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pm.java new file mode 100644 index 000000000..27bca17fa --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pm.java @@ -0,0 +1,114 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.data; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Pm { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("channel") + @Expose + private Integer channel; + @SerializedName("pid") + @Expose + private Integer pid; + @SerializedName("value") + @Expose + private Integer value; + @SerializedName("set") + @Expose + private Double set; + @SerializedName("typ") + @Expose + private String typ; + @SerializedName("set_color") + @Expose + private String setColor; + @SerializedName("value_color") + @Expose + private String valueColor; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getChannel() { + return channel; + } + + public void setChannel(Integer channel) { + this.channel = channel; + } + + public Integer getPid() { + return pid; + } + + public void setPid(Integer pid) { + this.pid = pid; + } + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + + public Double getSet() { + return set; + } + + public void setSet(Double set) { + this.set = set; + } + + public String getTyp() { + return typ; + } + + public void setTyp(String typ) { + this.typ = typ; + } + + public String getSetColor() { + return setColor; + } + + public void setSetColor(String setColor) { + this.setColor = setColor; + } + + public String getValueColor() { + return valueColor; + } + + public void setValueColor(String valueColor) { + this.valueColor = valueColor; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/System.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/System.java new file mode 100644 index 000000000..6a1286008 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/System.java @@ -0,0 +1,92 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.data; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class System { + + @SerializedName("time") + @Expose + private String time; + @SerializedName("unit") + @Expose + private String unit; + @SerializedName("soc") + @Expose + private Integer soc; + @SerializedName("charge") + @Expose + private Boolean charge; + @SerializedName("rssi") + @Expose + private Integer rssi; + @SerializedName("online") + @Expose + private Integer online; + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public Integer getSoc() { + return soc; + } + + public void setSoc(Integer soc) { + this.soc = soc; + } + + public Boolean getCharge() { + return charge; + } + + public void setCharge(Boolean charge) { + this.charge = charge; + } + + public Integer getRssi() { + return rssi; + } + + public void setRssi(Integer rssi) { + this.rssi = rssi; + } + + public Integer getOnline() { + return online; + } + + public void setOnline(Integer online) { + this.online = online; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Api.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Api.java new file mode 100644 index 000000000..64fffdaac --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Api.java @@ -0,0 +1,37 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Api { + + @SerializedName("version") + @Expose + private String version; + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Device.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Device.java new file mode 100644 index 000000000..95552be39 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Device.java @@ -0,0 +1,114 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Device { + + @SerializedName("device") + @Expose + private String device; + @SerializedName("serial") + @Expose + private String serial; + @SerializedName("cpu") + @Expose + private String cpu; + @SerializedName("flash_size") + @Expose + private Integer flashSize; + @SerializedName("hw_version") + @Expose + private String hwVersion; + @SerializedName("sw_version") + @Expose + private String swVersion; + @SerializedName("api_version") + @Expose + private String apiVersion; + @SerializedName("language") + @Expose + private String language; + + public String getDevice() { + return device; + } + + public void setDevice(String device) { + this.device = device; + } + + public String getSerial() { + return serial; + } + + public void setSerial(String serial) { + this.serial = serial; + } + + public String getCpu() { + return cpu; + } + + public void setCpu(String cpu) { + this.cpu = cpu; + } + + public Integer getFlashSize() { + return flashSize; + } + + public void setFlashSize(Integer flashSize) { + this.flashSize = flashSize; + } + + public String getHwVersion() { + return hwVersion; + } + + public void setHwVersion(String hwVersion) { + this.hwVersion = hwVersion; + } + + public String getSwVersion() { + return swVersion; + } + + public void setSwVersion(String swVersion) { + this.swVersion = swVersion; + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Display.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Display.java new file mode 100644 index 000000000..205977cf7 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Display.java @@ -0,0 +1,48 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Display { + + @SerializedName("updname") + @Expose + private String updname; + @SerializedName("orientation") + @Expose + private Integer orientation; + + public String getUpdname() { + return updname; + } + + public void setUpdname(String updname) { + this.updname = updname; + } + + public Integer getOrientation() { + return orientation; + } + + public void setOrientation(Integer orientation) { + this.orientation = orientation; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Ext.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Ext.java new file mode 100644 index 000000000..985ec0a7a --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Ext.java @@ -0,0 +1,94 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Ext { + + @SerializedName("on") + @Expose + private Integer on; + @SerializedName("token") + @Expose + private String token; + @SerializedName("id") + @Expose + private String id; + @SerializedName("repeat") + @Expose + private Integer repeat; + @SerializedName("service") + @Expose + private Integer service; + @SerializedName("services") + @Expose + private List services = null; + + public Integer getOn() { + return on; + } + + public void setOn(Integer on) { + this.on = on; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getRepeat() { + return repeat; + } + + public void setRepeat(Integer repeat) { + this.repeat = repeat; + } + + public Integer getService() { + return service; + } + + public void setService(Integer service) { + this.service = service; + } + + public List getServices() { + return services; + } + + public void setServices(List services) { + this.services = services; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Features.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Features.java new file mode 100644 index 000000000..bd4b2d39d --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Features.java @@ -0,0 +1,48 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Features { + + @SerializedName("bluetooth") + @Expose + private Boolean bluetooth; + @SerializedName("pitmaster") + @Expose + private Boolean pitmaster; + + public Boolean getBluetooth() { + return bluetooth; + } + + public void setBluetooth(Boolean bluetooth) { + this.bluetooth = bluetooth; + } + + public Boolean getPitmaster() { + return pitmaster; + } + + public void setPitmaster(Boolean pitmaster) { + this.pitmaster = pitmaster; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Iot.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Iot.java new file mode 100644 index 000000000..e3033a497 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Iot.java @@ -0,0 +1,147 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Iot { + + @SerializedName("PMQhost") + @Expose + private String pMQhost; + @SerializedName("PMQport") + @Expose + private Integer pMQport; + @SerializedName("PMQuser") + @Expose + private String pMQuser; + @SerializedName("PMQpass") + @Expose + private String pMQpass; + @SerializedName("PMQqos") + @Expose + private Integer pMQqos; + @SerializedName("PMQon") + @Expose + private Boolean pMQon; + @SerializedName("PMQint") + @Expose + private Integer pMQint; + @SerializedName("CLon") + @Expose + private Boolean cLon; + @SerializedName("CLtoken") + @Expose + private String cLtoken; + @SerializedName("CLint") + @Expose + private Integer cLint; + @SerializedName("CLurl") + @Expose + private String cLurl; + + public String getPMQhost() { + return pMQhost; + } + + public void setPMQhost(String pMQhost) { + this.pMQhost = pMQhost; + } + + public Integer getPMQport() { + return pMQport; + } + + public void setPMQport(Integer pMQport) { + this.pMQport = pMQport; + } + + public String getPMQuser() { + return pMQuser; + } + + public void setPMQuser(String pMQuser) { + this.pMQuser = pMQuser; + } + + public String getPMQpass() { + return pMQpass; + } + + public void setPMQpass(String pMQpass) { + this.pMQpass = pMQpass; + } + + public Integer getPMQqos() { + return pMQqos; + } + + public void setPMQqos(Integer pMQqos) { + this.pMQqos = pMQqos; + } + + public Boolean getPMQon() { + return pMQon; + } + + public void setPMQon(Boolean pMQon) { + this.pMQon = pMQon; + } + + public Integer getPMQint() { + return pMQint; + } + + public void setPMQint(Integer pMQint) { + this.pMQint = pMQint; + } + + public Boolean getCLon() { + return cLon; + } + + public void setCLon(Boolean cLon) { + this.cLon = cLon; + } + + public String getCLtoken() { + return cLtoken; + } + + public void setCLtoken(String cLtoken) { + this.cLtoken = cLtoken; + } + + public Integer getCLint() { + return cLint; + } + + public void setCLint(Integer cLint) { + this.cLint = cLint; + } + + public String getCLurl() { + return cLurl; + } + + public void setCLurl(String cLurl) { + this.cLurl = cLurl; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Notes.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Notes.java new file mode 100644 index 000000000..f4d5cc54b --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Notes.java @@ -0,0 +1,50 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Notes { + + @SerializedName("fcm") + @Expose + private List fcm = null; + @SerializedName("ext") + @Expose + private Ext ext; + + public List getFcm() { + return fcm; + } + + public void setFcm(List fcm) { + this.fcm = fcm; + } + + public Ext getExt() { + return ext; + } + + public void setExt(Ext ext) { + this.ext = ext; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Pid.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Pid.java new file mode 100644 index 000000000..512545110 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Pid.java @@ -0,0 +1,180 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Pid { + + @SerializedName("name") + @Expose + private String name; + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("aktor") + @Expose + private Integer aktor; + @SerializedName("Kp") + @Expose + private Double kp; + @SerializedName("Ki") + @Expose + private Double ki; + @SerializedName("Kd") + @Expose + private Double kd; + @SerializedName("DCmmin") + @Expose + private Double dCmmin; + @SerializedName("DCmmax") + @Expose + private Double dCmmax; + @SerializedName("opl") + @Expose + private Integer opl; + @SerializedName("SPmin") + @Expose + private Double sPmin; + @SerializedName("SPmax") + @Expose + private Double sPmax; + @SerializedName("link") + @Expose + private Integer link; + @SerializedName("tune") + @Expose + private Integer tune; + @SerializedName("jp") + @Expose + private Integer jp; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getAktor() { + return aktor; + } + + public void setAktor(Integer aktor) { + this.aktor = aktor; + } + + public Double getKp() { + return kp; + } + + public void setKp(Double kp) { + this.kp = kp; + } + + public Double getKi() { + return ki; + } + + public void setKi(Double ki) { + this.ki = ki; + } + + public Double getKd() { + return kd; + } + + public void setKd(Double kd) { + this.kd = kd; + } + + public Double getDCmmin() { + return dCmmin; + } + + public void setDCmmin(Double dCmmin) { + this.dCmmin = dCmmin; + } + + public Double getDCmmax() { + return dCmmax; + } + + public void setDCmmax(Double dCmmax) { + this.dCmmax = dCmmax; + } + + public Integer getOpl() { + return opl; + } + + public void setOpl(Integer opl) { + this.opl = opl; + } + + public Double getSPmin() { + return sPmin; + } + + public void setSPmin(Double sPmin) { + this.sPmin = sPmin; + } + + public Double getSPmax() { + return sPmax; + } + + public void setSPmax(Double sPmax) { + this.sPmax = sPmax; + } + + public Integer getLink() { + return link; + } + + public void setLink(Integer link) { + this.link = link; + } + + public Integer getTune() { + return tune; + } + + public void setTune(Integer tune) { + this.tune = tune; + } + + public Integer getJp() { + return jp; + } + + public void setJp(Integer jp) { + this.jp = jp; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Sensor.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Sensor.java new file mode 100644 index 000000000..e2dc02279 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Sensor.java @@ -0,0 +1,59 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Sensor { + + @SerializedName("type") + @Expose + private Integer type; + @SerializedName("name") + @Expose + private String name; + @SerializedName("fixed") + @Expose + private Boolean fixed; + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getFixed() { + return fixed; + } + + public void setFixed(Boolean fixed) { + this.fixed = fixed; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Settings.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Settings.java new file mode 100644 index 000000000..dc1250861 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Settings.java @@ -0,0 +1,149 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class Settings { + + @SerializedName("device") + @Expose + private Device device; + @SerializedName("system") + @Expose + private System system; + @SerializedName("hardware") + @Expose + private List hardware = null; + @SerializedName("api") + @Expose + private Api api; + @SerializedName("sensors") + @Expose + private List sensors = null; + @SerializedName("features") + @Expose + private Features features; + @SerializedName("pid") + @Expose + private List pid = null; + @SerializedName("aktor") + @Expose + private List aktor = null; + @SerializedName("display") + @Expose + private Display display; + @SerializedName("iot") + @Expose + private Iot iot; + @SerializedName("notes") + @Expose + private Notes notes; + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } + + public System getSystem() { + return system; + } + + public void setSystem(System system) { + this.system = system; + } + + public List getHardware() { + return hardware; + } + + public void setHardware(List hardware) { + this.hardware = hardware; + } + + public Api getApi() { + return api; + } + + public void setApi(Api api) { + this.api = api; + } + + public List getSensors() { + return sensors; + } + + public void setSensors(List sensors) { + this.sensors = sensors; + } + + public Features getFeatures() { + return features; + } + + public void setFeatures(Features features) { + this.features = features; + } + + public List getPid() { + return pid; + } + + public void setPid(List pid) { + this.pid = pid; + } + + public List getAktor() { + return aktor; + } + + public void setAktor(List aktor) { + this.aktor = aktor; + } + + public Display getDisplay() { + return display; + } + + public void setDisplay(Display display) { + this.display = display; + } + + public Iot getIot() { + return iot; + } + + public void setIot(Iot iot) { + this.iot = iot; + } + + public Notes getNotes() { + return notes; + } + + public void setNotes(Notes notes) { + this.notes = notes; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/System.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/System.java new file mode 100644 index 000000000..e10af5d64 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/System.java @@ -0,0 +1,136 @@ +/** + * 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.wlanthermo.internal.api.esp32.dto.settings; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This DTO is used to parse the JSON + * Class is auto-generated from JSON using http://www.jsonschema2pojo.org/ + * + * @author Christian Schlipp - Initial contribution + */ +public class System { + + @SerializedName("time") + @Expose + private String time; + @SerializedName("unit") + @Expose + private String unit; + @SerializedName("ap") + @Expose + private String ap; + @SerializedName("host") + @Expose + private String host; + @SerializedName("language") + @Expose + private String language; + @SerializedName("version") + @Expose + private String version; + @SerializedName("getupdate") + @Expose + private String getupdate; + @SerializedName("autoupd") + @Expose + private Boolean autoupd; + @SerializedName("prerelease") + @Expose + private Boolean prerelease; + @SerializedName("hwversion") + @Expose + private String hwversion; + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public String getAp() { + return ap; + } + + public void setAp(String ap) { + this.ap = ap; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getGetupdate() { + return getupdate; + } + + public void setGetupdate(String getupdate) { + this.getupdate = getupdate; + } + + public Boolean getAutoupd() { + return autoupd; + } + + public void setAutoupd(Boolean autoupd) { + this.autoupd = autoupd; + } + + public Boolean getPrerelease() { + return prerelease; + } + + public void setPrerelease(Boolean prerelease) { + this.prerelease = prerelease; + } + + public String getHwversion() { + return hwversion; + } + + public void setHwversion(String hwversion) { + this.hwversion = hwversion; + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandler.java new file mode 100644 index 000000000..ccdb04462 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandler.java @@ -0,0 +1,165 @@ +/** + * 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.wlanthermo.internal.api.mini; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*; +import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull; + +import java.awt.*; + +import javax.measure.Unit; +import javax.measure.quantity.Temperature; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants; +import org.openhab.binding.wlanthermo.internal.WlanThermoInputException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException; +import org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin.*; +import org.openhab.core.library.types.*; +import org.openhab.core.library.unit.ImperialUnits; +import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +/** + * The {@link WlanThermoMiniCommandHandler} is responsible for mapping the Commands to the respective data fields + * of the API. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoMiniCommandHandler { + + public static final String ERROR = "er"; + + public static State getState(ChannelUID channelUID, App app) + throws WlanThermoUnknownChannelException, WlanThermoInputException { + String groupId = requireNonNull(channelUID.getGroupId()); + Unit unit = "fahrenheit".equals(app.getTempUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS; + + if (SYSTEM.equals(groupId)) { + switch (channelUID.getIdWithoutGroup()) { + case WlanThermoBindingConstants.SYSTEM_CPU_TEMP: + if (app.getCpuTemp() == null) { + return UnDefType.UNDEF; + } else { + return new DecimalType(app.getCpuTemp()); + } + case WlanThermoBindingConstants.SYSTEM_CPU_LOAD: + if (app.getCpuLoad() == null) { + return UnDefType.UNDEF; + } else { + return new DecimalType(app.getCpuLoad()); + } + } + } else if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())); + if (channelId >= 0 && channelId <= 9) { + Channel channel = app.getChannel(); + if (channel == null) { + return UnDefType.UNDEF; + } + Data data = channel.getData(channelId); + switch (channelUID.getIdWithoutGroup()) { + case WlanThermoBindingConstants.CHANNEL_NAME: + return new StringType(data.getName()); + case WlanThermoBindingConstants.CHANNEL_TEMP: + if (data.getState().equals(ERROR)) { + return UnDefType.UNDEF; + } else { + return new QuantityType<>(data.getTemp(), unit); + } + case WlanThermoBindingConstants.CHANNEL_MIN: + return new QuantityType<>(data.getTempMin(), unit); + case WlanThermoBindingConstants.CHANNEL_MAX: + return new QuantityType<>(data.getTempMax(), unit); + case WlanThermoBindingConstants.CHANNEL_ALARM_DEVICE: + return OnOffType.from(data.getAlert()); + case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_HIGH: + if (!data.getState().equals(ERROR) && data.getTemp() > data.getTempMax()) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_LOW: + if (!data.getState().equals(ERROR) && data.getTemp() < data.getTempMin()) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + case WlanThermoBindingConstants.CHANNEL_COLOR: + Color c = Color.decode(WlanThermoMiniUtil.toHex(data.getColor())); + return HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue()); + case WlanThermoBindingConstants.CHANNEL_COLOR_NAME: + return new StringType(data.getColor()); + } + } + } else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) { + Pit pit; + if (groupId.equals(CHANNEL_PITMASTER_1)) { + pit = app.getPit(); + } else if (groupId.equals(CHANNEL_PITMASTER_2)) { + pit = app.getPit2(); + } else { + return UnDefType.UNDEF; + } + if (pit == null || !pit.getEnabled()) { + return UnDefType.UNDEF; + } + switch (channelUID.getIdWithoutGroup()) { + case WlanThermoBindingConstants.CHANNEL_PITMASTER_ENABLED: + return OnOffType.from(pit.getEnabled()); + case WlanThermoBindingConstants.CHANNEL_PITMASTER_CURRENT: + return new DecimalType(pit.getCurrent()); + case WlanThermoBindingConstants.CHANNEL_PITMASTER_SETPOINT: + return new QuantityType<>(pit.getSetpoint(), unit); + case WlanThermoBindingConstants.CHANNEL_PITMASTER_DUTY_CYCLE: + return new DecimalType(pit.getControlOut()); + case WlanThermoBindingConstants.CHANNEL_PITMASTER_LID_OPEN: + return OnOffType.from(pit.getOpenLid().equals("True")); + case WlanThermoBindingConstants.CHANNEL_PITMASTER_CHANNEL_ID: + return new DecimalType(pit.getCh()); + } + } + throw new WlanThermoUnknownChannelException(channelUID); + } + + public static String getTrigger(ChannelUID channelUID, App app) + throws WlanThermoUnknownChannelException, WlanThermoInputException { + String groupId = requireNonNull(channelUID.getGroupId()); + + if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1; + if (channelId >= 0 && channelId <= 9) { + Channel channel = app.getChannel(); + if (channel == null) { + throw new WlanThermoInputException(); + } + Data data = channel.getData(channelId); + if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) { + if (!data.getState().equals(ERROR)) { + if (data.getTemp() > data.getTempMax()) { + return TRIGGER_ALARM_MAX; + } else if (data.getTemp() < data.getTempMin()) { + return TRIGGER_ALARM_MIN; + } else { + return TRIGGER_NONE; + } + } + } + } + } + throw new WlanThermoUnknownChannelException(channelUID); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniHandler.java new file mode 100644 index 000000000..b5a57c737 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniHandler.java @@ -0,0 +1,85 @@ +/** + * 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.wlanthermo.internal.api.mini; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.client.HttpClient; +import org.openhab.binding.wlanthermo.internal.*; +import org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin.App; +import org.openhab.core.thing.*; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; + +/** + * The {@link WlanThermoMiniHandler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoMiniHandler extends WlanThermoHandler { + + private App app = new App(); + + public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) { + super(thing, httpClient, false); + } + + @Override + protected State getState(ChannelUID channelUID) throws WlanThermoInputException, WlanThermoUnknownChannelException { + return WlanThermoMiniCommandHandler.getState(channelUID, app); + } + + @Override + protected boolean setState(ChannelUID channelUID, Command command) { + // Mini is read-only! + return false; + } + + @Override + protected void push() { + // Unused, Mini is read-only! + } + + @Override + protected void pull() { + try { + // Update objects with data from device + app = doGet("/app.php", App.class); + + // Update channels + for (Channel channel : thing.getChannels()) { + try { + State state = WlanThermoMiniCommandHandler.getState(channel.getUID(), app); + updateState(channel.getUID(), state); + } catch (WlanThermoUnknownChannelException e) { + // if we could not obtain a state, try trigger instead + try { + String trigger = WlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app); + if (!trigger.equals(TRIGGER_NONE)) { + triggerChannel(channel.getUID(), trigger); + } + } catch (WlanThermoUnknownChannelException e1) { + logger.debug("{}", e.getMessage()); + } + } + } + } catch (WlanThermoException ignore) { + // Nothing more to do + } catch (InterruptedException e) { + logger.debug("Update interrupted. {}", e.getMessage()); + } + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/UtilMini.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniUtil.java similarity index 86% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/UtilMini.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniUtil.java index e1513cd3e..69a84a7ba 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/UtilMini.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniUtil.java @@ -10,21 +10,25 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.mini.builtin; +package org.openhab.binding.wlanthermo.internal.api.mini; import java.util.HashMap; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.wlanthermo.internal.WlanThermoUtil; + /** - * The {@link UtilMini} class provides conversion functions for the WlanThermo Mini + * The {@link WlanThermoMiniUtil} class provides conversion functions for the WlanThermo Mini * * @author Christian Schlipp - Initial contribution */ -public class UtilMini { +@NonNullByDefault +public class WlanThermoMiniUtil extends WlanThermoUtil { private static final Map COLOR_MAPPINGS = createColorMap(); private static final String DEFAULT_HEX = "#ffffff"; - private UtilMini() { + private WlanThermoMiniUtil() { // hidden } diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/WlanThermoMiniCommandHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/WlanThermoMiniCommandHandler.java deleted file mode 100644 index 4ebda7826..000000000 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/WlanThermoMiniCommandHandler.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * 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.wlanthermo.internal.api.mini.builtin; - -import java.awt.*; - -import org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants; -import org.openhab.core.library.types.DecimalType; -import org.openhab.core.library.types.HSBType; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.StringType; -import org.openhab.core.thing.ChannelUID; -import org.openhab.core.types.State; -import org.openhab.core.types.UnDefType; - -/** - * The {@link WlanThermoMiniCommandHandler} is responsible for mapping the Commands to the respective data fields - * of the API. - * - * @author Christian Schlipp - Initial contribution - */ -public class WlanThermoMiniCommandHandler { - - public State getState(ChannelUID channelUID, App app) { - State state = null; - if ("system".equals(channelUID.getGroupId())) { - switch (channelUID.getIdWithoutGroup()) { - case WlanThermoBindingConstants.SYSTEM_CPU_TEMP: - if (app.getCpuTemp() == null) { - state = UnDefType.UNDEF; - } else { - state = new DecimalType(app.getCpuTemp()); - } - break; - case WlanThermoBindingConstants.SYSTEM_CPU_LOAD: - if (app.getCpuLoad() == null) { - state = UnDefType.UNDEF; - } else { - state = new DecimalType(app.getCpuLoad()); - } - break; - } - } else if (channelUID.getId().startsWith("channel")) { - int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())); - if (channelId >= 0 && channelId <= 9) { - Channel channel = app.getChannel(); - if (channel == null) { - return UnDefType.UNDEF; - } - Data data = channel.getData(channelId); - switch (channelUID.getIdWithoutGroup()) { - case WlanThermoBindingConstants.CHANNEL_NAME: - state = new StringType(data.getName()); - break; - case WlanThermoBindingConstants.CHANNEL_TEMP: - if (data.getState().equals("er")) { - state = UnDefType.UNDEF; - } else { - state = new DecimalType(data.getTemp()); - } - break; - case WlanThermoBindingConstants.CHANNEL_MIN: - state = new DecimalType(data.getTempMin()); - break; - case WlanThermoBindingConstants.CHANNEL_MAX: - state = new DecimalType(data.getTempMax()); - break; - case WlanThermoBindingConstants.CHANNEL_ALARM_DEVICE: - state = OnOffType.from(data.getAlert()); - break; - case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_HIGH: - if (!data.getState().equals("er") && data.getTemp() > data.getTempMax()) { - state = OnOffType.ON; - } else { - state = OnOffType.OFF; - } - break; - case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_LOW: - if (!data.getState().equals("er") && data.getTemp() < data.getTempMin()) { - state = OnOffType.ON; - } else { - state = OnOffType.OFF; - } - break; - case WlanThermoBindingConstants.CHANNEL_COLOR: - Color c = Color.decode(UtilMini.toHex(data.getColor())); - state = HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue()); - break; - case WlanThermoBindingConstants.CHANNEL_COLOR_NAME: - state = new StringType(data.getColor()); - break; - } - } - } else if (channelUID.getId().startsWith("pit")) { - Pit pit; - if (channelUID.getGroupId().equals("pit1")) { - pit = app.getPit(); - } else if (channelUID.getGroupId().equals("pit2")) { - pit = app.getPit2(); - } else { - return UnDefType.UNDEF; - } - if (pit == null || !pit.getEnabled()) { - return UnDefType.UNDEF; - } - switch (channelUID.getIdWithoutGroup()) { - case WlanThermoBindingConstants.CHANNEL_PITMASTER_ENABLED: - state = OnOffType.from(pit.getEnabled()); - break; - case WlanThermoBindingConstants.CHANNEL_PITMASTER_CURRENT: - state = new DecimalType(pit.getCurrent()); - break; - case WlanThermoBindingConstants.CHANNEL_PITMASTER_SETPOINT: - state = new DecimalType(pit.getSetpoint()); - break; - case WlanThermoBindingConstants.CHANNEL_PITMASTER_DUTY_CYCLE: - state = new DecimalType(pit.getControlOut()); - break; - case WlanThermoBindingConstants.CHANNEL_PITMASTER_LID_OPEN: - state = OnOffType.from(pit.getOpenLid().equals("True")); - break; - case WlanThermoBindingConstants.CHANNEL_PITMASTER_CHANNEL_ID: - state = new DecimalType(pit.getCh()); - break; - } - } - return state; - } - - public String getTrigger(ChannelUID channelUID, App app) { - String trigger = null; - if (channelUID.getId().startsWith("channel")) { - int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1; - if (channelId >= 0 && channelId <= 9) { - Channel channel = app.getChannel(); - if (channel == null) { - return ""; - } - Data data = channel.getData(channelId); - switch (channelUID.getIdWithoutGroup()) { - case "alarm_openhab": - if (!data.getState().equals("er")) { - if (data.getTemp() > data.getTempMax()) { - trigger = WlanThermoBindingConstants.TRIGGER_ALARM_MAX; - } else if (data.getTemp() < data.getTempMin()) { - trigger = WlanThermoBindingConstants.TRIGGER_ALARM_MIN; - } - } - } - } - } - return trigger; - } -} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/App.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/App.java similarity index 98% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/App.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/App.java index f45c16bec..2b3cd6fb8 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/App.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/App.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.mini.builtin; +package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Channel.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Channel.java similarity index 98% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Channel.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Channel.java index 5329d3378..0dec13cf4 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Channel.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Channel.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.mini.builtin; +package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Data.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Data.java similarity index 98% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Data.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Data.java index 3dc0ee6b7..ef8c015a3 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Data.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Data.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.mini.builtin; +package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Pit.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Pit.java similarity index 98% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Pit.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Pit.java index cabe12523..396a7a9f2 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Pit.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Pit.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.mini.builtin; +package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoCommandHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoCommandHandler.java deleted file mode 100644 index f6d9dfa67..000000000 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoCommandHandler.java +++ /dev/null @@ -1,261 +0,0 @@ -/** - * 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.wlanthermo.internal.api.nano; - -import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*; - -import java.awt.*; -import java.math.BigInteger; -import java.util.List; - -import org.openhab.binding.wlanthermo.internal.api.nano.data.Channel; -import org.openhab.binding.wlanthermo.internal.api.nano.data.Data; -import org.openhab.binding.wlanthermo.internal.api.nano.data.Pm; -import org.openhab.binding.wlanthermo.internal.api.nano.data.System; -import org.openhab.binding.wlanthermo.internal.api.nano.settings.Settings; -import org.openhab.core.library.types.*; -import org.openhab.core.thing.ChannelUID; -import org.openhab.core.types.Command; -import org.openhab.core.types.State; -import org.openhab.core.types.UnDefType; - -/** - * The {@link WlanThermoNanoCommandHandler} is responsible for mapping the Commands to the respective data fields - * of the API. - * - * @author Christian Schlipp - Initial contribution - */ -public class WlanThermoNanoCommandHandler { - - public State getState(ChannelUID channelUID, Data data, Settings settings) { - State state = null; - System system = data.getSystem(); - List channel = data.getChannel(); - if ("system".equals(channelUID.getGroupId()) && system != null) { - switch (channelUID.getIdWithoutGroup()) { - case SYSTEM_SOC: - state = new DecimalType(system.getSoc()); - break; - case SYSTEM_CHARGE: - state = OnOffType.from(system.getCharge()); - break; - case SYSTEM_RSSI_SIGNALSTRENGTH: - int dbm = system.getRssi(); - if (dbm >= -80) { - state = new DecimalType(4); - } else if (dbm >= -95) { - state = new DecimalType(3); - } else if (dbm >= -105) { - state = new DecimalType(2); - } else { - state = new DecimalType(1); - } - break; - case SYSTEM_RSSI: - state = new DecimalType(system.getRssi()); - break; - } - } else if (channelUID.getId().startsWith("channel")) { - int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1; - if (channel.size() > 0 && channelId <= channel.size()) { - switch (channelUID.getIdWithoutGroup()) { - case CHANNEL_NAME: - state = new StringType(channel.get(channelId).getName()); - break; - case CHANNEL_TYP: - state = new StringType(settings.sensors.get(channel.get(channelId).getTyp())); - break; - case CHANNEL_TEMP: - if (channel.get(channelId).getTemp() == 999.0) { - state = UnDefType.UNDEF; - } else { - state = new DecimalType(channel.get(channelId).getTemp()); - } - break; - case CHANNEL_MIN: - state = new DecimalType(channel.get(channelId).getMin()); - break; - case CHANNEL_MAX: - state = new DecimalType(channel.get(channelId).getMax()); - break; - case CHANNEL_ALARM_DEVICE: - state = OnOffType.from(BigInteger.valueOf(channel.get(channelId).getAlarm()).testBit(1)); - break; - case CHANNEL_ALARM_PUSH: - state = OnOffType.from(BigInteger.valueOf(channel.get(channelId).getAlarm()).testBit(0)); - break; - case CHANNEL_ALARM_OPENHAB_HIGH: - if (channel.get(channelId).getTemp() != 999 - && channel.get(channelId).getTemp() > channel.get(channelId).getMax()) { - state = OnOffType.ON; - } else { - state = OnOffType.OFF; - } - break; - case CHANNEL_ALARM_OPENHAB_LOW: - if (channel.get(channelId).getTemp() != 999 - && channel.get(channelId).getTemp() < channel.get(channelId).getMin()) { - state = OnOffType.ON; - } else { - state = OnOffType.OFF; - } - break; - case CHANNEL_COLOR: - String color = channel.get(channelId).getColor(); - if (color != null && !color.isEmpty()) { - Color c = Color.decode(color); - state = HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue()); - } - break; - case CHANNEL_COLOR_NAME: - String colorHex = channel.get(channelId).getColor(); - if (colorHex != null && !colorHex.isEmpty()) { - state = new StringType(UtilNano.toColorName(colorHex)); - } - break; - } - } - } else if (channelUID.getId().startsWith("pit1")) { - if (data.getPitmaster() != null && data.getPitmaster().getPm() != null - && data.getPitmaster().getPm().size() > 0) { - Pm pm = data.getPitmaster().getPm().get(0); - switch (channelUID.getIdWithoutGroup()) { - case CHANNEL_PITMASTER_CHANNEL_ID: - state = new DecimalType(pm.getChannel()); - break; - case CHANNEL_PITMASTER_PIDPROFILE: - state = new DecimalType(pm.getPid()); - break; - case CHANNEL_PITMASTER_DUTY_CYCLE: - state = new DecimalType(pm.getValue()); - break; - case CHANNEL_PITMASTER_SETPOINT: - state = new DecimalType(pm.getSet()); - break; - case CHANNEL_PITMASTER_STATE: - state = new StringType(pm.getTyp()); - } - } else { - return UnDefType.UNDEF; - } - } - return state; - } - - public boolean setState(ChannelUID channelUID, Command command, Data data) { - boolean success = false; - List channel = data.getChannel(); - if (channelUID.getId().startsWith("channel")) { - int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1; - if (channel.size() > 0 && channelId <= channel.size()) { - switch (channelUID.getIdWithoutGroup()) { - case CHANNEL_NAME: - if (command instanceof StringType) { - channel.get(channelId).setName(command.toFullString()); - success = true; - } - break; - case CHANNEL_MIN: - if (command instanceof QuantityType) { - channel.get(channelId).setMin(((QuantityType) command).doubleValue()); - success = true; - } - break; - case CHANNEL_MAX: - if (command instanceof QuantityType) { - channel.get(channelId).setMax(((QuantityType) command).doubleValue()); - success = true; - } - break; - case CHANNEL_ALARM_DEVICE: - if (command instanceof OnOffType) { - BigInteger value; - if (command == OnOffType.ON) { - value = BigInteger.valueOf(channel.get(channelId).getAlarm()).setBit(1); - } else { - value = BigInteger.valueOf(channel.get(channelId).getAlarm()).clearBit(1); - } - channel.get(channelId).setAlarm(value.intValue()); - success = true; - } - break; - case CHANNEL_ALARM_PUSH: - if (command instanceof OnOffType) { - BigInteger value; - if (command == OnOffType.ON) { - value = BigInteger.valueOf(channel.get(channelId).getAlarm()).setBit(0); - } else { - value = BigInteger.valueOf(channel.get(channelId).getAlarm()).clearBit(0); - } - channel.get(channelId).setAlarm(value.intValue()); - success = true; - } - break; - case CHANNEL_COLOR_NAME: - if (command instanceof StringType) { - channel.get(channelId).setColor(UtilNano.toHex(((StringType) command).toString())); - success = true; - } - break; - } - } - } else if (channelUID.getId().equals("pit1")) { - if (data.getPitmaster() != null && data.getPitmaster().getPm() != null - && data.getPitmaster().getPm().size() > 0) { - Pm pm = data.getPitmaster().getPm().get(0); - switch (channelUID.getIdWithoutGroup()) { - case CHANNEL_PITMASTER_CHANNEL_ID: - pm.setChannel(((QuantityType) command).intValue()); - success = true; - break; - case CHANNEL_PITMASTER_PIDPROFILE: - pm.setPid(((QuantityType) command).intValue()); - success = true; - break; - case CHANNEL_PITMASTER_SETPOINT: - pm.setSet(((QuantityType) command).doubleValue()); - success = true; - break; - case CHANNEL_PITMASTER_STATE: - String state = ((StringType) command).toString(); - if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual") - || state.equalsIgnoreCase("auto")) { - pm.setTyp(state); - success = true; - } - } - } - } - return success; - } - - public String getTrigger(ChannelUID channelUID, Data data) { - String trigger = null; - List channel = data.getChannel(); - if (channelUID.getId().startsWith("channel")) { - int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1; - if (channel.size() > 0 && channelId <= channel.size()) { - if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) { - if (channel.get(channelId).getTemp() != 999) { - if (channel.get(channelId).getTemp() > channel.get(channelId).getMax()) { - trigger = TRIGGER_ALARM_MAX; - } else if (channel.get(channelId).getTemp() < channel.get(channelId).getMin()) { - trigger = TRIGGER_ALARM_MIN; - } - } - } - } - } - return trigger; - } -} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandler.java new file mode 100644 index 000000000..a8b6a04c4 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandler.java @@ -0,0 +1,282 @@ +/** + * 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.wlanthermo.internal.api.nano; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*; +import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull; + +import java.awt.*; +import java.math.BigInteger; +import java.util.List; + +import javax.measure.Unit; +import javax.measure.quantity.Temperature; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.wlanthermo.internal.WlanThermoInputException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Channel; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Data; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Pm; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.System; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.settings.Settings; +import org.openhab.core.library.types.*; +import org.openhab.core.library.unit.ImperialUnits; +import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.library.unit.Units; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +/** + * The {@link WlanThermoNanoV1CommandHandler} is responsible for mapping the Commands to the respective data fields + * of the API. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoNanoV1CommandHandler { + + public static State getState(ChannelUID channelUID, Data data, Settings settings) + throws WlanThermoUnknownChannelException, WlanThermoInputException { + String groupId = requireNonNull(channelUID.getGroupId()); + System system = data.getSystem(); + Unit unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS; + List channelList = data.getChannel(); + + if (SYSTEM.equals(groupId)) { + switch (channelUID.getIdWithoutGroup()) { + case SYSTEM_SOC: + return new DecimalType(system.getSoc()); + case SYSTEM_CHARGE: + return OnOffType.from(system.getCharge()); + case SYSTEM_RSSI_SIGNALSTRENGTH: + int dbm = system.getRssi(); + if (dbm >= -80) { + return SIGNAL_STRENGTH_4; + } else if (dbm >= -95) { + return SIGNAL_STRENGTH_3; + } else if (dbm >= -105) { + return SIGNAL_STRENGTH_2; + } else { + return SIGNAL_STRENGTH_1; + } + case SYSTEM_RSSI: + return new QuantityType<>(system.getRssi(), Units.DECIBEL_MILLIWATTS); + } + } else if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1; + if (channelList.size() > 0 && channelId < channelList.size()) { + Channel channel = channelList.get(channelId); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_NAME: + return new StringType(channel.getName()); + case CHANNEL_TYP: + return new StringType(settings.sensors.get(channel.getTyp())); + case CHANNEL_TEMP: + return channel.getTemp() == 999.0 ? UnDefType.UNDEF + : new QuantityType<>(channel.getTemp(), unit); + case CHANNEL_MIN: + return new QuantityType<>(channel.getMin(), unit); + case CHANNEL_MAX: + return new QuantityType<>(channel.getMax(), unit); + case CHANNEL_ALARM_DEVICE: + return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(1)); + case CHANNEL_ALARM_PUSH: + return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(0)); + case CHANNEL_ALARM_OPENHAB_HIGH: + if (channel.getTemp() != 999 && channel.getTemp() > channel.getMax()) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + case CHANNEL_ALARM_OPENHAB_LOW: + if (channel.getTemp() != 999 && channel.getTemp() < channel.getMin()) { + return OnOffType.ON; + } else { + return OnOffType.OFF; + } + case CHANNEL_COLOR: + String color = channel.getColor(); + if (color != null && !color.isEmpty()) { + Color c = Color.decode(color); + return HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue()); + } else { + return UnDefType.UNDEF; + } + case CHANNEL_COLOR_NAME: + String colorHex = channel.getColor(); + if (colorHex != null && !colorHex.isEmpty()) { + return new StringType(WlanThermoNanoV1Util.toColorName(colorHex)); + } else { + return UnDefType.UNDEF; + } + } + } + } else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_1)) { + if (data.getPitmaster() != null && data.getPitmaster().getPm() != null + && data.getPitmaster().getPm().size() > 0) { + Pm pm = data.getPitmaster().getPm().get(0); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_PITMASTER_CHANNEL_ID: + return new DecimalType(pm.getChannel()); + case CHANNEL_PITMASTER_PIDPROFILE: + return new DecimalType(pm.getPid()); + case CHANNEL_PITMASTER_DUTY_CYCLE: + return new DecimalType(pm.getValue()); + case CHANNEL_PITMASTER_SETPOINT: + return new QuantityType<>(pm.getSet(), unit); + case CHANNEL_PITMASTER_STATE: + return new StringType(pm.getTyp()); + } + } else { + return UnDefType.UNDEF; + } + } + throw new WlanThermoUnknownChannelException(channelUID); + } + + public static boolean setState(ChannelUID channelUID, Command command, Data data) { + String groupId; + try { + groupId = requireNonNull(channelUID.getGroupId()); + } catch (WlanThermoInputException e) { + return false; + } + + List channelList = data.getChannel(); + System system = data.getSystem(); + Unit unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS; + + if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1; + if (channelList.size() > 0 && channelId < channelList.size()) { + Channel channel = channelList.get(channelId); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_NAME: + if (command instanceof StringType) { + channel.setName(command.toFullString()); + return true; + } + return false; + case CHANNEL_MIN: + if (command instanceof QuantityType) { + try { + channel.setMin(requireNonNull(((QuantityType) command).toUnit(unit)).doubleValue()); + return true; + } catch (WlanThermoInputException ignore) { + return false; + } + } + return false; + case CHANNEL_MAX: + if (command instanceof QuantityType) { + try { + channel.setMax(requireNonNull(((QuantityType) command).toUnit(unit)).doubleValue()); + return true; + } catch (WlanThermoInputException ignore) { + return false; + } + } + return false; + case CHANNEL_ALARM_DEVICE: + if (command instanceof OnOffType) { + BigInteger value; + if (command == OnOffType.ON) { + value = BigInteger.valueOf(channel.getAlarm()).setBit(1); + } else { + value = BigInteger.valueOf(channel.getAlarm()).clearBit(1); + } + channel.setAlarm(value.intValue()); + return true; + } + return false; + case CHANNEL_ALARM_PUSH: + if (command instanceof OnOffType) { + BigInteger value; + if (command == OnOffType.ON) { + value = BigInteger.valueOf(channel.getAlarm()).setBit(0); + } else { + value = BigInteger.valueOf(channel.getAlarm()).clearBit(0); + } + channel.setAlarm(value.intValue()); + return true; + } + return false; + case CHANNEL_COLOR_NAME: + if (command instanceof StringType) { + channel.setColor(WlanThermoNanoV1Util.toHex(((StringType) command).toString())); + return true; + } + return false; + } + } + } else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_1)) { + if (data.getPitmaster() != null && data.getPitmaster().getPm() != null + && data.getPitmaster().getPm().size() > 0) { + Pm pm = data.getPitmaster().getPm().get(0); + switch (channelUID.getIdWithoutGroup()) { + case CHANNEL_PITMASTER_CHANNEL_ID: + pm.setChannel(((DecimalType) command).intValue()); + return true; + case CHANNEL_PITMASTER_PIDPROFILE: + pm.setPid(((DecimalType) command).intValue()); + return true; + case CHANNEL_PITMASTER_SETPOINT: + try { + pm.setSet(requireNonNull(((QuantityType) command).toUnit(unit)).doubleValue()); + return true; + } catch (WlanThermoInputException ignore) { + return false; + } + case CHANNEL_PITMASTER_STATE: + String state = ((StringType) command).toString(); + if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual") + || state.equalsIgnoreCase("auto")) { + pm.setTyp(state); + return true; + } + return false; + } + } + } + return false; + } + + public static String getTrigger(ChannelUID channelUID, Data data) + throws WlanThermoUnknownChannelException, WlanThermoInputException { + + String groupId = requireNonNull(channelUID.getGroupId()); + List channelList = data.getChannel(); + + if (channelUID.getId().startsWith(CHANNEL_PREFIX)) { + int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1; + if (channelList.size() > 0 && channelId < channelList.size()) { + Channel channel = channelList.get(channelId); + if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) { + if (channel.getTemp() != 999) { + if (channel.getTemp() > channel.getMax()) { + return TRIGGER_ALARM_MAX; + } else if (channel.getTemp() < channel.getMin()) { + return TRIGGER_ALARM_MIN; + } else { + return TRIGGER_NONE; + } + } + } + } + } + throw new WlanThermoUnknownChannelException(channelUID); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Handler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Handler.java new file mode 100644 index 000000000..0232ccc9d --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Handler.java @@ -0,0 +1,106 @@ +/** + * 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.wlanthermo.internal.api.nano; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.client.HttpClient; +import org.openhab.binding.wlanthermo.internal.*; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Data; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.settings.Settings; +import org.openhab.core.thing.*; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; + +/** + * The {@link WlanThermoNanoV1Handler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +public class WlanThermoNanoV1Handler extends WlanThermoHandler { + + private Data data = new Data(); + private Settings settings = new Settings(); + + public WlanThermoNanoV1Handler(Thing thing, HttpClient httpClient) { + super(thing, httpClient, true); + } + + @Override + protected State getState(ChannelUID channelUID) throws WlanThermoInputException, WlanThermoUnknownChannelException { + return WlanThermoNanoV1CommandHandler.getState(channelUID, data, settings); + } + + @Override + protected boolean setState(ChannelUID channelUID, Command command) { + return WlanThermoNanoV1CommandHandler.setState(channelUID, command, data); + } + + @Override + protected void push() { + // push update for sensor channels + for (org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Channel c : data.getChannel()) { + try { + String json = gson.toJson(c); + if (!doPost("/setchannels", json)) { + break; + } + } catch (InterruptedException e) { + logger.debug("Push interrupted. {}", e.getMessage()); + return; + } + } + + // push update for pitmaster channels + try { + String json = gson.toJson(data.getPitmaster().getPm()); + doPost("/setpitmaster", json); + } catch (InterruptedException e) { + logger.debug("Push interrupted. {}", e.getMessage()); + } + } + + @Override + protected void pull() { + try { + // Update objects with data from device + data = doGet("/data", Data.class); + settings = doGet("/settings", Settings.class); + + // Update channels + for (Channel channel : thing.getChannels()) { + try { + State state = WlanThermoNanoV1CommandHandler.getState(channel.getUID(), data, settings); + updateState(channel.getUID(), state); + } catch (WlanThermoUnknownChannelException e) { + // if we could not obtain a state, try trigger instead + try { + String trigger = WlanThermoNanoV1CommandHandler.getTrigger(channel.getUID(), data); + if (!trigger.equals(TRIGGER_NONE)) { + triggerChannel(channel.getUID(), trigger); + } + } catch (WlanThermoUnknownChannelException e1) { + logger.debug("{}", e.getMessage()); + } + } + } + } catch (WlanThermoException ignore) { + // Nothing more to do + } catch (InterruptedException e) { + logger.debug("Update interrupted. {}", e.getMessage()); + } + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/UtilNano.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Util.java similarity index 74% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/UtilNano.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Util.java index c488248c1..950acc6dc 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/UtilNano.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Util.java @@ -15,18 +15,22 @@ package org.openhab.binding.wlanthermo.internal.api.nano; import java.util.HashMap; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.wlanthermo.internal.WlanThermoUtil; + /** - * The {@link UtilNano} class provides conversion functions for the WlanThermo Nano + * The {@link WlanThermoNanoV1Util} class provides conversion functions for the WlanThermo Nano V1+ * * @author Christian Schlipp - Initial contribution */ -public class UtilNano { +@NonNullByDefault +public class WlanThermoNanoV1Util extends WlanThermoUtil { private static final Map COLOR_MAPPINGS = createColorMap(); private static final String DEFAULT_HEX = "#ffffff"; private static final String DEFAULT_COLORNAME = "niagara"; - private UtilNano() { + private WlanThermoNanoV1Util() { // hidden } @@ -56,18 +60,6 @@ public class UtilNano { } public static String toColorName(String colorHex) { - String colorName = null; - if (!colorHex.startsWith("#")) { - colorHex = "#" + colorHex; - } - for (Map.Entry entry : COLOR_MAPPINGS.entrySet()) { - if (entry.getValue().equalsIgnoreCase(colorHex)) { - colorName = entry.getKey(); - } - } - if (colorName == null) { - colorName = DEFAULT_COLORNAME; - } - return colorName; + return toColorName(colorHex, COLOR_MAPPINGS, DEFAULT_COLORNAME); } } diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Channel.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Channel.java similarity index 98% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Channel.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Channel.java index 429bb33d8..9d1672cf5 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Channel.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Channel.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.data; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.data; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Data.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Data.java similarity index 97% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Data.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Data.java index 0ca7bc0dc..b1225216d 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Data.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Data.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.data; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.data; import java.util.ArrayList; import java.util.List; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pitmaster.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pitmaster.java similarity index 96% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pitmaster.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pitmaster.java index 50234024d..7205aa3fd 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pitmaster.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pitmaster.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.data; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.data; import java.util.ArrayList; import java.util.List; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pm.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pm.java similarity index 98% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pm.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pm.java index 3f1162a54..43c96511e 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pm.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pm.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.data; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.data; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/System.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/System.java similarity index 97% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/System.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/System.java index e441af341..c50c1a894 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/System.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/System.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.data; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.data; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Api.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Api.java similarity index 91% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Api.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Api.java index ba2429a3f..7e0fbc7cd 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Api.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Api.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Device.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Device.java similarity index 94% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Device.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Device.java index 2c921a4e5..e3663a5d9 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Device.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Device.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Ext.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Ext.java similarity index 94% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Ext.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Ext.java index 093a12cdf..6cb19d8b3 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Ext.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Ext.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import java.util.ArrayList; import java.util.List; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Iot.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Iot.java similarity index 95% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Iot.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Iot.java index a5ee2976c..18b331af0 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Iot.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Iot.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Notes.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Notes.java similarity index 92% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Notes.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Notes.java index 4c04e0160..15710ff48 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Notes.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Notes.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import java.util.ArrayList; import java.util.List; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Pid.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Pid.java similarity index 95% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Pid.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Pid.java index ea5b7d306..a3d099da5 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Pid.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Pid.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Settings.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Settings.java similarity index 95% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Settings.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Settings.java index 20dd854f8..f2c960ba2 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Settings.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Settings.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import java.util.ArrayList; import java.util.List; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/System.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/System.java similarity index 95% rename from bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/System.java rename to bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/System.java index 4a762bdf9..8c988d9f3 100644 --- a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/System.java +++ b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/System.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.wlanthermo.internal.api.nano.settings; +package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-esp32.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-esp32.xml new file mode 100644 index 000000000..f9b207c52 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-esp32.xml @@ -0,0 +1,51 @@ + + + + + + This group contains all system channels + + + + + + + + + + + + Sensor + + + + + + + + + + + + + + + + + + + + Sensor + + + + + + + + + + diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-mini.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-mini.xml new file mode 100644 index 000000000..0b73407cd --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-mini.xml @@ -0,0 +1,47 @@ + + + + + + This group contains all system channels + + + + + + + + + + Sensor + + + + + + + + + + + + + + + + + + Sensor + + + + + + + + + + diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-nano.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-nano.xml new file mode 100644 index 000000000..8a178d528 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-nano.xml @@ -0,0 +1,52 @@ + + + + + + This group contains all system channels + + + + + + + + + + + + Sensor + + + + + + + + + + + + + + + + + + + + Sensor + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-types.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-types.xml new file mode 100644 index 000000000..b75a20253 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-types.xml @@ -0,0 +1,259 @@ + + + + Number + + + + + + String + + Text + + + + String + + Text + + + + + String + + Text + + + + + Number:Temperature + + Temperature + + + + + Number:Temperature + + Temperature + + + + + Number:Temperature + + Temperature + + + + + Number:Temperature + + Temperature + + + + + Number:Temperature + + Temperature + + + + + Switch + + Switch + + + + Switch + + Switch + + + + + Switch + + Switch + + + + trigger + + + + + + + + + + + Switch + + + + + + Switch + + + + + + Color + + Colorpicker + + + + String + + Colorpicker + + + + + + + + + + + + + + + + + + String + + Colorpicker + + + + + + + + + + + + + + + + + + + + + + + + + + + Color + + Colorpicker + + + + + String + + Text + + + + + Switch + + + + + + Number:Temperature + + Temperature + + + + + Number + + + + + + Switch + + + + + + Number + + + + + + String + + + + + + + + + + + + Number + + + + + + Number + + + + + + Number:Temperature + + Temperature + + + + + Number + + + + + + Switch + + Energy + + + + + Number:Power + + Number + + + diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-esp32.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-esp32.xml new file mode 100644 index 000000000..fbb08037c --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-esp32.xml @@ -0,0 +1,151 @@ + + + + + ESP32 processor, such as Mini V2 (ESP32), Nano V3, Link V1 ]]> + + + + + + This group contains all channels for temperature probe 1 + + + + This group contains all channels for temperature probe 2 + + + + This group contains all channels for temperature probe 3 + + + + This group contains all channels for temperature probe 4 + + + + This group contains all channels for temperature probe 5 + + + + This group contains all channels for temperature probe 6 + + + + This group contains all channels for temperature probe 7 + + + + This group contains all channels for temperature probe 8 + + + + This group contains all channels for temperature probe 9 + + + + This group contains all channels for temperature probe 10 + + + + This group contains all channels for temperature probe 11 + + + + This group contains all channels for temperature probe 12 + + + + This group contains all channels for temperature probe 13 + + + + This group contains all channels for temperature probe 14 + + + + This group contains all channels for temperature probe 15 + + + + This group contains all channels for temperature probe 16 + + + + This group contains all channels for temperature probe 17 + + + + This group contains all channels for temperature probe 18 + + + + This group contains all channels for temperature probe 19 + + + + This group contains all channels for temperature probe 20 + + + + This group contains all channels for temperature probe 21 + + + + This group contains all channels for temperature probe 22 + + + + This group contains all channels for temperature probe 23 + + + + This group contains all channels for temperature probe 24 + + + + This group contains all channels for pitmaster channel 1 + + + + This group contains all channels for pitmaster channel 2 + + + + + Model + Serial Number + Bluetooth available + Pitmaster available + Temperature channels + Pitmaster channels + + + + + network-address + + Network address of the WlanThermo Nano. + + + + Optional, only required for write access. Default: 'admin' + admin + + + password + + Optional, only required for write access. Default: 'admin' + admin + + + + Seconds between fetching values from the WlanThermo Nano. + 10 + + + + diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-mini.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-mini.xml new file mode 100644 index 000000000..c0946abfd --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-mini.xml @@ -0,0 +1,79 @@ + + + + + + + Raspberry Pi processor, such as Mini V1/V2 ]]> + + + + + + This group contains all channels for temperature probe 1 + + + + This group contains all channels for temperature probe 2 + + + + This group contains all channels for temperature probe 3 + + + + This group contains all channels for temperature probe 4 + + + + This group contains all channels for temperature probe 5 + + + + This group contains all channels for temperature probe 6 + + + + This group contains all channels for temperature probe 7 + + + + This group contains all channels for temperature probe 8 + + + + This group contains all channels for temperature probe 9 + + + + This group contains all channels for temperature probe 10 + + + + This group contains all channels for pitmaster channel 1 + + + + This group contains all channels for pitmaster channel 2 + + + + + + network-address + + Network address of the WlanThermo Mini. + + + + Seconds between fetching values from the WlanThermo Mini. + 10 + + + + + + diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-nano.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-nano.xml new file mode 100644 index 000000000..e6955e8e3 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-nano.xml @@ -0,0 +1,74 @@ + + + + + WlanThermo Nano V1/V1+ + + + + + + This group contains all channels for temperature probe 1 + + + + This group contains all channels for temperature probe 2 + + + + This group contains all channels for temperature probe 3 + + + + This group contains all channels for temperature probe 4 + + + + This group contains all channels for temperature probe 5 + + + + This group contains all channels for temperature probe 6 + + + + This group contains all channels for temperature probe 7 + + + + This group contains all channels for temperature probe 8 + + + + This group contains all channels for pitmaster channel 1 + + + + + + network-address + + Network address of the WlanThermo Nano. + + + + Optional, only required for write access. Default: 'admin' + admin + + + password + + Optional, only required for write access. Default: 'admin' + admin + + + + Seconds between fetching values from the WlanThermo Nano. + 10 + + + + diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types.xml deleted file mode 100644 index 13171663f..000000000 --- a/bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types.xml +++ /dev/null @@ -1,463 +0,0 @@ - - - - - - WlanThermo Nano V1/V1+ - - - - - - This group contains all channels for temperature probe 1 - - - - This group contains all channels for temperature probe 2 - - - - This group contains all channels for temperature probe 3 - - - - This group contains all channels for temperature probe 4 - - - - This group contains all channels for temperature probe 5 - - - - This group contains all channels for temperature probe 6 - - - - This group contains all channels for temperature probe 7 - - - - This group contains all channels for temperature probe 8 - - - - This group contains all channels for pitmaster channel 1 - - - - - - network-address - - Network address of the WlanThermo Nano. - - - - Optional, only required for write access. Default: 'admin' - admin - - - password - - Optional, only required for write access. Default: 'admin' - admin - - - - Seconds between fetching values from the WlanThermo Nano. - 10 - - - - - - - - WlanThermo Mini - - - - - - This group contains all channels for temperature probe 1 - - - - This group contains all channels for temperature probe 2 - - - - This group contains all channels for temperature probe 3 - - - - This group contains all channels for temperature probe 4 - - - - This group contains all channels for temperature probe 5 - - - - This group contains all channels for temperature probe 6 - - - - This group contains all channels for temperature probe 7 - - - - This group contains all channels for temperature probe 8 - - - - This group contains all channels for temperature probe 9 - - - - This group contains all channels for temperature probe 10 - - - - This group contains all channels for pitmaster channel 1 - - - - This group contains all channels for pitmaster channel 2 - - - - - - network-address - - Network address of the WlanThermo Mini. - - - - Seconds between fetching values from the WlanThermo Mini. - 10 - - - - - - - - - This group contains all system channels - - - - - - - - - - Switch - - Energy - - - - - Number - - Text - - - - - - - This group contains all system channels - - - - - - - - Number - - - - - - - - Sensor - - - - - - - - - - - - - - - - - - - - Sensor - - - - - - - - - - - - - - - - - String - - Text - - - - String - - Text - - - - - String - - Text - - - - - Number:Temperature - - Temperature - - - - - Number:Temperature - - Temperature - - - - - Number:Temperature - - Temperature - - - - - Number:Temperature - - Temperature - - - - - Number:Temperature - - Temperature - - - - - Switch - - Switch - - - - Switch - - Switch - - - - - Switch - - Switch - - - - trigger - - - - - - - - - - - Switch - - - - - - Switch - - - - - - Color - - Colorpicker - - - - - String - - Colorpicker - - - - - - - - - - - - - - - - - - Color - - Colorpicker - - - - - String - - Text - - - - - - - Sensor - - - - - - - - - - - - Switch - - - - - - Number:Temperature - - Temperature - - - - - Number - - - - - - Switch - - - - - - Number - - - - - - - - Sensor - - - - - - - - - - - String - - - - - - - - - - - - - Number - - - - - - Number - - - - - - Number:Temperature - - Temperature - - - - - Number - - - - - diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandlerTest.java b/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandlerTest.java new file mode 100644 index 000000000..6184268f5 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandlerTest.java @@ -0,0 +1,224 @@ +/** + * 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.wlanthermo.internal.api.esp32; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*; +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE; + +import java.awt.*; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.function.Executable; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.openhab.binding.wlanthermo.internal.WlanThermoException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUtil; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Data; +import org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings.Settings; +import org.openhab.core.library.types.*; +import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.library.unit.Units; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +import com.google.gson.Gson; + +/** + * The {@link WlanThermoEsp32CommandHandlerTest} class tests the {@link WlanThermoEsp32CommandHandler} + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +class WlanThermoEsp32CommandHandlerTest { + + private static final ThingUID THING_UID = new ThingUID("wlanthermo", "esp32", "test"); + + @Nullable + private Data data; + @Nullable + private Settings settings; + + @BeforeEach + void setUp() { + Gson gson = new Gson(); + ClassLoader classLoader = Objects.requireNonNull(WlanThermoEsp32CommandHandlerTest.class.getClassLoader()); + InputStream dataStream = Objects.requireNonNull(classLoader.getResourceAsStream("esp32/data.json")); + InputStream settingsStream = Objects.requireNonNull(classLoader.getResourceAsStream("esp32/settings.json")); + data = gson.fromJson(new InputStreamReader(dataStream, StandardCharsets.UTF_8), Data.class); + settings = gson.fromJson(new InputStreamReader(settingsStream, StandardCharsets.UTF_8), Settings.class); + } + + static Stream getState() { + return Stream.of( + // System channels + Arguments.of(SYSTEM, SYSTEM_SOC, new DecimalType(89), null), + Arguments.of(SYSTEM, SYSTEM_CHARGE, OnOffType.OFF, null), + Arguments.of(SYSTEM, SYSTEM_RSSI_SIGNALSTRENGTH, new DecimalType(4), null), + Arguments.of(SYSTEM, SYSTEM_RSSI, new QuantityType<>(-32, Units.DECIBEL_MILLIWATTS), null), + + // All channels + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), null), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), null), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), null), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), null), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), null), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), null), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), null), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), null), + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"), null), + Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_NAME, new StringType("Kanal 10"), null), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "11", CHANNEL_NAME, UnDefType.UNDEF, + WlanThermoUnknownChannelException.class), + + // all channel values + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(17, SIUnits.CELSIUS), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(104, SIUnits.CELSIUS), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR, + HSBType.fromRGB(Color.decode("#270000").getRed(), Color.decode("#270000").getGreen(), + Color.decode("#270000").getBlue()), + null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME, + new StringType(WlanThermoEsp32Util.toColorName("#270000")), null), + + // all pitmaster + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), null), + Arguments.of(CHANNEL_PITMASTER_2, CHANNEL_PITMASTER_CHANNEL_ID, UnDefType.UNDEF, null), + + // all pitmaster values + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(1), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(70), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(50, SIUnits.CELSIUS), + null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("manual"), null)); + } + + static Stream getTrigger() { + return Stream.of( + // all channels + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "11", CHANNEL_ALARM_OPENHAB, "", + WlanThermoUnknownChannelException.class)); + } + + static Stream setState() { + return Stream.of( + // All channels + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), true), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), true), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), true), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), true), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), true), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), true), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), true), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), true), + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"), true), + Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_NAME, new StringType("Kanal 10"), true), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "11", CHANNEL_NAME, new StringType("Kanal 11"), false), + + // all channel values + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(17, SIUnits.CELSIUS), true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(104, SIUnits.CELSIUS), true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR, + HSBType.fromRGB(Color.decode("#270000").getRed(), Color.decode("#270000").getGreen(), + Color.decode("#270000").getBlue()), + true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME, + new StringType(WlanThermoEsp32Util.toColorName("#270000")), true), + + // all pitmaster + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), true), + Arguments.of(CHANNEL_PITMASTER_2, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), false), + + // all pitmaster values + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), true), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(0), true), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(0), false), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(100, SIUnits.CELSIUS), + true), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("off"), true)); + } + + @ParameterizedTest + @MethodSource("getTrigger") + void getTrigger(String groupId, String id, String expectedTrigger, + @Nullable Class exceptionClass) { + Executable test = () -> Assertions.assertEquals(expectedTrigger, WlanThermoEsp32CommandHandler + .getTrigger(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(data))); + if (exceptionClass != null) { + Assertions.assertThrows(exceptionClass, test); + } else { + Assertions.assertDoesNotThrow(test); + } + } + + @ParameterizedTest + @MethodSource("getState") + void getState(String groupId, String id, State expectedState, @Nullable Class exceptionClass) { + Executable test = () -> Assertions.assertEquals(expectedState, + WlanThermoEsp32CommandHandler.getState(new ChannelUID(THING_UID, groupId, id), + WlanThermoUtil.requireNonNull(data), WlanThermoUtil.requireNonNull(settings))); + if (exceptionClass != null) { + Assertions.assertThrows(exceptionClass, test); + } else { + Assertions.assertDoesNotThrow(test); + } + } + + @ParameterizedTest + @MethodSource("setState") + void setState(String groupId, String id, Command command, boolean expectedResult) { + Assertions.assertDoesNotThrow(() -> Assertions.assertEquals(expectedResult, + WlanThermoEsp32CommandHandler.setState(new ChannelUID(THING_UID, groupId, id), command, + WlanThermoUtil.requireNonNull(data), WlanThermoUtil.requireNonNull(settings)))); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandlerTest.java b/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandlerTest.java new file mode 100644 index 000000000..214571132 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandlerTest.java @@ -0,0 +1,160 @@ +/** + * 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.wlanthermo.internal.api.mini; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*; + +import java.awt.*; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.function.Executable; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.openhab.binding.wlanthermo.internal.WlanThermoException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUtil; +import org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin.App; +import org.openhab.core.library.types.*; +import org.openhab.core.library.unit.ImperialUnits; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +import com.google.gson.Gson; + +/** + * The {@link WlanThermoMiniCommandHandlerTest} class tests the {@link WlanThermoMiniCommandHandler} + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +class WlanThermoMiniCommandHandlerTest { + + private static final ThingUID THING_UID = new ThingUID("wlanthermo", "mini", "test"); + + @Nullable + private App app; + + @BeforeEach + void setUp() { + ClassLoader classLoader = Objects.requireNonNull(WlanThermoMiniCommandHandlerTest.class.getClassLoader()); + InputStream stream = Objects.requireNonNull(classLoader.getResourceAsStream("mini/app.json")); + app = new Gson().fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), App.class); + } + + static Stream getState() { + return Stream.of( + // System channels + Arguments.of(SYSTEM, SYSTEM_CPU_TEMP, new DecimalType(93.56), null), + Arguments.of(SYSTEM, SYSTEM_CPU_LOAD, new DecimalType(94.267515923567), null), + + // all channels + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_NAME, new StringType("Kanal0"), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal1"), null), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal2"), null), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal3"), null), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal4"), null), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal5"), null), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal6"), null), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal7"), null), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal8 - Maverick 1"), null), + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal9 - Maverick 2"), null), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_NAME, UnDefType.UNDEF, + WlanThermoUnknownChannelException.class), + + // all channel values + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_NAME, new StringType("Kanal0"), null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_TEMP, new QuantityType<>(78.28, ImperialUnits.FAHRENHEIT), + null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_MIN, new QuantityType<>(-20, ImperialUnits.FAHRENHEIT), + null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_MAX, new QuantityType<>(200, ImperialUnits.FAHRENHEIT), + null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_DEVICE, OnOffType.from("false"), null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_COLOR, + HSBType.fromRGB(Color.decode(WlanThermoMiniUtil.toHex("green")).getRed(), + Color.decode(WlanThermoMiniUtil.toHex("green")).getGreen(), + Color.decode(WlanThermoMiniUtil.toHex("green")).getBlue()), + null), + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_COLOR_NAME, new StringType("green"), null), + + // all pitmaster + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_ENABLED, OnOffType.from(true), null), + Arguments.of(CHANNEL_PITMASTER_2, CHANNEL_PITMASTER_ENABLED, UnDefType.UNDEF, null), + + // all pitmaster values + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_ENABLED, OnOffType.from(true), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CURRENT, new DecimalType(77.86), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, + new QuantityType<>(110, ImperialUnits.FAHRENHEIT), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(100), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_LID_OPEN, OnOffType.OFF, null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(0), null)); + } + + static Stream getTrigger() { + return Stream.of( + // all channels + Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_ALARM_OPENHAB, "", + WlanThermoUnknownChannelException.class)); + } + + @ParameterizedTest + @MethodSource("getTrigger") + void getTrigger(String groupId, String id, String expectedTrigger, + @Nullable Class exceptionClass) { + Executable test = () -> Assertions.assertEquals(expectedTrigger, WlanThermoMiniCommandHandler + .getTrigger(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(app))); + if (exceptionClass != null) { + Assertions.assertThrows(exceptionClass, test); + } else { + Assertions.assertDoesNotThrow(test); + } + } + + @ParameterizedTest + @MethodSource("getState") + void getState(String groupId, String id, State expectedState, @Nullable Class exceptionClass) { + Executable test = () -> Assertions.assertEquals(expectedState, WlanThermoMiniCommandHandler + .getState(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(app))); + if (exceptionClass != null) { + Assertions.assertThrows(exceptionClass, test); + } else { + Assertions.assertDoesNotThrow(test); + } + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandlerTest.java b/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandlerTest.java new file mode 100644 index 000000000..1d32bde30 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandlerTest.java @@ -0,0 +1,207 @@ +/** + * 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.wlanthermo.internal.api.nano; + +import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*; + +import java.awt.*; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.function.Executable; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.openhab.binding.wlanthermo.internal.WlanThermoException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException; +import org.openhab.binding.wlanthermo.internal.WlanThermoUtil; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Data; +import org.openhab.binding.wlanthermo.internal.api.nano.dto.settings.Settings; +import org.openhab.core.library.types.*; +import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.library.unit.Units; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; + +import com.google.gson.Gson; + +/** + * The {@link WlanThermoNanoV1CommandHandlerTest} class tests the {@link WlanThermoNanoV1CommandHandler} + * + * @author Christian Schlipp - Initial contribution + */ +@NonNullByDefault +class WlanThermoNanoV1CommandHandlerTest { + private static final ThingUID THING_UID = new ThingUID("wlanthermo", "nano", "test"); + + @Nullable + private Data data; + @Nullable + private Settings settings; + + @BeforeEach + void setUp() { + Gson gson = new Gson(); + ClassLoader classLoader = Objects.requireNonNull(WlanThermoNanoV1CommandHandlerTest.class.getClassLoader()); + InputStream dataStream = Objects.requireNonNull(classLoader.getResourceAsStream("nanov1/data.json")); + InputStream settingsStream = Objects.requireNonNull(classLoader.getResourceAsStream("nanov1/settings.json")); + data = gson.fromJson(new InputStreamReader(dataStream, StandardCharsets.UTF_8), Data.class); + settings = gson.fromJson(new InputStreamReader(settingsStream, StandardCharsets.UTF_8), Settings.class); + } + + static Stream getState() { + return Stream.of( + // System channels + Arguments.of(SYSTEM, SYSTEM_SOC, new DecimalType(32), null), + Arguments.of(SYSTEM, SYSTEM_CHARGE, OnOffType.OFF, null), + Arguments.of(SYSTEM, SYSTEM_RSSI_SIGNALSTRENGTH, new DecimalType(4), null), + Arguments.of(SYSTEM, SYSTEM_RSSI, new QuantityType<>(-47, Units.DECIBEL_MILLIWATTS), null), + + // All channels + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), null), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), null), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), null), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), null), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), null), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), null), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), null), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), null), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"), + WlanThermoUnknownChannelException.class), + + // all channel values + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(11, SIUnits.CELSIUS), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(155, SIUnits.CELSIUS), null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR, + HSBType.fromRGB(Color.decode("#EF562D").getRed(), Color.decode("#EF562D").getGreen(), + Color.decode("#EF562D").getBlue()), + null), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME, + new StringType(WlanThermoNanoV1Util.toColorName("#EF562D")), null), + + // all pitmaster values + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(0), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(0), null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(50, SIUnits.CELSIUS), + null), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("off"), null)); + } + + static Stream getTrigger() { + return Stream.of( + // all channels + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class)); + } + + static Stream setState() { + return Stream.of( + // All channels + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), true), + Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), true), + Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), true), + Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), true), + Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), true), + Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), true), + Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), true), + Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), true), + // invalid channel number + Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"), false), + + // all channel values + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(11, SIUnits.CELSIUS), true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(155, SIUnits.CELSIUS), true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, true), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR, + HSBType.fromRGB(Color.decode("#EF562D").getRed(), Color.decode("#EF562D").getGreen(), + Color.decode("#EF562D").getBlue()), + false), + Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME, + new StringType(WlanThermoNanoV1Util.toColorName("#EF562D")), true), + + // all pitmaster values + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), true), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(0), true), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(0), false), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(50, SIUnits.CELSIUS), + true), + Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("off"), true) + + ); + } + + @ParameterizedTest + @MethodSource("getTrigger") + void getTrigger(String groupId, String id, String expectedTrigger, + @Nullable Class exceptionClass) { + Executable test = () -> Assertions.assertEquals(expectedTrigger, WlanThermoNanoV1CommandHandler + .getTrigger(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(data))); + if (exceptionClass != null) { + Assertions.assertThrows(exceptionClass, test); + } else { + Assertions.assertDoesNotThrow(test); + } + } + + @ParameterizedTest + @MethodSource("getState") + void getState(String groupId, String id, State expectedState, @Nullable Class exceptionClass) { + Executable test = () -> Assertions.assertEquals(expectedState, + WlanThermoNanoV1CommandHandler.getState(new ChannelUID(THING_UID, groupId, id), + WlanThermoUtil.requireNonNull(data), WlanThermoUtil.requireNonNull(settings))); + if (exceptionClass != null) { + Assertions.assertThrows(exceptionClass, test); + } else { + Assertions.assertDoesNotThrow(test); + } + } + + @ParameterizedTest + @MethodSource("setState") + void setState(String groupId, String id, Command command, boolean expectedResult) { + Assertions.assertDoesNotThrow(() -> Assertions.assertEquals(expectedResult, WlanThermoNanoV1CommandHandler + .setState(new ChannelUID(THING_UID, groupId, id), command, WlanThermoUtil.requireNonNull(data)))); + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/data.json b/bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/data.json new file mode 100644 index 000000000..24eddd0eb --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/data.json @@ -0,0 +1,151 @@ +{ + "system": { + "time": "1610894101", + "unit": "C", + "soc": 89, + "charge": false, + "rssi": -32, + "online": 0 + }, + "channel": [ + { + "number": 1, + "name": "Kanal Eins", + "typ": 0, + "temp": 23.7, + "min": 17, + "max": 104, + "alarm": 1, + "color": "#270000", + "fixed": false, + "connected": false + }, + { + "number": 2, + "name": "Kanal 2", + "typ": 0, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#22B14C", + "fixed": false, + "connected": false + }, + { + "number": 3, + "name": "Kanal 3", + "typ": 0, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#EF562D", + "fixed": false, + "connected": false + }, + { + "number": 4, + "name": "Kanal 4", + "typ": 0, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#FFC100", + "fixed": false, + "connected": false + }, + { + "number": 5, + "name": "Kanal 5", + "typ": 0, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#A349A4", + "fixed": false, + "connected": false + }, + { + "number": 6, + "name": "Kanal 6", + "typ": 0, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#804000", + "fixed": false, + "connected": false + }, + { + "number": 7, + "name": "Kanal 7", + "typ": 0, + "temp": 23.7, + "min": 10, + "max": 95, + "alarm": 0, + "color": "#5587A2", + "fixed": false, + "connected": false + }, + { + "number": 8, + "name": "Kanal 8", + "typ": 0, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#5C7148", + "fixed": false, + "connected": false + }, + { + "number": 9, + "name": "Kanal 9", + "typ": 16, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#A349A4", + "fixed": true, + "connected": false + }, + { + "number": 10, + "name": "Kanal 10", + "typ": 16, + "temp": 999, + "min": 50, + "max": 95, + "alarm": 0, + "color": "#5587A2", + "fixed": true, + "connected": false + } + ], + "pitmaster": { + "type": [ + "off", + "manual", + "auto" + ], + "pm": [ + { + "id": 0, + "channel": 1, + "pid": 1, + "value": 70, + "set": 50, + "typ": "manual", + "set_color": "#ff0000", + "value_color": "#000000" + } + ] + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/settings.json b/bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/settings.json new file mode 100644 index 000000000..49f6e503e --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/settings.json @@ -0,0 +1,229 @@ +{ + "device": { + "device": "nano", + "serial": "98f4ab7570c0", + "cpu": "esp32", + "flash_size": 16777216, + "item": "n3j04oA200B", + "hw_version": "v3", + "sw_version": "v1.1.0", + "api_version": "1", + "language": "de" + }, + "system": { + "time": "1610894186", + "unit": "C", + "ap": "WLANTHERMO-AP", + "host": "NANO-98f4ab7570c0", + "language": "de", + "version": "v1.1.0", + "getupdate": "false", + "autoupd": true, + "prerelease": true, + "hwversion": "V3" + }, + "hardware": [ + "V3" + ], + "api": { + "version": "1" + }, + "sensors": [ + { + "type": 0, + "name": "1000K/Maverick", + "fixed": false + }, + { + "type": 1, + "name": "Fantast-Neu", + "fixed": false + }, + { + "type": 2, + "name": "Fantast", + "fixed": false + }, + { + "type": 3, + "name": "100K/iGrill2", + "fixed": false + }, + { + "type": 4, + "name": "ET-73", + "fixed": false + }, + { + "type": 5, + "name": "Perfektion", + "fixed": false + }, + { + "type": 6, + "name": "50K", + "fixed": false + }, + { + "type": 7, + "name": "Inkbird", + "fixed": false + }, + { + "type": 8, + "name": "100K6A1B", + "fixed": false + }, + { + "type": 9, + "name": "Weber_6743", + "fixed": false + }, + { + "type": 10, + "name": "Santos", + "fixed": false + }, + { + "type": 11, + "name": "5K3A1B", + "fixed": false + }, + { + "type": 12, + "name": "PT100", + "fixed": false + }, + { + "type": 13, + "name": "PT1000", + "fixed": false + }, + { + "type": 14, + "name": "ThermoWorks", + "fixed": false + }, + { + "type": 15, + "name": "Typ K", + "fixed": true + }, + { + "type": 16, + "name": "Bluetooth", + "fixed": true + }, + { + "type": 17, + "name": "Maverick", + "fixed": true + } + ], + "features": { + "bluetooth": true, + "pitmaster": true + }, + "pid": [ + { + "name": "SSR SousVide", + "id": 0, + "aktor": 0, + "Kp": 104, + "Ki": 0.2, + "Kd": 0, + "DCmmin": 0, + "DCmmax": 100, + "opl": 0, + "SPmin": 0, + "SPmax": 0, + "link": 0, + "tune": 0, + "jp": 100 + }, + { + "name": "TITAN 50x50", + "id": 1, + "aktor": 1, + "Kp": 7, + "Ki": 0.01, + "Kd": 128, + "DCmmin": 25, + "DCmmax": 100, + "opl": 0, + "SPmin": 0, + "SPmax": 0, + "link": 0, + "tune": 0, + "jp": 70 + }, + { + "name": "Servo MG995", + "id": 2, + "aktor": 2, + "Kp": 104, + "Ki": 0.2, + "Kd": 0, + "DCmmin": 0, + "DCmmax": 100, + "opl": 0, + "SPmin": 25, + "SPmax": 75, + "link": 0, + "tune": 0, + "jp": 100 + }, + { + "name": "Custom", + "id": 3, + "aktor": 1, + "Kp": 7, + "Ki": 0.2, + "Kd": 0, + "DCmmin": 0, + "DCmmax": 100, + "opl": 0, + "SPmin": 0, + "SPmax": 100, + "link": 0, + "tune": 0, + "jp": 100 + } + ], + "aktor": [ + "SSR", + "FAN", + "SERVO" + ], + "display": { + "updname": "", + "orientation": 0 + }, + "iot": { + "PMQhost": "192.168.2.1", + "PMQport": 1883, + "PMQuser": "", + "PMQpass": "", + "PMQqos": 0, + "PMQon": false, + "PMQint": 30, + "CLon": false, + "CLtoken": "thisisnotatoken", + "CLint": 30, + "CLurl": "cloud.wlanthermo.de/index.html" + }, + "notes": { + "fcm": [], + "ext": { + "on": 0, + "token": "", + "id": "", + "repeat": 1, + "service": 0, + "services": [ + "telegram", + "pushover" + ] + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/resources/mini/app.json b/bundles/org.openhab.binding.wlanthermo/src/test/resources/mini/app.json new file mode 100644 index 000000000..a88861a20 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/resources/mini/app.json @@ -0,0 +1,121 @@ +{ + "temp_unit": "fahrenheit", + "pit": { + "enabled": true, + "timestamp": "2020-05-29T17:00:54-05:00", + "setpoint": 110, + "current": 77.86, + "control_out": 100, + "ch": 0, + "type": "False", + "open_lid": "False" + }, + "pit2": { + "enabled": false + }, + "cpu_load": 94.267515923567, + "cpu_temp": 93.56, + "channel": { + "0": { + "temp": 78.28, + "color": "green", + "state": "ok", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal0", + "alert": false, + "show": true + }, + "1": { + "temp": 0, + "color": "red", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal1", + "alert": false, + "show": true + }, + "2": { + "temp": 0, + "color": "blue", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal2", + "alert": false, + "show": true + }, + "3": { + "temp": 0, + "color": "olive", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal3", + "alert": false, + "show": true + }, + "4": { + "temp": 0, + "color": "magenta", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal4", + "alert": false, + "show": true + }, + "5": { + "temp": 0, + "color": "yellow", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal5", + "alert": false, + "show": true + }, + "6": { + "temp": 0, + "color": "violet", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal6", + "alert": false, + "show": true + }, + "7": { + "temp": 0, + "color": "purple", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal7", + "alert": false, + "show": true + }, + "8": { + "temp": 0, + "color": "dark-violet", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal8 - Maverick 1", + "alert": false, + "show": true + }, + "9": { + "temp": 0, + "color": "seagreen", + "state": "er", + "temp_min": -20, + "temp_max": 200, + "name": "Kanal9 - Maverick 2", + "alert": false, + "show": true + } + }, + "timestamp": "2020-05-29T16:06:00-05:00" +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/data.json b/bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/data.json new file mode 100644 index 000000000..7ed291b0c --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/data.json @@ -0,0 +1,109 @@ +{ + "system": { + "time": "1610899485", + "unit": "C", + "soc": 32, + "charge": false, + "rssi": -47, + "online": 0 + }, + "channel": [ + { + "number": 1, + "name": "Kanal 1", + "typ": 0, + "temp": 23.7, + "min": 11, + "max": 155, + "alarm": 1, + "color": "#EF562D" + }, + { + "number": 2, + "name": "Kanal 2", + "typ": 3, + "temp": 999, + "min": 0, + "max": 48, + "alarm": 0, + "color": "#22B14C" + }, + { + "number": 3, + "name": "Kanal 3", + "typ": 3, + "temp": 999, + "min": 10, + "max": 35, + "alarm": 0, + "color": "#EF562D" + }, + { + "number": 4, + "name": "Kanal 4", + "typ": 3, + "temp": 999, + "min": 10, + "max": 54, + "alarm": 0, + "color": "#FFC100" + }, + { + "number": 5, + "name": "Kanal 5", + "typ": 3, + "temp": 999, + "min": 0, + "max": 69, + "alarm": 0, + "color": "#A349A4" + }, + { + "number": 6, + "name": "Kanal 6", + "typ": 0, + "temp": 999, + "min": 150, + "max": 170, + "alarm": 0, + "color": "#804000" + }, + { + "number": 7, + "name": "Kanal 7", + "typ": 0, + "temp": 23.6, + "min": 0, + "max": 54, + "alarm": 0, + "color": "#5587A2" + }, + { + "number": 8, + "name": "Kanal 8", + "typ": 0, + "temp": 999, + "min": 10, + "max": 35, + "alarm": 0, + "color": "#5C7148" + } + ], + "pitmaster": { + "type": [ + "off" + ], + "pm": [ + { + "id": 0, + "channel": 1, + "pid": 0, + "value": 0, + "set": 50, + "typ": "off", + "set_color": "#ff0000", + "value_color": "#000000" + } + ] + } +} diff --git a/bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/settings.json b/bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/settings.json new file mode 100644 index 000000000..0bad23905 --- /dev/null +++ b/bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/settings.json @@ -0,0 +1,117 @@ +{ + "device": { + "device": "nano", + "serial": "33e8bb", + "item": "n2E04o42000", + "hw_version": "v2", + "sw_version": "v1.0.6", + "api_version": "1", + "language": "de" + }, + "system": { + "time": "1610899506", + "unit": "C", + "ap": "NANO-AP", + "host": "NANO-33e8bb", + "language": "de", + "version": "v1.0.6", + "getupdate": "false", + "autoupd": true, + "hwversion": "V1+", + "god": 0 + }, + "hardware": [ + "V1", + "V1+" + ], + "api": { + "version": "1" + }, + "sensors": [ + "1000K/Maverick", + "Fantast-Neu", + "Fantast", + "100K/iGrill2", + "ET-73", + "Perfektion", + "50K", + "Inkbird", + "100K6A1B", + "Weber_6743", + "Santos", + "5K3A1B" + ], + "pid": [ + { + "name": "SSR SousVide", + "id": 0, + "aktor": 0, + "Kp": 104, + "Ki": 0.2, + "Kd": 0, + "DCmmin": 0, + "DCmmax": 100, + "opl": 0, + "tune": 0, + "jp": 100 + }, + { + "name": "TITAN 50x50", + "id": 1, + "aktor": 1, + "Kp": 3.8, + "Ki": 0.01, + "Kd": 128, + "DCmmin": 25, + "DCmmax": 100, + "opl": 0, + "tune": 0, + "jp": 70 + }, + { + "name": "Kamado 50x50", + "id": 2, + "aktor": 1, + "Kp": 7, + "Ki": 0.02, + "Kd": 630, + "DCmmin": 25, + "DCmmax": 100, + "opl": 0, + "tune": 0, + "jp": 70 + } + ], + "aktor": [ + "SSR", + "FAN", + "SERVO" + ], + "iot": { + "PMQhost": "192.168.2.1", + "PMQport": 1883, + "PMQuser": "", + "PMQpass": "", + "PMQqos": 0, + "PMQon": false, + "PMQint": 30, + "CLon": false, + "CLtoken": "thisisnotatoken", + "CLint": 30, + "CLurl": "cloud.wlanthermo.de/index.html" + }, + "notes": { + "fcm": [], + "ext": { + "on": 0, + "token": "", + "id": "", + "repeat": 1, + "service": 0, + "services": [ + "telegram", + "pushover" + ] + } + } +} \ No newline at end of file