]> git.basschouten.com Git - openhab-addons.git/commitdiff
[WlanThermo] Add support for new ESP32-powered devices [V3.x] (#9579)
authorCSchlipp <christian@schlipp.de>
Mon, 18 Jan 2021 23:58:20 +0000 (00:58 +0100)
committerGitHub <noreply@github.com>
Mon, 18 Jan 2021 23:58:20 +0000 (15:58 -0800)
* Add support for ESP32 devices
* Add Unit Tests
Ensure Gson objects are NonNull
Generify Handlers
Generify Utils

Signed-off-by: Christian Schlipp <christian@schlipp.de>
92 files changed:
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoBindingConstants.java
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoConfiguration.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoException.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoExtendedConfiguration.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoHandlerFactory.java
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoInputException.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniConfiguration.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniHandler.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoConfiguration.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoNanoHandler.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUnknownChannelException.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoUtil.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Handler.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32Util.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Channel.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Data.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pitmaster.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/Pm.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/data/System.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Api.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Device.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Display.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Ext.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Features.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Iot.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Notes.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Pid.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Sensor.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/Settings.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/esp32/dto/settings/System.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniUtil.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/App.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Channel.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Data.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/Pit.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/UtilMini.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/builtin/WlanThermoMiniCommandHandler.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/App.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Channel.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Data.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Pit.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/UtilNano.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoCommandHandler.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Handler.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Util.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Channel.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Data.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pitmaster.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Pm.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/System.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Channel.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Data.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pitmaster.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pm.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/System.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Api.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Device.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Ext.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Iot.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Notes.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Pid.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Settings.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/System.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Api.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Device.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Ext.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Iot.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Notes.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Pid.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/Settings.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/settings/System.java [deleted file]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-esp32.xml [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-mini.xml [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-group-types-nano.xml [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/channel-types.xml [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-esp32.xml [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-mini.xml [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types-nano.xml [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/main/resources/OH-INF/thing/thing-types.xml [deleted file]
bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/esp32/WlanThermoEsp32CommandHandlerTest.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniCommandHandlerTest.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/test/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1CommandHandlerTest.java [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/data.json [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/test/resources/esp32/settings.json [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/test/resources/mini/app.json [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/data.json [new file with mode: 0644]
bundles/org.openhab.binding.wlanthermo/src/test/resources/nanov1/settings.json [new file with mode: 0644]

index 92c6a00fdd59f0e30c5bd1b51044105928e3f358..0fa5a2465d07c162205878ac1c8652e6ba4dd07a 100644 (file)
@@ -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/WlanThermoConfiguration.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoConfiguration.java
new file mode 100644 (file)
index 0000000..41508eb
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * 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;
+
+/**
+ * The {@link WlanThermoConfiguration} class contains fields mapping thing configuration parameters.
+ *
+ * @author Christian Schlipp - Initial contribution
+ */
+@NonNullByDefault
+public class WlanThermoConfiguration {
+
+    /**
+     * IP Address of WlanThermo.
+     */
+    private String ipAddress = "";
+
+    /**
+     * 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;
+    }
+
+    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/WlanThermoException.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoException.java
new file mode 100644 (file)
index 0000000..f334838
--- /dev/null
@@ -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 (file)
index 0000000..c78d341
--- /dev/null
@@ -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 (file)
index 0000000..3a8bacc
--- /dev/null
@@ -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> T doGet(String endpoint, Class<T> 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);
+}
index c84195ddb162bdc0068110426fa1bc78dd9061ca..da0d991a39a8e4a45475dc8ecf08aefe16b18143 100644 (file)
@@ -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<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<ThingTypeUID>(
-            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 (file)
index 0000000..3955a3f
--- /dev/null
@@ -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/WlanThermoMiniConfiguration.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniConfiguration.java
deleted file mode 100644 (file)
index f62571d..0000000
+++ /dev/null
@@ -1,71 +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;
-
-/**
- * The {@link WlanThermoMiniConfiguration} class contains fields mapping thing configuration parameters.
- *
- * @author Christian Schlipp - Initial contribution
- */
-@NonNullByDefault
-public class WlanThermoMiniConfiguration {
-
-    /**
-     * IP Address of WlanThermo.
-     */
-    private String ipAddress = "";
-
-    /**
-     * 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;
-    }
-
-    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/WlanThermoMiniHandler.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/WlanThermoMiniHandler.java
deleted file mode 100644 (file)
index eb0c389..0000000
+++ /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 (file)
index 378b5b6..0000000
+++ /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 (file)
index 0b44d3e..0000000
+++ /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 (file)
index 0000000..ca01536
--- /dev/null
@@ -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 (file)
index 0000000..d6ff837
--- /dev/null
@@ -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<String, String> colorMappings, String defaultColorName) {
+        if (!colorHex.startsWith("#")) {
+            colorHex = "#" + colorHex;
+        }
+
+        for (Map.Entry<String, String> 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> 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 (file)
index 0000000..cf72a89
--- /dev/null
@@ -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<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
+
+        List<Channel> 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<Channel> channelList = data.getChannel();
+        System system = data.getSystem();
+        Unit<Temperature> 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<Channel> 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 (file)
index 0000000..b42c882
--- /dev/null
@@ -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<String, String> 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 (file)
index 0000000..cef43ae
--- /dev/null
@@ -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<String, String> COLOR_MAPPINGS = createColorMap();
+    private static final String DEFAULT_HEX = "#FFFFFF";
+    private static final String DEFAULT_COLORNAME = "undefined";
+
+    private WlanThermoEsp32Util() {
+        // hidden
+    }
+
+    private static Map<String, String> createColorMap() {
+        HashMap<String, String> 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 (file)
index 0000000..3301918
--- /dev/null
@@ -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 (file)
index 0000000..470d880
--- /dev/null
@@ -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> channel = null;
+    @SerializedName("pitmaster")
+    @Expose
+    private Pitmaster pitmaster;
+
+    public System getSystem() {
+        return system;
+    }
+
+    public void setSystem(System system) {
+        this.system = system;
+    }
+
+    public List<Channel> getChannel() {
+        return channel;
+    }
+
+    public void setChannel(List<Channel> 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 (file)
index 0000000..3d6f542
--- /dev/null
@@ -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<String> type = null;
+    @SerializedName("pm")
+    @Expose
+    private List<Pm> pm = null;
+
+    public List<String> getType() {
+        return type;
+    }
+
+    public void setType(List<String> type) {
+        this.type = type;
+    }
+
+    public List<Pm> getPm() {
+        return pm;
+    }
+
+    public void setPm(List<Pm> 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 (file)
index 0000000..27bca17
--- /dev/null
@@ -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 (file)
index 0000000..6a12860
--- /dev/null
@@ -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 (file)
index 0000000..64fffda
--- /dev/null
@@ -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 (file)
index 0000000..95552be
--- /dev/null
@@ -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 (file)
index 0000000..205977c
--- /dev/null
@@ -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 (file)
index 0000000..985ec0a
--- /dev/null
@@ -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<String> 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<String> getServices() {
+        return services;
+    }
+
+    public void setServices(List<String> 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 (file)
index 0000000..bd4b2d3
--- /dev/null
@@ -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 (file)
index 0000000..e3033a4
--- /dev/null
@@ -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 (file)
index 0000000..f4d5cc5
--- /dev/null
@@ -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<Object> fcm = null;
+    @SerializedName("ext")
+    @Expose
+    private Ext ext;
+
+    public List<Object> getFcm() {
+        return fcm;
+    }
+
+    public void setFcm(List<Object> 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 (file)
index 0000000..5125451
--- /dev/null
@@ -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 (file)
index 0000000..e2dc022
--- /dev/null
@@ -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 (file)
index 0000000..dc12508
--- /dev/null
@@ -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<String> hardware = null;
+    @SerializedName("api")
+    @Expose
+    private Api api;
+    @SerializedName("sensors")
+    @Expose
+    private List<Sensor> sensors = null;
+    @SerializedName("features")
+    @Expose
+    private Features features;
+    @SerializedName("pid")
+    @Expose
+    private List<Pid> pid = null;
+    @SerializedName("aktor")
+    @Expose
+    private List<String> 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<String> getHardware() {
+        return hardware;
+    }
+
+    public void setHardware(List<String> hardware) {
+        this.hardware = hardware;
+    }
+
+    public Api getApi() {
+        return api;
+    }
+
+    public void setApi(Api api) {
+        this.api = api;
+    }
+
+    public List<Sensor> getSensors() {
+        return sensors;
+    }
+
+    public void setSensors(List<Sensor> sensors) {
+        this.sensors = sensors;
+    }
+
+    public Features getFeatures() {
+        return features;
+    }
+
+    public void setFeatures(Features features) {
+        this.features = features;
+    }
+
+    public List<Pid> getPid() {
+        return pid;
+    }
+
+    public void setPid(List<Pid> pid) {
+        this.pid = pid;
+    }
+
+    public List<String> getAktor() {
+        return aktor;
+    }
+
+    public void setAktor(List<String> 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 (file)
index 0000000..e10af5d
--- /dev/null
@@ -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 (file)
index 0000000..ccdb044
--- /dev/null
@@ -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<Temperature> 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 (file)
index 0000000..b5a57c7
--- /dev/null
@@ -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/WlanThermoMiniUtil.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/WlanThermoMiniUtil.java
new file mode 100644 (file)
index 0000000..69a84a7
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
+
+/**
+ * The {@link WlanThermoMiniUtil} class provides conversion functions for the WlanThermo Mini
+ *
+ * @author Christian Schlipp - Initial contribution
+ */
+@NonNullByDefault
+public class WlanThermoMiniUtil extends WlanThermoUtil {
+    private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
+    private static final String DEFAULT_HEX = "#ffffff";
+
+    private WlanThermoMiniUtil() {
+        // hidden
+    }
+
+    private static Map<String, String> createColorMap() {
+        HashMap<String, String> map = new HashMap<>();
+        map.put("green", "#008000");
+        map.put("red", "#FF0000");
+        map.put("blue", "#0000FF");
+        map.put("olive", "#808000");
+        map.put("magenta", "#FF00FF");
+        map.put("yellow", "#FFFF00");
+        map.put("violet", "#EE82EE");
+        map.put("orange", "#FFA500");
+        map.put("mediumpurple3", "#9370DB");
+        map.put("aquamarine", "#7FFFD4");
+        map.put("brown", "#A52A2A");
+        map.put("plum", "#DDA0DD");
+        map.put("skyblue", "#87CEEB");
+        map.put("orange-red", "#FF4500");
+        map.put("salmon", "#FA8072");
+        map.put("black", "#000000");
+        map.put("dark-grey", "#A9A9A9");
+        map.put("purple", "800080");
+        map.put("turquoise", "#40E0D0");
+        map.put("khaki", "#F0E68C");
+        map.put("dark-violet", "#9400D3");
+        map.put("seagreen", "#2E8B57");
+        map.put("web-blue", "#0080ff");
+        map.put("steelblue", "#4682B4");
+        map.put("gold", "#FFD700");
+        map.put("dark-green", "#006400");
+        map.put("midnight-blue", "#191970");
+        map.put("dark-khaki", "#BDB76B");
+        map.put("dark-olivegreen", "#556B2F");
+        map.put("pink", "#FFC0CB");
+        map.put("chartreuse", "#7FFF00");
+        map.put("gray", "#808080");
+        map.put("slategrey", "#708090");
+        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);
+    }
+}
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/builtin/App.java
deleted file mode 100644 (file)
index f45c16b..0000000
+++ /dev/null
@@ -1,167 +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 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/
- * Be careful to not overwrite the getState/getTrigger function mapping the Data to OH channels!
- *
- * @author Christian Schlipp - Initial contribution
- */
-public class App {
-
-    @SerializedName("temp_unit")
-    @Expose
-    private String tempUnit;
-    @SerializedName("pit")
-    @Expose
-    private Pit pit;
-    @SerializedName("pit2")
-    @Expose
-    private Pit pit2;
-    @SerializedName("cpu_load")
-    @Expose
-    private Double cpuLoad;
-    @SerializedName("cpu_temp")
-    @Expose
-    private Double cpuTemp;
-    @SerializedName("channel")
-    @Expose
-    private Channel channel;
-    @SerializedName("timestamp")
-    @Expose
-    private String timestamp;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public App() {
-    }
-
-    /**
-     * 
-     * @param cpuLoad
-     * @param pit2
-     * @param tempUnit
-     * @param channel
-     * @param pit
-     * @param cpuTemp
-     * @param timestamp
-     */
-    public App(String tempUnit, Pit pit, Pit pit2, Double cpuLoad, Double cpuTemp, Channel channel, String timestamp) {
-        super();
-        this.tempUnit = tempUnit;
-        this.pit = pit;
-        this.pit2 = pit2;
-        this.cpuLoad = cpuLoad;
-        this.cpuTemp = cpuTemp;
-        this.channel = channel;
-        this.timestamp = timestamp;
-    }
-
-    public String getTempUnit() {
-        return tempUnit;
-    }
-
-    public void setTempUnit(String tempUnit) {
-        this.tempUnit = tempUnit;
-    }
-
-    public App withTempUnit(String tempUnit) {
-        this.tempUnit = tempUnit;
-        return this;
-    }
-
-    public Pit getPit() {
-        return pit;
-    }
-
-    public void setPit(Pit pit) {
-        this.pit = pit;
-    }
-
-    public App withPit(Pit pit) {
-        this.pit = pit;
-        return this;
-    }
-
-    public Pit getPit2() {
-        return pit2;
-    }
-
-    public void setPit2(Pit pit2) {
-        this.pit2 = pit2;
-    }
-
-    public App withPit2(Pit pit2) {
-        this.pit2 = pit2;
-        return this;
-    }
-
-    public Double getCpuLoad() {
-        return cpuLoad;
-    }
-
-    public void setCpuLoad(Double cpuLoad) {
-        this.cpuLoad = cpuLoad;
-    }
-
-    public App withCpuLoad(Double cpuLoad) {
-        this.cpuLoad = cpuLoad;
-        return this;
-    }
-
-    public Double getCpuTemp() {
-        return cpuTemp;
-    }
-
-    public void setCpuTemp(Double cpuTemp) {
-        this.cpuTemp = cpuTemp;
-    }
-
-    public App withCpuTemp(Double cpuTemp) {
-        this.cpuTemp = cpuTemp;
-        return this;
-    }
-
-    public Channel getChannel() {
-        return channel;
-    }
-
-    public void setChannel(Channel channel) {
-        this.channel = channel;
-    }
-
-    public App withChannel(Channel channel) {
-        this.channel = channel;
-        return this;
-    }
-
-    public String getTimestamp() {
-        return timestamp;
-    }
-
-    public void setTimestamp(String timestamp) {
-        this.timestamp = timestamp;
-    }
-
-    public App withTimestamp(String timestamp) {
-        this.timestamp = timestamp;
-        return this;
-    }
-}
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/builtin/Channel.java
deleted file mode 100644 (file)
index 5329d33..0000000
+++ /dev/null
@@ -1,247 +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 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("0")
-    @Expose
-    private Data _0;
-    @SerializedName("1")
-    @Expose
-    private Data _1;
-    @SerializedName("2")
-    @Expose
-    private Data _2;
-    @SerializedName("3")
-    @Expose
-    private Data _3;
-    @SerializedName("4")
-    @Expose
-    private Data _4;
-    @SerializedName("5")
-    @Expose
-    private Data _5;
-    @SerializedName("6")
-    @Expose
-    private Data _6;
-    @SerializedName("7")
-    @Expose
-    private Data _7;
-    @SerializedName("8")
-    @Expose
-    private Data _8;
-    @SerializedName("9")
-    @Expose
-    private Data _9;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public Channel() {
-    }
-
-    /**
-     * 
-     * @param _0
-     * @param _1
-     * @param _2
-     * @param _3
-     * @param _4
-     * @param _5
-     * @param _6
-     * @param _7
-     * @param _8
-     * @param _9
-     */
-    public Channel(Data _0, Data _1, Data _2, Data _3, Data _4, Data _5, Data _6, Data _7, Data _8, Data _9) {
-        super();
-        this._0 = _0;
-        this._1 = _1;
-        this._2 = _2;
-        this._3 = _3;
-        this._4 = _4;
-        this._5 = _5;
-        this._6 = _6;
-        this._7 = _7;
-        this._8 = _8;
-        this._9 = _9;
-    }
-
-    public Data get0() {
-        return _0;
-    }
-
-    public void set0(Data _0) {
-        this._0 = _0;
-    }
-
-    public Channel with0(Data _0) {
-        this._0 = _0;
-        return this;
-    }
-
-    public Data get1() {
-        return _1;
-    }
-
-    public void set1(Data _1) {
-        this._1 = _1;
-    }
-
-    public Channel with1(Data _1) {
-        this._1 = _1;
-        return this;
-    }
-
-    public Data get2() {
-        return _2;
-    }
-
-    public void set2(Data _2) {
-        this._2 = _2;
-    }
-
-    public Channel with2(Data _2) {
-        this._2 = _2;
-        return this;
-    }
-
-    public Data get3() {
-        return _3;
-    }
-
-    public void set3(Data _3) {
-        this._3 = _3;
-    }
-
-    public Channel with3(Data _3) {
-        this._3 = _3;
-        return this;
-    }
-
-    public Data get4() {
-        return _4;
-    }
-
-    public void set4(Data _4) {
-        this._4 = _4;
-    }
-
-    public Channel with4(Data _4) {
-        this._4 = _4;
-        return this;
-    }
-
-    public Data get5() {
-        return _5;
-    }
-
-    public void set5(Data _5) {
-        this._5 = _5;
-    }
-
-    public Channel with5(Data _5) {
-        this._5 = _5;
-        return this;
-    }
-
-    public Data get6() {
-        return _6;
-    }
-
-    public void set6(Data _6) {
-        this._6 = _6;
-    }
-
-    public Channel with6(Data _6) {
-        this._6 = _6;
-        return this;
-    }
-
-    public Data get7() {
-        return _7;
-    }
-
-    public void set7(Data _7) {
-        this._7 = _7;
-    }
-
-    public Channel with7(Data _7) {
-        this._7 = _7;
-        return this;
-    }
-
-    public Data get8() {
-        return _8;
-    }
-
-    public void set8(Data _8) {
-        this._8 = _8;
-    }
-
-    public Channel with8(Data _8) {
-        this._8 = _8;
-        return this;
-    }
-
-    public Data get9() {
-        return _9;
-    }
-
-    public void set9(Data _9) {
-        this._9 = _9;
-    }
-
-    public Channel with9(Data _9) {
-        this._9 = _9;
-        return this;
-    }
-
-    public Data getData(int i) {
-        switch (i) {
-            case 0:
-                return get0();
-            case 1:
-                return get1();
-            case 2:
-                return get2();
-            case 3:
-                return get3();
-            case 4:
-                return get4();
-            case 5:
-                return get5();
-            case 6:
-                return get6();
-            case 7:
-                return get7();
-            case 8:
-                return get8();
-            case 9:
-                return get9();
-            default:
-                return null;
-        }
-    }
-}
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/builtin/Data.java
deleted file mode 100644 (file)
index 3dc0ee6..0000000
+++ /dev/null
@@ -1,185 +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 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("temp")
-    @Expose
-    private Double temp;
-    @SerializedName("color")
-    @Expose
-    private String color;
-    @SerializedName("state")
-    @Expose
-    private String state;
-    @SerializedName("temp_min")
-    @Expose
-    private Double tempMin;
-    @SerializedName("temp_max")
-    @Expose
-    private Double tempMax;
-    @SerializedName("name")
-    @Expose
-    private String name;
-    @SerializedName("alert")
-    @Expose
-    private Boolean alert;
-    @SerializedName("show")
-    @Expose
-    private Boolean show;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public Data() {
-    }
-
-    /**
-     * 
-     * @param tempMax
-     * @param temp
-     * @param color
-     * @param alert
-     * @param name
-     * @param show
-     * @param state
-     * @param tempMin
-     */
-    public Data(Double temp, String color, String state, Double tempMin, Double tempMax, String name, Boolean alert,
-            Boolean show) {
-        super();
-        this.temp = temp;
-        this.color = color;
-        this.state = state;
-        this.tempMin = tempMin;
-        this.tempMax = tempMax;
-        this.name = name;
-        this.alert = alert;
-        this.show = show;
-    }
-
-    public Double getTemp() {
-        return temp;
-    }
-
-    public void setTemp(Double temp) {
-        this.temp = temp;
-    }
-
-    public Data withTemp(Double temp) {
-        this.temp = temp;
-        return this;
-    }
-
-    public String getColor() {
-        return color;
-    }
-
-    public void setColor(String color) {
-        this.color = color;
-    }
-
-    public Data withColor(String color) {
-        this.color = color;
-        return this;
-    }
-
-    public String getState() {
-        return state;
-    }
-
-    public void setState(String state) {
-        this.state = state;
-    }
-
-    public Data withState(String state) {
-        this.state = state;
-        return this;
-    }
-
-    public Double getTempMin() {
-        return tempMin;
-    }
-
-    public void setTempMin(Double tempMin) {
-        this.tempMin = tempMin;
-    }
-
-    public Data withTempMin(Double tempMin) {
-        this.tempMin = tempMin;
-        return this;
-    }
-
-    public Double getTempMax() {
-        return tempMax;
-    }
-
-    public void setTempMax(Double tempMax) {
-        this.tempMax = tempMax;
-    }
-
-    public Data withTempMax(Double tempMax) {
-        this.tempMax = tempMax;
-        return this;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Data withName(String name) {
-        this.name = name;
-        return this;
-    }
-
-    public Boolean getAlert() {
-        return alert;
-    }
-
-    public void setAlert(Boolean alert) {
-        this.alert = alert;
-    }
-
-    public Data withAlert(Boolean alert) {
-        this.alert = alert;
-        return this;
-    }
-
-    public Boolean getShow() {
-        return show;
-    }
-
-    public void setShow(Boolean show) {
-        this.show = show;
-    }
-
-    public Data withShow(Boolean show) {
-        this.show = show;
-        return this;
-    }
-}
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/builtin/Pit.java
deleted file mode 100644 (file)
index cabe125..0000000
+++ /dev/null
@@ -1,185 +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 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 Pit {
-
-    @SerializedName("enabled")
-    @Expose
-    private Boolean enabled;
-    @SerializedName("timestamp")
-    @Expose
-    private String timestamp;
-    @SerializedName("setpoint")
-    @Expose
-    private Double setpoint;
-    @SerializedName("current")
-    @Expose
-    private Double current;
-    @SerializedName("control_out")
-    @Expose
-    private Integer controlOut;
-    @SerializedName("ch")
-    @Expose
-    private Integer ch;
-    @SerializedName("type")
-    @Expose
-    private String type;
-    @SerializedName("open_lid")
-    @Expose
-    private String openLid;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public Pit() {
-    }
-
-    /**
-     * 
-     * @param current
-     * @param setpoint
-     * @param ch
-     * @param openLid
-     * @param controlOut
-     * @param type
-     * @param enabled
-     * @param timestamp
-     */
-    public Pit(Boolean enabled, String timestamp, Double setpoint, Double current, Integer controlOut, Integer ch,
-            String type, String openLid) {
-        super();
-        this.enabled = enabled;
-        this.timestamp = timestamp;
-        this.setpoint = setpoint;
-        this.current = current;
-        this.controlOut = controlOut;
-        this.ch = ch;
-        this.type = type;
-        this.openLid = openLid;
-    }
-
-    public Boolean getEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(Boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    public Pit withEnabled(Boolean enabled) {
-        this.enabled = enabled;
-        return this;
-    }
-
-    public String getTimestamp() {
-        return timestamp;
-    }
-
-    public void setTimestamp(String timestamp) {
-        this.timestamp = timestamp;
-    }
-
-    public Pit withTimestamp(String timestamp) {
-        this.timestamp = timestamp;
-        return this;
-    }
-
-    public Double getSetpoint() {
-        return setpoint;
-    }
-
-    public void setSetpoint(Double setpoint) {
-        this.setpoint = setpoint;
-    }
-
-    public Pit withSetpoint(Double setpoint) {
-        this.setpoint = setpoint;
-        return this;
-    }
-
-    public Double getCurrent() {
-        return current;
-    }
-
-    public void setCurrent(Double current) {
-        this.current = current;
-    }
-
-    public Pit withCurrent(Double current) {
-        this.current = current;
-        return this;
-    }
-
-    public Integer getControlOut() {
-        return controlOut;
-    }
-
-    public void setControlOut(Integer controlOut) {
-        this.controlOut = controlOut;
-    }
-
-    public Pit withControlOut(Integer controlOut) {
-        this.controlOut = controlOut;
-        return this;
-    }
-
-    public Integer getCh() {
-        return ch;
-    }
-
-    public void setCh(Integer ch) {
-        this.ch = ch;
-    }
-
-    public Pit withCh(Integer ch) {
-        this.ch = ch;
-        return this;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public Pit withType(String type) {
-        this.type = type;
-        return this;
-    }
-
-    public String getOpenLid() {
-        return openLid;
-    }
-
-    public void setOpenLid(String openLid) {
-        this.openLid = openLid;
-    }
-
-    public Pit withOpenLid(String openLid) {
-        this.openLid = openLid;
-        return this;
-    }
-}
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/builtin/UtilMini.java
deleted file mode 100644 (file)
index e1513cd..0000000
+++ /dev/null
@@ -1,78 +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.util.HashMap;
-import java.util.Map;
-
-/**
- * The {@link UtilMini} class provides conversion functions for the WlanThermo Mini
- *
- * @author Christian Schlipp - Initial contribution
- */
-public class UtilMini {
-    private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
-    private static final String DEFAULT_HEX = "#ffffff";
-
-    private UtilMini() {
-        // hidden
-    }
-
-    private static Map<String, String> createColorMap() {
-        HashMap<String, String> map = new HashMap<>();
-        map.put("green", "#008000");
-        map.put("red", "#FF0000");
-        map.put("blue", "#0000FF");
-        map.put("olive", "#808000");
-        map.put("magenta", "#FF00FF");
-        map.put("yellow", "#FFFF00");
-        map.put("violet", "#EE82EE");
-        map.put("orange", "#FFA500");
-        map.put("mediumpurple3", "#9370DB");
-        map.put("aquamarine", "#7FFFD4");
-        map.put("brown", "#A52A2A");
-        map.put("plum", "#DDA0DD");
-        map.put("skyblue", "#87CEEB");
-        map.put("orange-red", "#FF4500");
-        map.put("salmon", "#FA8072");
-        map.put("black", "#000000");
-        map.put("dark-grey", "#A9A9A9");
-        map.put("purple", "800080");
-        map.put("turquoise", "#40E0D0");
-        map.put("khaki", "#F0E68C");
-        map.put("dark-violet", "#9400D3");
-        map.put("seagreen", "#2E8B57");
-        map.put("web-blue", "#0080ff");
-        map.put("steelblue", "#4682B4");
-        map.put("gold", "#FFD700");
-        map.put("dark-green", "#006400");
-        map.put("midnight-blue", "#191970");
-        map.put("dark-khaki", "#BDB76B");
-        map.put("dark-olivegreen", "#556B2F");
-        map.put("pink", "#FFC0CB");
-        map.put("chartreuse", "#7FFF00");
-        map.put("gray", "#808080");
-        map.put("slategrey", "#708090");
-        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);
-    }
-}
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 (file)
index 4ebda78..0000000
+++ /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/dto/builtin/App.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/App.java
new file mode 100644 (file)
index 0000000..2b3cd6f
--- /dev/null
@@ -0,0 +1,167 @@
+/**
+ * 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.dto.builtin;
+
+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/
+ * Be careful to not overwrite the getState/getTrigger function mapping the Data to OH channels!
+ *
+ * @author Christian Schlipp - Initial contribution
+ */
+public class App {
+
+    @SerializedName("temp_unit")
+    @Expose
+    private String tempUnit;
+    @SerializedName("pit")
+    @Expose
+    private Pit pit;
+    @SerializedName("pit2")
+    @Expose
+    private Pit pit2;
+    @SerializedName("cpu_load")
+    @Expose
+    private Double cpuLoad;
+    @SerializedName("cpu_temp")
+    @Expose
+    private Double cpuTemp;
+    @SerializedName("channel")
+    @Expose
+    private Channel channel;
+    @SerializedName("timestamp")
+    @Expose
+    private String timestamp;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public App() {
+    }
+
+    /**
+     * 
+     * @param cpuLoad
+     * @param pit2
+     * @param tempUnit
+     * @param channel
+     * @param pit
+     * @param cpuTemp
+     * @param timestamp
+     */
+    public App(String tempUnit, Pit pit, Pit pit2, Double cpuLoad, Double cpuTemp, Channel channel, String timestamp) {
+        super();
+        this.tempUnit = tempUnit;
+        this.pit = pit;
+        this.pit2 = pit2;
+        this.cpuLoad = cpuLoad;
+        this.cpuTemp = cpuTemp;
+        this.channel = channel;
+        this.timestamp = timestamp;
+    }
+
+    public String getTempUnit() {
+        return tempUnit;
+    }
+
+    public void setTempUnit(String tempUnit) {
+        this.tempUnit = tempUnit;
+    }
+
+    public App withTempUnit(String tempUnit) {
+        this.tempUnit = tempUnit;
+        return this;
+    }
+
+    public Pit getPit() {
+        return pit;
+    }
+
+    public void setPit(Pit pit) {
+        this.pit = pit;
+    }
+
+    public App withPit(Pit pit) {
+        this.pit = pit;
+        return this;
+    }
+
+    public Pit getPit2() {
+        return pit2;
+    }
+
+    public void setPit2(Pit pit2) {
+        this.pit2 = pit2;
+    }
+
+    public App withPit2(Pit pit2) {
+        this.pit2 = pit2;
+        return this;
+    }
+
+    public Double getCpuLoad() {
+        return cpuLoad;
+    }
+
+    public void setCpuLoad(Double cpuLoad) {
+        this.cpuLoad = cpuLoad;
+    }
+
+    public App withCpuLoad(Double cpuLoad) {
+        this.cpuLoad = cpuLoad;
+        return this;
+    }
+
+    public Double getCpuTemp() {
+        return cpuTemp;
+    }
+
+    public void setCpuTemp(Double cpuTemp) {
+        this.cpuTemp = cpuTemp;
+    }
+
+    public App withCpuTemp(Double cpuTemp) {
+        this.cpuTemp = cpuTemp;
+        return this;
+    }
+
+    public Channel getChannel() {
+        return channel;
+    }
+
+    public void setChannel(Channel channel) {
+        this.channel = channel;
+    }
+
+    public App withChannel(Channel channel) {
+        this.channel = channel;
+        return this;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public App withTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+        return this;
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Channel.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Channel.java
new file mode 100644 (file)
index 0000000..0dec13c
--- /dev/null
@@ -0,0 +1,247 @@
+/**
+ * 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.dto.builtin;
+
+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("0")
+    @Expose
+    private Data _0;
+    @SerializedName("1")
+    @Expose
+    private Data _1;
+    @SerializedName("2")
+    @Expose
+    private Data _2;
+    @SerializedName("3")
+    @Expose
+    private Data _3;
+    @SerializedName("4")
+    @Expose
+    private Data _4;
+    @SerializedName("5")
+    @Expose
+    private Data _5;
+    @SerializedName("6")
+    @Expose
+    private Data _6;
+    @SerializedName("7")
+    @Expose
+    private Data _7;
+    @SerializedName("8")
+    @Expose
+    private Data _8;
+    @SerializedName("9")
+    @Expose
+    private Data _9;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public Channel() {
+    }
+
+    /**
+     * 
+     * @param _0
+     * @param _1
+     * @param _2
+     * @param _3
+     * @param _4
+     * @param _5
+     * @param _6
+     * @param _7
+     * @param _8
+     * @param _9
+     */
+    public Channel(Data _0, Data _1, Data _2, Data _3, Data _4, Data _5, Data _6, Data _7, Data _8, Data _9) {
+        super();
+        this._0 = _0;
+        this._1 = _1;
+        this._2 = _2;
+        this._3 = _3;
+        this._4 = _4;
+        this._5 = _5;
+        this._6 = _6;
+        this._7 = _7;
+        this._8 = _8;
+        this._9 = _9;
+    }
+
+    public Data get0() {
+        return _0;
+    }
+
+    public void set0(Data _0) {
+        this._0 = _0;
+    }
+
+    public Channel with0(Data _0) {
+        this._0 = _0;
+        return this;
+    }
+
+    public Data get1() {
+        return _1;
+    }
+
+    public void set1(Data _1) {
+        this._1 = _1;
+    }
+
+    public Channel with1(Data _1) {
+        this._1 = _1;
+        return this;
+    }
+
+    public Data get2() {
+        return _2;
+    }
+
+    public void set2(Data _2) {
+        this._2 = _2;
+    }
+
+    public Channel with2(Data _2) {
+        this._2 = _2;
+        return this;
+    }
+
+    public Data get3() {
+        return _3;
+    }
+
+    public void set3(Data _3) {
+        this._3 = _3;
+    }
+
+    public Channel with3(Data _3) {
+        this._3 = _3;
+        return this;
+    }
+
+    public Data get4() {
+        return _4;
+    }
+
+    public void set4(Data _4) {
+        this._4 = _4;
+    }
+
+    public Channel with4(Data _4) {
+        this._4 = _4;
+        return this;
+    }
+
+    public Data get5() {
+        return _5;
+    }
+
+    public void set5(Data _5) {
+        this._5 = _5;
+    }
+
+    public Channel with5(Data _5) {
+        this._5 = _5;
+        return this;
+    }
+
+    public Data get6() {
+        return _6;
+    }
+
+    public void set6(Data _6) {
+        this._6 = _6;
+    }
+
+    public Channel with6(Data _6) {
+        this._6 = _6;
+        return this;
+    }
+
+    public Data get7() {
+        return _7;
+    }
+
+    public void set7(Data _7) {
+        this._7 = _7;
+    }
+
+    public Channel with7(Data _7) {
+        this._7 = _7;
+        return this;
+    }
+
+    public Data get8() {
+        return _8;
+    }
+
+    public void set8(Data _8) {
+        this._8 = _8;
+    }
+
+    public Channel with8(Data _8) {
+        this._8 = _8;
+        return this;
+    }
+
+    public Data get9() {
+        return _9;
+    }
+
+    public void set9(Data _9) {
+        this._9 = _9;
+    }
+
+    public Channel with9(Data _9) {
+        this._9 = _9;
+        return this;
+    }
+
+    public Data getData(int i) {
+        switch (i) {
+            case 0:
+                return get0();
+            case 1:
+                return get1();
+            case 2:
+                return get2();
+            case 3:
+                return get3();
+            case 4:
+                return get4();
+            case 5:
+                return get5();
+            case 6:
+                return get6();
+            case 7:
+                return get7();
+            case 8:
+                return get8();
+            case 9:
+                return get9();
+            default:
+                return null;
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Data.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Data.java
new file mode 100644 (file)
index 0000000..ef8c015
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * 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.dto.builtin;
+
+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("temp")
+    @Expose
+    private Double temp;
+    @SerializedName("color")
+    @Expose
+    private String color;
+    @SerializedName("state")
+    @Expose
+    private String state;
+    @SerializedName("temp_min")
+    @Expose
+    private Double tempMin;
+    @SerializedName("temp_max")
+    @Expose
+    private Double tempMax;
+    @SerializedName("name")
+    @Expose
+    private String name;
+    @SerializedName("alert")
+    @Expose
+    private Boolean alert;
+    @SerializedName("show")
+    @Expose
+    private Boolean show;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public Data() {
+    }
+
+    /**
+     * 
+     * @param tempMax
+     * @param temp
+     * @param color
+     * @param alert
+     * @param name
+     * @param show
+     * @param state
+     * @param tempMin
+     */
+    public Data(Double temp, String color, String state, Double tempMin, Double tempMax, String name, Boolean alert,
+            Boolean show) {
+        super();
+        this.temp = temp;
+        this.color = color;
+        this.state = state;
+        this.tempMin = tempMin;
+        this.tempMax = tempMax;
+        this.name = name;
+        this.alert = alert;
+        this.show = show;
+    }
+
+    public Double getTemp() {
+        return temp;
+    }
+
+    public void setTemp(Double temp) {
+        this.temp = temp;
+    }
+
+    public Data withTemp(Double temp) {
+        this.temp = temp;
+        return this;
+    }
+
+    public String getColor() {
+        return color;
+    }
+
+    public void setColor(String color) {
+        this.color = color;
+    }
+
+    public Data withColor(String color) {
+        this.color = color;
+        return this;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public Data withState(String state) {
+        this.state = state;
+        return this;
+    }
+
+    public Double getTempMin() {
+        return tempMin;
+    }
+
+    public void setTempMin(Double tempMin) {
+        this.tempMin = tempMin;
+    }
+
+    public Data withTempMin(Double tempMin) {
+        this.tempMin = tempMin;
+        return this;
+    }
+
+    public Double getTempMax() {
+        return tempMax;
+    }
+
+    public void setTempMax(Double tempMax) {
+        this.tempMax = tempMax;
+    }
+
+    public Data withTempMax(Double tempMax) {
+        this.tempMax = tempMax;
+        return this;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Data withName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    public Boolean getAlert() {
+        return alert;
+    }
+
+    public void setAlert(Boolean alert) {
+        this.alert = alert;
+    }
+
+    public Data withAlert(Boolean alert) {
+        this.alert = alert;
+        return this;
+    }
+
+    public Boolean getShow() {
+        return show;
+    }
+
+    public void setShow(Boolean show) {
+        this.show = show;
+    }
+
+    public Data withShow(Boolean show) {
+        this.show = show;
+        return this;
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Pit.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/mini/dto/builtin/Pit.java
new file mode 100644 (file)
index 0000000..396a7a9
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * 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.dto.builtin;
+
+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 Pit {
+
+    @SerializedName("enabled")
+    @Expose
+    private Boolean enabled;
+    @SerializedName("timestamp")
+    @Expose
+    private String timestamp;
+    @SerializedName("setpoint")
+    @Expose
+    private Double setpoint;
+    @SerializedName("current")
+    @Expose
+    private Double current;
+    @SerializedName("control_out")
+    @Expose
+    private Integer controlOut;
+    @SerializedName("ch")
+    @Expose
+    private Integer ch;
+    @SerializedName("type")
+    @Expose
+    private String type;
+    @SerializedName("open_lid")
+    @Expose
+    private String openLid;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public Pit() {
+    }
+
+    /**
+     * 
+     * @param current
+     * @param setpoint
+     * @param ch
+     * @param openLid
+     * @param controlOut
+     * @param type
+     * @param enabled
+     * @param timestamp
+     */
+    public Pit(Boolean enabled, String timestamp, Double setpoint, Double current, Integer controlOut, Integer ch,
+            String type, String openLid) {
+        super();
+        this.enabled = enabled;
+        this.timestamp = timestamp;
+        this.setpoint = setpoint;
+        this.current = current;
+        this.controlOut = controlOut;
+        this.ch = ch;
+        this.type = type;
+        this.openLid = openLid;
+    }
+
+    public Boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(Boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public Pit withEnabled(Boolean enabled) {
+        this.enabled = enabled;
+        return this;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public Pit withTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+        return this;
+    }
+
+    public Double getSetpoint() {
+        return setpoint;
+    }
+
+    public void setSetpoint(Double setpoint) {
+        this.setpoint = setpoint;
+    }
+
+    public Pit withSetpoint(Double setpoint) {
+        this.setpoint = setpoint;
+        return this;
+    }
+
+    public Double getCurrent() {
+        return current;
+    }
+
+    public void setCurrent(Double current) {
+        this.current = current;
+    }
+
+    public Pit withCurrent(Double current) {
+        this.current = current;
+        return this;
+    }
+
+    public Integer getControlOut() {
+        return controlOut;
+    }
+
+    public void setControlOut(Integer controlOut) {
+        this.controlOut = controlOut;
+    }
+
+    public Pit withControlOut(Integer controlOut) {
+        this.controlOut = controlOut;
+        return this;
+    }
+
+    public Integer getCh() {
+        return ch;
+    }
+
+    public void setCh(Integer ch) {
+        this.ch = ch;
+    }
+
+    public Pit withCh(Integer ch) {
+        this.ch = ch;
+        return this;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Pit withType(String type) {
+        this.type = type;
+        return this;
+    }
+
+    public String getOpenLid() {
+        return openLid;
+    }
+
+    public void setOpenLid(String openLid) {
+        this.openLid = openLid;
+    }
+
+    public Pit withOpenLid(String openLid) {
+        this.openLid = openLid;
+        return this;
+    }
+}
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/UtilNano.java
deleted file mode 100644 (file)
index c488248..0000000
+++ /dev/null
@@ -1,73 +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 java.util.HashMap;
-import java.util.Map;
-
-/**
- * The {@link UtilNano} class provides conversion functions for the WlanThermo Nano
- *
- * @author Christian Schlipp - Initial contribution
- */
-public class UtilNano {
-
-    private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
-    private static final String DEFAULT_HEX = "#ffffff";
-    private static final String DEFAULT_COLORNAME = "niagara";
-
-    private UtilNano() {
-        // hidden
-    }
-
-    private static Map<String, String> createColorMap() {
-        HashMap<String, String> map = new HashMap<>();
-        map.put("niagara", "#5587A2");
-        map.put("rosa", "#FFAEC9");
-        map.put("lapis blue", "#0C4C88");
-        map.put("orange", "#EF562D");
-        map.put("lila", "#A349A4");
-        map.put("red", "#ED1C24");
-        map.put("green", "#22B14C");
-        map.put("gold", "#FFC100");
-        map.put("kale", "#5C7148");
-        map.put("brown", "#804000");
-        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) {
-        String colorName = null;
-        if (!colorHex.startsWith("#")) {
-            colorHex = "#" + colorHex;
-        }
-        for (Map.Entry<String, String> entry : COLOR_MAPPINGS.entrySet()) {
-            if (entry.getValue().equalsIgnoreCase(colorHex)) {
-                colorName = entry.getKey();
-            }
-        }
-        if (colorName == null) {
-            colorName = DEFAULT_COLORNAME;
-        }
-        return colorName;
-    }
-}
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 (file)
index f6d9dfa..0000000
+++ /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> 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> 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> 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 (file)
index 0000000..a8b6a04
--- /dev/null
@@ -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<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
+        List<Channel> 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<Channel> channelList = data.getChannel();
+        System system = data.getSystem();
+        Unit<Temperature> 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<Channel> 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 (file)
index 0000000..0232ccc
--- /dev/null
@@ -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/WlanThermoNanoV1Util.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/WlanThermoNanoV1Util.java
new file mode 100644 (file)
index 0000000..950acc6
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
+
+/**
+ * The {@link WlanThermoNanoV1Util} class provides conversion functions for the WlanThermo Nano V1+
+ *
+ * @author Christian Schlipp - Initial contribution
+ */
+@NonNullByDefault
+public class WlanThermoNanoV1Util extends WlanThermoUtil {
+
+    private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
+    private static final String DEFAULT_HEX = "#ffffff";
+    private static final String DEFAULT_COLORNAME = "niagara";
+
+    private WlanThermoNanoV1Util() {
+        // hidden
+    }
+
+    private static Map<String, String> createColorMap() {
+        HashMap<String, String> map = new HashMap<>();
+        map.put("niagara", "#5587A2");
+        map.put("rosa", "#FFAEC9");
+        map.put("lapis blue", "#0C4C88");
+        map.put("orange", "#EF562D");
+        map.put("lila", "#A349A4");
+        map.put("red", "#ED1C24");
+        map.put("green", "#22B14C");
+        map.put("gold", "#FFC100");
+        map.put("kale", "#5C7148");
+        map.put("brown", "#804000");
+        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/nano/data/Channel.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/data/Channel.java
deleted file mode 100644 (file)
index 429bb33..0000000
+++ /dev/null
@@ -1,185 +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.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;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public Channel() {
-    }
-
-    /**
-     * 
-     * @param number
-     * @param temp
-     * @param min
-     * @param color
-     * @param max
-     * @param name
-     * @param alarm
-     * @param typ
-     */
-    public Channel(Integer number, String name, Integer typ, Double temp, Double min, Double max, Integer alarm,
-            String color) {
-        super();
-        this.number = number;
-        this.name = name;
-        this.typ = typ;
-        this.temp = temp;
-        this.min = min;
-        this.max = max;
-        this.alarm = alarm;
-        this.color = color;
-    }
-
-    public Integer getNumber() {
-        return number;
-    }
-
-    public void setNumber(Integer number) {
-        this.number = number;
-    }
-
-    public Channel withNumber(Integer number) {
-        this.number = number;
-        return this;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Channel withName(String name) {
-        this.name = name;
-        return this;
-    }
-
-    public Integer getTyp() {
-        return typ;
-    }
-
-    public void setTyp(Integer typ) {
-        this.typ = typ;
-    }
-
-    public Channel withTyp(Integer typ) {
-        this.typ = typ;
-        return this;
-    }
-
-    public Double getTemp() {
-        return temp;
-    }
-
-    public void setTemp(Double temp) {
-        this.temp = temp;
-    }
-
-    public Channel withTemp(Double temp) {
-        this.temp = temp;
-        return this;
-    }
-
-    public Double getMin() {
-        return min;
-    }
-
-    public void setMin(Double min) {
-        this.min = min;
-    }
-
-    public Channel withMin(Double min) {
-        this.min = min;
-        return this;
-    }
-
-    public Double getMax() {
-        return max;
-    }
-
-    public void setMax(Double max) {
-        this.max = max;
-    }
-
-    public Channel withMax(Double max) {
-        this.max = max;
-        return this;
-    }
-
-    public Integer getAlarm() {
-        return alarm;
-    }
-
-    public void setAlarm(Integer alarm) {
-        this.alarm = alarm;
-    }
-
-    public Channel withAlarm(Integer alarm) {
-        this.alarm = alarm;
-        return this;
-    }
-
-    public String getColor() {
-        return color;
-    }
-
-    public void setColor(String color) {
-        this.color = color;
-    }
-
-    public Channel withColor(String color) {
-        this.color = color;
-        return this;
-    }
-}
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/data/Data.java
deleted file mode 100644 (file)
index 0ca7bc0..0000000
+++ /dev/null
@@ -1,92 +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.data;
-
-import java.util.ArrayList;
-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/
- * Be careful to not overwrite the setState/getState/getTrigger function mapping the Data to OH channels!
- *
- * @author Christian Schlipp - Initial contribution
- */
-public class Data {
-
-    @SerializedName("system")
-    @Expose
-    private System system;
-    @SerializedName("channel")
-    @Expose
-    private List<Channel> channel = new ArrayList<>();
-    @SerializedName("pitmaster")
-    @Expose
-    private Pitmaster pitmaster;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public Data() {
-    }
-
-    public Data(System system, List<Channel> channel, Pitmaster pitmaster) {
-        super();
-        this.system = system;
-        this.channel = channel;
-        this.pitmaster = pitmaster;
-    }
-
-    public System getSystem() {
-        return system;
-    }
-
-    public void setSystem(System system) {
-        this.system = system;
-    }
-
-    public Data withSystem(System system) {
-        this.system = system;
-        return this;
-    }
-
-    public List<Channel> getChannel() {
-        return channel;
-    }
-
-    public void setChannel(List<Channel> channel) {
-        this.channel = channel;
-    }
-
-    public Data withChannel(List<Channel> channel) {
-        this.channel = channel;
-        return this;
-    }
-
-    public Pitmaster getPitmaster() {
-        return pitmaster;
-    }
-
-    public void setPitmaster(Pitmaster pitmaster) {
-        this.pitmaster = pitmaster;
-    }
-
-    public Data withPitmaster(Pitmaster pitmaster) {
-        this.pitmaster = pitmaster;
-        return this;
-    }
-}
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/data/Pitmaster.java
deleted file mode 100644 (file)
index 5023402..0000000
+++ /dev/null
@@ -1,79 +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.data;
-
-import java.util.ArrayList;
-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<String> type = new ArrayList<String>();
-    @SerializedName("pm")
-    @Expose
-    private List<Pm> pm = new ArrayList<Pm>();
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public Pitmaster() {
-    }
-
-    /**
-     * 
-     * @param type
-     * @param pm
-     */
-    public Pitmaster(List<String> type, List<Pm> pm) {
-        super();
-        this.type = type;
-        this.pm = pm;
-    }
-
-    public List<String> getType() {
-        return type;
-    }
-
-    public void setType(List<String> type) {
-        this.type = type;
-    }
-
-    public Pitmaster withType(List<String> type) {
-        this.type = type;
-        return this;
-    }
-
-    public List<Pm> getPm() {
-        return pm;
-    }
-
-    public void setPm(List<Pm> pm) {
-        this.pm = pm;
-    }
-
-    public Pitmaster withPm(List<Pm> pm) {
-        this.pm = pm;
-        return this;
-    }
-}
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/data/Pm.java
deleted file mode 100644 (file)
index 3f1162a..0000000
+++ /dev/null
@@ -1,185 +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.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;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public Pm() {
-    }
-
-    /**
-     * 
-     * @param set
-     * @param setColor
-     * @param channel
-     * @param pid
-     * @param typ
-     * @param id
-     * @param value
-     * @param valueColor
-     */
-    public Pm(Integer id, Integer channel, Integer pid, Integer value, Double set, String typ, String setColor,
-            String valueColor) {
-        super();
-        this.id = id;
-        this.channel = channel;
-        this.pid = pid;
-        this.value = value;
-        this.set = set;
-        this.typ = typ;
-        this.setColor = setColor;
-        this.valueColor = valueColor;
-    }
-
-    public Integer getId() {
-        return id;
-    }
-
-    public void setId(Integer id) {
-        this.id = id;
-    }
-
-    public Pm withId(Integer id) {
-        this.id = id;
-        return this;
-    }
-
-    public Integer getChannel() {
-        return channel;
-    }
-
-    public void setChannel(Integer channel) {
-        this.channel = channel;
-    }
-
-    public Pm withChannel(Integer channel) {
-        this.channel = channel;
-        return this;
-    }
-
-    public Integer getPid() {
-        return pid;
-    }
-
-    public void setPid(Integer pid) {
-        this.pid = pid;
-    }
-
-    public Pm withPid(Integer pid) {
-        this.pid = pid;
-        return this;
-    }
-
-    public Integer getValue() {
-        return value;
-    }
-
-    public void setValue(Integer value) {
-        this.value = value;
-    }
-
-    public Pm withValue(Integer value) {
-        this.value = value;
-        return this;
-    }
-
-    public Double getSet() {
-        return set;
-    }
-
-    public void setSet(Double set) {
-        this.set = set;
-    }
-
-    public Pm withSet(Double set) {
-        this.set = set;
-        return this;
-    }
-
-    public String getTyp() {
-        return typ;
-    }
-
-    public void setTyp(String typ) {
-        this.typ = typ;
-    }
-
-    public Pm withTyp(String typ) {
-        this.typ = typ;
-        return this;
-    }
-
-    public String getSetColor() {
-        return setColor;
-    }
-
-    public void setSetColor(String setColor) {
-        this.setColor = setColor;
-    }
-
-    public Pm withSetColor(String setColor) {
-        this.setColor = setColor;
-        return this;
-    }
-
-    public String getValueColor() {
-        return valueColor;
-    }
-
-    public void setValueColor(String valueColor) {
-        this.valueColor = valueColor;
-    }
-
-    public Pm withValueColor(String valueColor) {
-        this.valueColor = valueColor;
-        return this;
-    }
-}
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/data/System.java
deleted file mode 100644 (file)
index e441af3..0000000
+++ /dev/null
@@ -1,148 +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.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;
-
-    /**
-     * No args constructor for use in serialization
-     * 
-     */
-    public System() {
-    }
-
-    /**
-     * 
-     * @param unit
-     * @param rssi
-     * @param charge
-     * @param soc
-     * @param online
-     * @param time
-     */
-    public System(String time, String unit, Integer soc, Boolean charge, Integer rssi, Integer online) {
-        super();
-        this.time = time;
-        this.unit = unit;
-        this.soc = soc;
-        this.charge = charge;
-        this.rssi = rssi;
-        this.online = online;
-    }
-
-    public String getTime() {
-        return time;
-    }
-
-    public void setTime(String time) {
-        this.time = time;
-    }
-
-    public System withTime(String time) {
-        this.time = time;
-        return this;
-    }
-
-    public String getUnit() {
-        return unit;
-    }
-
-    public void setUnit(String unit) {
-        this.unit = unit;
-    }
-
-    public System withUnit(String unit) {
-        this.unit = unit;
-        return this;
-    }
-
-    public Integer getSoc() {
-        return soc;
-    }
-
-    public void setSoc(Integer soc) {
-        this.soc = soc;
-    }
-
-    public System withSoc(Integer soc) {
-        this.soc = soc;
-        return this;
-    }
-
-    public Boolean getCharge() {
-        return charge;
-    }
-
-    public void setCharge(Boolean charge) {
-        this.charge = charge;
-    }
-
-    public System withCharge(Boolean charge) {
-        this.charge = charge;
-        return this;
-    }
-
-    public Integer getRssi() {
-        return rssi;
-    }
-
-    public void setRssi(Integer rssi) {
-        this.rssi = rssi;
-    }
-
-    public System withRssi(Integer rssi) {
-        this.rssi = rssi;
-        return this;
-    }
-
-    public Integer getOnline() {
-        return online;
-    }
-
-    public void setOnline(Integer online) {
-        this.online = online;
-    }
-
-    public System withOnline(Integer online) {
-        this.online = online;
-        return this;
-    }
-}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Channel.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Channel.java
new file mode 100644 (file)
index 0000000..9d1672c
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * 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.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;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public Channel() {
+    }
+
+    /**
+     * 
+     * @param number
+     * @param temp
+     * @param min
+     * @param color
+     * @param max
+     * @param name
+     * @param alarm
+     * @param typ
+     */
+    public Channel(Integer number, String name, Integer typ, Double temp, Double min, Double max, Integer alarm,
+            String color) {
+        super();
+        this.number = number;
+        this.name = name;
+        this.typ = typ;
+        this.temp = temp;
+        this.min = min;
+        this.max = max;
+        this.alarm = alarm;
+        this.color = color;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Channel withNumber(Integer number) {
+        this.number = number;
+        return this;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Channel withName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    public Integer getTyp() {
+        return typ;
+    }
+
+    public void setTyp(Integer typ) {
+        this.typ = typ;
+    }
+
+    public Channel withTyp(Integer typ) {
+        this.typ = typ;
+        return this;
+    }
+
+    public Double getTemp() {
+        return temp;
+    }
+
+    public void setTemp(Double temp) {
+        this.temp = temp;
+    }
+
+    public Channel withTemp(Double temp) {
+        this.temp = temp;
+        return this;
+    }
+
+    public Double getMin() {
+        return min;
+    }
+
+    public void setMin(Double min) {
+        this.min = min;
+    }
+
+    public Channel withMin(Double min) {
+        this.min = min;
+        return this;
+    }
+
+    public Double getMax() {
+        return max;
+    }
+
+    public void setMax(Double max) {
+        this.max = max;
+    }
+
+    public Channel withMax(Double max) {
+        this.max = max;
+        return this;
+    }
+
+    public Integer getAlarm() {
+        return alarm;
+    }
+
+    public void setAlarm(Integer alarm) {
+        this.alarm = alarm;
+    }
+
+    public Channel withAlarm(Integer alarm) {
+        this.alarm = alarm;
+        return this;
+    }
+
+    public String getColor() {
+        return color;
+    }
+
+    public void setColor(String color) {
+        this.color = color;
+    }
+
+    public Channel withColor(String color) {
+        this.color = color;
+        return this;
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Data.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Data.java
new file mode 100644 (file)
index 0000000..b122521
--- /dev/null
@@ -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.nano.dto.data;
+
+import java.util.ArrayList;
+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/
+ * Be careful to not overwrite the setState/getState/getTrigger function mapping the Data to OH channels!
+ *
+ * @author Christian Schlipp - Initial contribution
+ */
+public class Data {
+
+    @SerializedName("system")
+    @Expose
+    private System system;
+    @SerializedName("channel")
+    @Expose
+    private List<Channel> channel = new ArrayList<>();
+    @SerializedName("pitmaster")
+    @Expose
+    private Pitmaster pitmaster;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public Data() {
+    }
+
+    public Data(System system, List<Channel> channel, Pitmaster pitmaster) {
+        super();
+        this.system = system;
+        this.channel = channel;
+        this.pitmaster = pitmaster;
+    }
+
+    public System getSystem() {
+        return system;
+    }
+
+    public void setSystem(System system) {
+        this.system = system;
+    }
+
+    public Data withSystem(System system) {
+        this.system = system;
+        return this;
+    }
+
+    public List<Channel> getChannel() {
+        return channel;
+    }
+
+    public void setChannel(List<Channel> channel) {
+        this.channel = channel;
+    }
+
+    public Data withChannel(List<Channel> channel) {
+        this.channel = channel;
+        return this;
+    }
+
+    public Pitmaster getPitmaster() {
+        return pitmaster;
+    }
+
+    public void setPitmaster(Pitmaster pitmaster) {
+        this.pitmaster = pitmaster;
+    }
+
+    public Data withPitmaster(Pitmaster pitmaster) {
+        this.pitmaster = pitmaster;
+        return this;
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pitmaster.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pitmaster.java
new file mode 100644 (file)
index 0000000..7205aa3
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * 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.dto.data;
+
+import java.util.ArrayList;
+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<String> type = new ArrayList<String>();
+    @SerializedName("pm")
+    @Expose
+    private List<Pm> pm = new ArrayList<Pm>();
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public Pitmaster() {
+    }
+
+    /**
+     * 
+     * @param type
+     * @param pm
+     */
+    public Pitmaster(List<String> type, List<Pm> pm) {
+        super();
+        this.type = type;
+        this.pm = pm;
+    }
+
+    public List<String> getType() {
+        return type;
+    }
+
+    public void setType(List<String> type) {
+        this.type = type;
+    }
+
+    public Pitmaster withType(List<String> type) {
+        this.type = type;
+        return this;
+    }
+
+    public List<Pm> getPm() {
+        return pm;
+    }
+
+    public void setPm(List<Pm> pm) {
+        this.pm = pm;
+    }
+
+    public Pitmaster withPm(List<Pm> pm) {
+        this.pm = pm;
+        return this;
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pm.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/Pm.java
new file mode 100644 (file)
index 0000000..43c9651
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * 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.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;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public Pm() {
+    }
+
+    /**
+     * 
+     * @param set
+     * @param setColor
+     * @param channel
+     * @param pid
+     * @param typ
+     * @param id
+     * @param value
+     * @param valueColor
+     */
+    public Pm(Integer id, Integer channel, Integer pid, Integer value, Double set, String typ, String setColor,
+            String valueColor) {
+        super();
+        this.id = id;
+        this.channel = channel;
+        this.pid = pid;
+        this.value = value;
+        this.set = set;
+        this.typ = typ;
+        this.setColor = setColor;
+        this.valueColor = valueColor;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Pm withId(Integer id) {
+        this.id = id;
+        return this;
+    }
+
+    public Integer getChannel() {
+        return channel;
+    }
+
+    public void setChannel(Integer channel) {
+        this.channel = channel;
+    }
+
+    public Pm withChannel(Integer channel) {
+        this.channel = channel;
+        return this;
+    }
+
+    public Integer getPid() {
+        return pid;
+    }
+
+    public void setPid(Integer pid) {
+        this.pid = pid;
+    }
+
+    public Pm withPid(Integer pid) {
+        this.pid = pid;
+        return this;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    public void setValue(Integer value) {
+        this.value = value;
+    }
+
+    public Pm withValue(Integer value) {
+        this.value = value;
+        return this;
+    }
+
+    public Double getSet() {
+        return set;
+    }
+
+    public void setSet(Double set) {
+        this.set = set;
+    }
+
+    public Pm withSet(Double set) {
+        this.set = set;
+        return this;
+    }
+
+    public String getTyp() {
+        return typ;
+    }
+
+    public void setTyp(String typ) {
+        this.typ = typ;
+    }
+
+    public Pm withTyp(String typ) {
+        this.typ = typ;
+        return this;
+    }
+
+    public String getSetColor() {
+        return setColor;
+    }
+
+    public void setSetColor(String setColor) {
+        this.setColor = setColor;
+    }
+
+    public Pm withSetColor(String setColor) {
+        this.setColor = setColor;
+        return this;
+    }
+
+    public String getValueColor() {
+        return valueColor;
+    }
+
+    public void setValueColor(String valueColor) {
+        this.valueColor = valueColor;
+    }
+
+    public Pm withValueColor(String valueColor) {
+        this.valueColor = valueColor;
+        return this;
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/System.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/data/System.java
new file mode 100644 (file)
index 0000000..c50c1a8
--- /dev/null
@@ -0,0 +1,148 @@
+/**
+ * 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.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;
+
+    /**
+     * No args constructor for use in serialization
+     * 
+     */
+    public System() {
+    }
+
+    /**
+     * 
+     * @param unit
+     * @param rssi
+     * @param charge
+     * @param soc
+     * @param online
+     * @param time
+     */
+    public System(String time, String unit, Integer soc, Boolean charge, Integer rssi, Integer online) {
+        super();
+        this.time = time;
+        this.unit = unit;
+        this.soc = soc;
+        this.charge = charge;
+        this.rssi = rssi;
+        this.online = online;
+    }
+
+    public String getTime() {
+        return time;
+    }
+
+    public void setTime(String time) {
+        this.time = time;
+    }
+
+    public System withTime(String time) {
+        this.time = time;
+        return this;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public System withUnit(String unit) {
+        this.unit = unit;
+        return this;
+    }
+
+    public Integer getSoc() {
+        return soc;
+    }
+
+    public void setSoc(Integer soc) {
+        this.soc = soc;
+    }
+
+    public System withSoc(Integer soc) {
+        this.soc = soc;
+        return this;
+    }
+
+    public Boolean getCharge() {
+        return charge;
+    }
+
+    public void setCharge(Boolean charge) {
+        this.charge = charge;
+    }
+
+    public System withCharge(Boolean charge) {
+        this.charge = charge;
+        return this;
+    }
+
+    public Integer getRssi() {
+        return rssi;
+    }
+
+    public void setRssi(Integer rssi) {
+        this.rssi = rssi;
+    }
+
+    public System withRssi(Integer rssi) {
+        this.rssi = rssi;
+        return this;
+    }
+
+    public Integer getOnline() {
+        return online;
+    }
+
+    public void setOnline(Integer online) {
+        this.online = online;
+    }
+
+    public System withOnline(Integer online) {
+        this.online = online;
+        return this;
+    }
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Api.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Api.java
new file mode 100644 (file)
index 0000000..7e0fbc7
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * 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.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
+    public String version;
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Device.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Device.java
new file mode 100644 (file)
index 0000000..e3663a5
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * 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.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
+    public String device;
+    @SerializedName("serial")
+    @Expose
+    public String serial;
+    @SerializedName("item")
+    @Expose
+    public String item;
+    @SerializedName("hw_version")
+    @Expose
+    public String hwVersion;
+    @SerializedName("sw_version")
+    @Expose
+    public String swVersion;
+    @SerializedName("api_version")
+    @Expose
+    public String apiVersion;
+    @SerializedName("language")
+    @Expose
+    public String language;
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Ext.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Ext.java
new file mode 100644 (file)
index 0000000..6cb19d8
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * 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.dto.settings;
+
+import java.util.ArrayList;
+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
+    public Integer on;
+    @SerializedName("token")
+    @Expose
+    public String token;
+    @SerializedName("id")
+    @Expose
+    public String id;
+    @SerializedName("repeat")
+    @Expose
+    public Integer repeat;
+    @SerializedName("service")
+    @Expose
+    public Integer service;
+    @SerializedName("services")
+    @Expose
+    public List<String> services = new ArrayList<String>();
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Iot.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Iot.java
new file mode 100644 (file)
index 0000000..18b331a
--- /dev/null
@@ -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.nano.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
+    public String pMQhost;
+    @SerializedName("PMQport")
+    @Expose
+    public Integer pMQport;
+    @SerializedName("PMQuser")
+    @Expose
+    public String pMQuser;
+    @SerializedName("PMQpass")
+    @Expose
+    public String pMQpass;
+    @SerializedName("PMQqos")
+    @Expose
+    public Integer pMQqos;
+    @SerializedName("PMQon")
+    @Expose
+    public Boolean pMQon;
+    @SerializedName("PMQint")
+    @Expose
+    public Integer pMQint;
+    @SerializedName("CLon")
+    @Expose
+    public Boolean cLon;
+    @SerializedName("CLtoken")
+    @Expose
+    public String cLtoken;
+    @SerializedName("CLint")
+    @Expose
+    public Integer cLint;
+    @SerializedName("CLurl")
+    @Expose
+    public String cLurl;
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Notes.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Notes.java
new file mode 100644 (file)
index 0000000..15710ff
--- /dev/null
@@ -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.api.nano.dto.settings;
+
+import java.util.ArrayList;
+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
+    public List<Object> fcm = new ArrayList<Object>();
+    @SerializedName("ext")
+    @Expose
+    public Ext ext;
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Pid.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Pid.java
new file mode 100644 (file)
index 0000000..a3d099d
--- /dev/null
@@ -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.nano.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
+    public String name;
+    @SerializedName("id")
+    @Expose
+    public Integer id;
+    @SerializedName("aktor")
+    @Expose
+    public Integer aktor;
+    @SerializedName("Kp")
+    @Expose
+    public Double kp;
+    @SerializedName("Ki")
+    @Expose
+    public Double ki;
+    @SerializedName("Kd")
+    @Expose
+    public Double kd;
+    @SerializedName("DCmmin")
+    @Expose
+    public Double dCmmin;
+    @SerializedName("DCmmax")
+    @Expose
+    public Double dCmmax;
+    @SerializedName("opl")
+    @Expose
+    public Integer opl;
+    @SerializedName("tune")
+    @Expose
+    public Integer tune;
+    @SerializedName("jp")
+    @Expose
+    public Integer jp;
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Settings.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/Settings.java
new file mode 100644 (file)
index 0000000..f2c960b
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * 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.dto.settings;
+
+import java.util.ArrayList;
+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
+    public Device device;
+    @SerializedName("system")
+    @Expose
+    public System system;
+    @SerializedName("hardware")
+    @Expose
+    public List<String> hardware = new ArrayList<String>();
+    @SerializedName("api")
+    @Expose
+    public Api api;
+    @SerializedName("sensors")
+    @Expose
+    public List<String> sensors = new ArrayList<String>();
+    @SerializedName("pid")
+    @Expose
+    public List<Pid> pid = new ArrayList<Pid>();
+    @SerializedName("aktor")
+    @Expose
+    public List<String> aktor = new ArrayList<String>();
+    @SerializedName("iot")
+    @Expose
+    public Iot iot;
+    @SerializedName("notes")
+    @Expose
+    public Notes notes;
+}
diff --git a/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/System.java b/bundles/org.openhab.binding.wlanthermo/src/main/java/org/openhab/binding/wlanthermo/internal/api/nano/dto/settings/System.java
new file mode 100644 (file)
index 0000000..8c988d9
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * 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.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
+    public String time;
+    @SerializedName("unit")
+    @Expose
+    public String unit;
+    @SerializedName("ap")
+    @Expose
+    public String ap;
+    @SerializedName("host")
+    @Expose
+    public String host;
+    @SerializedName("language")
+    @Expose
+    public String language;
+    @SerializedName("version")
+    @Expose
+    public String version;
+    @SerializedName("getupdate")
+    @Expose
+    public String getupdate;
+    @SerializedName("autoupd")
+    @Expose
+    public Boolean autoupd;
+    @SerializedName("hwversion")
+    @Expose
+    public String hwversion;
+    @SerializedName("god")
+    @Expose
+    public Integer god;
+}
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/settings/Api.java
deleted file mode 100644 (file)
index ba2429a..0000000
+++ /dev/null
@@ -1,29 +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.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
-    public String version;
-}
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/settings/Device.java
deleted file mode 100644 (file)
index 2c921a4..0000000
+++ /dev/null
@@ -1,47 +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.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
-    public String device;
-    @SerializedName("serial")
-    @Expose
-    public String serial;
-    @SerializedName("item")
-    @Expose
-    public String item;
-    @SerializedName("hw_version")
-    @Expose
-    public String hwVersion;
-    @SerializedName("sw_version")
-    @Expose
-    public String swVersion;
-    @SerializedName("api_version")
-    @Expose
-    public String apiVersion;
-    @SerializedName("language")
-    @Expose
-    public String language;
-}
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/settings/Ext.java
deleted file mode 100644 (file)
index 093a12c..0000000
+++ /dev/null
@@ -1,47 +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.settings;
-
-import java.util.ArrayList;
-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
-    public Integer on;
-    @SerializedName("token")
-    @Expose
-    public String token;
-    @SerializedName("id")
-    @Expose
-    public String id;
-    @SerializedName("repeat")
-    @Expose
-    public Integer repeat;
-    @SerializedName("service")
-    @Expose
-    public Integer service;
-    @SerializedName("services")
-    @Expose
-    public List<String> services = new ArrayList<String>();
-}
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/settings/Iot.java
deleted file mode 100644 (file)
index a5ee297..0000000
+++ /dev/null
@@ -1,59 +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.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
-    public String pMQhost;
-    @SerializedName("PMQport")
-    @Expose
-    public Integer pMQport;
-    @SerializedName("PMQuser")
-    @Expose
-    public String pMQuser;
-    @SerializedName("PMQpass")
-    @Expose
-    public String pMQpass;
-    @SerializedName("PMQqos")
-    @Expose
-    public Integer pMQqos;
-    @SerializedName("PMQon")
-    @Expose
-    public Boolean pMQon;
-    @SerializedName("PMQint")
-    @Expose
-    public Integer pMQint;
-    @SerializedName("CLon")
-    @Expose
-    public Boolean cLon;
-    @SerializedName("CLtoken")
-    @Expose
-    public String cLtoken;
-    @SerializedName("CLint")
-    @Expose
-    public Integer cLint;
-    @SerializedName("CLurl")
-    @Expose
-    public String cLurl;
-}
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/settings/Notes.java
deleted file mode 100644 (file)
index 4c04e01..0000000
+++ /dev/null
@@ -1,35 +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.settings;
-
-import java.util.ArrayList;
-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
-    public List<Object> fcm = new ArrayList<Object>();
-    @SerializedName("ext")
-    @Expose
-    public Ext ext;
-}
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/settings/Pid.java
deleted file mode 100644 (file)
index ea5b7d3..0000000
+++ /dev/null
@@ -1,59 +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.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
-    public String name;
-    @SerializedName("id")
-    @Expose
-    public Integer id;
-    @SerializedName("aktor")
-    @Expose
-    public Integer aktor;
-    @SerializedName("Kp")
-    @Expose
-    public Double kp;
-    @SerializedName("Ki")
-    @Expose
-    public Double ki;
-    @SerializedName("Kd")
-    @Expose
-    public Double kd;
-    @SerializedName("DCmmin")
-    @Expose
-    public Double dCmmin;
-    @SerializedName("DCmmax")
-    @Expose
-    public Double dCmmax;
-    @SerializedName("opl")
-    @Expose
-    public Integer opl;
-    @SerializedName("tune")
-    @Expose
-    public Integer tune;
-    @SerializedName("jp")
-    @Expose
-    public Integer jp;
-}
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/settings/Settings.java
deleted file mode 100644 (file)
index 20dd854..0000000
+++ /dev/null
@@ -1,56 +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.settings;
-
-import java.util.ArrayList;
-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
-    public Device device;
-    @SerializedName("system")
-    @Expose
-    public System system;
-    @SerializedName("hardware")
-    @Expose
-    public List<String> hardware = new ArrayList<String>();
-    @SerializedName("api")
-    @Expose
-    public Api api;
-    @SerializedName("sensors")
-    @Expose
-    public List<String> sensors = new ArrayList<String>();
-    @SerializedName("pid")
-    @Expose
-    public List<Pid> pid = new ArrayList<Pid>();
-    @SerializedName("aktor")
-    @Expose
-    public List<String> aktor = new ArrayList<String>();
-    @SerializedName("iot")
-    @Expose
-    public Iot iot;
-    @SerializedName("notes")
-    @Expose
-    public Notes notes;
-}
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/settings/System.java
deleted file mode 100644 (file)
index 4a762bd..0000000
+++ /dev/null
@@ -1,56 +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.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
-    public String time;
-    @SerializedName("unit")
-    @Expose
-    public String unit;
-    @SerializedName("ap")
-    @Expose
-    public String ap;
-    @SerializedName("host")
-    @Expose
-    public String host;
-    @SerializedName("language")
-    @Expose
-    public String language;
-    @SerializedName("version")
-    @Expose
-    public String version;
-    @SerializedName("getupdate")
-    @Expose
-    public String getupdate;
-    @SerializedName("autoupd")
-    @Expose
-    public Boolean autoupd;
-    @SerializedName("hwversion")
-    @Expose
-    public String hwversion;
-    @SerializedName("god")
-    @Expose
-    public Integer god;
-}
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 (file)
index 0000000..f9b207c
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="wlanthermo"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <!-- System Group ESP32 -->
+       <channel-group-type id="cg_system_esp32">
+               <label>System Channels</label>
+               <description>This group contains all system channels</description>
+               <channels>
+                       <channel id="soc" typeId="system.battery-level"/>
+                       <channel id="charge" typeId="charging"/>
+                       <channel id="rssi" typeId="rssi"/>
+                       <channel id="rssi_signalstrength" typeId="system.signal-strength"/>
+               </channels>
+       </channel-group-type>
+
+       <!-- Temperature Group ESP32 -->
+       <channel-group-type id="cg_temperature_esp32">
+               <label>Temperature Sensor</label>
+               <category>Sensor</category>
+               <channels>
+                       <channel id="name" typeId="name"/>
+                       <channel id="typ" typeId="typ"/>
+                       <channel id="temp" typeId="temperature"/>
+                       <channel id="min" typeId="temperature_min"/>
+                       <channel id="max" typeId="temperature_max"/>
+                       <channel id="alarm_device" typeId="alarm_device"/>
+                       <channel id="alarm_push" typeId="alarm_push"/>
+                       <channel id="alarm_openhab" typeId="alarm_openhab"/>
+                       <channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
+                       <channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
+                       <channel id="color" typeId="color"/>
+                       <channel id="color_name" typeId="color_name_esp32"/>
+               </channels>
+       </channel-group-type>
+
+       <!-- Pitmaster ESP32 -->
+       <channel-group-type id="cg_pitmaster_esp32">
+               <label>Pitmaster</label>
+               <category>Sensor</category>
+               <channels>
+                       <channel id="state" typeId="pitmaster_type"/>
+                       <channel id="setpoint" typeId="temperature_setpoint"/>
+                       <channel id="duty_cycle" typeId="duty_cycle"/>
+                       <channel id="channel_id" typeId="channel_id"/>
+                       <channel id="pid_id" typeId="pid_id"/>
+               </channels>
+       </channel-group-type>
+
+</thing:thing-descriptions>
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 (file)
index 0000000..0b73407
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="wlanthermo"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <!-- System Group Mini V1 -->
+       <channel-group-type id="cg_system_mini">
+               <label>System Channel</label>
+               <description>This group contains all system channels</description>
+               <channels>
+                       <channel id="cpu_load" typeId="cpu_load"/>
+                       <channel id="cpu_temp" typeId="temperature"/>
+               </channels>
+       </channel-group-type>
+
+       <!-- Channel Group Temperature Mini V1 -->
+       <channel-group-type id="cg_temperature_mini">
+               <label>Sensor Mini</label>
+               <category>Sensor</category>
+               <channels>
+                       <channel id="name" typeId="name_ro"/>
+                       <channel id="temp" typeId="temperature"/>
+                       <channel id="min" typeId="temperature_min_ro"/>
+                       <channel id="max" typeId="temperature_max_ro"/>
+                       <channel id="alarm_device" typeId="alarm_device_ro"/>
+                       <channel id="alarm_openhab" typeId="alarm_openhab"/>
+                       <channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
+                       <channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
+                       <channel id="color" typeId="color_ro"/>
+                       <channel id="color_name" typeId="color_name_mini_ro"/>
+               </channels>
+       </channel-group-type>
+
+       <!-- Pitmaster Mini V1 -->
+       <channel-group-type id="cg_pitmaster_mini">
+               <label>Pitmaster Mini</label>
+               <category>Sensor</category>
+               <channels>
+                       <channel id="enabled" typeId="enabled"/>
+                       <channel id="current" typeId="temperature"/>
+                       <channel id="setpoint" typeId="temperature_setpoint_ro"/>
+                       <channel id="duty_cycle" typeId="duty_cycle_ro"/>
+                       <channel id="lid_open" typeId="lid_open"/>
+                       <channel id="channel_id" typeId="channel_id_ro"/>
+               </channels>
+       </channel-group-type>
+</thing:thing-descriptions>
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 (file)
index 0000000..8a178d5
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="wlanthermo"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <!-- System Group Nano -->
+       <channel-group-type id="cg_system_nano">
+               <label>System Channel</label>
+               <description>This group contains all system channels</description>
+               <channels>
+                       <channel id="soc" typeId="system.battery-level"/>
+                       <channel id="charge" typeId="charging"/>
+                       <channel id="rssi" typeId="rssi"/>
+                       <channel id="rssi_signalstrength" typeId="system.signal-strength"/>
+               </channels>
+       </channel-group-type>
+
+       <!-- Temperature Group Nano -->
+       <channel-group-type id="cg_temperature_nano">
+               <label>Sensor Nano</label>
+               <category>Sensor</category>
+               <channels>
+                       <channel id="name" typeId="name"/>
+                       <channel id="typ" typeId="typ"/>
+                       <channel id="temp" typeId="temperature"/>
+                       <channel id="min" typeId="temperature_min"/>
+                       <channel id="max" typeId="temperature_max"/>
+                       <channel id="alarm_device" typeId="alarm_device"/>
+                       <channel id="alarm_push" typeId="alarm_push"/>
+                       <channel id="alarm_openhab" typeId="alarm_openhab"/>
+                       <channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
+                       <channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
+                       <channel id="color" typeId="color_ro"/>
+                       <channel id="color_name" typeId="color_name_nano"/>
+               </channels>
+       </channel-group-type>
+
+       <!-- Pitmaster Nano -->
+       <channel-group-type id="cg_pitmaster_nano">
+               <label>Pitmaster Nano</label>
+               <category>Sensor</category>
+               <channels>
+                       <channel id="state" typeId="pitmaster_type"/>
+                       <channel id="setpoint" typeId="temperature_setpoint"/>
+                       <channel id="duty_cycle" typeId="duty_cycle"/>
+                       <channel id="channel_id" typeId="channel_id"/>
+                       <channel id="pid_id" typeId="pid_id"/>
+               </channels>
+       </channel-group-type>
+
+
+</thing:thing-descriptions>
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 (file)
index 0000000..b75a202
--- /dev/null
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="wlanthermo"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <channel-type id="cpu_load" advanced="true">
+               <item-type>Number</item-type>
+               <label>CPU Load</label>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="name" advanced="false">
+               <item-type>String</item-type>
+               <label>Name</label>
+               <category>Text</category>
+       </channel-type>
+
+       <channel-type id="name_ro" advanced="false">
+               <item-type>String</item-type>
+               <label>Name</label>
+               <category>Text</category>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="typ" advanced="true">
+               <item-type>String</item-type>
+               <label>Type</label>
+               <category>Text</category>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="temperature" advanced="false">
+               <item-type>Number:Temperature</item-type>
+               <label>Current Temperature</label>
+               <category>Temperature</category>
+               <state min="0" pattern="%.1f %unit%" readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="temperature_min" advanced="true">
+               <item-type>Number:Temperature</item-type>
+               <label>Low Temperature Alarm</label>
+               <category>Temperature</category>
+               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
+       </channel-type>
+
+       <channel-type id="temperature_max" advanced="true">
+               <item-type>Number:Temperature</item-type>
+               <label>High Temperature Alarm</label>
+               <category>Temperature</category>
+               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
+       </channel-type>
+
+       <channel-type id="temperature_min_ro" advanced="true">
+               <item-type>Number:Temperature</item-type>
+               <label>Low Temperature Alarm</label>
+               <category>Temperature</category>
+               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="temperature_max_ro" advanced="true">
+               <item-type>Number:Temperature</item-type>
+               <label>High Temperature Alarm</label>
+               <category>Temperature</category>
+               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="alarm_device" advanced="true">
+               <item-type>Switch</item-type>
+               <label>Alarm Buzzer</label>
+               <category>Switch</category>
+       </channel-type>
+
+       <channel-type id="alarm_device_ro" advanced="true">
+               <item-type>Switch</item-type>
+               <label>Alarm Buzzer</label>
+               <category>Switch</category>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="alarm_push" advanced="true">
+               <item-type>Switch</item-type>
+               <label>Push-Alarm</label>
+               <category>Switch</category>
+       </channel-type>
+
+       <channel-type id="alarm_openhab" advanced="true">
+               <kind>trigger</kind>
+               <label>OpenHAB Alarm Trigger</label>
+               <event>
+                       <options>
+                               <option value="MIN">Low Temperature Alarm</option>
+                               <option value="MAX">High Temperature Alarm</option>
+                       </options>
+               </event>
+       </channel-type>
+
+       <channel-type id="alarm_openhab_low" advanced="false">
+               <item-type>Switch</item-type>
+               <label>Low Temperature Alarm</label>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="alarm_openhab_high" advanced="false">
+               <item-type>Switch</item-type>
+               <label>High Temperature Alarm</label>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="color" advanced="true">
+               <item-type>Color</item-type>
+               <label>Color</label>
+               <category>Colorpicker</category>
+       </channel-type>
+
+       <channel-type id="color_name_nano" advanced="true">
+               <item-type>String</item-type>
+               <label>Color</label>
+               <category>Colorpicker</category>
+               <state>
+                       <options>
+                               <option value="niagara">Niagara</option>
+                               <option value="rosa">Rosa</option>
+                               <option value="lapis blue">Lapis Blue</option>
+                               <option value="orange">Orange</option>
+                               <option value="lila">Lila</option>
+                               <option value="red">Red</option>
+                               <option value="green">Green</option>
+                               <option value="gold">Gold</option>
+                               <option value="kale">Kale</option>
+                               <option value="brown">Brown</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="color_name_esp32" advanced="true">
+               <item-type>String</item-type>
+               <label>Color</label>
+               <category>Colorpicker</category>
+               <state>
+                       <options>
+                               <option value="#FFFF00">yellow</option>
+                               <option value="#FFC002">dark yellow</option>
+                               <option value="#00FF00">green</option>
+                               <option value="#FFFFFF">white</option>
+                               <option value="#FF1DC4">pink</option>
+                               <option value="#E46C0A">orange</option>
+                               <option value="#C3D69B">olive</option>
+                               <option value="#0FE6F1">light blue</option>
+                               <option value="#0000FF">blue</option>
+                               <option value="#03A923">dark green</option>
+                               <option value="#C84B32">brown</option>
+                               <option value="#FF9B69">light brown</option>
+                               <option value="#5082BE">dark blue</option>
+                               <option value="#FFB1D0">light pink</option>
+                               <option value="#A6EF03">light green</option>
+                               <option value="#D42A6B">dark pink</option>
+                               <option value="#FFDA8F">beige</option>
+                               <option value="#00B0F0">azure</option>
+                               <option value="#948A54">dark olive</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="color_ro" advanced="true">
+               <item-type>Color</item-type>
+               <label>Color</label>
+               <category>Colorpicker</category>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="color_name_mini_ro" advanced="true">
+               <item-type>String</item-type>
+               <label>Color Name</label>
+               <category>Text</category>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="enabled" advanced="false">
+               <item-type>Switch</item-type>
+               <label>Enabled</label>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="temperature_setpoint_ro" advanced="false">
+               <item-type>Number:Temperature</item-type>
+               <label>Setpoint Temperature</label>
+               <category>Temperature</category>
+               <state min="0" pattern="%.1f %unit%" readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="duty_cycle_ro" advanced="false">
+               <item-type>Number</item-type>
+               <label>Duty Cycle / Control Out</label>
+               <state min="0" max="100" pattern="%d" readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="lid_open" advanced="false">
+               <item-type>Switch</item-type>
+               <label>Lid Open</label>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="channel_id_ro" advanced="false">
+               <item-type>Number</item-type>
+               <label>Channel ID</label>
+               <state min="0" max="9" pattern="%d" readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="pitmaster_type" advanced="false">
+               <item-type>String</item-type>
+               <label>State</label>
+               <state>
+                       <options>
+                               <option value="off">Off</option>
+                               <option value="manual">Manual</option>
+                               <option value="auto">Auto</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="duty_cycle" advanced="false">
+               <item-type>Number</item-type>
+               <label>Duty Cycle / Control Out</label>
+               <state min="0" max="100" pattern="%d"/>
+       </channel-type>
+
+       <channel-type id="pid_id" advanced="false">
+               <item-type>Number</item-type>
+               <label>PID Profile ID</label>
+               <state pattern="%d"/>
+       </channel-type>
+
+       <channel-type id="temperature_setpoint" advanced="false">
+               <item-type>Number:Temperature</item-type>
+               <label>Setpoint Temperature</label>
+               <category>Temperature</category>
+               <state min="0" pattern="%.1f %unit%"/>
+       </channel-type>
+
+       <channel-type id="channel_id" advanced="false">
+               <item-type>Number</item-type>
+               <label>Temperature Channel ID</label>
+               <state min="1" pattern="%d"/>
+       </channel-type>
+
+       <channel-type id="charging" advanced="true">
+               <item-type>Switch</item-type>
+               <label>Charging</label>
+               <category>Energy</category>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="rssi" advanced="true">
+               <item-type>Number:Power</item-type>
+               <label>RSSI in dBm</label>
+               <category>Number</category>
+               <state readOnly="true"/>
+       </channel-type>
+</thing:thing-descriptions>
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 (file)
index 0000000..fbb0803
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="wlanthermo"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <thing-type id="esp32">
+               <label>WlanThermo Mini V2, Nano V3, Link V1</label>
+               <description><![CDATA[ WlanThermo device with <b>ESP32 processor</b>, such as Mini V2 (ESP32), Nano V3, Link V1 ]]></description>
+
+               <channel-groups>
+                       <channel-group id="system" typeId="cg_system_esp32"/>
+                       <channel-group id="channel1" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 1</label>
+                               <description>This group contains all channels for temperature probe 1</description>
+                       </channel-group>
+                       <channel-group id="channel2" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 2</label>
+                               <description>This group contains all channels for temperature probe 2</description>
+                       </channel-group>
+                       <channel-group id="channel3" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 3</label>
+                               <description>This group contains all channels for temperature probe 3</description>
+                       </channel-group>
+                       <channel-group id="channel4" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 4</label>
+                               <description>This group contains all channels for temperature probe 4</description>
+                       </channel-group>
+                       <channel-group id="channel5" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 5</label>
+                               <description>This group contains all channels for temperature probe 5</description>
+                       </channel-group>
+                       <channel-group id="channel6" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 6</label>
+                               <description>This group contains all channels for temperature probe 6</description>
+                       </channel-group>
+                       <channel-group id="channel7" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 7</label>
+                               <description>This group contains all channels for temperature probe 7</description>
+                       </channel-group>
+                       <channel-group id="channel8" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 8</label>
+                               <description>This group contains all channels for temperature probe 8</description>
+                       </channel-group>
+                       <channel-group id="channel9" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 9</label>
+                               <description>This group contains all channels for temperature probe 9</description>
+                       </channel-group>
+                       <channel-group id="channel10" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 10</label>
+                               <description>This group contains all channels for temperature probe 10</description>
+                       </channel-group>
+                       <channel-group id="channel11" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 11</label>
+                               <description>This group contains all channels for temperature probe 11</description>
+                       </channel-group>
+                       <channel-group id="channel12" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 12</label>
+                               <description>This group contains all channels for temperature probe 12</description>
+                       </channel-group>
+                       <channel-group id="channel13" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 13</label>
+                               <description>This group contains all channels for temperature probe 13</description>
+                       </channel-group>
+                       <channel-group id="channel14" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 14</label>
+                               <description>This group contains all channels for temperature probe 14</description>
+                       </channel-group>
+                       <channel-group id="channel15" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 15</label>
+                               <description>This group contains all channels for temperature probe 15</description>
+                       </channel-group>
+                       <channel-group id="channel16" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 16</label>
+                               <description>This group contains all channels for temperature probe 16</description>
+                       </channel-group>
+                       <channel-group id="channel17" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 17</label>
+                               <description>This group contains all channels for temperature probe 17</description>
+                       </channel-group>
+                       <channel-group id="channel18" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 18</label>
+                               <description>This group contains all channels for temperature probe 18</description>
+                       </channel-group>
+                       <channel-group id="channel19" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 19</label>
+                               <description>This group contains all channels for temperature probe 19</description>
+                       </channel-group>
+                       <channel-group id="channel20" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 20</label>
+                               <description>This group contains all channels for temperature probe 20</description>
+                       </channel-group>
+                       <channel-group id="channel21" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 21</label>
+                               <description>This group contains all channels for temperature probe 21</description>
+                       </channel-group>
+                       <channel-group id="channel22" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 22</label>
+                               <description>This group contains all channels for temperature probe 22</description>
+                       </channel-group>
+                       <channel-group id="channel23" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 23</label>
+                               <description>This group contains all channels for temperature probe 23</description>
+                       </channel-group>
+                       <channel-group id="channel24" typeId="cg_temperature_esp32">
+                               <label>Temperature Probe 24</label>
+                               <description>This group contains all channels for temperature probe 24</description>
+                       </channel-group>
+                       <channel-group id="pit1" typeId="cg_pitmaster_esp32">
+                               <label>Pitmaster 1</label>
+                               <description>This group contains all channels for pitmaster channel 1</description>
+                       </channel-group>
+                       <channel-group id="pit2" typeId="cg_pitmaster_esp32">
+                               <label>Pitmaster 2</label>
+                               <description>This group contains all channels for pitmaster channel 2</description>
+                       </channel-group>
+               </channel-groups>
+
+               <properties>
+                       <property name="model">Model</property>
+                       <property name="serial">Serial Number</property>
+                       <property name="esp32_bt_enabled">Bluetooth available</property>
+                       <property name="esp32_pm_enabled">Pitmaster available</property>
+                       <property name="esp32_temp_channels">Temperature channels</property>
+                       <property name="esp32_pm_channels">Pitmaster channels</property>
+               </properties>
+
+               <config-description>
+                       <parameter name="ipAddress" type="text" required="true">
+                               <context>network-address</context>
+                               <label>Network Address</label>
+                               <description>Network address of the WlanThermo Nano.</description>
+                       </parameter>
+                       <parameter name="username" type="text">
+                               <label>Username</label>
+                               <description>Optional, only required for write access. Default: 'admin'</description>
+                               <default>admin</default>
+                       </parameter>
+                       <parameter name="password" type="text">
+                               <context>password</context>
+                               <label>Password</label>
+                               <description>Optional, only required for write access. Default: 'admin'</description>
+                               <default>admin</default>
+                       </parameter>
+                       <parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
+                               <label>Polling Interval</label>
+                               <description>Seconds between fetching values from the WlanThermo Nano.</description>
+                               <default>10</default>
+                       </parameter>
+               </config-description>
+       </thing-type>
+</thing:thing-descriptions>
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 (file)
index 0000000..c0946ab
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="wlanthermo"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+
+       <thing-type id="mini">
+               <label>WlanThermo Mini V1/V2</label>
+               <description><![CDATA[ WlanThermo Mini with <b>Raspberry Pi processor</b>, such as Mini V1/V2 ]]></description>
+
+               <channel-groups>
+                       <channel-group id="system" typeId="cg_system_mini"/>
+                       <channel-group id="channel0" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 1</label>
+                               <description>This group contains all channels for temperature probe 1</description>
+                       </channel-group>
+                       <channel-group id="channel1" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 2</label>
+                               <description>This group contains all channels for temperature probe 2</description>
+                       </channel-group>
+                       <channel-group id="channel2" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 3</label>
+                               <description>This group contains all channels for temperature probe 3</description>
+                       </channel-group>
+                       <channel-group id="channel3" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 4</label>
+                               <description>This group contains all channels for temperature probe 4</description>
+                       </channel-group>
+                       <channel-group id="channel4" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 5</label>
+                               <description>This group contains all channels for temperature probe 5</description>
+                       </channel-group>
+                       <channel-group id="channel5" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 6</label>
+                               <description>This group contains all channels for temperature probe 6</description>
+                       </channel-group>
+                       <channel-group id="channel6" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 7</label>
+                               <description>This group contains all channels for temperature probe 7</description>
+                       </channel-group>
+                       <channel-group id="channel7" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 8</label>
+                               <description>This group contains all channels for temperature probe 8</description>
+                       </channel-group>
+                       <channel-group id="channel8" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 9</label>
+                               <description>This group contains all channels for temperature probe 9</description>
+                       </channel-group>
+                       <channel-group id="channel9" typeId="cg_temperature_mini">
+                               <label>Temperature Probe 10</label>
+                               <description>This group contains all channels for temperature probe 10</description>
+                       </channel-group>
+                       <channel-group id="pit1" typeId="cg_pitmaster_mini">
+                               <label>Pitmaster 1</label>
+                               <description>This group contains all channels for pitmaster channel 1</description>
+                       </channel-group>
+                       <channel-group id="pit2" typeId="cg_pitmaster_mini">
+                               <label>Pitmaster 2</label>
+                               <description>This group contains all channels for pitmaster channel 2</description>
+                       </channel-group>
+               </channel-groups>
+
+               <config-description>
+                       <parameter name="ipAddress" type="text" required="true">
+                               <context>network-address</context>
+                               <label>Network Address</label>
+                               <description>Network address of the WlanThermo Mini.</description>
+                       </parameter>
+                       <parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
+                               <label>Polling Interval</label>
+                               <description>Seconds between fetching values from the WlanThermo Mini.</description>
+                               <default>10</default>
+                       </parameter>
+               </config-description>
+
+       </thing-type>
+
+</thing:thing-descriptions>
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 (file)
index 0000000..e6955e8
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="wlanthermo"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+       <thing-type id="nano">
+               <label>WlanThermo Nano</label>
+               <description>WlanThermo Nano V1/V1+</description>
+
+               <channel-groups>
+                       <channel-group id="system" typeId="cg_system_nano"/>
+                       <channel-group id="channel1" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 1</label>
+                               <description>This group contains all channels for temperature probe 1</description>
+                       </channel-group>
+                       <channel-group id="channel2" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 2</label>
+                               <description>This group contains all channels for temperature probe 2</description>
+                       </channel-group>
+                       <channel-group id="channel3" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 3</label>
+                               <description>This group contains all channels for temperature probe 3</description>
+                       </channel-group>
+                       <channel-group id="channel4" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 4</label>
+                               <description>This group contains all channels for temperature probe 4</description>
+                       </channel-group>
+                       <channel-group id="channel5" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 5</label>
+                               <description>This group contains all channels for temperature probe 5</description>
+                       </channel-group>
+                       <channel-group id="channel6" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 6</label>
+                               <description>This group contains all channels for temperature probe 6</description>
+                       </channel-group>
+                       <channel-group id="channel7" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 7</label>
+                               <description>This group contains all channels for temperature probe 7</description>
+                       </channel-group>
+                       <channel-group id="channel8" typeId="cg_temperature_nano">
+                               <label>Temperature Probe 8</label>
+                               <description>This group contains all channels for temperature probe 8</description>
+                       </channel-group>
+                       <channel-group id="pit1" typeId="cg_pitmaster_nano">
+                               <label>Pitmaster 1</label>
+                               <description>This group contains all channels for pitmaster channel 1</description>
+                       </channel-group>
+               </channel-groups>
+
+               <config-description>
+                       <parameter name="ipAddress" type="text" required="true">
+                               <context>network-address</context>
+                               <label>Network Address</label>
+                               <description>Network address of the WlanThermo Nano.</description>
+                       </parameter>
+                       <parameter name="username" type="text">
+                               <label>Username</label>
+                               <description>Optional, only required for write access. Default: 'admin'</description>
+                               <default>admin</default>
+                       </parameter>
+                       <parameter name="password" type="text">
+                               <context>password</context>
+                               <label>Password</label>
+                               <description>Optional, only required for write access. Default: 'admin'</description>
+                               <default>admin</default>
+                       </parameter>
+                       <parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
+                               <label>Polling Interval</label>
+                               <description>Seconds between fetching values from the WlanThermo Nano.</description>
+                               <default>10</default>
+                       </parameter>
+               </config-description>
+       </thing-type>
+</thing:thing-descriptions>
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 (file)
index 1317166..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<thing:thing-descriptions bindingId="wlanthermo"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
-       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
-
-       <thing-type id="nano">
-               <label>WlanThermo Nano</label>
-               <description>WlanThermo Nano V1/V1+</description>
-
-               <channel-groups>
-                       <channel-group id="system" typeId="cg_system_nano"/>
-                       <channel-group id="channel1" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 1</label>
-                               <description>This group contains all channels for temperature probe 1</description>
-                       </channel-group>
-                       <channel-group id="channel2" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 2</label>
-                               <description>This group contains all channels for temperature probe 2</description>
-                       </channel-group>
-                       <channel-group id="channel3" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 3</label>
-                               <description>This group contains all channels for temperature probe 3</description>
-                       </channel-group>
-                       <channel-group id="channel4" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 4</label>
-                               <description>This group contains all channels for temperature probe 4</description>
-                       </channel-group>
-                       <channel-group id="channel5" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 5</label>
-                               <description>This group contains all channels for temperature probe 5</description>
-                       </channel-group>
-                       <channel-group id="channel6" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 6</label>
-                               <description>This group contains all channels for temperature probe 6</description>
-                       </channel-group>
-                       <channel-group id="channel7" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 7</label>
-                               <description>This group contains all channels for temperature probe 7</description>
-                       </channel-group>
-                       <channel-group id="channel8" typeId="cg_temperature_nano">
-                               <label>Temperature Probe 8</label>
-                               <description>This group contains all channels for temperature probe 8</description>
-                       </channel-group>
-                       <channel-group id="pit1" typeId="cg_pitmaster_nano">
-                               <label>Pitmaster 1</label>
-                               <description>This group contains all channels for pitmaster channel 1</description>
-                       </channel-group>
-               </channel-groups>
-
-               <config-description>
-                       <parameter name="ipAddress" type="text" required="true">
-                               <context>network-address</context>
-                               <label>Network Address</label>
-                               <description>Network address of the WlanThermo Nano.</description>
-                       </parameter>
-                       <parameter name="username" type="text">
-                               <label>Username</label>
-                               <description>Optional, only required for write access. Default: 'admin'</description>
-                               <default>admin</default>
-                       </parameter>
-                       <parameter name="password" type="text">
-                               <context>password</context>
-                               <label>Password</label>
-                               <description>Optional, only required for write access. Default: 'admin'</description>
-                               <default>admin</default>
-                       </parameter>
-                       <parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
-                               <label>Polling Interval</label>
-                               <description>Seconds between fetching values from the WlanThermo Nano.</description>
-                               <default>10</default>
-                       </parameter>
-               </config-description>
-
-       </thing-type>
-
-       <thing-type id="mini">
-               <label>WlanThermo Mini</label>
-               <description>WlanThermo Mini</description>
-
-               <channel-groups>
-                       <channel-group id="system" typeId="cg_system_mini"/>
-                       <channel-group id="channel0" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 1</label>
-                               <description>This group contains all channels for temperature probe 1</description>
-                       </channel-group>
-                       <channel-group id="channel1" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 2</label>
-                               <description>This group contains all channels for temperature probe 2</description>
-                       </channel-group>
-                       <channel-group id="channel2" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 3</label>
-                               <description>This group contains all channels for temperature probe 3</description>
-                       </channel-group>
-                       <channel-group id="channel3" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 4</label>
-                               <description>This group contains all channels for temperature probe 4</description>
-                       </channel-group>
-                       <channel-group id="channel4" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 5</label>
-                               <description>This group contains all channels for temperature probe 5</description>
-                       </channel-group>
-                       <channel-group id="channel5" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 6</label>
-                               <description>This group contains all channels for temperature probe 6</description>
-                       </channel-group>
-                       <channel-group id="channel6" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 7</label>
-                               <description>This group contains all channels for temperature probe 7</description>
-                       </channel-group>
-                       <channel-group id="channel7" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 8</label>
-                               <description>This group contains all channels for temperature probe 8</description>
-                       </channel-group>
-                       <channel-group id="channel8" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 9</label>
-                               <description>This group contains all channels for temperature probe 9</description>
-                       </channel-group>
-                       <channel-group id="channel9" typeId="cg_temperature_mini">
-                               <label>Temperature Probe 10</label>
-                               <description>This group contains all channels for temperature probe 10</description>
-                       </channel-group>
-                       <channel-group id="pit1" typeId="cg_pitmaster_mini">
-                               <label>Pitmaster 1</label>
-                               <description>This group contains all channels for pitmaster channel 1</description>
-                       </channel-group>
-                       <channel-group id="pit2" typeId="cg_pitmaster_mini">
-                               <label>Pitmaster 2</label>
-                               <description>This group contains all channels for pitmaster channel 2</description>
-                       </channel-group>
-               </channel-groups>
-
-               <config-description>
-                       <parameter name="ipAddress" type="text" required="true">
-                               <context>network-address</context>
-                               <label>Network Address</label>
-                               <description>Network address of the WlanThermo Mini.</description>
-                       </parameter>
-                       <parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
-                               <label>Polling Interval</label>
-                               <description>Seconds between fetching values from the WlanThermo Mini.</description>
-                               <default>10</default>
-                       </parameter>
-               </config-description>
-
-       </thing-type>
-
-       <!-- System Group Nano -->
-       <channel-group-type id="cg_system_nano">
-               <label>System Channel</label>
-               <description>This group contains all system channels</description>
-               <channels>
-                       <channel id="soc" typeId="system.battery-level"/>
-                       <channel id="charge" typeId="charging"/>
-                       <channel id="rssi" typeId="rssi"/>
-                       <channel id="rssi_signalstrength" typeId="system.signal-strength"/>
-               </channels>
-       </channel-group-type>
-
-       <channel-type id="charging" advanced="true">
-               <item-type>Switch</item-type>
-               <label>Charging</label>
-               <category>Energy</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="rssi" advanced="true">
-               <item-type>Number</item-type>
-               <label>RSSI in dBm</label>
-               <category>Text</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <!-- System Group Mini -->
-       <channel-group-type id="cg_system_mini">
-               <label>System Channel</label>
-               <description>This group contains all system channels</description>
-               <channels>
-                       <channel id="cpu_load" typeId="cpu_load"/>
-                       <channel id="cpu_temp" typeId="temperature"/>
-               </channels>
-       </channel-group-type>
-
-       <channel-type id="cpu_load" advanced="true">
-               <item-type>Number</item-type>
-               <label>CPU Load</label>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <!-- Temperature Group Nano -->
-       <channel-group-type id="cg_temperature_nano">
-               <label>Sensor Nano</label>
-               <category>Sensor</category>
-               <channels>
-                       <channel id="name" typeId="name"/>
-                       <channel id="typ" typeId="typ"/>
-                       <channel id="temp" typeId="temperature"/>
-                       <channel id="min" typeId="temperature_min"/>
-                       <channel id="max" typeId="temperature_max"/>
-                       <channel id="alarm_device" typeId="alarm_device"/>
-                       <channel id="alarm_push" typeId="alarm_push"/>
-                       <channel id="alarm_openhab" typeId="alarm_openhab"/>
-                       <channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
-                       <channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
-                       <channel id="color" typeId="color"/>
-                       <channel id="color_name" typeId="color_name"/>
-               </channels>
-       </channel-group-type>
-
-       <!-- Channel Group Temperature Mini -->
-       <channel-group-type id="cg_temperature_mini">
-               <label>Sensor Mini</label>
-               <category>Sensor</category>
-               <channels>
-                       <channel id="name" typeId="name_ro"/>
-                       <channel id="temp" typeId="temperature"/>
-                       <channel id="min" typeId="temperature_min_ro"/>
-                       <channel id="max" typeId="temperature_max_ro"/>
-                       <channel id="alarm_device" typeId="alarm_device_ro"/>
-                       <channel id="alarm_openhab" typeId="alarm_openhab"/>
-                       <channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
-                       <channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
-                       <channel id="color" typeId="color_ro"/>
-                       <channel id="color_name" typeId="color_name_ro"/>
-               </channels>
-       </channel-group-type>
-
-       <!-- Fundamental channel types -->
-       <channel-type id="name" advanced="false">
-               <item-type>String</item-type>
-               <label>Probe Name</label>
-               <category>Text</category>
-       </channel-type>
-
-       <channel-type id="name_ro" advanced="false">
-               <item-type>String</item-type>
-               <label>Probe Name</label>
-               <category>Text</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="typ" advanced="true">
-               <item-type>String</item-type>
-               <label>Probe Type</label>
-               <category>Text</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="temperature" advanced="false">
-               <item-type>Number:Temperature</item-type>
-               <label>Current Temperature</label>
-               <category>Temperature</category>
-               <state min="0" pattern="%.1f %unit%" readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="temperature_min" advanced="true">
-               <item-type>Number:Temperature</item-type>
-               <label>Low Temperature Alarm</label>
-               <category>Temperature</category>
-               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
-       </channel-type>
-
-       <channel-type id="temperature_max" advanced="true">
-               <item-type>Number:Temperature</item-type>
-               <label>High Temperature Alarm</label>
-               <category>Temperature</category>
-               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
-       </channel-type>
-
-       <channel-type id="temperature_min_ro" advanced="true">
-               <item-type>Number:Temperature</item-type>
-               <label>Low Temperature Alarm</label>
-               <category>Temperature</category>
-               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="temperature_max_ro" advanced="true">
-               <item-type>Number:Temperature</item-type>
-               <label>High Temperature Alarm</label>
-               <category>Temperature</category>
-               <state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="alarm_device" advanced="true">
-               <item-type>Switch</item-type>
-               <label>Alarm Buzzer</label>
-               <category>Switch</category>
-       </channel-type>
-
-       <channel-type id="alarm_device_ro" advanced="true">
-               <item-type>Switch</item-type>
-               <label>Alarm Buzzer</label>
-               <category>Switch</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="alarm_push" advanced="true">
-               <item-type>Switch</item-type>
-               <label>Push-Alarm</label>
-               <category>Switch</category>
-       </channel-type>
-
-       <channel-type id="alarm_openhab" advanced="true">
-               <kind>trigger</kind>
-               <label>Openhab Alarm Trigger</label>
-               <event>
-                       <options>
-                               <option value="MIN">Low Temperature Alarm</option>
-                               <option value="MAX">High Temperature Alarm</option>
-                       </options>
-               </event>
-       </channel-type>
-
-       <channel-type id="alarm_openhab_low" advanced="false">
-               <item-type>Switch</item-type>
-               <label>Low Temperature Alarm</label>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="alarm_openhab_high" advanced="false">
-               <item-type>Switch</item-type>
-               <label>High Temperature Alarm</label>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="color" advanced="true">
-               <item-type>Color</item-type>
-               <label>Color</label>
-               <category>Colorpicker</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="color_name" advanced="true">
-               <item-type>String</item-type>
-               <label>Probe Color</label>
-               <category>Colorpicker</category>
-               <state>
-                       <options>
-                               <option value="niagara">Niagara</option>
-                               <option value="rosa">Rosa</option>
-                               <option value="lapis blue">Lapis Blue</option>
-                               <option value="orange">Orange</option>
-                               <option value="lila">Lila</option>
-                               <option value="red">Red</option>
-                               <option value="green">Green</option>
-                               <option value="gold">Gold</option>
-                               <option value="kale">Kale</option>
-                               <option value="brown">Brown</option>
-                       </options>
-               </state>
-       </channel-type>
-
-       <channel-type id="color_ro" advanced="true">
-               <item-type>Color</item-type>
-               <label>Probe Color</label>
-               <category>Colorpicker</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="color_name_ro" advanced="true">
-               <item-type>String</item-type>
-               <label>Probe Color Name</label>
-               <category>Text</category>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <!-- Pitmaster Mini -->
-       <channel-group-type id="cg_pitmaster_mini">
-               <label>Pitmaster Mini</label>
-               <category>Sensor</category>
-               <channels>
-                       <channel id="enabled" typeId="enabled"/>
-                       <channel id="current" typeId="temperature"/>
-                       <channel id="setpoint" typeId="temperature_setpoint_ro"/>
-                       <channel id="duty_cycle" typeId="duty_cycle_ro"/>
-                       <channel id="lid_open" typeId="lid_open"/>
-                       <channel id="channel_id" typeId="channel_id_ro"/>
-               </channels>
-       </channel-group-type>
-
-       <channel-type id="enabled" advanced="false">
-               <item-type>Switch</item-type>
-               <label>Pitmaster Enabled</label>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="temperature_setpoint_ro" advanced="false">
-               <item-type>Number:Temperature</item-type>
-               <label>Pitmaster Setpoint Temperature</label>
-               <category>Temperature</category>
-               <state min="0" pattern="%.1f %unit%" readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="duty_cycle_ro" advanced="false">
-               <item-type>Number</item-type>
-               <label>Pitmaster Duty Cycle / Control Out</label>
-               <state min="0" max="100" pattern="%d" readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="lid_open" advanced="false">
-               <item-type>Switch</item-type>
-               <label>Pitmaster Lid Open</label>
-               <state readOnly="true"/>
-       </channel-type>
-
-       <channel-type id="channel_id_ro" advanced="false">
-               <item-type>Number</item-type>
-               <label>Pitmaster Channel ID</label>
-               <state min="0" max="9" pattern="%d" readOnly="true"/>
-       </channel-type>
-
-       <!-- Pitmaster Nano -->
-       <channel-group-type id="cg_pitmaster_nano">
-               <label>Pitmaster Nano</label>
-               <category>Sensor</category>
-               <channels>
-                       <channel id="state" typeId="pitmaster_type"/>
-                       <channel id="setpoint" typeId="temperature_setpoint"/>
-                       <channel id="duty_cycle" typeId="duty_cycle"/>
-                       <channel id="channel_id" typeId="channel_id"/>
-                       <channel id="pid_id" typeId="pid_id"/>
-               </channels>
-       </channel-group-type>
-
-       <channel-type id="pitmaster_type" advanced="false">
-               <item-type>String</item-type>
-               <label>Pitmaster State</label>
-               <state>
-                       <options>
-                               <option value="off">Off</option>
-                               <option value="manual">Manual</option>
-                               <option value="auto">Auto</option>
-                               <!--<option value="autotune">Autotune</option> Not clear if still supported -->
-                       </options>
-               </state>
-       </channel-type>
-
-       <channel-type id="duty_cycle" advanced="false">
-               <item-type>Number</item-type>
-               <label>Pitmaster Duty Cycle / Control Out</label>
-               <state min="0" max="100" pattern="%d"/>
-       </channel-type>
-
-       <channel-type id="pid_id" advanced="false">
-               <item-type>Number</item-type>
-               <label>PID Profile ID</label>
-               <state pattern="%d"/>
-       </channel-type>
-
-       <channel-type id="temperature_setpoint" advanced="false">
-               <item-type>Number:Temperature</item-type>
-               <label>Pitmaster Setpoint Temperature</label>
-               <category>Temperature</category>
-               <state min="0" pattern="%.1f %unit%"/>
-       </channel-type>
-
-       <channel-type id="channel_id" advanced="false">
-               <item-type>Number</item-type>
-               <label>Pitmaster Channel ID</label>
-               <state min="1" max="8" pattern="%d"/>
-       </channel-type>
-
-</thing:thing-descriptions>
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 (file)
index 0000000..6184268
--- /dev/null
@@ -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<Arguments> 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<Arguments> 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<Arguments> 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<WlanThermoException> 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<WlanThermoException> 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 (file)
index 0000000..2145711
--- /dev/null
@@ -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<Arguments> 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<Arguments> 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<WlanThermoException> 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<WlanThermoException> 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 (file)
index 0000000..1d32bde
--- /dev/null
@@ -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<Arguments> 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<Arguments> 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<Arguments> 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<WlanThermoException> 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<WlanThermoException> 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 (file)
index 0000000..24eddd0
--- /dev/null
@@ -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 (file)
index 0000000..49f6e50
--- /dev/null
@@ -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 (file)
index 0000000..a88861a
--- /dev/null
@@ -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 (file)
index 0000000..7ed291b
--- /dev/null
@@ -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 (file)
index 0000000..0bad239
--- /dev/null
@@ -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