[WlanThermo] Add support for new ESP32-powered devices [V3.x] (#9579)
* Add support for ESP32 devices * Add Unit Tests Ensure Gson objects are NonNull Generify Handlers Generify Utils Signed-off-by: Christian Schlipp <christian@schlipp.de>
This commit is contained in:
parent
ce6954a891
commit
d8e5a57de9
|
@ -13,6 +13,7 @@
|
||||||
package org.openhab.binding.wlanthermo.internal;
|
package org.openhab.binding.wlanthermo.internal;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.library.types.DecimalType;
|
||||||
import org.openhab.core.thing.ThingTypeUID;
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,11 +28,17 @@ public class WlanThermoBindingConstants {
|
||||||
private static final String BINDING_ID = "wlanthermo";
|
private static final String BINDING_ID = "wlanthermo";
|
||||||
|
|
||||||
// List of all Thing Type UIDs
|
// 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_MINI = new ThingTypeUID(BINDING_ID, "mini");
|
||||||
|
public static final ThingTypeUID THING_TYPE_WLANTHERMO_ESP32 = new ThingTypeUID(BINDING_ID, "esp32");
|
||||||
|
|
||||||
// ThreadPool
|
// Properties
|
||||||
public static final String WLANTHERMO_THREAD_POOL = "wlanthermo";
|
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
|
// List of all Channel ids
|
||||||
// System Channels
|
// System Channels
|
||||||
|
@ -43,16 +50,7 @@ public class WlanThermoBindingConstants {
|
||||||
public static final String SYSTEM_CPU_LOAD = "cpu_load";
|
public static final String SYSTEM_CPU_LOAD = "cpu_load";
|
||||||
public static final String SYSTEM_CPU_TEMP = "cpu_temp";
|
public static final String SYSTEM_CPU_TEMP = "cpu_temp";
|
||||||
|
|
||||||
public static final String CHANNEL0 = "channel0";
|
public static final String CHANNEL_PREFIX = "channel";
|
||||||
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_NAME = "name";
|
public static final String CHANNEL_NAME = "name";
|
||||||
public static final String CHANNEL_TYP = "typ";
|
public static final String CHANNEL_TYP = "typ";
|
||||||
|
@ -67,6 +65,9 @@ public class WlanThermoBindingConstants {
|
||||||
public static final String CHANNEL_COLOR = "color";
|
public static final String CHANNEL_COLOR = "color";
|
||||||
public static final String CHANNEL_COLOR_NAME = "color_name";
|
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_ENABLED = "enabled"; // Mini
|
||||||
public static final String CHANNEL_PITMASTER_CURRENT = "current"; // 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_SETPOINT = "setpoint"; // Mini+Nano
|
||||||
|
@ -76,7 +77,12 @@ public class WlanThermoBindingConstants {
|
||||||
public static final String CHANNEL_PITMASTER_STATE = "state"; // Nano
|
public static final String CHANNEL_PITMASTER_STATE = "state"; // Nano
|
||||||
public static final String CHANNEL_PITMASTER_PIDPROFILE = "pid_id"; // 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_MIN = "MIN";
|
||||||
public static final String TRIGGER_ALARM_MAX = "MAX";
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@ import java.net.URISyntaxException;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link WlanThermoMiniConfiguration} class contains fields mapping thing configuration parameters.
|
* The {@link WlanThermoConfiguration} class contains fields mapping thing configuration parameters.
|
||||||
*
|
*
|
||||||
* @author Christian Schlipp - Initial contribution
|
* @author Christian Schlipp - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class WlanThermoMiniConfiguration {
|
public class WlanThermoConfiguration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IP Address of WlanThermo.
|
* IP Address of WlanThermo.
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoException} is thrown if an exception in WlanThermoBinding occurs.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoException extends Exception {
|
||||||
|
|
||||||
|
static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public WlanThermoException(String reason) {
|
||||||
|
super(reason, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WlanThermoException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WlanThermoException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WlanThermoException() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoExtendedConfiguration} class contains fields mapping thing configuration parameters.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoExtendedConfiguration extends WlanThermoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username of WlanThermo user.
|
||||||
|
*/
|
||||||
|
private String username = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password of WlanThermo user.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private String password = "";
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.eclipse.jetty.client.api.Authentication;
|
||||||
|
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||||
|
import org.eclipse.jetty.client.util.DigestAuthentication;
|
||||||
|
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||||
|
import org.openhab.core.thing.*;
|
||||||
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.RefreshType;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoHandler} is responsible for handling commands, which are
|
||||||
|
* sent to one of the channels.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public abstract class WlanThermoHandler extends BaseThingHandler {
|
||||||
|
|
||||||
|
private final boolean extendedConfig;
|
||||||
|
protected WlanThermoConfiguration config = new WlanThermoConfiguration();
|
||||||
|
protected final HttpClient httpClient;
|
||||||
|
protected final Logger logger = LoggerFactory.getLogger(WlanThermoHandler.class);
|
||||||
|
protected final Gson gson = new Gson();
|
||||||
|
protected @Nullable ScheduledFuture<?> pollingScheduler;
|
||||||
|
|
||||||
|
public WlanThermoHandler(Thing thing, HttpClient httpClient, boolean extendedConfig) {
|
||||||
|
super(thing);
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
this.extendedConfig = extendedConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
|
try {
|
||||||
|
if (extendedConfig) {
|
||||||
|
config = getConfigAs(WlanThermoExtendedConfiguration.class);
|
||||||
|
WlanThermoExtendedConfiguration extendedConfig = (WlanThermoExtendedConfiguration) config;
|
||||||
|
if (extendedConfig.getUsername().isEmpty() && !extendedConfig.getPassword().isEmpty()) {
|
||||||
|
AuthenticationStore authStore = httpClient.getAuthenticationStore();
|
||||||
|
authStore.addAuthentication(new DigestAuthentication(config.getUri(), Authentication.ANY_REALM,
|
||||||
|
extendedConfig.getUsername(), extendedConfig.getPassword()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config = getConfigAs(WlanThermoConfiguration.class);
|
||||||
|
}
|
||||||
|
pollingScheduler = scheduler.scheduleWithFixedDelay(this::checkConnectionAndUpdate, 0,
|
||||||
|
config.getPollingInterval(), TimeUnit.SECONDS);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"Failed to initialize WlanThermo: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
||||||
|
if (oldScheduler != null) {
|
||||||
|
boolean stopped = oldScheduler.cancel(true);
|
||||||
|
logger.debug("Stopped polling: {}", stopped);
|
||||||
|
}
|
||||||
|
pollingScheduler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkConnectionAndUpdate() {
|
||||||
|
if (this.thing.getStatus() != ThingStatus.ONLINE) {
|
||||||
|
try {
|
||||||
|
if (httpClient.GET(config.getUri()).getStatus() == 200) {
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
// rerun immediately to update state
|
||||||
|
checkConnectionAndUpdate();
|
||||||
|
} else {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"WlanThermo not found under given address.");
|
||||||
|
}
|
||||||
|
} catch (URISyntaxException | ExecutionException | TimeoutException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"Could not connect to WlanThermo at " + config.getIpAddress() + ": " + e.getMessage());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Connection check interrupted. {}", e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean doPost(String endpoint, String json) throws InterruptedException {
|
||||||
|
try {
|
||||||
|
URI uri = config.getUri(endpoint);
|
||||||
|
int status = httpClient.POST(uri).content(new StringContentProvider(json), "application/json")
|
||||||
|
.timeout(5, TimeUnit.SECONDS).send().getStatus();
|
||||||
|
if (status == 401) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"No or wrong login credentials provided. Please configure username/password for write access to WlanThermo!");
|
||||||
|
return false;
|
||||||
|
} else if (status != 200) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"Failed to update channel on device, Statuscode " + status + " on URI " + uri.toString());
|
||||||
|
logger.debug("Payload sent: {}", json);
|
||||||
|
// Still continue to try next channel
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (TimeoutException | ExecutionException | URISyntaxException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"Failed to update channel on device: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T> T doGet(String endpoint, Class<T> object) throws InterruptedException, WlanThermoException {
|
||||||
|
try {
|
||||||
|
String json = httpClient.GET(config.getUri(endpoint)).getContentAsString();
|
||||||
|
logger.debug("Received at {}: {}", endpoint, json);
|
||||||
|
return requireNonNull(gson.fromJson(json, object));
|
||||||
|
} catch (URISyntaxException | ExecutionException | TimeoutException | WlanThermoException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"Update failed: " + e.getMessage());
|
||||||
|
for (Channel channel : thing.getChannels()) {
|
||||||
|
updateState(channel.getUID(), UnDefType.UNDEF);
|
||||||
|
}
|
||||||
|
throw new WlanThermoException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||||
|
if (command instanceof RefreshType) {
|
||||||
|
try {
|
||||||
|
State s = getState(channelUID);
|
||||||
|
updateState(channelUID, s);
|
||||||
|
} catch (WlanThermoException e) {
|
||||||
|
logger.debug("Could not handle command of type {} for channel {}!",
|
||||||
|
command.getClass().toGenericString(), channelUID.getId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (setState(channelUID, command) && thing.getStatus() == ThingStatus.ONLINE) {
|
||||||
|
logger.debug("Data updated, pushing changes");
|
||||||
|
scheduler.execute(this::push);
|
||||||
|
} else {
|
||||||
|
logger.debug("Could not handle command of type {} for channel {}!",
|
||||||
|
command.getClass().toGenericString(), channelUID.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void push();
|
||||||
|
|
||||||
|
protected abstract void pull();
|
||||||
|
|
||||||
|
protected abstract State getState(ChannelUID channelUID)
|
||||||
|
throws WlanThermoInputException, WlanThermoUnknownChannelException;
|
||||||
|
|
||||||
|
protected abstract boolean setState(ChannelUID channelUID, Command command);
|
||||||
|
}
|
|
@ -19,6 +19,9 @@ import java.util.Set;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
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.io.net.http.HttpClientFactory;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
import org.openhab.core.thing.ThingTypeUID;
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
@ -40,8 +43,9 @@ import org.osgi.service.component.annotations.Reference;
|
||||||
public class WlanThermoHandlerFactory extends BaseThingHandlerFactory {
|
public class WlanThermoHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<ThingTypeUID>(
|
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<ThingTypeUID>(
|
||||||
Arrays.asList(WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO,
|
Arrays.asList(WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO_V1,
|
||||||
WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI));
|
WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI,
|
||||||
|
WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_ESP32));
|
||||||
private final HttpClient httpClient;
|
private final HttpClient httpClient;
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
|
@ -58,10 +62,12 @@ public class WlanThermoHandlerFactory extends BaseThingHandlerFactory {
|
||||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
|
|
||||||
if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO.equals(thingTypeUID)) {
|
if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO_V1.equals(thingTypeUID)) {
|
||||||
return new WlanThermoNanoHandler(thing, httpClient);
|
return new WlanThermoNanoV1Handler(thing, httpClient);
|
||||||
} else if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI.equals(thingTypeUID)) {
|
} else if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI.equals(thingTypeUID)) {
|
||||||
return new WlanThermoMiniHandler(thing, httpClient);
|
return new WlanThermoMiniHandler(thing, httpClient);
|
||||||
|
} else if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_ESP32.equals(thingTypeUID)) {
|
||||||
|
return new WlanThermoEsp32Handler(thing, httpClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoInputException} is thrown if input is invalid or null
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoInputException extends WlanThermoException {
|
||||||
|
|
||||||
|
static final long serialVersionUID = 1L;
|
||||||
|
public static final String INVALID_INPUT_EXCEPTION = "Input Data is invalid!";
|
||||||
|
|
||||||
|
public WlanThermoInputException() {
|
||||||
|
super(INVALID_INPUT_EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WlanThermoInputException(Throwable cause) {
|
||||||
|
super(INVALID_INPUT_EXCEPTION, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,152 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
|
||||||
*
|
|
||||||
* See the NOTICE file(s) distributed with this work for additional
|
|
||||||
* information.
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made available under the
|
|
||||||
* terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-2.0
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.wlanthermo.internal;
|
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.*;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.mini.builtin.App;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.mini.builtin.WlanThermoMiniCommandHandler;
|
|
||||||
import org.openhab.core.common.ThreadPoolManager;
|
|
||||||
import org.openhab.core.thing.*;
|
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.RefreshType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link WlanThermoMiniHandler} is responsible for handling commands, which are
|
|
||||||
* sent to one of the channels.
|
|
||||||
*
|
|
||||||
* @author Christian Schlipp - Initial contribution
|
|
||||||
*/
|
|
||||||
@NonNullByDefault
|
|
||||||
public class WlanThermoMiniHandler extends BaseThingHandler {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(WlanThermoMiniHandler.class);
|
|
||||||
private final WlanThermoMiniCommandHandler wlanThermoMiniCommandHandler = new WlanThermoMiniCommandHandler();
|
|
||||||
|
|
||||||
private WlanThermoMiniConfiguration config = new WlanThermoMiniConfiguration();
|
|
||||||
private final HttpClient httpClient;
|
|
||||||
private @Nullable ScheduledFuture<?> pollingScheduler;
|
|
||||||
private final ScheduledExecutorService scheduler = ThreadPoolManager
|
|
||||||
.getScheduledPool(WlanThermoBindingConstants.WLANTHERMO_THREAD_POOL);
|
|
||||||
private final Gson gson = new Gson();
|
|
||||||
private App app = new App();
|
|
||||||
|
|
||||||
public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) {
|
|
||||||
super(thing);
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize() {
|
|
||||||
logger.debug("Start initializing WlanThermo Mini!");
|
|
||||||
config = getConfigAs(WlanThermoMiniConfiguration.class);
|
|
||||||
|
|
||||||
updateStatus(ThingStatus.UNKNOWN);
|
|
||||||
scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
logger.debug("Finished initializing WlanThermo Mini!");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkConnection() {
|
|
||||||
try {
|
|
||||||
if (httpClient.GET(config.getUri("/app.php")).getStatus() == 200) {
|
|
||||||
updateStatus(ThingStatus.ONLINE);
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
oldScheduler.cancel(false);
|
|
||||||
}
|
|
||||||
pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(),
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} else {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
|
||||||
"WlanThermo not found under given address.");
|
|
||||||
}
|
|
||||||
} catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
|
|
||||||
logger.debug("Failed to connect.", e);
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
|
||||||
"Could not connect to WlanThermo at " + config.getIpAddress());
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
oldScheduler.cancel(false);
|
|
||||||
}
|
|
||||||
pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
|
||||||
if (command instanceof RefreshType) {
|
|
||||||
State s = wlanThermoMiniCommandHandler.getState(channelUID, app);
|
|
||||||
if (s != null)
|
|
||||||
updateState(channelUID, s);
|
|
||||||
}
|
|
||||||
// Mini is read only!
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update() {
|
|
||||||
try {
|
|
||||||
// Update objects with data from device
|
|
||||||
String json = httpClient.GET(config.getUri("/app.php")).getContentAsString();
|
|
||||||
app = Objects.requireNonNull(gson.fromJson(json, App.class));
|
|
||||||
logger.debug("Received at /app.php: {}", json);
|
|
||||||
|
|
||||||
// Update channels
|
|
||||||
for (Channel channel : thing.getChannels()) {
|
|
||||||
State state = wlanThermoMiniCommandHandler.getState(channel.getUID(), app);
|
|
||||||
if (state != null) {
|
|
||||||
updateState(channel.getUID(), state);
|
|
||||||
} else {
|
|
||||||
String trigger = wlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app);
|
|
||||||
if (trigger != null) {
|
|
||||||
triggerChannel(channel.getUID(), trigger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
|
|
||||||
logger.debug("Update failed, checking connection", e);
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Update failed, reconnecting...");
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
oldScheduler.cancel(false);
|
|
||||||
}
|
|
||||||
for (Channel channel : thing.getChannels()) {
|
|
||||||
updateState(channel.getUID(), UnDefType.UNDEF);
|
|
||||||
}
|
|
||||||
checkConnection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
boolean stopped = oldScheduler.cancel(true);
|
|
||||||
logger.debug("Stopped polling: {}", stopped);
|
|
||||||
}
|
|
||||||
pollingScheduler = null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
|
||||||
*
|
|
||||||
* See the NOTICE file(s) distributed with this work for additional
|
|
||||||
* information.
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made available under the
|
|
||||||
* terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-2.0
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.wlanthermo.internal;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link WlanThermoNanoConfiguration} class contains fields mapping thing configuration parameters.
|
|
||||||
*
|
|
||||||
* @author Christian Schlipp - Initial contribution
|
|
||||||
*/
|
|
||||||
@NonNullByDefault
|
|
||||||
public class WlanThermoNanoConfiguration {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IP Address of WlanThermo.
|
|
||||||
*/
|
|
||||||
private String ipAddress = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Username of WlanThermo user.
|
|
||||||
*/
|
|
||||||
private @Nullable String username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Password of WlanThermo user.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private @Nullable String password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Polling interval
|
|
||||||
*/
|
|
||||||
private int pollingInterval = 10;
|
|
||||||
|
|
||||||
public String getIpAddress() {
|
|
||||||
return ipAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public URI getUri(String path) throws URISyntaxException {
|
|
||||||
String uri = ipAddress;
|
|
||||||
if (!uri.startsWith("http://")) {
|
|
||||||
uri = "http://" + uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!path.startsWith("/") && !uri.endsWith("/")) {
|
|
||||||
uri = uri + "/";
|
|
||||||
}
|
|
||||||
uri = uri + path;
|
|
||||||
|
|
||||||
return new URI(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public URI getUri() throws URISyntaxException {
|
|
||||||
return getUri("");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIpAddress(String ipAddress) {
|
|
||||||
this.ipAddress = ipAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPollingInterval() {
|
|
||||||
return pollingInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPollingInterval(int pollingInterval) {
|
|
||||||
this.pollingInterval = pollingInterval;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,205 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
|
||||||
*
|
|
||||||
* See the NOTICE file(s) distributed with this work for additional
|
|
||||||
* information.
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made available under the
|
|
||||||
* terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-2.0
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.wlanthermo.internal;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.*;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
|
||||||
import org.eclipse.jetty.client.api.Authentication;
|
|
||||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
|
||||||
import org.eclipse.jetty.client.util.DigestAuthentication;
|
|
||||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.WlanThermoNanoCommandHandler;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.data.Data;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.settings.Settings;
|
|
||||||
import org.openhab.core.common.ThreadPoolManager;
|
|
||||||
import org.openhab.core.thing.*;
|
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.RefreshType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link WlanThermoNanoHandler} is responsible for handling commands, which are
|
|
||||||
* sent to one of the channels.
|
|
||||||
*
|
|
||||||
* @author Christian Schlipp - Initial contribution
|
|
||||||
*/
|
|
||||||
@NonNullByDefault
|
|
||||||
public class WlanThermoNanoHandler extends BaseThingHandler {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(WlanThermoNanoHandler.class);
|
|
||||||
|
|
||||||
private WlanThermoNanoConfiguration config = new WlanThermoNanoConfiguration();
|
|
||||||
private WlanThermoNanoCommandHandler wlanThermoNanoCommandHandler = new WlanThermoNanoCommandHandler();
|
|
||||||
private final HttpClient httpClient;
|
|
||||||
private @Nullable ScheduledFuture<?> pollingScheduler;
|
|
||||||
private final ScheduledExecutorService scheduler = ThreadPoolManager
|
|
||||||
.getScheduledPool(WlanThermoBindingConstants.WLANTHERMO_THREAD_POOL);
|
|
||||||
private final Gson gson = new Gson();
|
|
||||||
private Data data = new Data();
|
|
||||||
private Settings settings = new Settings();
|
|
||||||
|
|
||||||
public WlanThermoNanoHandler(Thing thing, HttpClient httpClient) {
|
|
||||||
super(thing);
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize() {
|
|
||||||
logger.debug("Start initializing WlanThermo Nano!");
|
|
||||||
config = getConfigAs(WlanThermoNanoConfiguration.class);
|
|
||||||
|
|
||||||
updateStatus(ThingStatus.UNKNOWN);
|
|
||||||
try {
|
|
||||||
if (config.getUsername() != null && !config.getUsername().isEmpty() && config.getPassword() != null
|
|
||||||
&& !config.getPassword().isEmpty()) {
|
|
||||||
AuthenticationStore authStore = httpClient.getAuthenticationStore();
|
|
||||||
authStore.addAuthentication(new DigestAuthentication(config.getUri(), Authentication.ANY_REALM,
|
|
||||||
config.getUsername(), config.getPassword()));
|
|
||||||
}
|
|
||||||
scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
logger.debug("Finished initializing WlanThermo Nano!");
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
|
||||||
"Failed to initialize WlanThermo Nano!");
|
|
||||||
logger.debug("Failed to initialize WlanThermo Nano!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkConnection() {
|
|
||||||
try {
|
|
||||||
if (httpClient.GET(config.getUri()).getStatus() == 200) {
|
|
||||||
updateStatus(ThingStatus.ONLINE);
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
oldScheduler.cancel(false);
|
|
||||||
}
|
|
||||||
pollingScheduler = scheduler.scheduleWithFixedDelay(this::update, 0, config.getPollingInterval(),
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} else {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
|
||||||
"WlanThermo not found under given address.");
|
|
||||||
}
|
|
||||||
} catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
|
|
||||||
logger.debug("Failed to connect.", e);
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
|
||||||
"Could not connect to WlanThermo at " + config.getIpAddress());
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
oldScheduler.cancel(false);
|
|
||||||
}
|
|
||||||
pollingScheduler = scheduler.schedule(this::checkConnection, config.getPollingInterval(), TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
|
||||||
if (command instanceof RefreshType) {
|
|
||||||
State s = wlanThermoNanoCommandHandler.getState(channelUID, data, settings);
|
|
||||||
if (s != null)
|
|
||||||
updateState(channelUID, s);
|
|
||||||
} else {
|
|
||||||
if (wlanThermoNanoCommandHandler.setState(channelUID, command, data)) {
|
|
||||||
logger.debug("Data updated, pushing changes");
|
|
||||||
push();
|
|
||||||
} else {
|
|
||||||
logger.debug("Could not handle command of type {} for channel {}!",
|
|
||||||
command.getClass().toGenericString(), channelUID.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update() {
|
|
||||||
try {
|
|
||||||
// Update objects with data from device
|
|
||||||
String json = httpClient.GET(config.getUri("/data")).getContentAsString();
|
|
||||||
data = Objects.requireNonNull(gson.fromJson(json, Data.class));
|
|
||||||
logger.debug("Received at /data: {}", json);
|
|
||||||
json = httpClient.GET(config.getUri("/settings")).getContentAsString();
|
|
||||||
settings = Objects.requireNonNull(gson.fromJson(json, Settings.class));
|
|
||||||
logger.debug("Received at /settings: {}", json);
|
|
||||||
|
|
||||||
// Update channels
|
|
||||||
for (Channel channel : thing.getChannels()) {
|
|
||||||
State state = wlanThermoNanoCommandHandler.getState(channel.getUID(), data, settings);
|
|
||||||
if (state != null) {
|
|
||||||
updateState(channel.getUID(), state);
|
|
||||||
} else {
|
|
||||||
// if we could not obtain a state, try trigger instead
|
|
||||||
String trigger = wlanThermoNanoCommandHandler.getTrigger(channel.getUID(), data);
|
|
||||||
if (trigger != null) {
|
|
||||||
triggerChannel(channel.getUID(), trigger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (URISyntaxException | InterruptedException | ExecutionException | TimeoutException e) {
|
|
||||||
logger.debug("Update failed, checking connection", e);
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Update failed, reconnecting...");
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
oldScheduler.cancel(false);
|
|
||||||
}
|
|
||||||
for (Channel channel : thing.getChannels()) {
|
|
||||||
updateState(channel.getUID(), UnDefType.UNDEF);
|
|
||||||
}
|
|
||||||
checkConnection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void push() {
|
|
||||||
data.getChannel().forEach(c -> {
|
|
||||||
try {
|
|
||||||
String json = gson.toJson(c);
|
|
||||||
logger.debug("Pushing: {}", json);
|
|
||||||
URI uri = config.getUri("/setchannels");
|
|
||||||
int status = httpClient.POST(uri).content(new StringContentProvider(json), "application/json")
|
|
||||||
.timeout(5, TimeUnit.SECONDS).send().getStatus();
|
|
||||||
if (status == 401) {
|
|
||||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
|
||||||
"No or wrong login credentials provided. Please configure username/password for write access to WlanThermo!");
|
|
||||||
} else if (status != 200) {
|
|
||||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Failed to update channel "
|
|
||||||
+ c.getName() + " on device, Statuscode " + status + " on URI " + uri.toString());
|
|
||||||
} else {
|
|
||||||
updateStatus(ThingStatus.ONLINE);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException | TimeoutException | ExecutionException | URISyntaxException e) {
|
|
||||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
|
||||||
"Failed to update channel " + c.getName() + " on device!");
|
|
||||||
logger.debug("Failed to update channel {} on device", c.getName(), e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
ScheduledFuture<?> oldScheduler = pollingScheduler;
|
|
||||||
if (oldScheduler != null) {
|
|
||||||
boolean stopped = oldScheduler.cancel(true);
|
|
||||||
logger.debug("Stopped polling: {}", stopped);
|
|
||||||
}
|
|
||||||
pollingScheduler = null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoUnknownChannelException} is thrown if a channel or trigger is unknown
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoUnknownChannelException extends WlanThermoException {
|
||||||
|
|
||||||
|
static final long serialVersionUID = 1L;
|
||||||
|
public static final String UNKNOWN_CHANNEL_EXCEPTION = "Channel or Trigger unknown!";
|
||||||
|
|
||||||
|
public WlanThermoUnknownChannelException() {
|
||||||
|
super(UNKNOWN_CHANNEL_EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WlanThermoUnknownChannelException(ChannelUID channelUID) {
|
||||||
|
super(UNKNOWN_CHANNEL_EXCEPTION + "ChannelUID: " + channelUID.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public WlanThermoUnknownChannelException(ChannelUID channelUID, Throwable cause) {
|
||||||
|
super(UNKNOWN_CHANNEL_EXCEPTION + "ChannelUID: " + channelUID.toString(), cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.library.types.HSBType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoUtil} class provides conversion functions for the WlanThermo
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoUtil {
|
||||||
|
|
||||||
|
public static String toColorName(String colorHex, Map<String, String> colorMappings, String defaultColorName) {
|
||||||
|
if (!colorHex.startsWith("#")) {
|
||||||
|
colorHex = "#" + colorHex;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : colorMappings.entrySet()) {
|
||||||
|
if (entry.getValue().equalsIgnoreCase(colorHex)) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultColorName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toHex(HSBType hsb) {
|
||||||
|
return "#" + String.format("%02X", hsb.getRed().intValue()) + String.format("%02X", hsb.getGreen().intValue())
|
||||||
|
+ String.format("%02X", hsb.getBlue().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T requireNonNull(@Nullable T obj) throws WlanThermoInputException {
|
||||||
|
if (obj == null)
|
||||||
|
throw new WlanThermoInputException();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,299 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.measure.Unit;
|
||||||
|
import javax.measure.quantity.Temperature;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoInputException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Channel;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Data;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Pm;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.System;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings.Settings;
|
||||||
|
import org.openhab.core.library.types.*;
|
||||||
|
import org.openhab.core.library.unit.ImperialUnits;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoEsp32CommandHandler} is responsible for mapping the Commands to the respective data fields
|
||||||
|
* of the API.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoEsp32CommandHandler {
|
||||||
|
|
||||||
|
public static State getState(ChannelUID channelUID, Data data, Settings settings)
|
||||||
|
throws WlanThermoUnknownChannelException, WlanThermoInputException {
|
||||||
|
|
||||||
|
String groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
System system = data.getSystem();
|
||||||
|
Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
|
||||||
|
|
||||||
|
List<Channel> channelList = data.getChannel();
|
||||||
|
if (SYSTEM.equals(groupId)) {
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case SYSTEM_SOC:
|
||||||
|
if (system.getSoc() != null) {
|
||||||
|
return new DecimalType(system.getSoc());
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
case SYSTEM_CHARGE:
|
||||||
|
if (system.getCharge() != null) {
|
||||||
|
return OnOffType.from(system.getCharge());
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
case SYSTEM_RSSI_SIGNALSTRENGTH:
|
||||||
|
int dbm = system.getRssi();
|
||||||
|
if (dbm >= -80) {
|
||||||
|
return SIGNAL_STRENGTH_4;
|
||||||
|
} else if (dbm >= -95) {
|
||||||
|
return SIGNAL_STRENGTH_3;
|
||||||
|
} else if (dbm >= -105) {
|
||||||
|
return SIGNAL_STRENGTH_2;
|
||||||
|
} else {
|
||||||
|
return SIGNAL_STRENGTH_1;
|
||||||
|
}
|
||||||
|
case SYSTEM_RSSI:
|
||||||
|
return new QuantityType<>(system.getRssi(), Units.DECIBEL_MILLIWATTS);
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
|
||||||
|
if (channelList != null && channelList.size() > 0 && channelId < channelList.size()) {
|
||||||
|
Channel channel = channelList.get(channelId);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_NAME:
|
||||||
|
return new StringType(channel.getName());
|
||||||
|
case CHANNEL_TYP:
|
||||||
|
return new StringType(settings.getSensors().get(channel.getTyp()).getName());
|
||||||
|
case CHANNEL_TEMP:
|
||||||
|
return channel.getTemp() == 999.0 ? UnDefType.UNDEF
|
||||||
|
: new QuantityType<>(channel.getTemp(), unit);
|
||||||
|
case CHANNEL_MIN:
|
||||||
|
return new QuantityType<>(channel.getMin(), unit);
|
||||||
|
case CHANNEL_MAX:
|
||||||
|
return new QuantityType<>(channel.getMax(), unit);
|
||||||
|
case CHANNEL_ALARM_DEVICE:
|
||||||
|
return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(1));
|
||||||
|
case CHANNEL_ALARM_PUSH:
|
||||||
|
return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(0));
|
||||||
|
case CHANNEL_ALARM_OPENHAB_HIGH:
|
||||||
|
if (channel.getTemp() != 999 && channel.getTemp() > channel.getMax()) {
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
case CHANNEL_ALARM_OPENHAB_LOW:
|
||||||
|
if (channel.getTemp() != 999 && channel.getTemp() < channel.getMin()) {
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
case CHANNEL_COLOR:
|
||||||
|
String color = channel.getColor();
|
||||||
|
if (color != null && !color.isEmpty()) {
|
||||||
|
Color c = Color.decode(color);
|
||||||
|
return HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue());
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
case CHANNEL_COLOR_NAME:
|
||||||
|
String colorHex = channel.getColor();
|
||||||
|
if (colorHex != null && !colorHex.isEmpty()) {
|
||||||
|
return new StringType(WlanThermoEsp32Util.toColorName(colorHex));
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PITMASTER_PREFIX.length())) - 1;
|
||||||
|
if (settings.getFeatures().getPitmaster() && data.getPitmaster() != null
|
||||||
|
&& data.getPitmaster().getPm() != null && data.getPitmaster().getPm().size() > channelId) {
|
||||||
|
Pm pm = data.getPitmaster().getPm().get(channelId);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_PITMASTER_CHANNEL_ID:
|
||||||
|
return new DecimalType(pm.getChannel());
|
||||||
|
case CHANNEL_PITMASTER_PIDPROFILE:
|
||||||
|
return new DecimalType(pm.getPid());
|
||||||
|
case CHANNEL_PITMASTER_DUTY_CYCLE:
|
||||||
|
return new DecimalType(pm.getValue());
|
||||||
|
case CHANNEL_PITMASTER_SETPOINT:
|
||||||
|
return new QuantityType<>(pm.getSet(), unit);
|
||||||
|
case CHANNEL_PITMASTER_STATE:
|
||||||
|
return new StringType(pm.getTyp());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new WlanThermoUnknownChannelException(channelUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean setState(ChannelUID channelUID, Command command, Data data, Settings settings) {
|
||||||
|
String groupId;
|
||||||
|
try {
|
||||||
|
groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
} catch (WlanThermoInputException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Channel> channelList = data.getChannel();
|
||||||
|
System system = data.getSystem();
|
||||||
|
Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
|
||||||
|
|
||||||
|
if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
|
||||||
|
if (channelList.size() > 0 && channelId < channelList.size()) {
|
||||||
|
Channel channel = channelList.get(channelId);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_NAME:
|
||||||
|
if (command instanceof StringType) {
|
||||||
|
channel.setName(command.toFullString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_MIN:
|
||||||
|
if (command instanceof QuantityType) {
|
||||||
|
try {
|
||||||
|
channel.setMin(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
|
||||||
|
return true;
|
||||||
|
} catch (WlanThermoInputException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_MAX:
|
||||||
|
if (command instanceof QuantityType) {
|
||||||
|
try {
|
||||||
|
channel.setMax(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
|
||||||
|
return true;
|
||||||
|
} catch (WlanThermoInputException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_ALARM_DEVICE:
|
||||||
|
if (command instanceof OnOffType) {
|
||||||
|
BigInteger value;
|
||||||
|
if (command == OnOffType.ON) {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).setBit(1);
|
||||||
|
} else {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).clearBit(1);
|
||||||
|
}
|
||||||
|
channel.setAlarm(value.intValue());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_ALARM_PUSH:
|
||||||
|
if (command instanceof OnOffType) {
|
||||||
|
BigInteger value;
|
||||||
|
if (command == OnOffType.ON) {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).setBit(0);
|
||||||
|
} else {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).clearBit(0);
|
||||||
|
}
|
||||||
|
channel.setAlarm(value.intValue());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_COLOR_NAME:
|
||||||
|
if (command instanceof StringType) {
|
||||||
|
channel.setColor(WlanThermoEsp32Util.toHex(((StringType) command).toString()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_COLOR:
|
||||||
|
if (command instanceof HSBType) {
|
||||||
|
channel.setColor(WlanThermoUtil.toHex((HSBType) command));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PITMASTER_PREFIX.length())) - 1;
|
||||||
|
if (settings.getFeatures().getPitmaster() && data.getPitmaster() != null
|
||||||
|
&& data.getPitmaster().getPm() != null && data.getPitmaster().getPm().size() > channelId) {
|
||||||
|
Pm pm = data.getPitmaster().getPm().get(channelId);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_PITMASTER_CHANNEL_ID:
|
||||||
|
pm.setChannel(((DecimalType) command).intValue());
|
||||||
|
return true;
|
||||||
|
case CHANNEL_PITMASTER_PIDPROFILE:
|
||||||
|
pm.setPid(((DecimalType) command).intValue());
|
||||||
|
return true;
|
||||||
|
case CHANNEL_PITMASTER_SETPOINT:
|
||||||
|
try {
|
||||||
|
pm.setSet(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
|
||||||
|
return true;
|
||||||
|
} catch (WlanThermoInputException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case CHANNEL_PITMASTER_STATE:
|
||||||
|
String state = ((StringType) command).toString();
|
||||||
|
if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual")
|
||||||
|
|| state.equalsIgnoreCase("auto")) {
|
||||||
|
pm.setTyp(state);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTrigger(ChannelUID channelUID, Data data)
|
||||||
|
throws WlanThermoUnknownChannelException, WlanThermoInputException {
|
||||||
|
String groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
List<Channel> channelList = data.getChannel();
|
||||||
|
|
||||||
|
if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
|
||||||
|
if (channelList.size() > 0 && channelId < channelList.size()) {
|
||||||
|
Channel channel = channelList.get(channelId);
|
||||||
|
if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) {
|
||||||
|
if (channel.getTemp() != 999) {
|
||||||
|
if (channel.getTemp() > channel.getMax()) {
|
||||||
|
return TRIGGER_ALARM_MAX;
|
||||||
|
} else if (channel.getTemp() < channel.getMin()) {
|
||||||
|
return TRIGGER_ALARM_MIN;
|
||||||
|
} else {
|
||||||
|
return TRIGGER_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new WlanThermoUnknownChannelException(channelUID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.*;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Data;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings.Settings;
|
||||||
|
import org.openhab.core.thing.*;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoEsp32Handler} is responsible for handling commands, which are
|
||||||
|
* sent to one of the channels.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoEsp32Handler extends WlanThermoHandler {
|
||||||
|
|
||||||
|
private Data data = new Data();
|
||||||
|
private Settings settings = new Settings();
|
||||||
|
|
||||||
|
public WlanThermoEsp32Handler(Thing thing, HttpClient httpClient) {
|
||||||
|
super(thing, httpClient, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected State getState(ChannelUID channelUID) throws WlanThermoInputException, WlanThermoUnknownChannelException {
|
||||||
|
return WlanThermoEsp32CommandHandler.getState(channelUID, data, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean setState(ChannelUID channelUID, Command command) {
|
||||||
|
return WlanThermoEsp32CommandHandler.setState(channelUID, command, data, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void push() {
|
||||||
|
// Push update for sensor channels
|
||||||
|
for (org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Channel c : data.getChannel()) {
|
||||||
|
try {
|
||||||
|
String json = gson.toJson(c);
|
||||||
|
if (!doPost("/setchannels", json)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Push interrupted. {}", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// push update for pitmaster channels
|
||||||
|
try {
|
||||||
|
String json = gson.toJson(data.getPitmaster().getPm());
|
||||||
|
doPost("/setpitmaster", json);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Push interrupted. {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void pull() {
|
||||||
|
try {
|
||||||
|
// Update objects with data from device
|
||||||
|
data = doGet("/data", Data.class);
|
||||||
|
settings = doGet("/settings", Settings.class);
|
||||||
|
|
||||||
|
// Update Channels if required
|
||||||
|
Map<String, String> properties = editProperties();
|
||||||
|
Boolean pmEnabled = settings.getFeatures().getBluetooth();
|
||||||
|
int pmChannels = pmEnabled ? data.getPitmaster().getPm().size() : 0;
|
||||||
|
int tempChannels = data.getChannel().size();
|
||||||
|
|
||||||
|
// Update properties
|
||||||
|
properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_MODEL, settings.getDevice().getDevice());
|
||||||
|
properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_SERIAL, settings.getDevice().getSerial());
|
||||||
|
properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_ESP32_BT_ENABLED,
|
||||||
|
settings.getFeatures().getBluetooth().toString());
|
||||||
|
properties.putIfAbsent(WlanThermoBindingConstants.PROPERTY_ESP32_PM_ENABLED, pmEnabled.toString());
|
||||||
|
properties.put(WlanThermoBindingConstants.PROPERTY_ESP32_TEMP_CHANNELS, String.valueOf(tempChannels));
|
||||||
|
properties.put(WlanThermoBindingConstants.PROPERTY_ESP32_PM_CHANNELS, String.valueOf(pmChannels));
|
||||||
|
updateProperties(properties);
|
||||||
|
|
||||||
|
// Update channel state
|
||||||
|
for (Channel channel : thing.getChannels()) {
|
||||||
|
try {
|
||||||
|
State state = WlanThermoEsp32CommandHandler.getState(channel.getUID(), data, settings);
|
||||||
|
updateState(channel.getUID(), state);
|
||||||
|
} catch (WlanThermoUnknownChannelException e) {
|
||||||
|
// if we could not obtain a state, try trigger instead
|
||||||
|
try {
|
||||||
|
String trigger = WlanThermoEsp32CommandHandler.getTrigger(channel.getUID(), data);
|
||||||
|
if (!trigger.equals(TRIGGER_NONE)) {
|
||||||
|
triggerChannel(channel.getUID(), trigger);
|
||||||
|
}
|
||||||
|
} catch (WlanThermoUnknownChannelException e1) {
|
||||||
|
logger.debug("{}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (WlanThermoException ignore) {
|
||||||
|
// Nothing more to do
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Update interrupted. {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoEsp32Util} class provides conversion functions for the WlanThermo Nano V3
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoEsp32Util extends WlanThermoUtil {
|
||||||
|
|
||||||
|
private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
|
||||||
|
private static final String DEFAULT_HEX = "#FFFFFF";
|
||||||
|
private static final String DEFAULT_COLORNAME = "undefined";
|
||||||
|
|
||||||
|
private WlanThermoEsp32Util() {
|
||||||
|
// hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> createColorMap() {
|
||||||
|
HashMap<String, String> map = new HashMap<>();
|
||||||
|
map.put("yellow", "#FFFF00");
|
||||||
|
map.put("dark yellow", "#FFC002");
|
||||||
|
map.put("green", "#00FF00");
|
||||||
|
map.put("white", "#FFFFFF");
|
||||||
|
map.put("pink", "#FF1DC4");
|
||||||
|
map.put("orange", "#E46C0A");
|
||||||
|
map.put("olive", "#C3D69B");
|
||||||
|
map.put("light blue", "#0FE6F1");
|
||||||
|
map.put("blue", "#0000FF");
|
||||||
|
map.put("dark green", "#03A923");
|
||||||
|
map.put("brown", "#C84B32");
|
||||||
|
map.put("light brown", "#FF9B69");
|
||||||
|
map.put("dark blue", "#5082BE");
|
||||||
|
map.put("light pink", "#FFB1D0");
|
||||||
|
map.put("light green", "#A6EF03");
|
||||||
|
map.put("dark pink", "#D42A6B");
|
||||||
|
map.put("beige", "#FFDA8F");
|
||||||
|
map.put("azure", "#00B0F0");
|
||||||
|
map.put("dark olive", "#948A54");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert WlanThermo Color Name to Hex
|
||||||
|
*
|
||||||
|
* @param colorName the WlanThermo color name
|
||||||
|
* @return The color as Hex String
|
||||||
|
*/
|
||||||
|
public static String toHex(String colorName) {
|
||||||
|
return COLOR_MAPPINGS.getOrDefault(colorName, DEFAULT_HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toColorName(String colorHex) {
|
||||||
|
return toColorName(colorHex, COLOR_MAPPINGS, DEFAULT_COLORNAME);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.data;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Channel {
|
||||||
|
|
||||||
|
@SerializedName("number")
|
||||||
|
@Expose
|
||||||
|
private Integer number;
|
||||||
|
@SerializedName("name")
|
||||||
|
@Expose
|
||||||
|
private String name;
|
||||||
|
@SerializedName("typ")
|
||||||
|
@Expose
|
||||||
|
private Integer typ;
|
||||||
|
@SerializedName("temp")
|
||||||
|
@Expose
|
||||||
|
private Double temp;
|
||||||
|
@SerializedName("min")
|
||||||
|
@Expose
|
||||||
|
private Double min;
|
||||||
|
@SerializedName("max")
|
||||||
|
@Expose
|
||||||
|
private Double max;
|
||||||
|
@SerializedName("alarm")
|
||||||
|
@Expose
|
||||||
|
private Integer alarm;
|
||||||
|
@SerializedName("color")
|
||||||
|
@Expose
|
||||||
|
private String color;
|
||||||
|
@SerializedName("fixed")
|
||||||
|
@Expose
|
||||||
|
private Boolean fixed;
|
||||||
|
@SerializedName("connected")
|
||||||
|
@Expose
|
||||||
|
private Boolean connected;
|
||||||
|
|
||||||
|
public Integer getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(Integer number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTyp() {
|
||||||
|
return typ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTyp(Integer typ) {
|
||||||
|
this.typ = typ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTemp() {
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemp(Double temp) {
|
||||||
|
this.temp = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMin() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMin(Double min) {
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax(Double max) {
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAlarm() {
|
||||||
|
return alarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlarm(Integer alarm) {
|
||||||
|
this.alarm = alarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(String color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getFixed() {
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFixed(Boolean fixed) {
|
||||||
|
this.fixed = fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnected(Boolean connected) {
|
||||||
|
this.connected = connected;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Data {
|
||||||
|
|
||||||
|
@SerializedName("system")
|
||||||
|
@Expose
|
||||||
|
private System system;
|
||||||
|
@SerializedName("channel")
|
||||||
|
@Expose
|
||||||
|
private List<Channel> channel = null;
|
||||||
|
@SerializedName("pitmaster")
|
||||||
|
@Expose
|
||||||
|
private Pitmaster pitmaster;
|
||||||
|
|
||||||
|
public System getSystem() {
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSystem(System system) {
|
||||||
|
this.system = system;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Channel> getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannel(List<Channel> channel) {
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pitmaster getPitmaster() {
|
||||||
|
return pitmaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPitmaster(Pitmaster pitmaster) {
|
||||||
|
this.pitmaster = pitmaster;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Pitmaster {
|
||||||
|
|
||||||
|
@SerializedName("type")
|
||||||
|
@Expose
|
||||||
|
private List<String> type = null;
|
||||||
|
@SerializedName("pm")
|
||||||
|
@Expose
|
||||||
|
private List<Pm> pm = null;
|
||||||
|
|
||||||
|
public List<String> getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(List<String> type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Pm> getPm() {
|
||||||
|
return pm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPm(List<Pm> pm) {
|
||||||
|
this.pm = pm;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.data;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Pm {
|
||||||
|
|
||||||
|
@SerializedName("id")
|
||||||
|
@Expose
|
||||||
|
private Integer id;
|
||||||
|
@SerializedName("channel")
|
||||||
|
@Expose
|
||||||
|
private Integer channel;
|
||||||
|
@SerializedName("pid")
|
||||||
|
@Expose
|
||||||
|
private Integer pid;
|
||||||
|
@SerializedName("value")
|
||||||
|
@Expose
|
||||||
|
private Integer value;
|
||||||
|
@SerializedName("set")
|
||||||
|
@Expose
|
||||||
|
private Double set;
|
||||||
|
@SerializedName("typ")
|
||||||
|
@Expose
|
||||||
|
private String typ;
|
||||||
|
@SerializedName("set_color")
|
||||||
|
@Expose
|
||||||
|
private String setColor;
|
||||||
|
@SerializedName("value_color")
|
||||||
|
@Expose
|
||||||
|
private String valueColor;
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannel(Integer channel) {
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPid() {
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPid(Integer pid) {
|
||||||
|
this.pid = pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Integer value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getSet() {
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSet(Double set) {
|
||||||
|
this.set = set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTyp() {
|
||||||
|
return typ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTyp(String typ) {
|
||||||
|
this.typ = typ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSetColor() {
|
||||||
|
return setColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetColor(String setColor) {
|
||||||
|
this.setColor = setColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValueColor() {
|
||||||
|
return valueColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValueColor(String valueColor) {
|
||||||
|
this.valueColor = valueColor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.data;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class System {
|
||||||
|
|
||||||
|
@SerializedName("time")
|
||||||
|
@Expose
|
||||||
|
private String time;
|
||||||
|
@SerializedName("unit")
|
||||||
|
@Expose
|
||||||
|
private String unit;
|
||||||
|
@SerializedName("soc")
|
||||||
|
@Expose
|
||||||
|
private Integer soc;
|
||||||
|
@SerializedName("charge")
|
||||||
|
@Expose
|
||||||
|
private Boolean charge;
|
||||||
|
@SerializedName("rssi")
|
||||||
|
@Expose
|
||||||
|
private Integer rssi;
|
||||||
|
@SerializedName("online")
|
||||||
|
@Expose
|
||||||
|
private Integer online;
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(String time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnit(String unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSoc() {
|
||||||
|
return soc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSoc(Integer soc) {
|
||||||
|
this.soc = soc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getCharge() {
|
||||||
|
return charge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharge(Boolean charge) {
|
||||||
|
this.charge = charge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRssi() {
|
||||||
|
return rssi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRssi(Integer rssi) {
|
||||||
|
this.rssi = rssi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOnline() {
|
||||||
|
return online;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnline(Integer online) {
|
||||||
|
this.online = online;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Api {
|
||||||
|
|
||||||
|
@SerializedName("version")
|
||||||
|
@Expose
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Device {
|
||||||
|
|
||||||
|
@SerializedName("device")
|
||||||
|
@Expose
|
||||||
|
private String device;
|
||||||
|
@SerializedName("serial")
|
||||||
|
@Expose
|
||||||
|
private String serial;
|
||||||
|
@SerializedName("cpu")
|
||||||
|
@Expose
|
||||||
|
private String cpu;
|
||||||
|
@SerializedName("flash_size")
|
||||||
|
@Expose
|
||||||
|
private Integer flashSize;
|
||||||
|
@SerializedName("hw_version")
|
||||||
|
@Expose
|
||||||
|
private String hwVersion;
|
||||||
|
@SerializedName("sw_version")
|
||||||
|
@Expose
|
||||||
|
private String swVersion;
|
||||||
|
@SerializedName("api_version")
|
||||||
|
@Expose
|
||||||
|
private String apiVersion;
|
||||||
|
@SerializedName("language")
|
||||||
|
@Expose
|
||||||
|
private String language;
|
||||||
|
|
||||||
|
public String getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDevice(String device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerial() {
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSerial(String serial) {
|
||||||
|
this.serial = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCpu() {
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCpu(String cpu) {
|
||||||
|
this.cpu = cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getFlashSize() {
|
||||||
|
return flashSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlashSize(Integer flashSize) {
|
||||||
|
this.flashSize = flashSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHwVersion() {
|
||||||
|
return hwVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHwVersion(String hwVersion) {
|
||||||
|
this.hwVersion = hwVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSwVersion() {
|
||||||
|
return swVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSwVersion(String swVersion) {
|
||||||
|
this.swVersion = swVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiVersion() {
|
||||||
|
return apiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiVersion(String apiVersion) {
|
||||||
|
this.apiVersion = apiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(String language) {
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Display {
|
||||||
|
|
||||||
|
@SerializedName("updname")
|
||||||
|
@Expose
|
||||||
|
private String updname;
|
||||||
|
@SerializedName("orientation")
|
||||||
|
@Expose
|
||||||
|
private Integer orientation;
|
||||||
|
|
||||||
|
public String getUpdname() {
|
||||||
|
return updname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdname(String updname) {
|
||||||
|
this.updname = updname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOrientation() {
|
||||||
|
return orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrientation(Integer orientation) {
|
||||||
|
this.orientation = orientation;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Ext {
|
||||||
|
|
||||||
|
@SerializedName("on")
|
||||||
|
@Expose
|
||||||
|
private Integer on;
|
||||||
|
@SerializedName("token")
|
||||||
|
@Expose
|
||||||
|
private String token;
|
||||||
|
@SerializedName("id")
|
||||||
|
@Expose
|
||||||
|
private String id;
|
||||||
|
@SerializedName("repeat")
|
||||||
|
@Expose
|
||||||
|
private Integer repeat;
|
||||||
|
@SerializedName("service")
|
||||||
|
@Expose
|
||||||
|
private Integer service;
|
||||||
|
@SerializedName("services")
|
||||||
|
@Expose
|
||||||
|
private List<String> services = null;
|
||||||
|
|
||||||
|
public Integer getOn() {
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOn(Integer on) {
|
||||||
|
this.on = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRepeat() {
|
||||||
|
return repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepeat(Integer repeat) {
|
||||||
|
this.repeat = repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getService() {
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setService(Integer service) {
|
||||||
|
this.service = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getServices() {
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServices(List<String> services) {
|
||||||
|
this.services = services;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Features {
|
||||||
|
|
||||||
|
@SerializedName("bluetooth")
|
||||||
|
@Expose
|
||||||
|
private Boolean bluetooth;
|
||||||
|
@SerializedName("pitmaster")
|
||||||
|
@Expose
|
||||||
|
private Boolean pitmaster;
|
||||||
|
|
||||||
|
public Boolean getBluetooth() {
|
||||||
|
return bluetooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBluetooth(Boolean bluetooth) {
|
||||||
|
this.bluetooth = bluetooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getPitmaster() {
|
||||||
|
return pitmaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPitmaster(Boolean pitmaster) {
|
||||||
|
this.pitmaster = pitmaster;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Iot {
|
||||||
|
|
||||||
|
@SerializedName("PMQhost")
|
||||||
|
@Expose
|
||||||
|
private String pMQhost;
|
||||||
|
@SerializedName("PMQport")
|
||||||
|
@Expose
|
||||||
|
private Integer pMQport;
|
||||||
|
@SerializedName("PMQuser")
|
||||||
|
@Expose
|
||||||
|
private String pMQuser;
|
||||||
|
@SerializedName("PMQpass")
|
||||||
|
@Expose
|
||||||
|
private String pMQpass;
|
||||||
|
@SerializedName("PMQqos")
|
||||||
|
@Expose
|
||||||
|
private Integer pMQqos;
|
||||||
|
@SerializedName("PMQon")
|
||||||
|
@Expose
|
||||||
|
private Boolean pMQon;
|
||||||
|
@SerializedName("PMQint")
|
||||||
|
@Expose
|
||||||
|
private Integer pMQint;
|
||||||
|
@SerializedName("CLon")
|
||||||
|
@Expose
|
||||||
|
private Boolean cLon;
|
||||||
|
@SerializedName("CLtoken")
|
||||||
|
@Expose
|
||||||
|
private String cLtoken;
|
||||||
|
@SerializedName("CLint")
|
||||||
|
@Expose
|
||||||
|
private Integer cLint;
|
||||||
|
@SerializedName("CLurl")
|
||||||
|
@Expose
|
||||||
|
private String cLurl;
|
||||||
|
|
||||||
|
public String getPMQhost() {
|
||||||
|
return pMQhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPMQhost(String pMQhost) {
|
||||||
|
this.pMQhost = pMQhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPMQport() {
|
||||||
|
return pMQport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPMQport(Integer pMQport) {
|
||||||
|
this.pMQport = pMQport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPMQuser() {
|
||||||
|
return pMQuser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPMQuser(String pMQuser) {
|
||||||
|
this.pMQuser = pMQuser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPMQpass() {
|
||||||
|
return pMQpass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPMQpass(String pMQpass) {
|
||||||
|
this.pMQpass = pMQpass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPMQqos() {
|
||||||
|
return pMQqos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPMQqos(Integer pMQqos) {
|
||||||
|
this.pMQqos = pMQqos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getPMQon() {
|
||||||
|
return pMQon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPMQon(Boolean pMQon) {
|
||||||
|
this.pMQon = pMQon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPMQint() {
|
||||||
|
return pMQint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPMQint(Integer pMQint) {
|
||||||
|
this.pMQint = pMQint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getCLon() {
|
||||||
|
return cLon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCLon(Boolean cLon) {
|
||||||
|
this.cLon = cLon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCLtoken() {
|
||||||
|
return cLtoken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCLtoken(String cLtoken) {
|
||||||
|
this.cLtoken = cLtoken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCLint() {
|
||||||
|
return cLint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCLint(Integer cLint) {
|
||||||
|
this.cLint = cLint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCLurl() {
|
||||||
|
return cLurl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCLurl(String cLurl) {
|
||||||
|
this.cLurl = cLurl;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Notes {
|
||||||
|
|
||||||
|
@SerializedName("fcm")
|
||||||
|
@Expose
|
||||||
|
private List<Object> fcm = null;
|
||||||
|
@SerializedName("ext")
|
||||||
|
@Expose
|
||||||
|
private Ext ext;
|
||||||
|
|
||||||
|
public List<Object> getFcm() {
|
||||||
|
return fcm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFcm(List<Object> fcm) {
|
||||||
|
this.fcm = fcm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ext getExt() {
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExt(Ext ext) {
|
||||||
|
this.ext = ext;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Pid {
|
||||||
|
|
||||||
|
@SerializedName("name")
|
||||||
|
@Expose
|
||||||
|
private String name;
|
||||||
|
@SerializedName("id")
|
||||||
|
@Expose
|
||||||
|
private Integer id;
|
||||||
|
@SerializedName("aktor")
|
||||||
|
@Expose
|
||||||
|
private Integer aktor;
|
||||||
|
@SerializedName("Kp")
|
||||||
|
@Expose
|
||||||
|
private Double kp;
|
||||||
|
@SerializedName("Ki")
|
||||||
|
@Expose
|
||||||
|
private Double ki;
|
||||||
|
@SerializedName("Kd")
|
||||||
|
@Expose
|
||||||
|
private Double kd;
|
||||||
|
@SerializedName("DCmmin")
|
||||||
|
@Expose
|
||||||
|
private Double dCmmin;
|
||||||
|
@SerializedName("DCmmax")
|
||||||
|
@Expose
|
||||||
|
private Double dCmmax;
|
||||||
|
@SerializedName("opl")
|
||||||
|
@Expose
|
||||||
|
private Integer opl;
|
||||||
|
@SerializedName("SPmin")
|
||||||
|
@Expose
|
||||||
|
private Double sPmin;
|
||||||
|
@SerializedName("SPmax")
|
||||||
|
@Expose
|
||||||
|
private Double sPmax;
|
||||||
|
@SerializedName("link")
|
||||||
|
@Expose
|
||||||
|
private Integer link;
|
||||||
|
@SerializedName("tune")
|
||||||
|
@Expose
|
||||||
|
private Integer tune;
|
||||||
|
@SerializedName("jp")
|
||||||
|
@Expose
|
||||||
|
private Integer jp;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAktor() {
|
||||||
|
return aktor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAktor(Integer aktor) {
|
||||||
|
this.aktor = aktor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getKp() {
|
||||||
|
return kp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKp(Double kp) {
|
||||||
|
this.kp = kp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getKi() {
|
||||||
|
return ki;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKi(Double ki) {
|
||||||
|
this.ki = ki;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getKd() {
|
||||||
|
return kd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKd(Double kd) {
|
||||||
|
this.kd = kd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getDCmmin() {
|
||||||
|
return dCmmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDCmmin(Double dCmmin) {
|
||||||
|
this.dCmmin = dCmmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getDCmmax() {
|
||||||
|
return dCmmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDCmmax(Double dCmmax) {
|
||||||
|
this.dCmmax = dCmmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOpl() {
|
||||||
|
return opl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpl(Integer opl) {
|
||||||
|
this.opl = opl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getSPmin() {
|
||||||
|
return sPmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSPmin(Double sPmin) {
|
||||||
|
this.sPmin = sPmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getSPmax() {
|
||||||
|
return sPmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSPmax(Double sPmax) {
|
||||||
|
this.sPmax = sPmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getLink() {
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLink(Integer link) {
|
||||||
|
this.link = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTune() {
|
||||||
|
return tune;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTune(Integer tune) {
|
||||||
|
this.tune = tune;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getJp() {
|
||||||
|
return jp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJp(Integer jp) {
|
||||||
|
this.jp = jp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Sensor {
|
||||||
|
|
||||||
|
@SerializedName("type")
|
||||||
|
@Expose
|
||||||
|
private Integer type;
|
||||||
|
@SerializedName("name")
|
||||||
|
@Expose
|
||||||
|
private String name;
|
||||||
|
@SerializedName("fixed")
|
||||||
|
@Expose
|
||||||
|
private Boolean fixed;
|
||||||
|
|
||||||
|
public Integer getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(Integer type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getFixed() {
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFixed(Boolean fixed) {
|
||||||
|
this.fixed = fixed;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Settings {
|
||||||
|
|
||||||
|
@SerializedName("device")
|
||||||
|
@Expose
|
||||||
|
private Device device;
|
||||||
|
@SerializedName("system")
|
||||||
|
@Expose
|
||||||
|
private System system;
|
||||||
|
@SerializedName("hardware")
|
||||||
|
@Expose
|
||||||
|
private List<String> hardware = null;
|
||||||
|
@SerializedName("api")
|
||||||
|
@Expose
|
||||||
|
private Api api;
|
||||||
|
@SerializedName("sensors")
|
||||||
|
@Expose
|
||||||
|
private List<Sensor> sensors = null;
|
||||||
|
@SerializedName("features")
|
||||||
|
@Expose
|
||||||
|
private Features features;
|
||||||
|
@SerializedName("pid")
|
||||||
|
@Expose
|
||||||
|
private List<Pid> pid = null;
|
||||||
|
@SerializedName("aktor")
|
||||||
|
@Expose
|
||||||
|
private List<String> aktor = null;
|
||||||
|
@SerializedName("display")
|
||||||
|
@Expose
|
||||||
|
private Display display;
|
||||||
|
@SerializedName("iot")
|
||||||
|
@Expose
|
||||||
|
private Iot iot;
|
||||||
|
@SerializedName("notes")
|
||||||
|
@Expose
|
||||||
|
private Notes notes;
|
||||||
|
|
||||||
|
public Device getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDevice(Device device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public System getSystem() {
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSystem(System system) {
|
||||||
|
this.system = system;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getHardware() {
|
||||||
|
return hardware;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHardware(List<String> hardware) {
|
||||||
|
this.hardware = hardware;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Api getApi() {
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApi(Api api) {
|
||||||
|
this.api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Sensor> getSensors() {
|
||||||
|
return sensors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSensors(List<Sensor> sensors) {
|
||||||
|
this.sensors = sensors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Features getFeatures() {
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeatures(Features features) {
|
||||||
|
this.features = features;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Pid> getPid() {
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPid(List<Pid> pid) {
|
||||||
|
this.pid = pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAktor() {
|
||||||
|
return aktor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAktor(List<String> aktor) {
|
||||||
|
this.aktor = aktor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display getDisplay() {
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplay(Display display) {
|
||||||
|
this.display = display;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iot getIot() {
|
||||||
|
return iot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIot(Iot iot) {
|
||||||
|
this.iot = iot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Notes getNotes() {
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotes(Notes notes) {
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO is used to parse the JSON
|
||||||
|
* Class is auto-generated from JSON using http://www.jsonschema2pojo.org/
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
public class System {
|
||||||
|
|
||||||
|
@SerializedName("time")
|
||||||
|
@Expose
|
||||||
|
private String time;
|
||||||
|
@SerializedName("unit")
|
||||||
|
@Expose
|
||||||
|
private String unit;
|
||||||
|
@SerializedName("ap")
|
||||||
|
@Expose
|
||||||
|
private String ap;
|
||||||
|
@SerializedName("host")
|
||||||
|
@Expose
|
||||||
|
private String host;
|
||||||
|
@SerializedName("language")
|
||||||
|
@Expose
|
||||||
|
private String language;
|
||||||
|
@SerializedName("version")
|
||||||
|
@Expose
|
||||||
|
private String version;
|
||||||
|
@SerializedName("getupdate")
|
||||||
|
@Expose
|
||||||
|
private String getupdate;
|
||||||
|
@SerializedName("autoupd")
|
||||||
|
@Expose
|
||||||
|
private Boolean autoupd;
|
||||||
|
@SerializedName("prerelease")
|
||||||
|
@Expose
|
||||||
|
private Boolean prerelease;
|
||||||
|
@SerializedName("hwversion")
|
||||||
|
@Expose
|
||||||
|
private String hwversion;
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(String time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnit(String unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAp() {
|
||||||
|
return ap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAp(String ap) {
|
||||||
|
this.ap = ap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(String language) {
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGetupdate() {
|
||||||
|
return getupdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGetupdate(String getupdate) {
|
||||||
|
this.getupdate = getupdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAutoupd() {
|
||||||
|
return autoupd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoupd(Boolean autoupd) {
|
||||||
|
this.autoupd = autoupd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getPrerelease() {
|
||||||
|
return prerelease;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrerelease(Boolean prerelease) {
|
||||||
|
this.prerelease = prerelease;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHwversion() {
|
||||||
|
return hwversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHwversion(String hwversion) {
|
||||||
|
this.hwversion = hwversion;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.mini;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
import javax.measure.Unit;
|
||||||
|
import javax.measure.quantity.Temperature;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoInputException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin.*;
|
||||||
|
import org.openhab.core.library.types.*;
|
||||||
|
import org.openhab.core.library.unit.ImperialUnits;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoMiniCommandHandler} is responsible for mapping the Commands to the respective data fields
|
||||||
|
* of the API.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoMiniCommandHandler {
|
||||||
|
|
||||||
|
public static final String ERROR = "er";
|
||||||
|
|
||||||
|
public static State getState(ChannelUID channelUID, App app)
|
||||||
|
throws WlanThermoUnknownChannelException, WlanThermoInputException {
|
||||||
|
String groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
Unit<Temperature> unit = "fahrenheit".equals(app.getTempUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
|
||||||
|
|
||||||
|
if (SYSTEM.equals(groupId)) {
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case WlanThermoBindingConstants.SYSTEM_CPU_TEMP:
|
||||||
|
if (app.getCpuTemp() == null) {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
} else {
|
||||||
|
return new DecimalType(app.getCpuTemp());
|
||||||
|
}
|
||||||
|
case WlanThermoBindingConstants.SYSTEM_CPU_LOAD:
|
||||||
|
if (app.getCpuLoad() == null) {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
} else {
|
||||||
|
return new DecimalType(app.getCpuLoad());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length()));
|
||||||
|
if (channelId >= 0 && channelId <= 9) {
|
||||||
|
Channel channel = app.getChannel();
|
||||||
|
if (channel == null) {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
Data data = channel.getData(channelId);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_NAME:
|
||||||
|
return new StringType(data.getName());
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_TEMP:
|
||||||
|
if (data.getState().equals(ERROR)) {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
} else {
|
||||||
|
return new QuantityType<>(data.getTemp(), unit);
|
||||||
|
}
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_MIN:
|
||||||
|
return new QuantityType<>(data.getTempMin(), unit);
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_MAX:
|
||||||
|
return new QuantityType<>(data.getTempMax(), unit);
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_ALARM_DEVICE:
|
||||||
|
return OnOffType.from(data.getAlert());
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_HIGH:
|
||||||
|
if (!data.getState().equals(ERROR) && data.getTemp() > data.getTempMax()) {
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_LOW:
|
||||||
|
if (!data.getState().equals(ERROR) && data.getTemp() < data.getTempMin()) {
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_COLOR:
|
||||||
|
Color c = Color.decode(WlanThermoMiniUtil.toHex(data.getColor()));
|
||||||
|
return HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue());
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_COLOR_NAME:
|
||||||
|
return new StringType(data.getColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) {
|
||||||
|
Pit pit;
|
||||||
|
if (groupId.equals(CHANNEL_PITMASTER_1)) {
|
||||||
|
pit = app.getPit();
|
||||||
|
} else if (groupId.equals(CHANNEL_PITMASTER_2)) {
|
||||||
|
pit = app.getPit2();
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
if (pit == null || !pit.getEnabled()) {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_PITMASTER_ENABLED:
|
||||||
|
return OnOffType.from(pit.getEnabled());
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_PITMASTER_CURRENT:
|
||||||
|
return new DecimalType(pit.getCurrent());
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_PITMASTER_SETPOINT:
|
||||||
|
return new QuantityType<>(pit.getSetpoint(), unit);
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_PITMASTER_DUTY_CYCLE:
|
||||||
|
return new DecimalType(pit.getControlOut());
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_PITMASTER_LID_OPEN:
|
||||||
|
return OnOffType.from(pit.getOpenLid().equals("True"));
|
||||||
|
case WlanThermoBindingConstants.CHANNEL_PITMASTER_CHANNEL_ID:
|
||||||
|
return new DecimalType(pit.getCh());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new WlanThermoUnknownChannelException(channelUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTrigger(ChannelUID channelUID, App app)
|
||||||
|
throws WlanThermoUnknownChannelException, WlanThermoInputException {
|
||||||
|
String groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
|
||||||
|
if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
|
||||||
|
if (channelId >= 0 && channelId <= 9) {
|
||||||
|
Channel channel = app.getChannel();
|
||||||
|
if (channel == null) {
|
||||||
|
throw new WlanThermoInputException();
|
||||||
|
}
|
||||||
|
Data data = channel.getData(channelId);
|
||||||
|
if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) {
|
||||||
|
if (!data.getState().equals(ERROR)) {
|
||||||
|
if (data.getTemp() > data.getTempMax()) {
|
||||||
|
return TRIGGER_ALARM_MAX;
|
||||||
|
} else if (data.getTemp() < data.getTempMin()) {
|
||||||
|
return TRIGGER_ALARM_MIN;
|
||||||
|
} else {
|
||||||
|
return TRIGGER_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new WlanThermoUnknownChannelException(channelUID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.mini;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.*;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin.App;
|
||||||
|
import org.openhab.core.thing.*;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoMiniHandler} is responsible for handling commands, which are
|
||||||
|
* sent to one of the channels.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoMiniHandler extends WlanThermoHandler {
|
||||||
|
|
||||||
|
private App app = new App();
|
||||||
|
|
||||||
|
public WlanThermoMiniHandler(Thing thing, HttpClient httpClient) {
|
||||||
|
super(thing, httpClient, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected State getState(ChannelUID channelUID) throws WlanThermoInputException, WlanThermoUnknownChannelException {
|
||||||
|
return WlanThermoMiniCommandHandler.getState(channelUID, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean setState(ChannelUID channelUID, Command command) {
|
||||||
|
// Mini is read-only!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void push() {
|
||||||
|
// Unused, Mini is read-only!
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void pull() {
|
||||||
|
try {
|
||||||
|
// Update objects with data from device
|
||||||
|
app = doGet("/app.php", App.class);
|
||||||
|
|
||||||
|
// Update channels
|
||||||
|
for (Channel channel : thing.getChannels()) {
|
||||||
|
try {
|
||||||
|
State state = WlanThermoMiniCommandHandler.getState(channel.getUID(), app);
|
||||||
|
updateState(channel.getUID(), state);
|
||||||
|
} catch (WlanThermoUnknownChannelException e) {
|
||||||
|
// if we could not obtain a state, try trigger instead
|
||||||
|
try {
|
||||||
|
String trigger = WlanThermoMiniCommandHandler.getTrigger(channel.getUID(), app);
|
||||||
|
if (!trigger.equals(TRIGGER_NONE)) {
|
||||||
|
triggerChannel(channel.getUID(), trigger);
|
||||||
|
}
|
||||||
|
} catch (WlanThermoUnknownChannelException e1) {
|
||||||
|
logger.debug("{}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (WlanThermoException ignore) {
|
||||||
|
// Nothing more to do
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Update interrupted. {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,21 +10,25 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
package org.openhab.binding.wlanthermo.internal.api.mini;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link UtilMini} class provides conversion functions for the WlanThermo Mini
|
* The {@link WlanThermoMiniUtil} class provides conversion functions for the WlanThermo Mini
|
||||||
*
|
*
|
||||||
* @author Christian Schlipp - Initial contribution
|
* @author Christian Schlipp - Initial contribution
|
||||||
*/
|
*/
|
||||||
public class UtilMini {
|
@NonNullByDefault
|
||||||
|
public class WlanThermoMiniUtil extends WlanThermoUtil {
|
||||||
private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
|
private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
|
||||||
private static final String DEFAULT_HEX = "#ffffff";
|
private static final String DEFAULT_HEX = "#ffffff";
|
||||||
|
|
||||||
private UtilMini() {
|
private WlanThermoMiniUtil() {
|
||||||
// hidden
|
// hidden
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,164 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
|
||||||
*
|
|
||||||
* See the NOTICE file(s) distributed with this work for additional
|
|
||||||
* information.
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made available under the
|
|
||||||
* terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-2.0
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
import org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants;
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.HSBType;
|
|
||||||
import org.openhab.core.library.types.OnOffType;
|
|
||||||
import org.openhab.core.library.types.StringType;
|
|
||||||
import org.openhab.core.thing.ChannelUID;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link WlanThermoMiniCommandHandler} is responsible for mapping the Commands to the respective data fields
|
|
||||||
* of the API.
|
|
||||||
*
|
|
||||||
* @author Christian Schlipp - Initial contribution
|
|
||||||
*/
|
|
||||||
public class WlanThermoMiniCommandHandler {
|
|
||||||
|
|
||||||
public State getState(ChannelUID channelUID, App app) {
|
|
||||||
State state = null;
|
|
||||||
if ("system".equals(channelUID.getGroupId())) {
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case WlanThermoBindingConstants.SYSTEM_CPU_TEMP:
|
|
||||||
if (app.getCpuTemp() == null) {
|
|
||||||
state = UnDefType.UNDEF;
|
|
||||||
} else {
|
|
||||||
state = new DecimalType(app.getCpuTemp());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.SYSTEM_CPU_LOAD:
|
|
||||||
if (app.getCpuLoad() == null) {
|
|
||||||
state = UnDefType.UNDEF;
|
|
||||||
} else {
|
|
||||||
state = new DecimalType(app.getCpuLoad());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (channelUID.getId().startsWith("channel")) {
|
|
||||||
int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length()));
|
|
||||||
if (channelId >= 0 && channelId <= 9) {
|
|
||||||
Channel channel = app.getChannel();
|
|
||||||
if (channel == null) {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
Data data = channel.getData(channelId);
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_NAME:
|
|
||||||
state = new StringType(data.getName());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_TEMP:
|
|
||||||
if (data.getState().equals("er")) {
|
|
||||||
state = UnDefType.UNDEF;
|
|
||||||
} else {
|
|
||||||
state = new DecimalType(data.getTemp());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_MIN:
|
|
||||||
state = new DecimalType(data.getTempMin());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_MAX:
|
|
||||||
state = new DecimalType(data.getTempMax());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_ALARM_DEVICE:
|
|
||||||
state = OnOffType.from(data.getAlert());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_HIGH:
|
|
||||||
if (!data.getState().equals("er") && data.getTemp() > data.getTempMax()) {
|
|
||||||
state = OnOffType.ON;
|
|
||||||
} else {
|
|
||||||
state = OnOffType.OFF;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_ALARM_OPENHAB_LOW:
|
|
||||||
if (!data.getState().equals("er") && data.getTemp() < data.getTempMin()) {
|
|
||||||
state = OnOffType.ON;
|
|
||||||
} else {
|
|
||||||
state = OnOffType.OFF;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_COLOR:
|
|
||||||
Color c = Color.decode(UtilMini.toHex(data.getColor()));
|
|
||||||
state = HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_COLOR_NAME:
|
|
||||||
state = new StringType(data.getColor());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (channelUID.getId().startsWith("pit")) {
|
|
||||||
Pit pit;
|
|
||||||
if (channelUID.getGroupId().equals("pit1")) {
|
|
||||||
pit = app.getPit();
|
|
||||||
} else if (channelUID.getGroupId().equals("pit2")) {
|
|
||||||
pit = app.getPit2();
|
|
||||||
} else {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
if (pit == null || !pit.getEnabled()) {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_PITMASTER_ENABLED:
|
|
||||||
state = OnOffType.from(pit.getEnabled());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_PITMASTER_CURRENT:
|
|
||||||
state = new DecimalType(pit.getCurrent());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_PITMASTER_SETPOINT:
|
|
||||||
state = new DecimalType(pit.getSetpoint());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_PITMASTER_DUTY_CYCLE:
|
|
||||||
state = new DecimalType(pit.getControlOut());
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_PITMASTER_LID_OPEN:
|
|
||||||
state = OnOffType.from(pit.getOpenLid().equals("True"));
|
|
||||||
break;
|
|
||||||
case WlanThermoBindingConstants.CHANNEL_PITMASTER_CHANNEL_ID:
|
|
||||||
state = new DecimalType(pit.getCh());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTrigger(ChannelUID channelUID, App app) {
|
|
||||||
String trigger = null;
|
|
||||||
if (channelUID.getId().startsWith("channel")) {
|
|
||||||
int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1;
|
|
||||||
if (channelId >= 0 && channelId <= 9) {
|
|
||||||
Channel channel = app.getChannel();
|
|
||||||
if (channel == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
Data data = channel.getData(channelId);
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case "alarm_openhab":
|
|
||||||
if (!data.getState().equals("er")) {
|
|
||||||
if (data.getTemp() > data.getTempMax()) {
|
|
||||||
trigger = WlanThermoBindingConstants.TRIGGER_ALARM_MAX;
|
|
||||||
} else if (data.getTemp() < data.getTempMin()) {
|
|
||||||
trigger = WlanThermoBindingConstants.TRIGGER_ALARM_MIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return trigger;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -1,261 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
|
||||||
*
|
|
||||||
* See the NOTICE file(s) distributed with this work for additional
|
|
||||||
* information.
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made available under the
|
|
||||||
* terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-2.0
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano;
|
|
||||||
|
|
||||||
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.data.Channel;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.data.Data;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.data.Pm;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.data.System;
|
|
||||||
import org.openhab.binding.wlanthermo.internal.api.nano.settings.Settings;
|
|
||||||
import org.openhab.core.library.types.*;
|
|
||||||
import org.openhab.core.thing.ChannelUID;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link WlanThermoNanoCommandHandler} is responsible for mapping the Commands to the respective data fields
|
|
||||||
* of the API.
|
|
||||||
*
|
|
||||||
* @author Christian Schlipp - Initial contribution
|
|
||||||
*/
|
|
||||||
public class WlanThermoNanoCommandHandler {
|
|
||||||
|
|
||||||
public State getState(ChannelUID channelUID, Data data, Settings settings) {
|
|
||||||
State state = null;
|
|
||||||
System system = data.getSystem();
|
|
||||||
List<Channel> channel = data.getChannel();
|
|
||||||
if ("system".equals(channelUID.getGroupId()) && system != null) {
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case SYSTEM_SOC:
|
|
||||||
state = new DecimalType(system.getSoc());
|
|
||||||
break;
|
|
||||||
case SYSTEM_CHARGE:
|
|
||||||
state = OnOffType.from(system.getCharge());
|
|
||||||
break;
|
|
||||||
case SYSTEM_RSSI_SIGNALSTRENGTH:
|
|
||||||
int dbm = system.getRssi();
|
|
||||||
if (dbm >= -80) {
|
|
||||||
state = new DecimalType(4);
|
|
||||||
} else if (dbm >= -95) {
|
|
||||||
state = new DecimalType(3);
|
|
||||||
} else if (dbm >= -105) {
|
|
||||||
state = new DecimalType(2);
|
|
||||||
} else {
|
|
||||||
state = new DecimalType(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SYSTEM_RSSI:
|
|
||||||
state = new DecimalType(system.getRssi());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (channelUID.getId().startsWith("channel")) {
|
|
||||||
int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1;
|
|
||||||
if (channel.size() > 0 && channelId <= channel.size()) {
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case CHANNEL_NAME:
|
|
||||||
state = new StringType(channel.get(channelId).getName());
|
|
||||||
break;
|
|
||||||
case CHANNEL_TYP:
|
|
||||||
state = new StringType(settings.sensors.get(channel.get(channelId).getTyp()));
|
|
||||||
break;
|
|
||||||
case CHANNEL_TEMP:
|
|
||||||
if (channel.get(channelId).getTemp() == 999.0) {
|
|
||||||
state = UnDefType.UNDEF;
|
|
||||||
} else {
|
|
||||||
state = new DecimalType(channel.get(channelId).getTemp());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_MIN:
|
|
||||||
state = new DecimalType(channel.get(channelId).getMin());
|
|
||||||
break;
|
|
||||||
case CHANNEL_MAX:
|
|
||||||
state = new DecimalType(channel.get(channelId).getMax());
|
|
||||||
break;
|
|
||||||
case CHANNEL_ALARM_DEVICE:
|
|
||||||
state = OnOffType.from(BigInteger.valueOf(channel.get(channelId).getAlarm()).testBit(1));
|
|
||||||
break;
|
|
||||||
case CHANNEL_ALARM_PUSH:
|
|
||||||
state = OnOffType.from(BigInteger.valueOf(channel.get(channelId).getAlarm()).testBit(0));
|
|
||||||
break;
|
|
||||||
case CHANNEL_ALARM_OPENHAB_HIGH:
|
|
||||||
if (channel.get(channelId).getTemp() != 999
|
|
||||||
&& channel.get(channelId).getTemp() > channel.get(channelId).getMax()) {
|
|
||||||
state = OnOffType.ON;
|
|
||||||
} else {
|
|
||||||
state = OnOffType.OFF;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_ALARM_OPENHAB_LOW:
|
|
||||||
if (channel.get(channelId).getTemp() != 999
|
|
||||||
&& channel.get(channelId).getTemp() < channel.get(channelId).getMin()) {
|
|
||||||
state = OnOffType.ON;
|
|
||||||
} else {
|
|
||||||
state = OnOffType.OFF;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_COLOR:
|
|
||||||
String color = channel.get(channelId).getColor();
|
|
||||||
if (color != null && !color.isEmpty()) {
|
|
||||||
Color c = Color.decode(color);
|
|
||||||
state = HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_COLOR_NAME:
|
|
||||||
String colorHex = channel.get(channelId).getColor();
|
|
||||||
if (colorHex != null && !colorHex.isEmpty()) {
|
|
||||||
state = new StringType(UtilNano.toColorName(colorHex));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (channelUID.getId().startsWith("pit1")) {
|
|
||||||
if (data.getPitmaster() != null && data.getPitmaster().getPm() != null
|
|
||||||
&& data.getPitmaster().getPm().size() > 0) {
|
|
||||||
Pm pm = data.getPitmaster().getPm().get(0);
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case CHANNEL_PITMASTER_CHANNEL_ID:
|
|
||||||
state = new DecimalType(pm.getChannel());
|
|
||||||
break;
|
|
||||||
case CHANNEL_PITMASTER_PIDPROFILE:
|
|
||||||
state = new DecimalType(pm.getPid());
|
|
||||||
break;
|
|
||||||
case CHANNEL_PITMASTER_DUTY_CYCLE:
|
|
||||||
state = new DecimalType(pm.getValue());
|
|
||||||
break;
|
|
||||||
case CHANNEL_PITMASTER_SETPOINT:
|
|
||||||
state = new DecimalType(pm.getSet());
|
|
||||||
break;
|
|
||||||
case CHANNEL_PITMASTER_STATE:
|
|
||||||
state = new StringType(pm.getTyp());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setState(ChannelUID channelUID, Command command, Data data) {
|
|
||||||
boolean success = false;
|
|
||||||
List<Channel> channel = data.getChannel();
|
|
||||||
if (channelUID.getId().startsWith("channel")) {
|
|
||||||
int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1;
|
|
||||||
if (channel.size() > 0 && channelId <= channel.size()) {
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case CHANNEL_NAME:
|
|
||||||
if (command instanceof StringType) {
|
|
||||||
channel.get(channelId).setName(command.toFullString());
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_MIN:
|
|
||||||
if (command instanceof QuantityType) {
|
|
||||||
channel.get(channelId).setMin(((QuantityType) command).doubleValue());
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_MAX:
|
|
||||||
if (command instanceof QuantityType) {
|
|
||||||
channel.get(channelId).setMax(((QuantityType) command).doubleValue());
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_ALARM_DEVICE:
|
|
||||||
if (command instanceof OnOffType) {
|
|
||||||
BigInteger value;
|
|
||||||
if (command == OnOffType.ON) {
|
|
||||||
value = BigInteger.valueOf(channel.get(channelId).getAlarm()).setBit(1);
|
|
||||||
} else {
|
|
||||||
value = BigInteger.valueOf(channel.get(channelId).getAlarm()).clearBit(1);
|
|
||||||
}
|
|
||||||
channel.get(channelId).setAlarm(value.intValue());
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_ALARM_PUSH:
|
|
||||||
if (command instanceof OnOffType) {
|
|
||||||
BigInteger value;
|
|
||||||
if (command == OnOffType.ON) {
|
|
||||||
value = BigInteger.valueOf(channel.get(channelId).getAlarm()).setBit(0);
|
|
||||||
} else {
|
|
||||||
value = BigInteger.valueOf(channel.get(channelId).getAlarm()).clearBit(0);
|
|
||||||
}
|
|
||||||
channel.get(channelId).setAlarm(value.intValue());
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CHANNEL_COLOR_NAME:
|
|
||||||
if (command instanceof StringType) {
|
|
||||||
channel.get(channelId).setColor(UtilNano.toHex(((StringType) command).toString()));
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (channelUID.getId().equals("pit1")) {
|
|
||||||
if (data.getPitmaster() != null && data.getPitmaster().getPm() != null
|
|
||||||
&& data.getPitmaster().getPm().size() > 0) {
|
|
||||||
Pm pm = data.getPitmaster().getPm().get(0);
|
|
||||||
switch (channelUID.getIdWithoutGroup()) {
|
|
||||||
case CHANNEL_PITMASTER_CHANNEL_ID:
|
|
||||||
pm.setChannel(((QuantityType) command).intValue());
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
case CHANNEL_PITMASTER_PIDPROFILE:
|
|
||||||
pm.setPid(((QuantityType) command).intValue());
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
case CHANNEL_PITMASTER_SETPOINT:
|
|
||||||
pm.setSet(((QuantityType) command).doubleValue());
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
case CHANNEL_PITMASTER_STATE:
|
|
||||||
String state = ((StringType) command).toString();
|
|
||||||
if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual")
|
|
||||||
|| state.equalsIgnoreCase("auto")) {
|
|
||||||
pm.setTyp(state);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTrigger(ChannelUID channelUID, Data data) {
|
|
||||||
String trigger = null;
|
|
||||||
List<Channel> channel = data.getChannel();
|
|
||||||
if (channelUID.getId().startsWith("channel")) {
|
|
||||||
int channelId = Integer.parseInt(channelUID.getGroupId().substring("channel".length())) - 1;
|
|
||||||
if (channel.size() > 0 && channelId <= channel.size()) {
|
|
||||||
if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) {
|
|
||||||
if (channel.get(channelId).getTemp() != 999) {
|
|
||||||
if (channel.get(channelId).getTemp() > channel.get(channelId).getMax()) {
|
|
||||||
trigger = TRIGGER_ALARM_MAX;
|
|
||||||
} else if (channel.get(channelId).getTemp() < channel.get(channelId).getMin()) {
|
|
||||||
trigger = TRIGGER_ALARM_MIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return trigger;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.nano;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.measure.Unit;
|
||||||
|
import javax.measure.quantity.Temperature;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoInputException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Channel;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Data;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Pm;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.System;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.settings.Settings;
|
||||||
|
import org.openhab.core.library.types.*;
|
||||||
|
import org.openhab.core.library.unit.ImperialUnits;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoNanoV1CommandHandler} is responsible for mapping the Commands to the respective data fields
|
||||||
|
* of the API.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoNanoV1CommandHandler {
|
||||||
|
|
||||||
|
public static State getState(ChannelUID channelUID, Data data, Settings settings)
|
||||||
|
throws WlanThermoUnknownChannelException, WlanThermoInputException {
|
||||||
|
String groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
System system = data.getSystem();
|
||||||
|
Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
|
||||||
|
List<Channel> channelList = data.getChannel();
|
||||||
|
|
||||||
|
if (SYSTEM.equals(groupId)) {
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case SYSTEM_SOC:
|
||||||
|
return new DecimalType(system.getSoc());
|
||||||
|
case SYSTEM_CHARGE:
|
||||||
|
return OnOffType.from(system.getCharge());
|
||||||
|
case SYSTEM_RSSI_SIGNALSTRENGTH:
|
||||||
|
int dbm = system.getRssi();
|
||||||
|
if (dbm >= -80) {
|
||||||
|
return SIGNAL_STRENGTH_4;
|
||||||
|
} else if (dbm >= -95) {
|
||||||
|
return SIGNAL_STRENGTH_3;
|
||||||
|
} else if (dbm >= -105) {
|
||||||
|
return SIGNAL_STRENGTH_2;
|
||||||
|
} else {
|
||||||
|
return SIGNAL_STRENGTH_1;
|
||||||
|
}
|
||||||
|
case SYSTEM_RSSI:
|
||||||
|
return new QuantityType<>(system.getRssi(), Units.DECIBEL_MILLIWATTS);
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
|
||||||
|
if (channelList.size() > 0 && channelId < channelList.size()) {
|
||||||
|
Channel channel = channelList.get(channelId);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_NAME:
|
||||||
|
return new StringType(channel.getName());
|
||||||
|
case CHANNEL_TYP:
|
||||||
|
return new StringType(settings.sensors.get(channel.getTyp()));
|
||||||
|
case CHANNEL_TEMP:
|
||||||
|
return channel.getTemp() == 999.0 ? UnDefType.UNDEF
|
||||||
|
: new QuantityType<>(channel.getTemp(), unit);
|
||||||
|
case CHANNEL_MIN:
|
||||||
|
return new QuantityType<>(channel.getMin(), unit);
|
||||||
|
case CHANNEL_MAX:
|
||||||
|
return new QuantityType<>(channel.getMax(), unit);
|
||||||
|
case CHANNEL_ALARM_DEVICE:
|
||||||
|
return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(1));
|
||||||
|
case CHANNEL_ALARM_PUSH:
|
||||||
|
return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(0));
|
||||||
|
case CHANNEL_ALARM_OPENHAB_HIGH:
|
||||||
|
if (channel.getTemp() != 999 && channel.getTemp() > channel.getMax()) {
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
case CHANNEL_ALARM_OPENHAB_LOW:
|
||||||
|
if (channel.getTemp() != 999 && channel.getTemp() < channel.getMin()) {
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
case CHANNEL_COLOR:
|
||||||
|
String color = channel.getColor();
|
||||||
|
if (color != null && !color.isEmpty()) {
|
||||||
|
Color c = Color.decode(color);
|
||||||
|
return HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue());
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
case CHANNEL_COLOR_NAME:
|
||||||
|
String colorHex = channel.getColor();
|
||||||
|
if (colorHex != null && !colorHex.isEmpty()) {
|
||||||
|
return new StringType(WlanThermoNanoV1Util.toColorName(colorHex));
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_1)) {
|
||||||
|
if (data.getPitmaster() != null && data.getPitmaster().getPm() != null
|
||||||
|
&& data.getPitmaster().getPm().size() > 0) {
|
||||||
|
Pm pm = data.getPitmaster().getPm().get(0);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_PITMASTER_CHANNEL_ID:
|
||||||
|
return new DecimalType(pm.getChannel());
|
||||||
|
case CHANNEL_PITMASTER_PIDPROFILE:
|
||||||
|
return new DecimalType(pm.getPid());
|
||||||
|
case CHANNEL_PITMASTER_DUTY_CYCLE:
|
||||||
|
return new DecimalType(pm.getValue());
|
||||||
|
case CHANNEL_PITMASTER_SETPOINT:
|
||||||
|
return new QuantityType<>(pm.getSet(), unit);
|
||||||
|
case CHANNEL_PITMASTER_STATE:
|
||||||
|
return new StringType(pm.getTyp());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new WlanThermoUnknownChannelException(channelUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean setState(ChannelUID channelUID, Command command, Data data) {
|
||||||
|
String groupId;
|
||||||
|
try {
|
||||||
|
groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
} catch (WlanThermoInputException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Channel> channelList = data.getChannel();
|
||||||
|
System system = data.getSystem();
|
||||||
|
Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
|
||||||
|
|
||||||
|
if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
|
||||||
|
if (channelList.size() > 0 && channelId < channelList.size()) {
|
||||||
|
Channel channel = channelList.get(channelId);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_NAME:
|
||||||
|
if (command instanceof StringType) {
|
||||||
|
channel.setName(command.toFullString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_MIN:
|
||||||
|
if (command instanceof QuantityType) {
|
||||||
|
try {
|
||||||
|
channel.setMin(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
|
||||||
|
return true;
|
||||||
|
} catch (WlanThermoInputException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_MAX:
|
||||||
|
if (command instanceof QuantityType) {
|
||||||
|
try {
|
||||||
|
channel.setMax(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
|
||||||
|
return true;
|
||||||
|
} catch (WlanThermoInputException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_ALARM_DEVICE:
|
||||||
|
if (command instanceof OnOffType) {
|
||||||
|
BigInteger value;
|
||||||
|
if (command == OnOffType.ON) {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).setBit(1);
|
||||||
|
} else {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).clearBit(1);
|
||||||
|
}
|
||||||
|
channel.setAlarm(value.intValue());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_ALARM_PUSH:
|
||||||
|
if (command instanceof OnOffType) {
|
||||||
|
BigInteger value;
|
||||||
|
if (command == OnOffType.ON) {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).setBit(0);
|
||||||
|
} else {
|
||||||
|
value = BigInteger.valueOf(channel.getAlarm()).clearBit(0);
|
||||||
|
}
|
||||||
|
channel.setAlarm(value.intValue());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CHANNEL_COLOR_NAME:
|
||||||
|
if (command instanceof StringType) {
|
||||||
|
channel.setColor(WlanThermoNanoV1Util.toHex(((StringType) command).toString()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_1)) {
|
||||||
|
if (data.getPitmaster() != null && data.getPitmaster().getPm() != null
|
||||||
|
&& data.getPitmaster().getPm().size() > 0) {
|
||||||
|
Pm pm = data.getPitmaster().getPm().get(0);
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case CHANNEL_PITMASTER_CHANNEL_ID:
|
||||||
|
pm.setChannel(((DecimalType) command).intValue());
|
||||||
|
return true;
|
||||||
|
case CHANNEL_PITMASTER_PIDPROFILE:
|
||||||
|
pm.setPid(((DecimalType) command).intValue());
|
||||||
|
return true;
|
||||||
|
case CHANNEL_PITMASTER_SETPOINT:
|
||||||
|
try {
|
||||||
|
pm.setSet(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
|
||||||
|
return true;
|
||||||
|
} catch (WlanThermoInputException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case CHANNEL_PITMASTER_STATE:
|
||||||
|
String state = ((StringType) command).toString();
|
||||||
|
if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual")
|
||||||
|
|| state.equalsIgnoreCase("auto")) {
|
||||||
|
pm.setTyp(state);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTrigger(ChannelUID channelUID, Data data)
|
||||||
|
throws WlanThermoUnknownChannelException, WlanThermoInputException {
|
||||||
|
|
||||||
|
String groupId = requireNonNull(channelUID.getGroupId());
|
||||||
|
List<Channel> channelList = data.getChannel();
|
||||||
|
|
||||||
|
if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
|
||||||
|
int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
|
||||||
|
if (channelList.size() > 0 && channelId < channelList.size()) {
|
||||||
|
Channel channel = channelList.get(channelId);
|
||||||
|
if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) {
|
||||||
|
if (channel.getTemp() != 999) {
|
||||||
|
if (channel.getTemp() > channel.getMax()) {
|
||||||
|
return TRIGGER_ALARM_MAX;
|
||||||
|
} else if (channel.getTemp() < channel.getMin()) {
|
||||||
|
return TRIGGER_ALARM_MIN;
|
||||||
|
} else {
|
||||||
|
return TRIGGER_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new WlanThermoUnknownChannelException(channelUID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.nano;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.*;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Data;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.settings.Settings;
|
||||||
|
import org.openhab.core.thing.*;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoNanoV1Handler} is responsible for handling commands, which are
|
||||||
|
* sent to one of the channels.
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class WlanThermoNanoV1Handler extends WlanThermoHandler {
|
||||||
|
|
||||||
|
private Data data = new Data();
|
||||||
|
private Settings settings = new Settings();
|
||||||
|
|
||||||
|
public WlanThermoNanoV1Handler(Thing thing, HttpClient httpClient) {
|
||||||
|
super(thing, httpClient, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected State getState(ChannelUID channelUID) throws WlanThermoInputException, WlanThermoUnknownChannelException {
|
||||||
|
return WlanThermoNanoV1CommandHandler.getState(channelUID, data, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean setState(ChannelUID channelUID, Command command) {
|
||||||
|
return WlanThermoNanoV1CommandHandler.setState(channelUID, command, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void push() {
|
||||||
|
// push update for sensor channels
|
||||||
|
for (org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Channel c : data.getChannel()) {
|
||||||
|
try {
|
||||||
|
String json = gson.toJson(c);
|
||||||
|
if (!doPost("/setchannels", json)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Push interrupted. {}", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// push update for pitmaster channels
|
||||||
|
try {
|
||||||
|
String json = gson.toJson(data.getPitmaster().getPm());
|
||||||
|
doPost("/setpitmaster", json);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Push interrupted. {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void pull() {
|
||||||
|
try {
|
||||||
|
// Update objects with data from device
|
||||||
|
data = doGet("/data", Data.class);
|
||||||
|
settings = doGet("/settings", Settings.class);
|
||||||
|
|
||||||
|
// Update channels
|
||||||
|
for (Channel channel : thing.getChannels()) {
|
||||||
|
try {
|
||||||
|
State state = WlanThermoNanoV1CommandHandler.getState(channel.getUID(), data, settings);
|
||||||
|
updateState(channel.getUID(), state);
|
||||||
|
} catch (WlanThermoUnknownChannelException e) {
|
||||||
|
// if we could not obtain a state, try trigger instead
|
||||||
|
try {
|
||||||
|
String trigger = WlanThermoNanoV1CommandHandler.getTrigger(channel.getUID(), data);
|
||||||
|
if (!trigger.equals(TRIGGER_NONE)) {
|
||||||
|
triggerChannel(channel.getUID(), trigger);
|
||||||
|
}
|
||||||
|
} catch (WlanThermoUnknownChannelException e1) {
|
||||||
|
logger.debug("{}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (WlanThermoException ignore) {
|
||||||
|
// Nothing more to do
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.debug("Update interrupted. {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,18 +15,22 @@ package org.openhab.binding.wlanthermo.internal.api.nano;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link UtilNano} class provides conversion functions for the WlanThermo Nano
|
* The {@link WlanThermoNanoV1Util} class provides conversion functions for the WlanThermo Nano V1+
|
||||||
*
|
*
|
||||||
* @author Christian Schlipp - Initial contribution
|
* @author Christian Schlipp - Initial contribution
|
||||||
*/
|
*/
|
||||||
public class UtilNano {
|
@NonNullByDefault
|
||||||
|
public class WlanThermoNanoV1Util extends WlanThermoUtil {
|
||||||
|
|
||||||
private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
|
private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
|
||||||
private static final String DEFAULT_HEX = "#ffffff";
|
private static final String DEFAULT_HEX = "#ffffff";
|
||||||
private static final String DEFAULT_COLORNAME = "niagara";
|
private static final String DEFAULT_COLORNAME = "niagara";
|
||||||
|
|
||||||
private UtilNano() {
|
private WlanThermoNanoV1Util() {
|
||||||
// hidden
|
// hidden
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,18 +60,6 @@ public class UtilNano {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toColorName(String colorHex) {
|
public static String toColorName(String colorHex) {
|
||||||
String colorName = null;
|
return toColorName(colorHex, COLOR_MAPPINGS, DEFAULT_COLORNAME);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="wlanthermo"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
<!-- System Group ESP32 -->
|
||||||
|
<channel-group-type id="cg_system_esp32">
|
||||||
|
<label>System Channels</label>
|
||||||
|
<description>This group contains all system channels</description>
|
||||||
|
<channels>
|
||||||
|
<channel id="soc" typeId="system.battery-level"/>
|
||||||
|
<channel id="charge" typeId="charging"/>
|
||||||
|
<channel id="rssi" typeId="rssi"/>
|
||||||
|
<channel id="rssi_signalstrength" typeId="system.signal-strength"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<!-- Temperature Group ESP32 -->
|
||||||
|
<channel-group-type id="cg_temperature_esp32">
|
||||||
|
<label>Temperature Sensor</label>
|
||||||
|
<category>Sensor</category>
|
||||||
|
<channels>
|
||||||
|
<channel id="name" typeId="name"/>
|
||||||
|
<channel id="typ" typeId="typ"/>
|
||||||
|
<channel id="temp" typeId="temperature"/>
|
||||||
|
<channel id="min" typeId="temperature_min"/>
|
||||||
|
<channel id="max" typeId="temperature_max"/>
|
||||||
|
<channel id="alarm_device" typeId="alarm_device"/>
|
||||||
|
<channel id="alarm_push" typeId="alarm_push"/>
|
||||||
|
<channel id="alarm_openhab" typeId="alarm_openhab"/>
|
||||||
|
<channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
|
||||||
|
<channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
|
||||||
|
<channel id="color" typeId="color"/>
|
||||||
|
<channel id="color_name" typeId="color_name_esp32"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<!-- Pitmaster ESP32 -->
|
||||||
|
<channel-group-type id="cg_pitmaster_esp32">
|
||||||
|
<label>Pitmaster</label>
|
||||||
|
<category>Sensor</category>
|
||||||
|
<channels>
|
||||||
|
<channel id="state" typeId="pitmaster_type"/>
|
||||||
|
<channel id="setpoint" typeId="temperature_setpoint"/>
|
||||||
|
<channel id="duty_cycle" typeId="duty_cycle"/>
|
||||||
|
<channel id="channel_id" typeId="channel_id"/>
|
||||||
|
<channel id="pid_id" typeId="pid_id"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
</thing:thing-descriptions>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="wlanthermo"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
<!-- System Group Mini V1 -->
|
||||||
|
<channel-group-type id="cg_system_mini">
|
||||||
|
<label>System Channel</label>
|
||||||
|
<description>This group contains all system channels</description>
|
||||||
|
<channels>
|
||||||
|
<channel id="cpu_load" typeId="cpu_load"/>
|
||||||
|
<channel id="cpu_temp" typeId="temperature"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<!-- Channel Group Temperature Mini V1 -->
|
||||||
|
<channel-group-type id="cg_temperature_mini">
|
||||||
|
<label>Sensor Mini</label>
|
||||||
|
<category>Sensor</category>
|
||||||
|
<channels>
|
||||||
|
<channel id="name" typeId="name_ro"/>
|
||||||
|
<channel id="temp" typeId="temperature"/>
|
||||||
|
<channel id="min" typeId="temperature_min_ro"/>
|
||||||
|
<channel id="max" typeId="temperature_max_ro"/>
|
||||||
|
<channel id="alarm_device" typeId="alarm_device_ro"/>
|
||||||
|
<channel id="alarm_openhab" typeId="alarm_openhab"/>
|
||||||
|
<channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
|
||||||
|
<channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
|
||||||
|
<channel id="color" typeId="color_ro"/>
|
||||||
|
<channel id="color_name" typeId="color_name_mini_ro"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<!-- Pitmaster Mini V1 -->
|
||||||
|
<channel-group-type id="cg_pitmaster_mini">
|
||||||
|
<label>Pitmaster Mini</label>
|
||||||
|
<category>Sensor</category>
|
||||||
|
<channels>
|
||||||
|
<channel id="enabled" typeId="enabled"/>
|
||||||
|
<channel id="current" typeId="temperature"/>
|
||||||
|
<channel id="setpoint" typeId="temperature_setpoint_ro"/>
|
||||||
|
<channel id="duty_cycle" typeId="duty_cycle_ro"/>
|
||||||
|
<channel id="lid_open" typeId="lid_open"/>
|
||||||
|
<channel id="channel_id" typeId="channel_id_ro"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
</thing:thing-descriptions>
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="wlanthermo"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
<!-- System Group Nano -->
|
||||||
|
<channel-group-type id="cg_system_nano">
|
||||||
|
<label>System Channel</label>
|
||||||
|
<description>This group contains all system channels</description>
|
||||||
|
<channels>
|
||||||
|
<channel id="soc" typeId="system.battery-level"/>
|
||||||
|
<channel id="charge" typeId="charging"/>
|
||||||
|
<channel id="rssi" typeId="rssi"/>
|
||||||
|
<channel id="rssi_signalstrength" typeId="system.signal-strength"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<!-- Temperature Group Nano -->
|
||||||
|
<channel-group-type id="cg_temperature_nano">
|
||||||
|
<label>Sensor Nano</label>
|
||||||
|
<category>Sensor</category>
|
||||||
|
<channels>
|
||||||
|
<channel id="name" typeId="name"/>
|
||||||
|
<channel id="typ" typeId="typ"/>
|
||||||
|
<channel id="temp" typeId="temperature"/>
|
||||||
|
<channel id="min" typeId="temperature_min"/>
|
||||||
|
<channel id="max" typeId="temperature_max"/>
|
||||||
|
<channel id="alarm_device" typeId="alarm_device"/>
|
||||||
|
<channel id="alarm_push" typeId="alarm_push"/>
|
||||||
|
<channel id="alarm_openhab" typeId="alarm_openhab"/>
|
||||||
|
<channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
|
||||||
|
<channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
|
||||||
|
<channel id="color" typeId="color_ro"/>
|
||||||
|
<channel id="color_name" typeId="color_name_nano"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<!-- Pitmaster Nano -->
|
||||||
|
<channel-group-type id="cg_pitmaster_nano">
|
||||||
|
<label>Pitmaster Nano</label>
|
||||||
|
<category>Sensor</category>
|
||||||
|
<channels>
|
||||||
|
<channel id="state" typeId="pitmaster_type"/>
|
||||||
|
<channel id="setpoint" typeId="temperature_setpoint"/>
|
||||||
|
<channel id="duty_cycle" typeId="duty_cycle"/>
|
||||||
|
<channel id="channel_id" typeId="channel_id"/>
|
||||||
|
<channel id="pid_id" typeId="pid_id"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
|
||||||
|
</thing:thing-descriptions>
|
|
@ -0,0 +1,259 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="wlanthermo"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
<channel-type id="cpu_load" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>CPU Load</label>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="name" advanced="false">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Name</label>
|
||||||
|
<category>Text</category>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="name_ro" advanced="false">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Name</label>
|
||||||
|
<category>Text</category>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="typ" advanced="true">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Type</label>
|
||||||
|
<category>Text</category>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="temperature" advanced="false">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>Current Temperature</label>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<state min="0" pattern="%.1f %unit%" readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="temperature_min" advanced="true">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>Low Temperature Alarm</label>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="temperature_max" advanced="true">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>High Temperature Alarm</label>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="temperature_min_ro" advanced="true">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>Low Temperature Alarm</label>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="temperature_max_ro" advanced="true">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>High Temperature Alarm</label>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="alarm_device" advanced="true">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Alarm Buzzer</label>
|
||||||
|
<category>Switch</category>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="alarm_device_ro" advanced="true">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Alarm Buzzer</label>
|
||||||
|
<category>Switch</category>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="alarm_push" advanced="true">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Push-Alarm</label>
|
||||||
|
<category>Switch</category>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="alarm_openhab" advanced="true">
|
||||||
|
<kind>trigger</kind>
|
||||||
|
<label>OpenHAB Alarm Trigger</label>
|
||||||
|
<event>
|
||||||
|
<options>
|
||||||
|
<option value="MIN">Low Temperature Alarm</option>
|
||||||
|
<option value="MAX">High Temperature Alarm</option>
|
||||||
|
</options>
|
||||||
|
</event>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="alarm_openhab_low" advanced="false">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Low Temperature Alarm</label>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="alarm_openhab_high" advanced="false">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>High Temperature Alarm</label>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="color" advanced="true">
|
||||||
|
<item-type>Color</item-type>
|
||||||
|
<label>Color</label>
|
||||||
|
<category>Colorpicker</category>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="color_name_nano" advanced="true">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Color</label>
|
||||||
|
<category>Colorpicker</category>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="niagara">Niagara</option>
|
||||||
|
<option value="rosa">Rosa</option>
|
||||||
|
<option value="lapis blue">Lapis Blue</option>
|
||||||
|
<option value="orange">Orange</option>
|
||||||
|
<option value="lila">Lila</option>
|
||||||
|
<option value="red">Red</option>
|
||||||
|
<option value="green">Green</option>
|
||||||
|
<option value="gold">Gold</option>
|
||||||
|
<option value="kale">Kale</option>
|
||||||
|
<option value="brown">Brown</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="color_name_esp32" advanced="true">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Color</label>
|
||||||
|
<category>Colorpicker</category>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="#FFFF00">yellow</option>
|
||||||
|
<option value="#FFC002">dark yellow</option>
|
||||||
|
<option value="#00FF00">green</option>
|
||||||
|
<option value="#FFFFFF">white</option>
|
||||||
|
<option value="#FF1DC4">pink</option>
|
||||||
|
<option value="#E46C0A">orange</option>
|
||||||
|
<option value="#C3D69B">olive</option>
|
||||||
|
<option value="#0FE6F1">light blue</option>
|
||||||
|
<option value="#0000FF">blue</option>
|
||||||
|
<option value="#03A923">dark green</option>
|
||||||
|
<option value="#C84B32">brown</option>
|
||||||
|
<option value="#FF9B69">light brown</option>
|
||||||
|
<option value="#5082BE">dark blue</option>
|
||||||
|
<option value="#FFB1D0">light pink</option>
|
||||||
|
<option value="#A6EF03">light green</option>
|
||||||
|
<option value="#D42A6B">dark pink</option>
|
||||||
|
<option value="#FFDA8F">beige</option>
|
||||||
|
<option value="#00B0F0">azure</option>
|
||||||
|
<option value="#948A54">dark olive</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="color_ro" advanced="true">
|
||||||
|
<item-type>Color</item-type>
|
||||||
|
<label>Color</label>
|
||||||
|
<category>Colorpicker</category>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="color_name_mini_ro" advanced="true">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Color Name</label>
|
||||||
|
<category>Text</category>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="enabled" advanced="false">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Enabled</label>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="temperature_setpoint_ro" advanced="false">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>Setpoint Temperature</label>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<state min="0" pattern="%.1f %unit%" readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="duty_cycle_ro" advanced="false">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Duty Cycle / Control Out</label>
|
||||||
|
<state min="0" max="100" pattern="%d" readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="lid_open" advanced="false">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Lid Open</label>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="channel_id_ro" advanced="false">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Channel ID</label>
|
||||||
|
<state min="0" max="9" pattern="%d" readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="pitmaster_type" advanced="false">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>State</label>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="off">Off</option>
|
||||||
|
<option value="manual">Manual</option>
|
||||||
|
<option value="auto">Auto</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="duty_cycle" advanced="false">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Duty Cycle / Control Out</label>
|
||||||
|
<state min="0" max="100" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="pid_id" advanced="false">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>PID Profile ID</label>
|
||||||
|
<state pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="temperature_setpoint" advanced="false">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>Setpoint Temperature</label>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<state min="0" pattern="%.1f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="channel_id" advanced="false">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Temperature Channel ID</label>
|
||||||
|
<state min="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="charging" advanced="true">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Charging</label>
|
||||||
|
<category>Energy</category>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="rssi" advanced="true">
|
||||||
|
<item-type>Number:Power</item-type>
|
||||||
|
<label>RSSI in dBm</label>
|
||||||
|
<category>Number</category>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
</thing:thing-descriptions>
|
|
@ -0,0 +1,151 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="wlanthermo"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
<thing-type id="esp32">
|
||||||
|
<label>WlanThermo Mini V2, Nano V3, Link V1</label>
|
||||||
|
<description><![CDATA[ WlanThermo device with <b>ESP32 processor</b>, such as Mini V2 (ESP32), Nano V3, Link V1 ]]></description>
|
||||||
|
|
||||||
|
<channel-groups>
|
||||||
|
<channel-group id="system" typeId="cg_system_esp32"/>
|
||||||
|
<channel-group id="channel1" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 1</label>
|
||||||
|
<description>This group contains all channels for temperature probe 1</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel2" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 2</label>
|
||||||
|
<description>This group contains all channels for temperature probe 2</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel3" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 3</label>
|
||||||
|
<description>This group contains all channels for temperature probe 3</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel4" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 4</label>
|
||||||
|
<description>This group contains all channels for temperature probe 4</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel5" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 5</label>
|
||||||
|
<description>This group contains all channels for temperature probe 5</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel6" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 6</label>
|
||||||
|
<description>This group contains all channels for temperature probe 6</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel7" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 7</label>
|
||||||
|
<description>This group contains all channels for temperature probe 7</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel8" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 8</label>
|
||||||
|
<description>This group contains all channels for temperature probe 8</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel9" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 9</label>
|
||||||
|
<description>This group contains all channels for temperature probe 9</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel10" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 10</label>
|
||||||
|
<description>This group contains all channels for temperature probe 10</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel11" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 11</label>
|
||||||
|
<description>This group contains all channels for temperature probe 11</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel12" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 12</label>
|
||||||
|
<description>This group contains all channels for temperature probe 12</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel13" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 13</label>
|
||||||
|
<description>This group contains all channels for temperature probe 13</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel14" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 14</label>
|
||||||
|
<description>This group contains all channels for temperature probe 14</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel15" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 15</label>
|
||||||
|
<description>This group contains all channels for temperature probe 15</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel16" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 16</label>
|
||||||
|
<description>This group contains all channels for temperature probe 16</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel17" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 17</label>
|
||||||
|
<description>This group contains all channels for temperature probe 17</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel18" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 18</label>
|
||||||
|
<description>This group contains all channels for temperature probe 18</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel19" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 19</label>
|
||||||
|
<description>This group contains all channels for temperature probe 19</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel20" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 20</label>
|
||||||
|
<description>This group contains all channels for temperature probe 20</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel21" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 21</label>
|
||||||
|
<description>This group contains all channels for temperature probe 21</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel22" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 22</label>
|
||||||
|
<description>This group contains all channels for temperature probe 22</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel23" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 23</label>
|
||||||
|
<description>This group contains all channels for temperature probe 23</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel24" typeId="cg_temperature_esp32">
|
||||||
|
<label>Temperature Probe 24</label>
|
||||||
|
<description>This group contains all channels for temperature probe 24</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="pit1" typeId="cg_pitmaster_esp32">
|
||||||
|
<label>Pitmaster 1</label>
|
||||||
|
<description>This group contains all channels for pitmaster channel 1</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="pit2" typeId="cg_pitmaster_esp32">
|
||||||
|
<label>Pitmaster 2</label>
|
||||||
|
<description>This group contains all channels for pitmaster channel 2</description>
|
||||||
|
</channel-group>
|
||||||
|
</channel-groups>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<property name="model">Model</property>
|
||||||
|
<property name="serial">Serial Number</property>
|
||||||
|
<property name="esp32_bt_enabled">Bluetooth available</property>
|
||||||
|
<property name="esp32_pm_enabled">Pitmaster available</property>
|
||||||
|
<property name="esp32_temp_channels">Temperature channels</property>
|
||||||
|
<property name="esp32_pm_channels">Pitmaster channels</property>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter name="ipAddress" type="text" required="true">
|
||||||
|
<context>network-address</context>
|
||||||
|
<label>Network Address</label>
|
||||||
|
<description>Network address of the WlanThermo Nano.</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="username" type="text">
|
||||||
|
<label>Username</label>
|
||||||
|
<description>Optional, only required for write access. Default: 'admin'</description>
|
||||||
|
<default>admin</default>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="password" type="text">
|
||||||
|
<context>password</context>
|
||||||
|
<label>Password</label>
|
||||||
|
<description>Optional, only required for write access. Default: 'admin'</description>
|
||||||
|
<default>admin</default>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
|
||||||
|
<label>Polling Interval</label>
|
||||||
|
<description>Seconds between fetching values from the WlanThermo Nano.</description>
|
||||||
|
<default>10</default>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
</thing-type>
|
||||||
|
</thing:thing-descriptions>
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="wlanthermo"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
|
||||||
|
|
||||||
|
<thing-type id="mini">
|
||||||
|
<label>WlanThermo Mini V1/V2</label>
|
||||||
|
<description><![CDATA[ WlanThermo Mini with <b>Raspberry Pi processor</b>, such as Mini V1/V2 ]]></description>
|
||||||
|
|
||||||
|
<channel-groups>
|
||||||
|
<channel-group id="system" typeId="cg_system_mini"/>
|
||||||
|
<channel-group id="channel0" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 1</label>
|
||||||
|
<description>This group contains all channels for temperature probe 1</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel1" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 2</label>
|
||||||
|
<description>This group contains all channels for temperature probe 2</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel2" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 3</label>
|
||||||
|
<description>This group contains all channels for temperature probe 3</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel3" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 4</label>
|
||||||
|
<description>This group contains all channels for temperature probe 4</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel4" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 5</label>
|
||||||
|
<description>This group contains all channels for temperature probe 5</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel5" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 6</label>
|
||||||
|
<description>This group contains all channels for temperature probe 6</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel6" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 7</label>
|
||||||
|
<description>This group contains all channels for temperature probe 7</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel7" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 8</label>
|
||||||
|
<description>This group contains all channels for temperature probe 8</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel8" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 9</label>
|
||||||
|
<description>This group contains all channels for temperature probe 9</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel9" typeId="cg_temperature_mini">
|
||||||
|
<label>Temperature Probe 10</label>
|
||||||
|
<description>This group contains all channels for temperature probe 10</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="pit1" typeId="cg_pitmaster_mini">
|
||||||
|
<label>Pitmaster 1</label>
|
||||||
|
<description>This group contains all channels for pitmaster channel 1</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="pit2" typeId="cg_pitmaster_mini">
|
||||||
|
<label>Pitmaster 2</label>
|
||||||
|
<description>This group contains all channels for pitmaster channel 2</description>
|
||||||
|
</channel-group>
|
||||||
|
</channel-groups>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter name="ipAddress" type="text" required="true">
|
||||||
|
<context>network-address</context>
|
||||||
|
<label>Network Address</label>
|
||||||
|
<description>Network address of the WlanThermo Mini.</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
|
||||||
|
<label>Polling Interval</label>
|
||||||
|
<description>Seconds between fetching values from the WlanThermo Mini.</description>
|
||||||
|
<default>10</default>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
|
||||||
|
</thing-type>
|
||||||
|
|
||||||
|
</thing:thing-descriptions>
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="wlanthermo"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
<thing-type id="nano">
|
||||||
|
<label>WlanThermo Nano</label>
|
||||||
|
<description>WlanThermo Nano V1/V1+</description>
|
||||||
|
|
||||||
|
<channel-groups>
|
||||||
|
<channel-group id="system" typeId="cg_system_nano"/>
|
||||||
|
<channel-group id="channel1" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 1</label>
|
||||||
|
<description>This group contains all channels for temperature probe 1</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel2" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 2</label>
|
||||||
|
<description>This group contains all channels for temperature probe 2</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel3" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 3</label>
|
||||||
|
<description>This group contains all channels for temperature probe 3</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel4" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 4</label>
|
||||||
|
<description>This group contains all channels for temperature probe 4</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel5" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 5</label>
|
||||||
|
<description>This group contains all channels for temperature probe 5</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel6" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 6</label>
|
||||||
|
<description>This group contains all channels for temperature probe 6</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel7" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 7</label>
|
||||||
|
<description>This group contains all channels for temperature probe 7</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="channel8" typeId="cg_temperature_nano">
|
||||||
|
<label>Temperature Probe 8</label>
|
||||||
|
<description>This group contains all channels for temperature probe 8</description>
|
||||||
|
</channel-group>
|
||||||
|
<channel-group id="pit1" typeId="cg_pitmaster_nano">
|
||||||
|
<label>Pitmaster 1</label>
|
||||||
|
<description>This group contains all channels for pitmaster channel 1</description>
|
||||||
|
</channel-group>
|
||||||
|
</channel-groups>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter name="ipAddress" type="text" required="true">
|
||||||
|
<context>network-address</context>
|
||||||
|
<label>Network Address</label>
|
||||||
|
<description>Network address of the WlanThermo Nano.</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="username" type="text">
|
||||||
|
<label>Username</label>
|
||||||
|
<description>Optional, only required for write access. Default: 'admin'</description>
|
||||||
|
<default>admin</default>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="password" type="text">
|
||||||
|
<context>password</context>
|
||||||
|
<label>Password</label>
|
||||||
|
<description>Optional, only required for write access. Default: 'admin'</description>
|
||||||
|
<default>admin</default>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
|
||||||
|
<label>Polling Interval</label>
|
||||||
|
<description>Seconds between fetching values from the WlanThermo Nano.</description>
|
||||||
|
<default>10</default>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
</thing-type>
|
||||||
|
</thing:thing-descriptions>
|
|
@ -1,463 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<thing:thing-descriptions bindingId="wlanthermo"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
|
||||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
|
||||||
|
|
||||||
<thing-type id="nano">
|
|
||||||
<label>WlanThermo Nano</label>
|
|
||||||
<description>WlanThermo Nano V1/V1+</description>
|
|
||||||
|
|
||||||
<channel-groups>
|
|
||||||
<channel-group id="system" typeId="cg_system_nano"/>
|
|
||||||
<channel-group id="channel1" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 1</label>
|
|
||||||
<description>This group contains all channels for temperature probe 1</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel2" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 2</label>
|
|
||||||
<description>This group contains all channels for temperature probe 2</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel3" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 3</label>
|
|
||||||
<description>This group contains all channels for temperature probe 3</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel4" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 4</label>
|
|
||||||
<description>This group contains all channels for temperature probe 4</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel5" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 5</label>
|
|
||||||
<description>This group contains all channels for temperature probe 5</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel6" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 6</label>
|
|
||||||
<description>This group contains all channels for temperature probe 6</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel7" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 7</label>
|
|
||||||
<description>This group contains all channels for temperature probe 7</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel8" typeId="cg_temperature_nano">
|
|
||||||
<label>Temperature Probe 8</label>
|
|
||||||
<description>This group contains all channels for temperature probe 8</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="pit1" typeId="cg_pitmaster_nano">
|
|
||||||
<label>Pitmaster 1</label>
|
|
||||||
<description>This group contains all channels for pitmaster channel 1</description>
|
|
||||||
</channel-group>
|
|
||||||
</channel-groups>
|
|
||||||
|
|
||||||
<config-description>
|
|
||||||
<parameter name="ipAddress" type="text" required="true">
|
|
||||||
<context>network-address</context>
|
|
||||||
<label>Network Address</label>
|
|
||||||
<description>Network address of the WlanThermo Nano.</description>
|
|
||||||
</parameter>
|
|
||||||
<parameter name="username" type="text">
|
|
||||||
<label>Username</label>
|
|
||||||
<description>Optional, only required for write access. Default: 'admin'</description>
|
|
||||||
<default>admin</default>
|
|
||||||
</parameter>
|
|
||||||
<parameter name="password" type="text">
|
|
||||||
<context>password</context>
|
|
||||||
<label>Password</label>
|
|
||||||
<description>Optional, only required for write access. Default: 'admin'</description>
|
|
||||||
<default>admin</default>
|
|
||||||
</parameter>
|
|
||||||
<parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
|
|
||||||
<label>Polling Interval</label>
|
|
||||||
<description>Seconds between fetching values from the WlanThermo Nano.</description>
|
|
||||||
<default>10</default>
|
|
||||||
</parameter>
|
|
||||||
</config-description>
|
|
||||||
|
|
||||||
</thing-type>
|
|
||||||
|
|
||||||
<thing-type id="mini">
|
|
||||||
<label>WlanThermo Mini</label>
|
|
||||||
<description>WlanThermo Mini</description>
|
|
||||||
|
|
||||||
<channel-groups>
|
|
||||||
<channel-group id="system" typeId="cg_system_mini"/>
|
|
||||||
<channel-group id="channel0" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 1</label>
|
|
||||||
<description>This group contains all channels for temperature probe 1</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel1" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 2</label>
|
|
||||||
<description>This group contains all channels for temperature probe 2</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel2" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 3</label>
|
|
||||||
<description>This group contains all channels for temperature probe 3</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel3" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 4</label>
|
|
||||||
<description>This group contains all channels for temperature probe 4</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel4" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 5</label>
|
|
||||||
<description>This group contains all channels for temperature probe 5</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel5" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 6</label>
|
|
||||||
<description>This group contains all channels for temperature probe 6</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel6" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 7</label>
|
|
||||||
<description>This group contains all channels for temperature probe 7</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel7" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 8</label>
|
|
||||||
<description>This group contains all channels for temperature probe 8</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel8" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 9</label>
|
|
||||||
<description>This group contains all channels for temperature probe 9</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="channel9" typeId="cg_temperature_mini">
|
|
||||||
<label>Temperature Probe 10</label>
|
|
||||||
<description>This group contains all channels for temperature probe 10</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="pit1" typeId="cg_pitmaster_mini">
|
|
||||||
<label>Pitmaster 1</label>
|
|
||||||
<description>This group contains all channels for pitmaster channel 1</description>
|
|
||||||
</channel-group>
|
|
||||||
<channel-group id="pit2" typeId="cg_pitmaster_mini">
|
|
||||||
<label>Pitmaster 2</label>
|
|
||||||
<description>This group contains all channels for pitmaster channel 2</description>
|
|
||||||
</channel-group>
|
|
||||||
</channel-groups>
|
|
||||||
|
|
||||||
<config-description>
|
|
||||||
<parameter name="ipAddress" type="text" required="true">
|
|
||||||
<context>network-address</context>
|
|
||||||
<label>Network Address</label>
|
|
||||||
<description>Network address of the WlanThermo Mini.</description>
|
|
||||||
</parameter>
|
|
||||||
<parameter name="pollingInterval" type="integer" min="1" step="1" unit="s" required="true">
|
|
||||||
<label>Polling Interval</label>
|
|
||||||
<description>Seconds between fetching values from the WlanThermo Mini.</description>
|
|
||||||
<default>10</default>
|
|
||||||
</parameter>
|
|
||||||
</config-description>
|
|
||||||
|
|
||||||
</thing-type>
|
|
||||||
|
|
||||||
<!-- System Group Nano -->
|
|
||||||
<channel-group-type id="cg_system_nano">
|
|
||||||
<label>System Channel</label>
|
|
||||||
<description>This group contains all system channels</description>
|
|
||||||
<channels>
|
|
||||||
<channel id="soc" typeId="system.battery-level"/>
|
|
||||||
<channel id="charge" typeId="charging"/>
|
|
||||||
<channel id="rssi" typeId="rssi"/>
|
|
||||||
<channel id="rssi_signalstrength" typeId="system.signal-strength"/>
|
|
||||||
</channels>
|
|
||||||
</channel-group-type>
|
|
||||||
|
|
||||||
<channel-type id="charging" advanced="true">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>Charging</label>
|
|
||||||
<category>Energy</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="rssi" advanced="true">
|
|
||||||
<item-type>Number</item-type>
|
|
||||||
<label>RSSI in dBm</label>
|
|
||||||
<category>Text</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<!-- System Group Mini -->
|
|
||||||
<channel-group-type id="cg_system_mini">
|
|
||||||
<label>System Channel</label>
|
|
||||||
<description>This group contains all system channels</description>
|
|
||||||
<channels>
|
|
||||||
<channel id="cpu_load" typeId="cpu_load"/>
|
|
||||||
<channel id="cpu_temp" typeId="temperature"/>
|
|
||||||
</channels>
|
|
||||||
</channel-group-type>
|
|
||||||
|
|
||||||
<channel-type id="cpu_load" advanced="true">
|
|
||||||
<item-type>Number</item-type>
|
|
||||||
<label>CPU Load</label>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<!-- Temperature Group Nano -->
|
|
||||||
<channel-group-type id="cg_temperature_nano">
|
|
||||||
<label>Sensor Nano</label>
|
|
||||||
<category>Sensor</category>
|
|
||||||
<channels>
|
|
||||||
<channel id="name" typeId="name"/>
|
|
||||||
<channel id="typ" typeId="typ"/>
|
|
||||||
<channel id="temp" typeId="temperature"/>
|
|
||||||
<channel id="min" typeId="temperature_min"/>
|
|
||||||
<channel id="max" typeId="temperature_max"/>
|
|
||||||
<channel id="alarm_device" typeId="alarm_device"/>
|
|
||||||
<channel id="alarm_push" typeId="alarm_push"/>
|
|
||||||
<channel id="alarm_openhab" typeId="alarm_openhab"/>
|
|
||||||
<channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
|
|
||||||
<channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
|
|
||||||
<channel id="color" typeId="color"/>
|
|
||||||
<channel id="color_name" typeId="color_name"/>
|
|
||||||
</channels>
|
|
||||||
</channel-group-type>
|
|
||||||
|
|
||||||
<!-- Channel Group Temperature Mini -->
|
|
||||||
<channel-group-type id="cg_temperature_mini">
|
|
||||||
<label>Sensor Mini</label>
|
|
||||||
<category>Sensor</category>
|
|
||||||
<channels>
|
|
||||||
<channel id="name" typeId="name_ro"/>
|
|
||||||
<channel id="temp" typeId="temperature"/>
|
|
||||||
<channel id="min" typeId="temperature_min_ro"/>
|
|
||||||
<channel id="max" typeId="temperature_max_ro"/>
|
|
||||||
<channel id="alarm_device" typeId="alarm_device_ro"/>
|
|
||||||
<channel id="alarm_openhab" typeId="alarm_openhab"/>
|
|
||||||
<channel id="alarm_openhab_low" typeId="alarm_openhab_low"/>
|
|
||||||
<channel id="alarm_openhab_high" typeId="alarm_openhab_high"/>
|
|
||||||
<channel id="color" typeId="color_ro"/>
|
|
||||||
<channel id="color_name" typeId="color_name_ro"/>
|
|
||||||
</channels>
|
|
||||||
</channel-group-type>
|
|
||||||
|
|
||||||
<!-- Fundamental channel types -->
|
|
||||||
<channel-type id="name" advanced="false">
|
|
||||||
<item-type>String</item-type>
|
|
||||||
<label>Probe Name</label>
|
|
||||||
<category>Text</category>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="name_ro" advanced="false">
|
|
||||||
<item-type>String</item-type>
|
|
||||||
<label>Probe Name</label>
|
|
||||||
<category>Text</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="typ" advanced="true">
|
|
||||||
<item-type>String</item-type>
|
|
||||||
<label>Probe Type</label>
|
|
||||||
<category>Text</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="temperature" advanced="false">
|
|
||||||
<item-type>Number:Temperature</item-type>
|
|
||||||
<label>Current Temperature</label>
|
|
||||||
<category>Temperature</category>
|
|
||||||
<state min="0" pattern="%.1f %unit%" readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="temperature_min" advanced="true">
|
|
||||||
<item-type>Number:Temperature</item-type>
|
|
||||||
<label>Low Temperature Alarm</label>
|
|
||||||
<category>Temperature</category>
|
|
||||||
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="temperature_max" advanced="true">
|
|
||||||
<item-type>Number:Temperature</item-type>
|
|
||||||
<label>High Temperature Alarm</label>
|
|
||||||
<category>Temperature</category>
|
|
||||||
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="temperature_min_ro" advanced="true">
|
|
||||||
<item-type>Number:Temperature</item-type>
|
|
||||||
<label>Low Temperature Alarm</label>
|
|
||||||
<category>Temperature</category>
|
|
||||||
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="temperature_max_ro" advanced="true">
|
|
||||||
<item-type>Number:Temperature</item-type>
|
|
||||||
<label>High Temperature Alarm</label>
|
|
||||||
<category>Temperature</category>
|
|
||||||
<state min="0" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="alarm_device" advanced="true">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>Alarm Buzzer</label>
|
|
||||||
<category>Switch</category>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="alarm_device_ro" advanced="true">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>Alarm Buzzer</label>
|
|
||||||
<category>Switch</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="alarm_push" advanced="true">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>Push-Alarm</label>
|
|
||||||
<category>Switch</category>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="alarm_openhab" advanced="true">
|
|
||||||
<kind>trigger</kind>
|
|
||||||
<label>Openhab Alarm Trigger</label>
|
|
||||||
<event>
|
|
||||||
<options>
|
|
||||||
<option value="MIN">Low Temperature Alarm</option>
|
|
||||||
<option value="MAX">High Temperature Alarm</option>
|
|
||||||
</options>
|
|
||||||
</event>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="alarm_openhab_low" advanced="false">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>Low Temperature Alarm</label>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="alarm_openhab_high" advanced="false">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>High Temperature Alarm</label>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="color" advanced="true">
|
|
||||||
<item-type>Color</item-type>
|
|
||||||
<label>Color</label>
|
|
||||||
<category>Colorpicker</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="color_name" advanced="true">
|
|
||||||
<item-type>String</item-type>
|
|
||||||
<label>Probe Color</label>
|
|
||||||
<category>Colorpicker</category>
|
|
||||||
<state>
|
|
||||||
<options>
|
|
||||||
<option value="niagara">Niagara</option>
|
|
||||||
<option value="rosa">Rosa</option>
|
|
||||||
<option value="lapis blue">Lapis Blue</option>
|
|
||||||
<option value="orange">Orange</option>
|
|
||||||
<option value="lila">Lila</option>
|
|
||||||
<option value="red">Red</option>
|
|
||||||
<option value="green">Green</option>
|
|
||||||
<option value="gold">Gold</option>
|
|
||||||
<option value="kale">Kale</option>
|
|
||||||
<option value="brown">Brown</option>
|
|
||||||
</options>
|
|
||||||
</state>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="color_ro" advanced="true">
|
|
||||||
<item-type>Color</item-type>
|
|
||||||
<label>Probe Color</label>
|
|
||||||
<category>Colorpicker</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="color_name_ro" advanced="true">
|
|
||||||
<item-type>String</item-type>
|
|
||||||
<label>Probe Color Name</label>
|
|
||||||
<category>Text</category>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<!-- Pitmaster Mini -->
|
|
||||||
<channel-group-type id="cg_pitmaster_mini">
|
|
||||||
<label>Pitmaster Mini</label>
|
|
||||||
<category>Sensor</category>
|
|
||||||
<channels>
|
|
||||||
<channel id="enabled" typeId="enabled"/>
|
|
||||||
<channel id="current" typeId="temperature"/>
|
|
||||||
<channel id="setpoint" typeId="temperature_setpoint_ro"/>
|
|
||||||
<channel id="duty_cycle" typeId="duty_cycle_ro"/>
|
|
||||||
<channel id="lid_open" typeId="lid_open"/>
|
|
||||||
<channel id="channel_id" typeId="channel_id_ro"/>
|
|
||||||
</channels>
|
|
||||||
</channel-group-type>
|
|
||||||
|
|
||||||
<channel-type id="enabled" advanced="false">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>Pitmaster Enabled</label>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="temperature_setpoint_ro" advanced="false">
|
|
||||||
<item-type>Number:Temperature</item-type>
|
|
||||||
<label>Pitmaster Setpoint Temperature</label>
|
|
||||||
<category>Temperature</category>
|
|
||||||
<state min="0" pattern="%.1f %unit%" readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="duty_cycle_ro" advanced="false">
|
|
||||||
<item-type>Number</item-type>
|
|
||||||
<label>Pitmaster Duty Cycle / Control Out</label>
|
|
||||||
<state min="0" max="100" pattern="%d" readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="lid_open" advanced="false">
|
|
||||||
<item-type>Switch</item-type>
|
|
||||||
<label>Pitmaster Lid Open</label>
|
|
||||||
<state readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="channel_id_ro" advanced="false">
|
|
||||||
<item-type>Number</item-type>
|
|
||||||
<label>Pitmaster Channel ID</label>
|
|
||||||
<state min="0" max="9" pattern="%d" readOnly="true"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<!-- Pitmaster Nano -->
|
|
||||||
<channel-group-type id="cg_pitmaster_nano">
|
|
||||||
<label>Pitmaster Nano</label>
|
|
||||||
<category>Sensor</category>
|
|
||||||
<channels>
|
|
||||||
<channel id="state" typeId="pitmaster_type"/>
|
|
||||||
<channel id="setpoint" typeId="temperature_setpoint"/>
|
|
||||||
<channel id="duty_cycle" typeId="duty_cycle"/>
|
|
||||||
<channel id="channel_id" typeId="channel_id"/>
|
|
||||||
<channel id="pid_id" typeId="pid_id"/>
|
|
||||||
</channels>
|
|
||||||
</channel-group-type>
|
|
||||||
|
|
||||||
<channel-type id="pitmaster_type" advanced="false">
|
|
||||||
<item-type>String</item-type>
|
|
||||||
<label>Pitmaster State</label>
|
|
||||||
<state>
|
|
||||||
<options>
|
|
||||||
<option value="off">Off</option>
|
|
||||||
<option value="manual">Manual</option>
|
|
||||||
<option value="auto">Auto</option>
|
|
||||||
<!--<option value="autotune">Autotune</option> Not clear if still supported -->
|
|
||||||
</options>
|
|
||||||
</state>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="duty_cycle" advanced="false">
|
|
||||||
<item-type>Number</item-type>
|
|
||||||
<label>Pitmaster Duty Cycle / Control Out</label>
|
|
||||||
<state min="0" max="100" pattern="%d"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="pid_id" advanced="false">
|
|
||||||
<item-type>Number</item-type>
|
|
||||||
<label>PID Profile ID</label>
|
|
||||||
<state pattern="%d"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="temperature_setpoint" advanced="false">
|
|
||||||
<item-type>Number:Temperature</item-type>
|
|
||||||
<label>Pitmaster Setpoint Temperature</label>
|
|
||||||
<category>Temperature</category>
|
|
||||||
<state min="0" pattern="%.1f %unit%"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
<channel-type id="channel_id" advanced="false">
|
|
||||||
<item-type>Number</item-type>
|
|
||||||
<label>Pitmaster Channel ID</label>
|
|
||||||
<state min="1" max="8" pattern="%d"/>
|
|
||||||
</channel-type>
|
|
||||||
|
|
||||||
</thing:thing-descriptions>
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.esp32;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.TRIGGER_NONE;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Data;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings.Settings;
|
||||||
|
import org.openhab.core.library.types.*;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.ThingUID;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoEsp32CommandHandlerTest} class tests the {@link WlanThermoEsp32CommandHandler}
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
class WlanThermoEsp32CommandHandlerTest {
|
||||||
|
|
||||||
|
private static final ThingUID THING_UID = new ThingUID("wlanthermo", "esp32", "test");
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Data data;
|
||||||
|
@Nullable
|
||||||
|
private Settings settings;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ClassLoader classLoader = Objects.requireNonNull(WlanThermoEsp32CommandHandlerTest.class.getClassLoader());
|
||||||
|
InputStream dataStream = Objects.requireNonNull(classLoader.getResourceAsStream("esp32/data.json"));
|
||||||
|
InputStream settingsStream = Objects.requireNonNull(classLoader.getResourceAsStream("esp32/settings.json"));
|
||||||
|
data = gson.fromJson(new InputStreamReader(dataStream, StandardCharsets.UTF_8), Data.class);
|
||||||
|
settings = gson.fromJson(new InputStreamReader(settingsStream, StandardCharsets.UTF_8), Settings.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> getState() {
|
||||||
|
return Stream.of(
|
||||||
|
// System channels
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_SOC, new DecimalType(89), null),
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_CHARGE, OnOffType.OFF, null),
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_RSSI_SIGNALSTRENGTH, new DecimalType(4), null),
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_RSSI, new QuantityType<>(-32, Units.DECIBEL_MILLIWATTS), null),
|
||||||
|
|
||||||
|
// All channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_NAME, new StringType("Kanal 10"), null),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "11", CHANNEL_NAME, UnDefType.UNDEF,
|
||||||
|
WlanThermoUnknownChannelException.class),
|
||||||
|
|
||||||
|
// all channel values
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(17, SIUnits.CELSIUS), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(104, SIUnits.CELSIUS), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR,
|
||||||
|
HSBType.fromRGB(Color.decode("#270000").getRed(), Color.decode("#270000").getGreen(),
|
||||||
|
Color.decode("#270000").getBlue()),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME,
|
||||||
|
new StringType(WlanThermoEsp32Util.toColorName("#270000")), null),
|
||||||
|
|
||||||
|
// all pitmaster
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_2, CHANNEL_PITMASTER_CHANNEL_ID, UnDefType.UNDEF, null),
|
||||||
|
|
||||||
|
// all pitmaster values
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(1), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(70), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(50, SIUnits.CELSIUS),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("manual"), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> getTrigger() {
|
||||||
|
return Stream.of(
|
||||||
|
// all channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "11", CHANNEL_ALARM_OPENHAB, "",
|
||||||
|
WlanThermoUnknownChannelException.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> setState() {
|
||||||
|
return Stream.of(
|
||||||
|
// All channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_NAME, new StringType("Kanal 10"), true),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "11", CHANNEL_NAME, new StringType("Kanal 11"), false),
|
||||||
|
|
||||||
|
// all channel values
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal Eins"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(17, SIUnits.CELSIUS), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(104, SIUnits.CELSIUS), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR,
|
||||||
|
HSBType.fromRGB(Color.decode("#270000").getRed(), Color.decode("#270000").getGreen(),
|
||||||
|
Color.decode("#270000").getBlue()),
|
||||||
|
true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME,
|
||||||
|
new StringType(WlanThermoEsp32Util.toColorName("#270000")), true),
|
||||||
|
|
||||||
|
// all pitmaster
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), true),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_2, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), false),
|
||||||
|
|
||||||
|
// all pitmaster values
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), true),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(0), true),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(0), false),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(100, SIUnits.CELSIUS),
|
||||||
|
true),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("off"), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getTrigger")
|
||||||
|
void getTrigger(String groupId, String id, String expectedTrigger,
|
||||||
|
@Nullable Class<WlanThermoException> exceptionClass) {
|
||||||
|
Executable test = () -> Assertions.assertEquals(expectedTrigger, WlanThermoEsp32CommandHandler
|
||||||
|
.getTrigger(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(data)));
|
||||||
|
if (exceptionClass != null) {
|
||||||
|
Assertions.assertThrows(exceptionClass, test);
|
||||||
|
} else {
|
||||||
|
Assertions.assertDoesNotThrow(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getState")
|
||||||
|
void getState(String groupId, String id, State expectedState, @Nullable Class<WlanThermoException> exceptionClass) {
|
||||||
|
Executable test = () -> Assertions.assertEquals(expectedState,
|
||||||
|
WlanThermoEsp32CommandHandler.getState(new ChannelUID(THING_UID, groupId, id),
|
||||||
|
WlanThermoUtil.requireNonNull(data), WlanThermoUtil.requireNonNull(settings)));
|
||||||
|
if (exceptionClass != null) {
|
||||||
|
Assertions.assertThrows(exceptionClass, test);
|
||||||
|
} else {
|
||||||
|
Assertions.assertDoesNotThrow(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("setState")
|
||||||
|
void setState(String groupId, String id, Command command, boolean expectedResult) {
|
||||||
|
Assertions.assertDoesNotThrow(() -> Assertions.assertEquals(expectedResult,
|
||||||
|
WlanThermoEsp32CommandHandler.setState(new ChannelUID(THING_UID, groupId, id), command,
|
||||||
|
WlanThermoUtil.requireNonNull(data), WlanThermoUtil.requireNonNull(settings))));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.mini;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin.App;
|
||||||
|
import org.openhab.core.library.types.*;
|
||||||
|
import org.openhab.core.library.unit.ImperialUnits;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.ThingUID;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoMiniCommandHandlerTest} class tests the {@link WlanThermoMiniCommandHandler}
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
class WlanThermoMiniCommandHandlerTest {
|
||||||
|
|
||||||
|
private static final ThingUID THING_UID = new ThingUID("wlanthermo", "mini", "test");
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private App app;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
ClassLoader classLoader = Objects.requireNonNull(WlanThermoMiniCommandHandlerTest.class.getClassLoader());
|
||||||
|
InputStream stream = Objects.requireNonNull(classLoader.getResourceAsStream("mini/app.json"));
|
||||||
|
app = new Gson().fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), App.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> getState() {
|
||||||
|
return Stream.of(
|
||||||
|
// System channels
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_CPU_TEMP, new DecimalType(93.56), null),
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_CPU_LOAD, new DecimalType(94.267515923567), null),
|
||||||
|
|
||||||
|
// all channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_NAME, new StringType("Kanal0"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal1"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal2"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal3"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal4"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal5"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal6"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal7"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal8 - Maverick 1"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal9 - Maverick 2"), null),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_NAME, UnDefType.UNDEF,
|
||||||
|
WlanThermoUnknownChannelException.class),
|
||||||
|
|
||||||
|
// all channel values
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_NAME, new StringType("Kanal0"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_TEMP, new QuantityType<>(78.28, ImperialUnits.FAHRENHEIT),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_MIN, new QuantityType<>(-20, ImperialUnits.FAHRENHEIT),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_MAX, new QuantityType<>(200, ImperialUnits.FAHRENHEIT),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_DEVICE, OnOffType.from("false"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_COLOR,
|
||||||
|
HSBType.fromRGB(Color.decode(WlanThermoMiniUtil.toHex("green")).getRed(),
|
||||||
|
Color.decode(WlanThermoMiniUtil.toHex("green")).getGreen(),
|
||||||
|
Color.decode(WlanThermoMiniUtil.toHex("green")).getBlue()),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_COLOR_NAME, new StringType("green"), null),
|
||||||
|
|
||||||
|
// all pitmaster
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_ENABLED, OnOffType.from(true), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_2, CHANNEL_PITMASTER_ENABLED, UnDefType.UNDEF, null),
|
||||||
|
|
||||||
|
// all pitmaster values
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_ENABLED, OnOffType.from(true), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CURRENT, new DecimalType(77.86), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT,
|
||||||
|
new QuantityType<>(110, ImperialUnits.FAHRENHEIT), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(100), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_LID_OPEN, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(0), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> getTrigger() {
|
||||||
|
return Stream.of(
|
||||||
|
// all channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "0", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "10", CHANNEL_ALARM_OPENHAB, "",
|
||||||
|
WlanThermoUnknownChannelException.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getTrigger")
|
||||||
|
void getTrigger(String groupId, String id, String expectedTrigger,
|
||||||
|
@Nullable Class<WlanThermoException> exceptionClass) {
|
||||||
|
Executable test = () -> Assertions.assertEquals(expectedTrigger, WlanThermoMiniCommandHandler
|
||||||
|
.getTrigger(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(app)));
|
||||||
|
if (exceptionClass != null) {
|
||||||
|
Assertions.assertThrows(exceptionClass, test);
|
||||||
|
} else {
|
||||||
|
Assertions.assertDoesNotThrow(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getState")
|
||||||
|
void getState(String groupId, String id, State expectedState, @Nullable Class<WlanThermoException> exceptionClass) {
|
||||||
|
Executable test = () -> Assertions.assertEquals(expectedState, WlanThermoMiniCommandHandler
|
||||||
|
.getState(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(app)));
|
||||||
|
if (exceptionClass != null) {
|
||||||
|
Assertions.assertThrows(exceptionClass, test);
|
||||||
|
} else {
|
||||||
|
Assertions.assertDoesNotThrow(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.wlanthermo.internal.api.nano;
|
||||||
|
|
||||||
|
import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.data.Data;
|
||||||
|
import org.openhab.binding.wlanthermo.internal.api.nano.dto.settings.Settings;
|
||||||
|
import org.openhab.core.library.types.*;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.ThingUID;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link WlanThermoNanoV1CommandHandlerTest} class tests the {@link WlanThermoNanoV1CommandHandler}
|
||||||
|
*
|
||||||
|
* @author Christian Schlipp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
class WlanThermoNanoV1CommandHandlerTest {
|
||||||
|
private static final ThingUID THING_UID = new ThingUID("wlanthermo", "nano", "test");
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Data data;
|
||||||
|
@Nullable
|
||||||
|
private Settings settings;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ClassLoader classLoader = Objects.requireNonNull(WlanThermoNanoV1CommandHandlerTest.class.getClassLoader());
|
||||||
|
InputStream dataStream = Objects.requireNonNull(classLoader.getResourceAsStream("nanov1/data.json"));
|
||||||
|
InputStream settingsStream = Objects.requireNonNull(classLoader.getResourceAsStream("nanov1/settings.json"));
|
||||||
|
data = gson.fromJson(new InputStreamReader(dataStream, StandardCharsets.UTF_8), Data.class);
|
||||||
|
settings = gson.fromJson(new InputStreamReader(settingsStream, StandardCharsets.UTF_8), Settings.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> getState() {
|
||||||
|
return Stream.of(
|
||||||
|
// System channels
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_SOC, new DecimalType(32), null),
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_CHARGE, OnOffType.OFF, null),
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_RSSI_SIGNALSTRENGTH, new DecimalType(4), null),
|
||||||
|
Arguments.of(SYSTEM, SYSTEM_RSSI, new QuantityType<>(-47, Units.DECIBEL_MILLIWATTS), null),
|
||||||
|
|
||||||
|
// All channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), null),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"),
|
||||||
|
WlanThermoUnknownChannelException.class),
|
||||||
|
|
||||||
|
// all channel values
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(11, SIUnits.CELSIUS), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(155, SIUnits.CELSIUS), null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR,
|
||||||
|
HSBType.fromRGB(Color.decode("#EF562D").getRed(), Color.decode("#EF562D").getGreen(),
|
||||||
|
Color.decode("#EF562D").getBlue()),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME,
|
||||||
|
new StringType(WlanThermoNanoV1Util.toColorName("#EF562D")), null),
|
||||||
|
|
||||||
|
// all pitmaster values
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(0), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(0), null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(50, SIUnits.CELSIUS),
|
||||||
|
null),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("off"), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> getTrigger() {
|
||||||
|
return Stream.of(
|
||||||
|
// all channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_ALARM_OPENHAB, TRIGGER_NONE, null),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_ALARM_OPENHAB, "", WlanThermoUnknownChannelException.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> setState() {
|
||||||
|
return Stream.of(
|
||||||
|
// All channels
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "2", CHANNEL_NAME, new StringType("Kanal 2"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "3", CHANNEL_NAME, new StringType("Kanal 3"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "4", CHANNEL_NAME, new StringType("Kanal 4"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "5", CHANNEL_NAME, new StringType("Kanal 5"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "6", CHANNEL_NAME, new StringType("Kanal 6"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "7", CHANNEL_NAME, new StringType("Kanal 7"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "8", CHANNEL_NAME, new StringType("Kanal 8"), true),
|
||||||
|
// invalid channel number
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "9", CHANNEL_NAME, new StringType("Kanal 9"), false),
|
||||||
|
|
||||||
|
// all channel values
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_NAME, new StringType("Kanal 1"), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TYP, new StringType("1000K/Maverick"), false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_TEMP, new QuantityType<>(23.7, SIUnits.CELSIUS), false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MIN, new QuantityType<>(11, SIUnits.CELSIUS), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_MAX, new QuantityType<>(155, SIUnits.CELSIUS), true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_DEVICE, OnOffType.OFF, true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_PUSH, OnOffType.ON, true),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_HIGH, OnOffType.OFF, false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_ALARM_OPENHAB_LOW, OnOffType.OFF, false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR,
|
||||||
|
HSBType.fromRGB(Color.decode("#EF562D").getRed(), Color.decode("#EF562D").getGreen(),
|
||||||
|
Color.decode("#EF562D").getBlue()),
|
||||||
|
false),
|
||||||
|
Arguments.of(CHANNEL_PREFIX + "1", CHANNEL_COLOR_NAME,
|
||||||
|
new StringType(WlanThermoNanoV1Util.toColorName("#EF562D")), true),
|
||||||
|
|
||||||
|
// all pitmaster values
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_CHANNEL_ID, new DecimalType(1), true),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_PIDPROFILE, new DecimalType(0), true),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_DUTY_CYCLE, new DecimalType(0), false),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_SETPOINT, new QuantityType<>(50, SIUnits.CELSIUS),
|
||||||
|
true),
|
||||||
|
Arguments.of(CHANNEL_PITMASTER_1, CHANNEL_PITMASTER_STATE, new StringType("off"), true)
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getTrigger")
|
||||||
|
void getTrigger(String groupId, String id, String expectedTrigger,
|
||||||
|
@Nullable Class<WlanThermoException> exceptionClass) {
|
||||||
|
Executable test = () -> Assertions.assertEquals(expectedTrigger, WlanThermoNanoV1CommandHandler
|
||||||
|
.getTrigger(new ChannelUID(THING_UID, groupId, id), WlanThermoUtil.requireNonNull(data)));
|
||||||
|
if (exceptionClass != null) {
|
||||||
|
Assertions.assertThrows(exceptionClass, test);
|
||||||
|
} else {
|
||||||
|
Assertions.assertDoesNotThrow(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getState")
|
||||||
|
void getState(String groupId, String id, State expectedState, @Nullable Class<WlanThermoException> exceptionClass) {
|
||||||
|
Executable test = () -> Assertions.assertEquals(expectedState,
|
||||||
|
WlanThermoNanoV1CommandHandler.getState(new ChannelUID(THING_UID, groupId, id),
|
||||||
|
WlanThermoUtil.requireNonNull(data), WlanThermoUtil.requireNonNull(settings)));
|
||||||
|
if (exceptionClass != null) {
|
||||||
|
Assertions.assertThrows(exceptionClass, test);
|
||||||
|
} else {
|
||||||
|
Assertions.assertDoesNotThrow(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("setState")
|
||||||
|
void setState(String groupId, String id, Command command, boolean expectedResult) {
|
||||||
|
Assertions.assertDoesNotThrow(() -> Assertions.assertEquals(expectedResult, WlanThermoNanoV1CommandHandler
|
||||||
|
.setState(new ChannelUID(THING_UID, groupId, id), command, WlanThermoUtil.requireNonNull(data))));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
{
|
||||||
|
"system": {
|
||||||
|
"time": "1610894101",
|
||||||
|
"unit": "C",
|
||||||
|
"soc": 89,
|
||||||
|
"charge": false,
|
||||||
|
"rssi": -32,
|
||||||
|
"online": 0
|
||||||
|
},
|
||||||
|
"channel": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"name": "Kanal Eins",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 23.7,
|
||||||
|
"min": 17,
|
||||||
|
"max": 104,
|
||||||
|
"alarm": 1,
|
||||||
|
"color": "#270000",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"name": "Kanal 2",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#22B14C",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 3,
|
||||||
|
"name": "Kanal 3",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#EF562D",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 4,
|
||||||
|
"name": "Kanal 4",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#FFC100",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 5,
|
||||||
|
"name": "Kanal 5",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#A349A4",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 6,
|
||||||
|
"name": "Kanal 6",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#804000",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 7,
|
||||||
|
"name": "Kanal 7",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 23.7,
|
||||||
|
"min": 10,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#5587A2",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 8,
|
||||||
|
"name": "Kanal 8",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#5C7148",
|
||||||
|
"fixed": false,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 9,
|
||||||
|
"name": "Kanal 9",
|
||||||
|
"typ": 16,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#A349A4",
|
||||||
|
"fixed": true,
|
||||||
|
"connected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 10,
|
||||||
|
"name": "Kanal 10",
|
||||||
|
"typ": 16,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 50,
|
||||||
|
"max": 95,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#5587A2",
|
||||||
|
"fixed": true,
|
||||||
|
"connected": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pitmaster": {
|
||||||
|
"type": [
|
||||||
|
"off",
|
||||||
|
"manual",
|
||||||
|
"auto"
|
||||||
|
],
|
||||||
|
"pm": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"channel": 1,
|
||||||
|
"pid": 1,
|
||||||
|
"value": 70,
|
||||||
|
"set": 50,
|
||||||
|
"typ": "manual",
|
||||||
|
"set_color": "#ff0000",
|
||||||
|
"value_color": "#000000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,229 @@
|
||||||
|
{
|
||||||
|
"device": {
|
||||||
|
"device": "nano",
|
||||||
|
"serial": "98f4ab7570c0",
|
||||||
|
"cpu": "esp32",
|
||||||
|
"flash_size": 16777216,
|
||||||
|
"item": "n3j04oA200B",
|
||||||
|
"hw_version": "v3",
|
||||||
|
"sw_version": "v1.1.0",
|
||||||
|
"api_version": "1",
|
||||||
|
"language": "de"
|
||||||
|
},
|
||||||
|
"system": {
|
||||||
|
"time": "1610894186",
|
||||||
|
"unit": "C",
|
||||||
|
"ap": "WLANTHERMO-AP",
|
||||||
|
"host": "NANO-98f4ab7570c0",
|
||||||
|
"language": "de",
|
||||||
|
"version": "v1.1.0",
|
||||||
|
"getupdate": "false",
|
||||||
|
"autoupd": true,
|
||||||
|
"prerelease": true,
|
||||||
|
"hwversion": "V3"
|
||||||
|
},
|
||||||
|
"hardware": [
|
||||||
|
"V3"
|
||||||
|
],
|
||||||
|
"api": {
|
||||||
|
"version": "1"
|
||||||
|
},
|
||||||
|
"sensors": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"name": "1000K/Maverick",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 1,
|
||||||
|
"name": "Fantast-Neu",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 2,
|
||||||
|
"name": "Fantast",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 3,
|
||||||
|
"name": "100K/iGrill2",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 4,
|
||||||
|
"name": "ET-73",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 5,
|
||||||
|
"name": "Perfektion",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 6,
|
||||||
|
"name": "50K",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 7,
|
||||||
|
"name": "Inkbird",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 8,
|
||||||
|
"name": "100K6A1B",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 9,
|
||||||
|
"name": "Weber_6743",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 10,
|
||||||
|
"name": "Santos",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 11,
|
||||||
|
"name": "5K3A1B",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 12,
|
||||||
|
"name": "PT100",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 13,
|
||||||
|
"name": "PT1000",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 14,
|
||||||
|
"name": "ThermoWorks",
|
||||||
|
"fixed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 15,
|
||||||
|
"name": "Typ K",
|
||||||
|
"fixed": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 16,
|
||||||
|
"name": "Bluetooth",
|
||||||
|
"fixed": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 17,
|
||||||
|
"name": "Maverick",
|
||||||
|
"fixed": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"features": {
|
||||||
|
"bluetooth": true,
|
||||||
|
"pitmaster": true
|
||||||
|
},
|
||||||
|
"pid": [
|
||||||
|
{
|
||||||
|
"name": "SSR SousVide",
|
||||||
|
"id": 0,
|
||||||
|
"aktor": 0,
|
||||||
|
"Kp": 104,
|
||||||
|
"Ki": 0.2,
|
||||||
|
"Kd": 0,
|
||||||
|
"DCmmin": 0,
|
||||||
|
"DCmmax": 100,
|
||||||
|
"opl": 0,
|
||||||
|
"SPmin": 0,
|
||||||
|
"SPmax": 0,
|
||||||
|
"link": 0,
|
||||||
|
"tune": 0,
|
||||||
|
"jp": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TITAN 50x50",
|
||||||
|
"id": 1,
|
||||||
|
"aktor": 1,
|
||||||
|
"Kp": 7,
|
||||||
|
"Ki": 0.01,
|
||||||
|
"Kd": 128,
|
||||||
|
"DCmmin": 25,
|
||||||
|
"DCmmax": 100,
|
||||||
|
"opl": 0,
|
||||||
|
"SPmin": 0,
|
||||||
|
"SPmax": 0,
|
||||||
|
"link": 0,
|
||||||
|
"tune": 0,
|
||||||
|
"jp": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Servo MG995",
|
||||||
|
"id": 2,
|
||||||
|
"aktor": 2,
|
||||||
|
"Kp": 104,
|
||||||
|
"Ki": 0.2,
|
||||||
|
"Kd": 0,
|
||||||
|
"DCmmin": 0,
|
||||||
|
"DCmmax": 100,
|
||||||
|
"opl": 0,
|
||||||
|
"SPmin": 25,
|
||||||
|
"SPmax": 75,
|
||||||
|
"link": 0,
|
||||||
|
"tune": 0,
|
||||||
|
"jp": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Custom",
|
||||||
|
"id": 3,
|
||||||
|
"aktor": 1,
|
||||||
|
"Kp": 7,
|
||||||
|
"Ki": 0.2,
|
||||||
|
"Kd": 0,
|
||||||
|
"DCmmin": 0,
|
||||||
|
"DCmmax": 100,
|
||||||
|
"opl": 0,
|
||||||
|
"SPmin": 0,
|
||||||
|
"SPmax": 100,
|
||||||
|
"link": 0,
|
||||||
|
"tune": 0,
|
||||||
|
"jp": 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"aktor": [
|
||||||
|
"SSR",
|
||||||
|
"FAN",
|
||||||
|
"SERVO"
|
||||||
|
],
|
||||||
|
"display": {
|
||||||
|
"updname": "",
|
||||||
|
"orientation": 0
|
||||||
|
},
|
||||||
|
"iot": {
|
||||||
|
"PMQhost": "192.168.2.1",
|
||||||
|
"PMQport": 1883,
|
||||||
|
"PMQuser": "",
|
||||||
|
"PMQpass": "",
|
||||||
|
"PMQqos": 0,
|
||||||
|
"PMQon": false,
|
||||||
|
"PMQint": 30,
|
||||||
|
"CLon": false,
|
||||||
|
"CLtoken": "thisisnotatoken",
|
||||||
|
"CLint": 30,
|
||||||
|
"CLurl": "cloud.wlanthermo.de/index.html"
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"fcm": [],
|
||||||
|
"ext": {
|
||||||
|
"on": 0,
|
||||||
|
"token": "",
|
||||||
|
"id": "",
|
||||||
|
"repeat": 1,
|
||||||
|
"service": 0,
|
||||||
|
"services": [
|
||||||
|
"telegram",
|
||||||
|
"pushover"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
{
|
||||||
|
"temp_unit": "fahrenheit",
|
||||||
|
"pit": {
|
||||||
|
"enabled": true,
|
||||||
|
"timestamp": "2020-05-29T17:00:54-05:00",
|
||||||
|
"setpoint": 110,
|
||||||
|
"current": 77.86,
|
||||||
|
"control_out": 100,
|
||||||
|
"ch": 0,
|
||||||
|
"type": "False",
|
||||||
|
"open_lid": "False"
|
||||||
|
},
|
||||||
|
"pit2": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"cpu_load": 94.267515923567,
|
||||||
|
"cpu_temp": 93.56,
|
||||||
|
"channel": {
|
||||||
|
"0": {
|
||||||
|
"temp": 78.28,
|
||||||
|
"color": "green",
|
||||||
|
"state": "ok",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal0",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "red",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal1",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "blue",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal2",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "olive",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal3",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "magenta",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal4",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "yellow",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal5",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "violet",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal6",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "purple",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal7",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"8": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "dark-violet",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal8 - Maverick 1",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
"9": {
|
||||||
|
"temp": 0,
|
||||||
|
"color": "seagreen",
|
||||||
|
"state": "er",
|
||||||
|
"temp_min": -20,
|
||||||
|
"temp_max": 200,
|
||||||
|
"name": "Kanal9 - Maverick 2",
|
||||||
|
"alert": false,
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"timestamp": "2020-05-29T16:06:00-05:00"
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
{
|
||||||
|
"system": {
|
||||||
|
"time": "1610899485",
|
||||||
|
"unit": "C",
|
||||||
|
"soc": 32,
|
||||||
|
"charge": false,
|
||||||
|
"rssi": -47,
|
||||||
|
"online": 0
|
||||||
|
},
|
||||||
|
"channel": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"name": "Kanal 1",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 23.7,
|
||||||
|
"min": 11,
|
||||||
|
"max": 155,
|
||||||
|
"alarm": 1,
|
||||||
|
"color": "#EF562D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"name": "Kanal 2",
|
||||||
|
"typ": 3,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 0,
|
||||||
|
"max": 48,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#22B14C"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 3,
|
||||||
|
"name": "Kanal 3",
|
||||||
|
"typ": 3,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 10,
|
||||||
|
"max": 35,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#EF562D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 4,
|
||||||
|
"name": "Kanal 4",
|
||||||
|
"typ": 3,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 10,
|
||||||
|
"max": 54,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#FFC100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 5,
|
||||||
|
"name": "Kanal 5",
|
||||||
|
"typ": 3,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 0,
|
||||||
|
"max": 69,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#A349A4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 6,
|
||||||
|
"name": "Kanal 6",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 150,
|
||||||
|
"max": 170,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#804000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 7,
|
||||||
|
"name": "Kanal 7",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 23.6,
|
||||||
|
"min": 0,
|
||||||
|
"max": 54,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#5587A2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 8,
|
||||||
|
"name": "Kanal 8",
|
||||||
|
"typ": 0,
|
||||||
|
"temp": 999,
|
||||||
|
"min": 10,
|
||||||
|
"max": 35,
|
||||||
|
"alarm": 0,
|
||||||
|
"color": "#5C7148"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pitmaster": {
|
||||||
|
"type": [
|
||||||
|
"off"
|
||||||
|
],
|
||||||
|
"pm": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"channel": 1,
|
||||||
|
"pid": 0,
|
||||||
|
"value": 0,
|
||||||
|
"set": 50,
|
||||||
|
"typ": "off",
|
||||||
|
"set_color": "#ff0000",
|
||||||
|
"value_color": "#000000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
{
|
||||||
|
"device": {
|
||||||
|
"device": "nano",
|
||||||
|
"serial": "33e8bb",
|
||||||
|
"item": "n2E04o42000",
|
||||||
|
"hw_version": "v2",
|
||||||
|
"sw_version": "v1.0.6",
|
||||||
|
"api_version": "1",
|
||||||
|
"language": "de"
|
||||||
|
},
|
||||||
|
"system": {
|
||||||
|
"time": "1610899506",
|
||||||
|
"unit": "C",
|
||||||
|
"ap": "NANO-AP",
|
||||||
|
"host": "NANO-33e8bb",
|
||||||
|
"language": "de",
|
||||||
|
"version": "v1.0.6",
|
||||||
|
"getupdate": "false",
|
||||||
|
"autoupd": true,
|
||||||
|
"hwversion": "V1+",
|
||||||
|
"god": 0
|
||||||
|
},
|
||||||
|
"hardware": [
|
||||||
|
"V1",
|
||||||
|
"V1+"
|
||||||
|
],
|
||||||
|
"api": {
|
||||||
|
"version": "1"
|
||||||
|
},
|
||||||
|
"sensors": [
|
||||||
|
"1000K/Maverick",
|
||||||
|
"Fantast-Neu",
|
||||||
|
"Fantast",
|
||||||
|
"100K/iGrill2",
|
||||||
|
"ET-73",
|
||||||
|
"Perfektion",
|
||||||
|
"50K",
|
||||||
|
"Inkbird",
|
||||||
|
"100K6A1B",
|
||||||
|
"Weber_6743",
|
||||||
|
"Santos",
|
||||||
|
"5K3A1B"
|
||||||
|
],
|
||||||
|
"pid": [
|
||||||
|
{
|
||||||
|
"name": "SSR SousVide",
|
||||||
|
"id": 0,
|
||||||
|
"aktor": 0,
|
||||||
|
"Kp": 104,
|
||||||
|
"Ki": 0.2,
|
||||||
|
"Kd": 0,
|
||||||
|
"DCmmin": 0,
|
||||||
|
"DCmmax": 100,
|
||||||
|
"opl": 0,
|
||||||
|
"tune": 0,
|
||||||
|
"jp": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TITAN 50x50",
|
||||||
|
"id": 1,
|
||||||
|
"aktor": 1,
|
||||||
|
"Kp": 3.8,
|
||||||
|
"Ki": 0.01,
|
||||||
|
"Kd": 128,
|
||||||
|
"DCmmin": 25,
|
||||||
|
"DCmmax": 100,
|
||||||
|
"opl": 0,
|
||||||
|
"tune": 0,
|
||||||
|
"jp": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kamado 50x50",
|
||||||
|
"id": 2,
|
||||||
|
"aktor": 1,
|
||||||
|
"Kp": 7,
|
||||||
|
"Ki": 0.02,
|
||||||
|
"Kd": 630,
|
||||||
|
"DCmmin": 25,
|
||||||
|
"DCmmax": 100,
|
||||||
|
"opl": 0,
|
||||||
|
"tune": 0,
|
||||||
|
"jp": 70
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"aktor": [
|
||||||
|
"SSR",
|
||||||
|
"FAN",
|
||||||
|
"SERVO"
|
||||||
|
],
|
||||||
|
"iot": {
|
||||||
|
"PMQhost": "192.168.2.1",
|
||||||
|
"PMQport": 1883,
|
||||||
|
"PMQuser": "",
|
||||||
|
"PMQpass": "",
|
||||||
|
"PMQqos": 0,
|
||||||
|
"PMQon": false,
|
||||||
|
"PMQint": 30,
|
||||||
|
"CLon": false,
|
||||||
|
"CLtoken": "thisisnotatoken",
|
||||||
|
"CLint": 30,
|
||||||
|
"CLurl": "cloud.wlanthermo.de/index.html"
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"fcm": [],
|
||||||
|
"ext": {
|
||||||
|
"on": 0,
|
||||||
|
"token": "",
|
||||||
|
"id": "",
|
||||||
|
"repeat": 1,
|
||||||
|
"service": 0,
|
||||||
|
"services": [
|
||||||
|
"telegram",
|
||||||
|
"pushover"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue