[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;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
|
@ -27,11 +28,17 @@ public class WlanThermoBindingConstants {
|
|||
private static final String BINDING_ID = "wlanthermo";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_WLANTHERMO_NANO = new ThingTypeUID(BINDING_ID, "nano");
|
||||
public static final ThingTypeUID THING_TYPE_WLANTHERMO_NANO_V1 = new ThingTypeUID(BINDING_ID, "nano");
|
||||
public static final ThingTypeUID THING_TYPE_WLANTHERMO_MINI = new ThingTypeUID(BINDING_ID, "mini");
|
||||
public static final ThingTypeUID THING_TYPE_WLANTHERMO_ESP32 = new ThingTypeUID(BINDING_ID, "esp32");
|
||||
|
||||
// ThreadPool
|
||||
public static final String WLANTHERMO_THREAD_POOL = "wlanthermo";
|
||||
// Properties
|
||||
public static final String PROPERTY_MODEL = "model";
|
||||
public static final String PROPERTY_SERIAL = "serial";
|
||||
public static final String PROPERTY_ESP32_BT_ENABLED = "esp32_bt_enabled";
|
||||
public static final String PROPERTY_ESP32_PM_ENABLED = "esp32_pm_enabled";
|
||||
public static final String PROPERTY_ESP32_TEMP_CHANNELS = "esp32_temp_channels";
|
||||
public static final String PROPERTY_ESP32_PM_CHANNELS = "esp32_pm_channels";
|
||||
|
||||
// List of all Channel ids
|
||||
// System Channels
|
||||
|
@ -43,16 +50,7 @@ public class WlanThermoBindingConstants {
|
|||
public static final String SYSTEM_CPU_LOAD = "cpu_load";
|
||||
public static final String SYSTEM_CPU_TEMP = "cpu_temp";
|
||||
|
||||
public static final String CHANNEL0 = "channel0";
|
||||
public static final String CHANNEL1 = "channel1";
|
||||
public static final String CHANNEL2 = "channel2";
|
||||
public static final String CHANNEL3 = "channel3";
|
||||
public static final String CHANNEL4 = "channel4";
|
||||
public static final String CHANNEL5 = "channel5";
|
||||
public static final String CHANNEL6 = "channel6";
|
||||
public static final String CHANNEL7 = "channel7";
|
||||
public static final String CHANNEL8 = "channel8";
|
||||
public static final String CHANNEL9 = "channel9";
|
||||
public static final String CHANNEL_PREFIX = "channel";
|
||||
|
||||
public static final String CHANNEL_NAME = "name";
|
||||
public static final String CHANNEL_TYP = "typ";
|
||||
|
@ -67,6 +65,9 @@ public class WlanThermoBindingConstants {
|
|||
public static final String CHANNEL_COLOR = "color";
|
||||
public static final String CHANNEL_COLOR_NAME = "color_name";
|
||||
|
||||
public static final String CHANNEL_PITMASTER_PREFIX = "pit";
|
||||
public static final String CHANNEL_PITMASTER_1 = "pit1";
|
||||
public static final String CHANNEL_PITMASTER_2 = "pit2";
|
||||
public static final String CHANNEL_PITMASTER_ENABLED = "enabled"; // Mini
|
||||
public static final String CHANNEL_PITMASTER_CURRENT = "current"; // Mini
|
||||
public static final String CHANNEL_PITMASTER_SETPOINT = "setpoint"; // Mini+Nano
|
||||
|
@ -76,7 +77,12 @@ public class WlanThermoBindingConstants {
|
|||
public static final String CHANNEL_PITMASTER_STATE = "state"; // Nano
|
||||
public static final String CHANNEL_PITMASTER_PIDPROFILE = "pid_id"; // Nano
|
||||
|
||||
public static final String TRIGGER_ALARM_OFF = "OFF";
|
||||
public static final String TRIGGER_NONE = "";
|
||||
public static final String TRIGGER_ALARM_MIN = "MIN";
|
||||
public static final String TRIGGER_ALARM_MAX = "MAX";
|
||||
|
||||
public static final DecimalType SIGNAL_STRENGTH_4 = new DecimalType(4);
|
||||
public static final DecimalType SIGNAL_STRENGTH_3 = new DecimalType(3);
|
||||
public static final DecimalType SIGNAL_STRENGTH_2 = new DecimalType(2);
|
||||
public static final DecimalType SIGNAL_STRENGTH_1 = new DecimalType(1);
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ import java.net.URISyntaxException;
|
|||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link WlanThermoMiniConfiguration} class contains fields mapping thing configuration parameters.
|
||||
* The {@link WlanThermoConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Christian Schlipp - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class WlanThermoMiniConfiguration {
|
||||
public class WlanThermoConfiguration {
|
||||
|
||||
/**
|
||||
* IP Address of WlanThermo.
|
|
@ -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.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.wlanthermo.internal.api.esp32.WlanThermoEsp32Handler;
|
||||
import org.openhab.binding.wlanthermo.internal.api.mini.WlanThermoMiniHandler;
|
||||
import org.openhab.binding.wlanthermo.internal.api.nano.WlanThermoNanoV1Handler;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
@ -40,8 +43,9 @@ import org.osgi.service.component.annotations.Reference;
|
|||
public class WlanThermoHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<ThingTypeUID>(
|
||||
Arrays.asList(WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO,
|
||||
WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI));
|
||||
Arrays.asList(WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO_V1,
|
||||
WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI,
|
||||
WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_ESP32));
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
|
@ -58,10 +62,12 @@ public class WlanThermoHandlerFactory extends BaseThingHandlerFactory {
|
|||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO.equals(thingTypeUID)) {
|
||||
return new WlanThermoNanoHandler(thing, httpClient);
|
||||
if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_NANO_V1.equals(thingTypeUID)) {
|
||||
return new WlanThermoNanoV1Handler(thing, httpClient);
|
||||
} else if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_MINI.equals(thingTypeUID)) {
|
||||
return new WlanThermoMiniHandler(thing, httpClient);
|
||||
} else if (WlanThermoBindingConstants.THING_TYPE_WLANTHERMO_ESP32.equals(thingTypeUID)) {
|
||||
return new WlanThermoEsp32Handler(thing, httpClient);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||
|
||||
/**
|
||||
* The {@link UtilMini} class provides conversion functions for the WlanThermo Mini
|
||||
* The {@link WlanThermoMiniUtil} class provides conversion functions for the WlanThermo Mini
|
||||
*
|
||||
* @author Christian Schlipp - Initial contribution
|
||||
*/
|
||||
public class UtilMini {
|
||||
@NonNullByDefault
|
||||
public class WlanThermoMiniUtil extends WlanThermoUtil {
|
||||
private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
|
||||
private static final String DEFAULT_HEX = "#ffffff";
|
||||
|
||||
private UtilMini() {
|
||||
private WlanThermoMiniUtil() {
|
||||
// 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
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.builtin;
|
||||
package org.openhab.binding.wlanthermo.internal.api.mini.dto.builtin;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -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.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
|
||||
|
||||
/**
|
||||
* The {@link UtilNano} class provides conversion functions for the WlanThermo Nano
|
||||
* The {@link WlanThermoNanoV1Util} class provides conversion functions for the WlanThermo Nano V1+
|
||||
*
|
||||
* @author Christian Schlipp - Initial contribution
|
||||
*/
|
||||
public class UtilNano {
|
||||
@NonNullByDefault
|
||||
public class WlanThermoNanoV1Util extends WlanThermoUtil {
|
||||
|
||||
private static final Map<String, String> COLOR_MAPPINGS = createColorMap();
|
||||
private static final String DEFAULT_HEX = "#ffffff";
|
||||
private static final String DEFAULT_COLORNAME = "niagara";
|
||||
|
||||
private UtilNano() {
|
||||
private WlanThermoNanoV1Util() {
|
||||
// hidden
|
||||
}
|
||||
|
||||
|
@ -56,18 +60,6 @@ public class UtilNano {
|
|||
}
|
||||
|
||||
public static String toColorName(String colorHex) {
|
||||
String colorName = null;
|
||||
if (!colorHex.startsWith("#")) {
|
||||
colorHex = "#" + colorHex;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : COLOR_MAPPINGS.entrySet()) {
|
||||
if (entry.getValue().equalsIgnoreCase(colorHex)) {
|
||||
colorName = entry.getKey();
|
||||
}
|
||||
}
|
||||
if (colorName == null) {
|
||||
colorName = DEFAULT_COLORNAME;
|
||||
}
|
||||
return colorName;
|
||||
return toColorName(colorHex, COLOR_MAPPINGS, DEFAULT_COLORNAME);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.data;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.data;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.settings;
|
||||
package org.openhab.binding.wlanthermo.internal.api.nano.dto.settings;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
|
@ -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