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;
/**
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
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";
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
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);
}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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() {
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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);
+}
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;
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
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;
--- /dev/null
+/**
+ * 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);
+ }
+}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+/**
+ * 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());
+ }
+ }
+}
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+/**
+ * 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());
+ }
+ }
+}
--- /dev/null
+/**
+ * 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);
+ }
+}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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);
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+/**
+ * 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());
+ }
+ }
+}
--- /dev/null
+/**
+ * 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);
+ }
+}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
+++ /dev/null
-/**
- * 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;
- }
-}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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;
+}
--- /dev/null
+/**
+ * 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;
+}
--- /dev/null
+/**
+ * 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>();
+}
--- /dev/null
+/**
+ * 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;
+}
--- /dev/null
+/**
+ * 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;
+}
--- /dev/null
+/**
+ * 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;
+}
--- /dev/null
+/**
+ * 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;
+}
--- /dev/null
+/**
+ * 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;
+}
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-/**
- * 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>();
-}
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-/**
- * 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;
-}
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
+++ /dev/null
-<?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>
--- /dev/null
+/**
+ * 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))));
+ }
+}
--- /dev/null
+/**
+ * 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);
+ }
+ }
+}
--- /dev/null
+/**
+ * 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))));
+ }
+}
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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"
+}
--- /dev/null
+{
+ "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"
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "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