added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.neohub-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-neohub" description="NeoHub Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.neohub/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link NeoBaseConfiguration} class contains the thing configuration
|
||||
* parameters for NeoStat and NeoPlug devices
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoBaseConfiguration {
|
||||
public String deviceNameInHub = "";
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData.AbstractRecord;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.BridgeHandler;
|
||||
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;
|
||||
|
||||
/**
|
||||
* The {@link NeoBaseHandler} is the openHAB Handler for NeoPlug devices
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoBaseHandler extends BaseThingHandler {
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(NeoBaseHandler.class);
|
||||
|
||||
protected @Nullable NeoBaseConfiguration config;
|
||||
|
||||
/*
|
||||
* error messages
|
||||
*/
|
||||
private static final String MSG_FMT_DEVICE_CONFIG = "device \"{}\" needs to configured in hub!";
|
||||
private static final String MSG_FMT_DEVICE_COMM = "device \"{}\" not communicating with hub!";
|
||||
private static final String MSG_FMT_COMMAND_OK = "command for \"{}\" succeeded.";
|
||||
private static final String MSG_FMT_COMMAND_BAD = "\"{}\" is an invalid or empty command!";
|
||||
private static final String MSG_DEVICE_NAME_NOT_CONFIGURED = "the parameter \"deviceNameInHub\" is not configured";
|
||||
|
||||
/*
|
||||
* an object used to de-bounce state changes between openHAB and the NeoHub
|
||||
*/
|
||||
protected NeoHubDebouncer debouncer = new NeoHubDebouncer();
|
||||
|
||||
public NeoBaseHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
// ======== BaseThingHandler methods that are overridden =============
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
@Nullable
|
||||
NeoHubHandler hub;
|
||||
|
||||
if ((hub = getNeoHub()) != null) {
|
||||
if (command == RefreshType.REFRESH) {
|
||||
hub.startFastPollingBurst();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
toNeoHubSendCommandSet(channelUID.getId(), command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
NeoBaseConfiguration config = getConfigAs(NeoBaseConfiguration.class);
|
||||
|
||||
if (config.deviceNameInHub.isEmpty()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, MSG_DEVICE_NAME_NOT_CONFIGURED);
|
||||
return;
|
||||
}
|
||||
|
||||
this.config = config;
|
||||
|
||||
NeoHubHandler hub = getNeoHub();
|
||||
if (hub == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, MSG_HUB_CONFIG);
|
||||
return;
|
||||
}
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.CONFIGURATION_PENDING);
|
||||
}
|
||||
|
||||
// ======== helper methods used by this class or descendants ===========
|
||||
|
||||
/*
|
||||
* this method is called back by the NeoHub handler to inform this handler about
|
||||
* polling results from the hub handler
|
||||
*/
|
||||
public void toBaseSendPollResponse(NeoHubAbstractDeviceData deviceData) {
|
||||
NeoBaseConfiguration config = this.config;
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractRecord deviceRecord = deviceData.getDeviceRecord(config.deviceNameInHub);
|
||||
|
||||
if (deviceRecord == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
logger.warn(MSG_FMT_DEVICE_CONFIG, thing.getLabel());
|
||||
return;
|
||||
}
|
||||
|
||||
ThingStatus thingStatus = getThing().getStatus();
|
||||
if (deviceRecord.offline() && (thingStatus == ThingStatus.ONLINE)) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
logger.debug(MSG_FMT_DEVICE_COMM, thing.getLabel());
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!deviceRecord.offline()) && (thingStatus != ThingStatus.ONLINE)) {
|
||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
|
||||
}
|
||||
|
||||
toOpenHabSendChannelValues(deviceRecord);
|
||||
}
|
||||
|
||||
/*
|
||||
* internal method used by by sendChannelValuesToOpenHab(); it checks the
|
||||
* de-bouncer before actually sending the channel value to openHAB; or if the
|
||||
* device has lost its connection to the RF mesh, either a) send no updates to
|
||||
* OpenHAB or b) send state = undefined, depending on the value of a
|
||||
* Configuration Parameter
|
||||
*/
|
||||
protected void toOpenHabSendValueDebounced(String channelId, State state, boolean offline) {
|
||||
/*
|
||||
* if the device has been lost from the RF mesh network there are two possible
|
||||
* behaviors: either a) do not report a state value, or b) show an undefined
|
||||
* state; the choice of a) or b) depends on whether the channel has the
|
||||
* Configuration Parameter holdOnlineState=true
|
||||
*/
|
||||
if (!offline) {
|
||||
if (debouncer.timeExpired(channelId)) {
|
||||
/*
|
||||
* in normal circumstances just forward the hub's reported state to OpenHAB
|
||||
*/
|
||||
updateState(channelId, state);
|
||||
}
|
||||
} else {
|
||||
ChannelUID channelUID = new ChannelUID(thing.getUID(), channelId);
|
||||
Channel channel = thing.getChannel(channelUID);
|
||||
if (channel != null) {
|
||||
Configuration config = channel.getConfiguration();
|
||||
Object holdOnlineState = config.get(PARAM_HOLD_ONLINE_STATE);
|
||||
if (holdOnlineState != null && (holdOnlineState instanceof Boolean)
|
||||
&& ((Boolean) holdOnlineState).booleanValue()) {
|
||||
/*
|
||||
* the Configuration Parameter "holdOnlineState" is True so do NOT send a
|
||||
* state update to OpenHAB
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* the Configuration Parameter "holdOnlineState" is either not existing or
|
||||
* it is False so send a state=undefined update to OpenHAB
|
||||
*/
|
||||
updateState(channelUID, UnDefType.UNDEF);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sends a channel command & value from openHAB => NeoHub. It delegates upwards
|
||||
* to the NeoHub to handle the command
|
||||
*/
|
||||
protected void toNeoHubSendCommand(String channelId, Command command) {
|
||||
String cmdStr = toNeoHubBuildCommandString(channelId, command);
|
||||
|
||||
if (!cmdStr.isEmpty()) {
|
||||
NeoHubHandler hub = getNeoHub();
|
||||
|
||||
if (hub != null) {
|
||||
/*
|
||||
* issue command, check result, and update status accordingly
|
||||
*/
|
||||
switch (hub.toNeoHubSendChannelValue(cmdStr)) {
|
||||
case SUCCEEDED:
|
||||
logger.debug(MSG_FMT_COMMAND_OK, getThing().getLabel());
|
||||
|
||||
if (getThing().getStatus() != ThingStatus.ONLINE) {
|
||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
|
||||
}
|
||||
|
||||
// initialize the de-bouncer for this channel
|
||||
debouncer.initialize(channelId);
|
||||
|
||||
break;
|
||||
|
||||
case ERR_COMMUNICATION:
|
||||
logger.debug(MSG_HUB_COMM);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
break;
|
||||
|
||||
case ERR_INITIALIZATION:
|
||||
logger.warn(MSG_HUB_CONFIG);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
logger.debug(MSG_HUB_CONFIG);
|
||||
}
|
||||
} else {
|
||||
logger.debug(MSG_FMT_COMMAND_BAD, command.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* internal getter returns the NeoHub handler
|
||||
*
|
||||
* @return the neohub handler or null
|
||||
*/
|
||||
protected @Nullable NeoHubHandler getNeoHub() {
|
||||
@Nullable
|
||||
Bridge b;
|
||||
@Nullable
|
||||
BridgeHandler h;
|
||||
|
||||
if ((b = getBridge()) != null && (h = b.getHandler()) != null && h instanceof NeoHubHandler) {
|
||||
return (NeoHubHandler) h;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// ========= methods that MAY / MUST be overridden in descendants ============
|
||||
|
||||
/*
|
||||
* NOTE: descendant classes MUST override this method. It builds the command
|
||||
* string to be sent to the NeoHub
|
||||
*/
|
||||
protected String toNeoHubBuildCommandString(String channelId, Command command) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: descendant classes MAY override this method e.g. to send additional
|
||||
* commands for dependent channels (if any)
|
||||
*/
|
||||
protected void toNeoHubSendCommandSet(String channelId, Command command) {
|
||||
toNeoHubSendCommand(channelId, command);
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: descendant classes MUST override this method method by which the
|
||||
* handler informs openHAB about channel state changes
|
||||
*/
|
||||
protected void toOpenHabSendChannelValues(AbstractRecord deviceRecord) {
|
||||
}
|
||||
|
||||
protected OnOffType invert(OnOffType value) {
|
||||
return OnOffType.from(value == OnOffType.OFF);
|
||||
}
|
||||
|
||||
protected Unit<?> getTemperatureUnit() {
|
||||
@Nullable
|
||||
NeoHubHandler hub = getNeoHub();
|
||||
if (hub != null) {
|
||||
return hub.getTemperatureUnit();
|
||||
}
|
||||
return SIUnits.CELSIUS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData.AbstractRecord;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
/**
|
||||
* The {@link NeoContactHandler} is the OpenHAB Handler for NeoContact devices
|
||||
*
|
||||
* Note: inherits almost all the functionality of a {@link NeoBaseHandler}
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoContactHandler extends NeoBaseHandler {
|
||||
|
||||
public NeoContactHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
// =========== methods of NeoBaseHandler that are overridden ================
|
||||
|
||||
@Override
|
||||
protected void toOpenHabSendChannelValues(AbstractRecord deviceRecord) {
|
||||
boolean offline = deviceRecord.offline();
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_CONTACT_STATE,
|
||||
deviceRecord.isWindowOpen() ? OpenClosedType.OPEN : OpenClosedType.CLOSED, offline);
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_BATTERY_LOW_ALARM, OnOffType.from(deviceRecord.isBatteryLow()), offline);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An abstract prototype for wrappers around JSON responses to JSON INFO or
|
||||
* GET_LIVE_DATA requests
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class NeoHubAbstractDeviceData {
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@NonNullByDefault
|
||||
public abstract static class AbstractRecord {
|
||||
|
||||
public abstract String getDeviceName();
|
||||
|
||||
public abstract BigDecimal getTargetTemperature();
|
||||
|
||||
public abstract BigDecimal getActualTemperature();
|
||||
|
||||
public abstract BigDecimal getFloorTemperature();
|
||||
|
||||
public abstract boolean isStandby();
|
||||
|
||||
public abstract boolean isHeating();
|
||||
|
||||
public abstract boolean isPreHeating();
|
||||
|
||||
public abstract boolean isTimerOn();
|
||||
|
||||
public abstract boolean offline();
|
||||
|
||||
public abstract boolean stateManual();
|
||||
|
||||
public abstract boolean stateAuto();
|
||||
|
||||
public abstract boolean isWindowOpen();
|
||||
|
||||
public abstract boolean isBatteryLow();
|
||||
|
||||
protected BigDecimal safeBigDecimal(@Nullable BigDecimal value) {
|
||||
return value != null ? value : BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the device record corresponding to a given device name
|
||||
*
|
||||
* @param deviceName the device name
|
||||
* @return its respective device record
|
||||
*/
|
||||
public abstract @Nullable AbstractRecord getDeviceRecord(String deviceName);
|
||||
|
||||
/**
|
||||
* @return the full list of device records
|
||||
*/
|
||||
public abstract @Nullable List<? extends AbstractRecord> getDevices();
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link NeoHubBindingConstants} class defines common constants
|
||||
*
|
||||
* @author Sebastian Prehn - Initial contribution (NeoHub command codes)
|
||||
* @author Andrew Fiddian-Green - Initial contribution (OpenHAB v2.x binding
|
||||
* code)
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubBindingConstants {
|
||||
|
||||
/*
|
||||
* binding id
|
||||
*/
|
||||
public static final String BINDING_ID = "neohub";
|
||||
|
||||
/*
|
||||
* device id's
|
||||
*/
|
||||
public static final String DEVICE_ID_NEOHUB = "neohub";
|
||||
public static final String DEVICE_ID_NEOSTAT = "neostat";
|
||||
public static final String DEVICE_ID_NEOPLUG = "neoplug";
|
||||
public static final String DEVICE_ID_NEOCONTACT = "neocontact";
|
||||
public static final String DEVICE_ID_NEOTEMPERATURESENSOR = "neotemperaturesensor";
|
||||
|
||||
/*
|
||||
* Thing Type UIDs
|
||||
*/
|
||||
public static final ThingTypeUID THING_TYPE_NEOHUB = new ThingTypeUID(BINDING_ID, DEVICE_ID_NEOHUB);
|
||||
public static final ThingTypeUID THING_TYPE_NEOSTAT = new ThingTypeUID(BINDING_ID, DEVICE_ID_NEOSTAT);
|
||||
public static final ThingTypeUID THING_TYPE_NEOPLUG = new ThingTypeUID(BINDING_ID, DEVICE_ID_NEOPLUG);
|
||||
public static final ThingTypeUID THING_TYPE_NEOCONTACT = new ThingTypeUID(BINDING_ID, DEVICE_ID_NEOCONTACT);
|
||||
public static final ThingTypeUID THING_TYPE_NEOTEMPERATURESENSOR = new ThingTypeUID(BINDING_ID,
|
||||
DEVICE_ID_NEOTEMPERATURESENSOR);
|
||||
|
||||
/*
|
||||
* Channel IDs for NeoHub
|
||||
*/
|
||||
public static final String CHAN_MESH_NETWORK_QOS = "meshNetworkQoS";
|
||||
|
||||
/*
|
||||
* Channel IDs common for several device types
|
||||
*/
|
||||
public static final String CHAN_BATTERY_LOW_ALARM = "batteryLowAlarm";
|
||||
|
||||
/*
|
||||
* Channel IDs for NeoStat thermostats
|
||||
*/
|
||||
public static final String CHAN_ROOM_TEMP = "roomTemperature";
|
||||
public static final String CHAN_TARGET_TEMP = "targetTemperature";
|
||||
public static final String CHAN_FLOOR_TEMP = "floorTemperature";
|
||||
public static final String CHAN_OCC_MODE_PRESENT = "occupancyModePresent";
|
||||
public static final String CHAN_STAT_OUTPUT_STATE = "thermostatOutputState";
|
||||
|
||||
/*
|
||||
* Channel IDs for NeoPlug smart plugs
|
||||
*/
|
||||
public static final String CHAN_PLUG_OUTPUT_STATE = "plugOutputState";
|
||||
public static final String CHAN_PLUG_AUTO_MODE = "plugAutoMode";
|
||||
|
||||
/*
|
||||
* Channel IDs for NeoContact (wireless) contact sensors
|
||||
*/
|
||||
public static final String CHAN_CONTACT_STATE = "contactState";
|
||||
|
||||
/*
|
||||
* Channel IDs for NeoTemperatureSensor (wireless) temperature sensors
|
||||
*/
|
||||
public static final String CHAN_TEMPERATURE_SENSOR = "sensorTemperature";
|
||||
|
||||
/*
|
||||
* Heatmiser Device Types
|
||||
*/
|
||||
public static final int HEATMISER_DEVICE_TYPE_CONTACT = 5;
|
||||
public static final int HEATMISER_DEVICE_TYPE_PLUG = 6;
|
||||
public static final int HEATMISER_DEVICE_TYPE_REPEATER = 10;
|
||||
public static final int HEATMISER_DEVICE_TYPE_TEMPERATURE_SENSOR = 14;
|
||||
|
||||
/*
|
||||
* configuration parameters
|
||||
*/
|
||||
public static final String PARAM_HOLD_ONLINE_STATE = "holdOnlineState";
|
||||
|
||||
/*
|
||||
* regular expression pattern matchers
|
||||
*/
|
||||
public static final Pattern MATCHER_HEATMISER_REPEATER = Pattern.compile("^repeaternode\\d+");
|
||||
public static final Pattern MATCHER_IP_ADDRESS = Pattern
|
||||
.compile("\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b");
|
||||
|
||||
/*
|
||||
* enumerator for results of method calls
|
||||
*/
|
||||
public static enum NeoHubReturnResult {
|
||||
SUCCEEDED,
|
||||
ERR_COMMUNICATION,
|
||||
ERR_INITIALIZATION
|
||||
}
|
||||
|
||||
/*
|
||||
* the property IdD for the name of a thing in the NeoHub note: names may differ
|
||||
* between the NeoHub and the OpenHAB framework
|
||||
*/
|
||||
public static final String DEVICE_NAME = "deviceNameInHub";
|
||||
|
||||
/*
|
||||
* setup parameters for de-bouncing of state changes (time in seconds) so state
|
||||
* changes that occur within this time window are ignored
|
||||
*/
|
||||
public static final long DEBOUNCE_DELAY = 15;
|
||||
|
||||
/*
|
||||
* setup parameters for lazy polling
|
||||
*/
|
||||
public static final int LAZY_POLL_INTERVAL = 60;
|
||||
|
||||
/*
|
||||
* setup parameters for fast polling bursts a burst comprises FAST_POLL_CYCLES
|
||||
* polling calls spaced at FAST_POLL_INTERVAL for example 5 polling calls made
|
||||
* at 4 second intervals (e.g. 5 x 4 => 20 seconds)
|
||||
*/
|
||||
public static final int FAST_POLL_CYCLES = 5;
|
||||
public static final int FAST_POLL_INTERVAL = 4;
|
||||
|
||||
/*
|
||||
* setup parameters for device discovery
|
||||
*/
|
||||
public static final int DISCOVERY_TIMEOUT = 5;
|
||||
public static final int DISCOVERY_START_DELAY = 30;
|
||||
public static final int DISCOVERY_REFRESH_PERIOD = 600;
|
||||
|
||||
/*
|
||||
* NeoHub JSON command codes strings: Thanks to Sebastian Prehn !!
|
||||
*/
|
||||
public static final String CMD_CODE_INFO = "{\"INFO\":0}";
|
||||
public static final String CMD_CODE_TEMP = "{\"SET_TEMP\":[%s, \"%s\"]}";
|
||||
public static final String CMD_CODE_AWAY = "{\"FROST_%s\":\"%s\"}";
|
||||
public static final String CMD_CODE_TIMER = "{\"TIMER_%s\":\"%s\"}";
|
||||
public static final String CMD_CODE_MANUAL = "{\"MANUAL_%s\":\"%s\"}";
|
||||
public static final String CMD_CODE_READ_DCB = "{\"READ_DCB\":100}";
|
||||
|
||||
/*
|
||||
* note: from NeoHub rev2.6 onwards the INFO command is "deprecated" and it
|
||||
* should be replaced partly each by the new GET_LIVE_DATA and GET_ENGINEERS
|
||||
* commands
|
||||
*/
|
||||
public static final String CMD_CODE_GET_LIVE_DATA = "{\"GET_LIVE_DATA\":0}";
|
||||
public static final String CMD_CODE_GET_ENGINEERS = "{\"GET_ENGINEERS\":0}";
|
||||
|
||||
/*
|
||||
* note: from NeoHub rev2.6 onwards the READ_DCB command is "deprecated" and it
|
||||
* should be replaced by the new GET_SYSTEM command
|
||||
*/
|
||||
public static final String CMD_CODE_GET_SYSTEM = "{\"GET_SYSTEM\":0}";
|
||||
|
||||
/*
|
||||
* openHAB status strings
|
||||
*/
|
||||
public static final String VAL_OFF = "Off";
|
||||
public static final String VAL_HEATING = "Heating";
|
||||
|
||||
/*
|
||||
* logger message strings
|
||||
*/
|
||||
public static final String PLEASE_REPORT_BUG = "Unexpected situation - please report a bug: ";
|
||||
public static final String MSG_HUB_CONFIG = PLEASE_REPORT_BUG + "hub needs to be initialized!";
|
||||
public static final String MSG_HUB_COMM = PLEASE_REPORT_BUG + "error communicating with the hub!";
|
||||
public static final String MSG_FMT_DEVICE_POLL_ERR = "Device data polling error: {}";
|
||||
public static final String MSG_FMT_SYSTEM_POLL_ERR = "System data polling error: {}";
|
||||
public static final String MSG_FMT_ENGINEERS_POLL_ERR = "Engineers data polling error: {}";
|
||||
public static final String MSG_FMT_SET_VALUE_ERR = "{} set value error: {}";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link NeoHubConfiguration} class contains the thing configuration
|
||||
* parameters
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubConfiguration {
|
||||
public String hostName = "";
|
||||
public int portNumber;
|
||||
public int pollingInterval;
|
||||
public int socketTimeout;
|
||||
public boolean preferLegacyApi;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.DEBOUNCE_DELAY;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link NeoHubDebouncer} determines if change events should be forwarded
|
||||
* to a channel
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubDebouncer {
|
||||
|
||||
private final Map<String, DebounceDelay> channels = new HashMap<>();
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@NonNullByDefault
|
||||
static class DebounceDelay {
|
||||
|
||||
private long expireTime;
|
||||
|
||||
public DebounceDelay(Boolean enabled) {
|
||||
if (enabled) {
|
||||
expireTime = new Date().getTime() + (DEBOUNCE_DELAY * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean timeExpired() {
|
||||
return (expireTime < new Date().getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public NeoHubDebouncer() {
|
||||
}
|
||||
|
||||
public void initialize(String channelId) {
|
||||
channels.put(channelId, new DebounceDelay(true));
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
public boolean timeExpired(String channelId) {
|
||||
return (channels.containsKey(channelId) ? channels.get(channelId).timeExpired() : true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData.AbstractRecord;
|
||||
import org.openhab.binding.neohub.internal.NeoHubInfoResponse.InfoRecord;
|
||||
import org.openhab.binding.neohub.internal.NeoHubLiveDeviceData.LiveDataRecord;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Discovery service for neo devices
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubDiscoveryService extends AbstractDiscoveryService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(NeoHubDiscoveryService.class);
|
||||
|
||||
private @Nullable ScheduledFuture<?> discoveryScheduler;
|
||||
|
||||
private NeoHubHandler hub;
|
||||
|
||||
public static final Set<ThingTypeUID> DISCOVERABLE_THING_TYPES_UIDS = Collections.unmodifiableSet(
|
||||
Stream.of(THING_TYPE_NEOSTAT, THING_TYPE_NEOPLUG, THING_TYPE_NEOCONTACT, THING_TYPE_NEOTEMPERATURESENSOR)
|
||||
.collect(Collectors.toSet()));
|
||||
|
||||
public NeoHubDiscoveryService(NeoHubHandler hub) {
|
||||
// note: background discovery is enabled in the super method
|
||||
super(DISCOVERABLE_THING_TYPES_UIDS, DISCOVERY_TIMEOUT);
|
||||
this.hub = hub;
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
super.activate(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScan() {
|
||||
if (hub.getThing().getStatus() == ThingStatus.ONLINE) {
|
||||
discoverDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
logger.debug("start background discovery..");
|
||||
|
||||
ScheduledFuture<?> discoveryScheduler = this.discoveryScheduler;
|
||||
if (discoveryScheduler == null || discoveryScheduler.isCancelled()) {
|
||||
this.discoveryScheduler = scheduler.scheduleWithFixedDelay(this::startScan, 10, DISCOVERY_REFRESH_PERIOD,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopBackgroundDiscovery() {
|
||||
logger.debug("stop background discovery..");
|
||||
|
||||
ScheduledFuture<?> discoveryScheduler = this.discoveryScheduler;
|
||||
if (discoveryScheduler != null && !discoveryScheduler.isCancelled()) {
|
||||
discoveryScheduler.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void discoverDevices() {
|
||||
NeoHubAbstractDeviceData deviceData = hub.fromNeoHubGetDeviceData();
|
||||
NeoHubGetEngineersData engineerData = hub.isLegacyApiSelected() ? null : hub.fromNeoHubGetEngineersData();
|
||||
|
||||
if (deviceData != null) {
|
||||
List<? extends AbstractRecord> deviceRecords = deviceData.getDevices();
|
||||
|
||||
if (deviceRecords != null) {
|
||||
int deviceType;
|
||||
|
||||
for (AbstractRecord deviceRecord : deviceRecords) {
|
||||
|
||||
// the record came from the legacy API (deviceType included)
|
||||
if (deviceRecord instanceof InfoRecord) {
|
||||
deviceType = ((InfoRecord) deviceRecord).getDeviceType();
|
||||
publishDevice((InfoRecord) deviceRecord, deviceType);
|
||||
continue;
|
||||
}
|
||||
|
||||
// the record came from the now API (deviceType NOT included)
|
||||
if (deviceRecord instanceof LiveDataRecord) {
|
||||
if (engineerData == null) {
|
||||
break;
|
||||
}
|
||||
String deviceName = ((LiveDataRecord) deviceRecord).getDeviceName();
|
||||
// exclude repeater nodes from being discovered
|
||||
if (MATCHER_HEATMISER_REPEATER.matcher(deviceName).matches()) {
|
||||
continue;
|
||||
}
|
||||
deviceType = engineerData.getDeviceType(deviceName);
|
||||
publishDevice((LiveDataRecord) deviceRecord, deviceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void publishDevice(AbstractRecord device, int deviceId) {
|
||||
if (deviceId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String deviceType;
|
||||
String deviceOpenHabId;
|
||||
String deviceNeohubName;
|
||||
ThingUID deviceUID;
|
||||
ThingTypeUID deviceTypeUID;
|
||||
DiscoveryResult discoveredDevice;
|
||||
|
||||
ThingUID bridgeUID = hub.getThing().getUID();
|
||||
|
||||
switch (deviceId) {
|
||||
case HEATMISER_DEVICE_TYPE_CONTACT: {
|
||||
deviceType = DEVICE_ID_NEOCONTACT;
|
||||
deviceTypeUID = THING_TYPE_NEOCONTACT;
|
||||
break;
|
||||
}
|
||||
case HEATMISER_DEVICE_TYPE_PLUG: {
|
||||
deviceType = DEVICE_ID_NEOPLUG;
|
||||
deviceTypeUID = THING_TYPE_NEOPLUG;
|
||||
break;
|
||||
}
|
||||
case HEATMISER_DEVICE_TYPE_TEMPERATURE_SENSOR: {
|
||||
deviceType = DEVICE_ID_NEOTEMPERATURESENSOR;
|
||||
deviceTypeUID = THING_TYPE_NEOTEMPERATURESENSOR;
|
||||
break;
|
||||
}
|
||||
// all other device types are assumed to be thermostats
|
||||
default: {
|
||||
deviceType = DEVICE_ID_NEOSTAT;
|
||||
deviceTypeUID = THING_TYPE_NEOSTAT;
|
||||
}
|
||||
}
|
||||
|
||||
deviceNeohubName = device.getDeviceName();
|
||||
deviceOpenHabId = deviceNeohubName.replaceAll("\\s+", "_");
|
||||
deviceUID = new ThingUID(deviceTypeUID, bridgeUID, deviceOpenHabId);
|
||||
|
||||
discoveredDevice = DiscoveryResultBuilder.create(deviceUID).withBridge(bridgeUID).withLabel(deviceOpenHabId)
|
||||
.withProperty(DEVICE_NAME, deviceNeohubName).withRepresentationProperty(DEVICE_NAME).build();
|
||||
|
||||
thingDiscovered(discoveredDevice);
|
||||
|
||||
logger.debug("discovered device: id={}, type={}, name={} ..", deviceId, deviceType, deviceOpenHabId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link NeoHubException} is a custom exception for NeoHub
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -7358712540781217363L;
|
||||
|
||||
public NeoHubException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* A wrapper around the JSON response to the JSON GET_ENGINEERS request
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubGetEngineersData {
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@NonNullByDefault
|
||||
private static class EngineersRecords extends HashMap<String, EngineersRecord> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@NonNullByDefault
|
||||
public class EngineersRecord {
|
||||
@SerializedName("DEVICE_TYPE")
|
||||
private @Nullable BigDecimal deviceType;
|
||||
|
||||
public int getDeviceType() {
|
||||
BigDecimal deviceType = this.deviceType;
|
||||
return deviceType != null ? deviceType.intValue() : -1;
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable EngineersRecords deviceRecords;
|
||||
|
||||
/**
|
||||
* Create wrapper around a JSON string
|
||||
*
|
||||
* @param fromJson the JSON string
|
||||
* @return a NeoHubGetEngData wrapper around the JSON string
|
||||
* @throws JsonSyntaxException
|
||||
*
|
||||
*/
|
||||
public NeoHubGetEngineersData(String fromJson) throws JsonSyntaxException {
|
||||
deviceRecords = GSON.fromJson(fromJson, EngineersRecords.class);
|
||||
}
|
||||
|
||||
public static @Nullable NeoHubGetEngineersData createEngineersData(String fromJson) throws JsonSyntaxException {
|
||||
return new NeoHubGetEngineersData(fromJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the device record corresponding to a given device name
|
||||
*
|
||||
* @param deviceName the device name
|
||||
* @return its respective device information record
|
||||
*/
|
||||
private @Nullable EngineersRecord getDevice(String deviceName) {
|
||||
EngineersRecords deviceRecords = this.deviceRecords;
|
||||
return deviceRecords != null ? deviceRecords.get(deviceName) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the deviceType corresponding to a given device name
|
||||
*
|
||||
* @param deviceName the device name
|
||||
* @return its respective device information record
|
||||
*/
|
||||
public int getDeviceType(String deviceName) {
|
||||
EngineersRecord record = getDevice(deviceName);
|
||||
return record != null ? record.getDeviceType() : -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,474 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData.AbstractRecord;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import tec.uom.se.unit.Units;
|
||||
|
||||
/**
|
||||
* The {@link NeoHubHandler} is the openHAB Handler for NeoHub devices
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution (v2.x binding code)
|
||||
* @author Sebastian Prehn - Initial contribution (v1.x hub communication)
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubHandler extends BaseBridgeHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(NeoHubHandler.class);
|
||||
|
||||
private final Map<String, Boolean> connectionStates = new HashMap<>();
|
||||
|
||||
private @Nullable NeoHubConfiguration config;
|
||||
private @Nullable NeoHubSocket socket;
|
||||
private @Nullable ScheduledFuture<?> lazyPollingScheduler;
|
||||
private @Nullable ScheduledFuture<?> fastPollingScheduler;
|
||||
|
||||
private final AtomicInteger fastPollingCallsToGo = new AtomicInteger();
|
||||
|
||||
private @Nullable NeoHubReadDcbResponse systemData = null;
|
||||
|
||||
private boolean isLegacyApiSelected = true;
|
||||
private boolean isApiOnline = false;
|
||||
|
||||
public NeoHubHandler(Bridge bridge) {
|
||||
super(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
// future: currently there is nothing to do for a NeoHub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
NeoHubConfiguration config = getConfigAs(NeoHubConfiguration.class);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("hostname={}", config.hostName);
|
||||
}
|
||||
|
||||
if (!MATCHER_IP_ADDRESS.matcher(config.hostName).matches()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "parameter hostName must be set!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("port={}", config.portNumber);
|
||||
}
|
||||
|
||||
if (config.portNumber <= 0 || config.portNumber > 0xFFFF) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "portNumber is invalid!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("polling interval={}", config.pollingInterval);
|
||||
}
|
||||
|
||||
if (config.pollingInterval < FAST_POLL_INTERVAL || config.pollingInterval > LAZY_POLL_INTERVAL) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, String
|
||||
.format("pollingInterval must be in range [%d..%d]!", FAST_POLL_INTERVAL, LAZY_POLL_INTERVAL));
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("socketTimeout={}", config.socketTimeout);
|
||||
}
|
||||
|
||||
if (config.socketTimeout < 5 || config.socketTimeout > 20) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
String.format("socketTimeout must be in range [%d..%d]!", 5, 20));
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("preferLegacyApi={}", config.preferLegacyApi);
|
||||
}
|
||||
|
||||
socket = new NeoHubSocket(config.hostName, config.portNumber, config.socketTimeout);
|
||||
this.config = config;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("start background polling..");
|
||||
}
|
||||
|
||||
// create a "lazy" polling scheduler
|
||||
ScheduledFuture<?> lazy = this.lazyPollingScheduler;
|
||||
if (lazy == null || lazy.isCancelled()) {
|
||||
this.lazyPollingScheduler = scheduler.scheduleWithFixedDelay(this::lazyPollingSchedulerExecute,
|
||||
config.pollingInterval, config.pollingInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// create a "fast" polling scheduler
|
||||
fastPollingCallsToGo.set(FAST_POLL_CYCLES);
|
||||
ScheduledFuture<?> fast = this.fastPollingScheduler;
|
||||
if (fast == null || fast.isCancelled()) {
|
||||
this.fastPollingScheduler = scheduler.scheduleWithFixedDelay(this::fastPollingSchedulerExecute,
|
||||
FAST_POLL_INTERVAL, FAST_POLL_INTERVAL, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
// start a fast polling burst to ensure the NeHub is initialized quickly
|
||||
startFastPollingBurst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("stop background polling..");
|
||||
}
|
||||
|
||||
// clean up the lazy polling scheduler
|
||||
ScheduledFuture<?> lazy = this.lazyPollingScheduler;
|
||||
if (lazy != null && !lazy.isCancelled()) {
|
||||
lazy.cancel(true);
|
||||
this.lazyPollingScheduler = null;
|
||||
}
|
||||
|
||||
// clean up the fast polling scheduler
|
||||
ScheduledFuture<?> fast = this.fastPollingScheduler;
|
||||
if (fast != null && !fast.isCancelled()) {
|
||||
fast.cancel(true);
|
||||
this.fastPollingScheduler = null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* device handlers call this to initiate a burst of fast polling requests (
|
||||
* improves response time to users when openHAB changes a channel value )
|
||||
*/
|
||||
public void startFastPollingBurst() {
|
||||
fastPollingCallsToGo.set(FAST_POLL_CYCLES);
|
||||
}
|
||||
|
||||
/*
|
||||
* device handlers call this method to issue commands to the NeoHub
|
||||
*/
|
||||
public synchronized NeoHubReturnResult toNeoHubSendChannelValue(String commandStr) {
|
||||
NeoHubSocket socket = this.socket;
|
||||
|
||||
if (socket == null || config == null) {
|
||||
return NeoHubReturnResult.ERR_INITIALIZATION;
|
||||
}
|
||||
|
||||
try {
|
||||
socket.sendMessage(commandStr);
|
||||
|
||||
// start a fast polling burst (to confirm the status change)
|
||||
startFastPollingBurst();
|
||||
|
||||
return NeoHubReturnResult.SUCCEEDED;
|
||||
} catch (Exception e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
logger.warn(MSG_FMT_SET_VALUE_ERR, commandStr, e.getMessage());
|
||||
return NeoHubReturnResult.ERR_COMMUNICATION;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sends a JSON request to the NeoHub to read the device data
|
||||
*
|
||||
* @return a class that contains the full status of all devices
|
||||
*/
|
||||
protected @Nullable NeoHubAbstractDeviceData fromNeoHubGetDeviceData() {
|
||||
NeoHubSocket socket = this.socket;
|
||||
|
||||
if (socket == null || config == null) {
|
||||
logger.warn(MSG_HUB_CONFIG);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String responseJson;
|
||||
NeoHubAbstractDeviceData deviceData;
|
||||
|
||||
if (isLegacyApiSelected) {
|
||||
responseJson = socket.sendMessage(CMD_CODE_INFO);
|
||||
deviceData = NeoHubInfoResponse.createDeviceData(responseJson);
|
||||
} else {
|
||||
responseJson = socket.sendMessage(CMD_CODE_GET_LIVE_DATA);
|
||||
deviceData = NeoHubLiveDeviceData.createDeviceData(responseJson);
|
||||
}
|
||||
|
||||
if (deviceData == null) {
|
||||
logger.warn(MSG_FMT_DEVICE_POLL_ERR, "failed to create device data response");
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
List<? extends AbstractRecord> devices = deviceData.getDevices();
|
||||
if (devices == null || devices.size() == 0) {
|
||||
logger.warn(MSG_FMT_DEVICE_POLL_ERR, "no devices found");
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (getThing().getStatus() != ThingStatus.ONLINE) {
|
||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
|
||||
}
|
||||
|
||||
// check if we also need to discard and update systemData
|
||||
NeoHubReadDcbResponse systemData = this.systemData;
|
||||
if (systemData != null) {
|
||||
if (deviceData instanceof NeoHubLiveDeviceData) {
|
||||
/*
|
||||
* note: time-stamps are measured in seconds from 1970-01-01T00:00:00Z
|
||||
*
|
||||
* new API: discard systemData if its time-stamp is older than the system
|
||||
* time-stamp on the hub
|
||||
*/
|
||||
if (systemData.timeStamp < ((NeoHubLiveDeviceData) deviceData).getTimestampSystem()) {
|
||||
this.systemData = null;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* note: time-stamps are measured in seconds from 1970-01-01T00:00:00Z
|
||||
*
|
||||
* legacy API: discard systemData if its time-stamp is older than one hour
|
||||
*/
|
||||
if (systemData.timeStamp < Instant.now().minus(1, ChronoUnit.HOURS).getEpochSecond()) {
|
||||
this.systemData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return deviceData;
|
||||
} catch (Exception e) {
|
||||
logger.warn(MSG_FMT_DEVICE_POLL_ERR, e.getMessage());
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sends a JSON request to the NeoHub to read the system data
|
||||
*
|
||||
* @return a class that contains the status of the system
|
||||
*/
|
||||
protected @Nullable NeoHubReadDcbResponse fromNeoHubReadSystemData() {
|
||||
NeoHubSocket socket = this.socket;
|
||||
|
||||
if (socket == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String responseJson;
|
||||
NeoHubReadDcbResponse systemData;
|
||||
|
||||
if (isLegacyApiSelected) {
|
||||
responseJson = socket.sendMessage(CMD_CODE_READ_DCB);
|
||||
systemData = NeoHubReadDcbResponse.createSystemData(responseJson);
|
||||
} else {
|
||||
responseJson = socket.sendMessage(CMD_CODE_GET_SYSTEM);
|
||||
systemData = NeoHubReadDcbResponse.createSystemData(responseJson);
|
||||
}
|
||||
|
||||
if (systemData == null) {
|
||||
logger.warn(MSG_FMT_SYSTEM_POLL_ERR, "failed to create system data response");
|
||||
return null;
|
||||
}
|
||||
|
||||
return systemData;
|
||||
} catch (Exception e) {
|
||||
logger.warn(MSG_FMT_SYSTEM_POLL_ERR, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this is the callback used by the lazy polling scheduler.. fetches the info
|
||||
* for all devices from the NeoHub, and passes the results the respective device
|
||||
* handlers
|
||||
*/
|
||||
private synchronized void lazyPollingSchedulerExecute() {
|
||||
// check which API is supported
|
||||
if (!isApiOnline) {
|
||||
selectApi();
|
||||
}
|
||||
|
||||
NeoHubAbstractDeviceData deviceData = fromNeoHubGetDeviceData();
|
||||
if (deviceData != null) {
|
||||
// dispatch deviceData to each of the hub's owned devices ..
|
||||
List<Thing> children = getThing().getThings();
|
||||
for (Thing child : children) {
|
||||
ThingHandler device = child.getHandler();
|
||||
if (device instanceof NeoBaseHandler) {
|
||||
((NeoBaseHandler) device).toBaseSendPollResponse(deviceData);
|
||||
}
|
||||
}
|
||||
|
||||
// evaluate and update the state of our RF mesh QoS channel
|
||||
List<? extends AbstractRecord> devices = deviceData.getDevices();
|
||||
State state;
|
||||
|
||||
if (devices == null || devices.isEmpty()) {
|
||||
state = UnDefType.UNDEF;
|
||||
} else {
|
||||
int totalDeviceCount = devices.size();
|
||||
int onlineDeviceCount = 0;
|
||||
|
||||
for (AbstractRecord device : devices) {
|
||||
String deviceName = device.getDeviceName();
|
||||
Boolean online = !device.offline();
|
||||
|
||||
@Nullable
|
||||
Boolean onlineBefore = connectionStates.put(deviceName, online);
|
||||
if (!online.equals(onlineBefore)) {
|
||||
logger.info("device \"{}\" has {} the RF mesh network", deviceName,
|
||||
online.booleanValue() ? "joined" : "left");
|
||||
}
|
||||
|
||||
if (online.booleanValue()) {
|
||||
onlineDeviceCount++;
|
||||
}
|
||||
}
|
||||
state = new QuantityType<>((100.0 * onlineDeviceCount) / totalDeviceCount, Units.PERCENT);
|
||||
}
|
||||
updateState(CHAN_MESH_NETWORK_QOS, state);
|
||||
}
|
||||
if (fastPollingCallsToGo.get() > 0) {
|
||||
fastPollingCallsToGo.decrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this is the callback used by the fast polling scheduler.. checks if a fast
|
||||
* polling burst is scheduled, and if so calls lazyPollingSchedulerExecute
|
||||
*/
|
||||
private void fastPollingSchedulerExecute() {
|
||||
if (fastPollingCallsToGo.get() > 0) {
|
||||
lazyPollingSchedulerExecute();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* select whether to use the old "deprecated" API or the new API
|
||||
*/
|
||||
private void selectApi() {
|
||||
boolean supportsLegacyApi = false;
|
||||
boolean supportsFutureApi = false;
|
||||
|
||||
NeoHubSocket socket = this.socket;
|
||||
if (socket != null) {
|
||||
String responseJson;
|
||||
NeoHubReadDcbResponse systemData;
|
||||
|
||||
try {
|
||||
responseJson = socket.sendMessage(CMD_CODE_READ_DCB);
|
||||
systemData = NeoHubReadDcbResponse.createSystemData(responseJson);
|
||||
supportsLegacyApi = systemData != null;
|
||||
if (!supportsLegacyApi) {
|
||||
throw new NeoHubException("legacy API not supported");
|
||||
}
|
||||
} catch (JsonSyntaxException | NeoHubException | IOException e) {
|
||||
// we learned that this API is not currently supported; no big deal
|
||||
logger.debug("Legacy API is not supported!");
|
||||
}
|
||||
try {
|
||||
responseJson = socket.sendMessage(CMD_CODE_GET_SYSTEM);
|
||||
systemData = NeoHubReadDcbResponse.createSystemData(responseJson);
|
||||
supportsFutureApi = systemData != null;
|
||||
if (!supportsFutureApi) {
|
||||
throw new NeoHubException("new API not supported");
|
||||
}
|
||||
} catch (JsonSyntaxException | NeoHubException | IOException e) {
|
||||
// we learned that this API is not currently supported; no big deal
|
||||
logger.debug("New API is not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
if (!supportsLegacyApi && !supportsFutureApi) {
|
||||
logger.warn("Currently neither legacy nor new API are supported!");
|
||||
isApiOnline = false;
|
||||
return;
|
||||
}
|
||||
|
||||
NeoHubConfiguration config = this.config;
|
||||
boolean isLegacyApiSelected = (supportsLegacyApi && config != null && config.preferLegacyApi);
|
||||
if (isLegacyApiSelected != this.isLegacyApiSelected) {
|
||||
logger.info("Changing API version: {}",
|
||||
isLegacyApiSelected ? "\"new\" => \"legacy\"" : "\"legacy\" => \"new\"");
|
||||
}
|
||||
this.isLegacyApiSelected = isLegacyApiSelected;
|
||||
this.isApiOnline = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the Engineers data
|
||||
*/
|
||||
public @Nullable NeoHubGetEngineersData fromNeoHubGetEngineersData() {
|
||||
NeoHubSocket socket = this.socket;
|
||||
if (socket != null) {
|
||||
String responseJson;
|
||||
try {
|
||||
responseJson = socket.sendMessage(CMD_CODE_GET_ENGINEERS);
|
||||
return NeoHubGetEngineersData.createEngineersData(responseJson);
|
||||
} catch (JsonSyntaxException | IOException | NeoHubException e) {
|
||||
logger.warn(MSG_FMT_ENGINEERS_POLL_ERR, e.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isLegacyApiSelected() {
|
||||
return isLegacyApiSelected;
|
||||
}
|
||||
|
||||
public Unit<?> getTemperatureUnit() {
|
||||
NeoHubReadDcbResponse systemData = this.systemData;
|
||||
if (systemData == null) {
|
||||
this.systemData = systemData = fromNeoHubReadSystemData();
|
||||
}
|
||||
if (systemData != null) {
|
||||
return systemData.getTemperatureUnit();
|
||||
}
|
||||
return SIUnits.CELSIUS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link NeoHubHandlerFactory} creates things and thing handlers
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.neohub", service = ThingHandlerFactory.class)
|
||||
public class NeoHubHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
|
||||
.unmodifiableSet(new HashSet<>(Arrays.asList(THING_TYPE_NEOHUB, THING_TYPE_NEOSTAT, THING_TYPE_NEOPLUG,
|
||||
THING_TYPE_NEOCONTACT, THING_TYPE_NEOTEMPERATURESENSOR)));
|
||||
|
||||
private final Map<ThingUID, ServiceRegistration<?>> discoServices = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if ((thingTypeUID.equals(THING_TYPE_NEOHUB)) && (thing instanceof Bridge)) {
|
||||
NeoHubHandler handler = new NeoHubHandler((Bridge) thing);
|
||||
createDiscoveryService(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_NEOSTAT)) {
|
||||
return new NeoStatHandler(thing);
|
||||
}
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_NEOPLUG)) {
|
||||
return new NeoPlugHandler(thing);
|
||||
}
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_NEOCONTACT)) {
|
||||
return new NeoContactHandler(thing);
|
||||
}
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_NEOTEMPERATURESENSOR)) {
|
||||
return new NeoTemperatureSensorHandler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void removeHandler(ThingHandler handler) {
|
||||
if (handler instanceof NeoHubHandler) {
|
||||
destroyDiscoveryService((NeoHubHandler) handler);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create a discovery service so that a newly created hub will find the
|
||||
* respective things tht are inside it
|
||||
*/
|
||||
private synchronized void createDiscoveryService(NeoHubHandler handler) {
|
||||
// create a new discovery service
|
||||
NeoHubDiscoveryService ds = new NeoHubDiscoveryService(handler);
|
||||
|
||||
// activate the discovery service
|
||||
ds.activate();
|
||||
|
||||
// register the discovery service
|
||||
ServiceRegistration<?> serviceReg = bundleContext.registerService(DiscoveryService.class.getName(), ds,
|
||||
new Hashtable<>());
|
||||
|
||||
/*
|
||||
* store service registration in a list so we can destroy it when the respective
|
||||
* hub is destroyed
|
||||
*/
|
||||
discoServices.put(handler.getThing().getUID(), serviceReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy the discovery service
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
private synchronized void destroyDiscoveryService(NeoHubHandler handler) {
|
||||
// fetch the respective thing's service registration from our list
|
||||
ServiceRegistration<?> serviceReg = discoServices.remove(handler.getThing().getUID());
|
||||
|
||||
if (serviceReg != null) {
|
||||
// retrieve the respective discovery service
|
||||
NeoHubDiscoveryService disco = (NeoHubDiscoveryService) bundleContext.getService(serviceReg.getReference());
|
||||
|
||||
// and unregister the service
|
||||
serviceReg.unregister();
|
||||
|
||||
// deactivate the service
|
||||
if (disco != null) {
|
||||
disco.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* A wrapper around the JSON response to the JSON INFO request
|
||||
*
|
||||
* @author Sebastian Prehn - Initial contribution
|
||||
* @author Andrew Fiddian-Green - Refactoring for openHAB v2.x
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubInfoResponse extends NeoHubAbstractDeviceData {
|
||||
|
||||
private static final Gson GSON = new GsonBuilder()
|
||||
.registerTypeAdapter(NeohubBool.class, new NeohubBoolDeserializer()).create();
|
||||
|
||||
@SerializedName("devices")
|
||||
private @Nullable List<InfoRecord> deviceRecords;
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@NonNullByDefault
|
||||
static class StatMode {
|
||||
@SerializedName("MANUAL_OFF")
|
||||
private @Nullable NeohubBool manualOff;
|
||||
@SerializedName("MANUAL_ON")
|
||||
private @Nullable NeohubBool manualOn;
|
||||
|
||||
private boolean stateManualOn() {
|
||||
NeohubBool manualOn = this.manualOn;
|
||||
return (manualOn == null ? false : manualOn.value);
|
||||
}
|
||||
|
||||
private boolean stateManualOff() {
|
||||
NeohubBool manualOff = this.manualOff;
|
||||
return (manualOff == null ? false : manualOff.value);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@NonNullByDefault
|
||||
public static class InfoRecord extends AbstractRecord {
|
||||
@SerializedName("device")
|
||||
private @Nullable String deviceName;
|
||||
@SerializedName("CURRENT_SET_TEMPERATURE")
|
||||
private @Nullable BigDecimal currentSetTemperature;
|
||||
@SerializedName("CURRENT_TEMPERATURE")
|
||||
private @Nullable BigDecimal currentTemperature;
|
||||
@SerializedName("CURRENT_FLOOR_TEMPERATURE")
|
||||
private @Nullable BigDecimal currentFloorTemperature;
|
||||
@SerializedName("COOL_INP")
|
||||
private @Nullable NeohubBool coolInput;
|
||||
@SerializedName("LOW_BATTERY")
|
||||
private @Nullable NeohubBool batteryLow;
|
||||
@SerializedName("STANDBY")
|
||||
private @Nullable NeohubBool standby;
|
||||
@SerializedName("HEATING")
|
||||
private @Nullable NeohubBool heating;
|
||||
@SerializedName("PREHEAT")
|
||||
private @Nullable NeohubBool preHeat;
|
||||
@SerializedName("TIMER")
|
||||
private @Nullable NeohubBool timerOn;
|
||||
@SerializedName("DEVICE_TYPE")
|
||||
private @Nullable BigDecimal deviceType;
|
||||
@SerializedName("OFFLINE")
|
||||
private @Nullable NeohubBool offline;
|
||||
@SerializedName("STAT_MODE")
|
||||
private @Nullable StatMode statMode = new StatMode();
|
||||
|
||||
private boolean safeBoolean(@Nullable NeohubBool value) {
|
||||
return (value == null ? false : value.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceName() {
|
||||
String deviceName = this.deviceName;
|
||||
return deviceName != null ? deviceName : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getTargetTemperature() {
|
||||
return safeBigDecimal(currentSetTemperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getActualTemperature() {
|
||||
return safeBigDecimal(currentTemperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getFloorTemperature() {
|
||||
return safeBigDecimal(currentFloorTemperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStandby() {
|
||||
return safeBoolean(standby);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeating() {
|
||||
return safeBoolean(heating);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreHeating() {
|
||||
return safeBoolean(preHeat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimerOn() {
|
||||
return safeBoolean(timerOn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offline() {
|
||||
return safeBoolean(offline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stateManual() {
|
||||
StatMode statMode = this.statMode;
|
||||
return (statMode != null && statMode.stateManualOn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stateAuto() {
|
||||
StatMode statMode = this.statMode;
|
||||
return (statMode != null && statMode.stateManualOff());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWindowOpen() {
|
||||
// legacy API misuses the cool input parameter
|
||||
return safeBoolean(coolInput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBatteryLow() {
|
||||
return safeBoolean(batteryLow);
|
||||
}
|
||||
|
||||
public int getDeviceType() {
|
||||
BigDecimal deviceType = this.deviceType;
|
||||
return deviceType != null ? deviceType.intValue() : -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create wrapper around a JSON string
|
||||
*
|
||||
* @param fromJson the JSON string
|
||||
* @return a NeoHubInfoResponse wrapper around the JSON
|
||||
* @throws JsonSyntaxException
|
||||
*
|
||||
*/
|
||||
public static @Nullable NeoHubInfoResponse createDeviceData(String fromJson) throws JsonSyntaxException {
|
||||
return GSON.fromJson(fromJson, NeoHubInfoResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the device record corresponding to a given device name
|
||||
*
|
||||
* @param deviceName the device name
|
||||
* @return its respective device record
|
||||
*/
|
||||
@Override
|
||||
public @Nullable AbstractRecord getDeviceRecord(String deviceName) {
|
||||
List<InfoRecord> deviceRecords = this.deviceRecords;
|
||||
if (deviceRecords != null) {
|
||||
for (AbstractRecord deviceRecord : deviceRecords) {
|
||||
if (deviceName.equals(deviceRecord.getDeviceName())) {
|
||||
return deviceRecord;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the full list of device records
|
||||
*/
|
||||
@Override
|
||||
public @Nullable List<InfoRecord> getDevices() {
|
||||
return deviceRecords;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* A wrapper around the JSON response to the JSON GET_LIVE_DATA request
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubLiveDeviceData extends NeoHubAbstractDeviceData {
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
@SerializedName("TIMESTAMP_ENGINEERS")
|
||||
private @Nullable BigDecimal timestampEngineers;
|
||||
@SerializedName("TIMESTAMP_SYSTEM")
|
||||
private @Nullable BigDecimal timestampSystem;
|
||||
|
||||
@SerializedName("devices")
|
||||
private @Nullable List<LiveDataRecord> deviceRecords;
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@NonNullByDefault
|
||||
public static class LiveDataRecord extends AbstractRecord {
|
||||
|
||||
// "alternate" is a special kludge for technical devices
|
||||
@SerializedName(value = "ZONE_NAME", alternate = { "device" })
|
||||
private @Nullable String deviceName;
|
||||
@SerializedName("SET_TEMP")
|
||||
private @Nullable BigDecimal currentSetTemperature;
|
||||
@SerializedName("ACTUAL_TEMP")
|
||||
private @Nullable BigDecimal currentTemperature;
|
||||
@SerializedName("CURRENT_FLOOR_TEMPERATURE")
|
||||
private @Nullable BigDecimal currentFloorTemperature;
|
||||
@SerializedName("WINDOW_OPEN")
|
||||
private @Nullable Boolean windowOpen;
|
||||
@SerializedName("LOW_BATTERY")
|
||||
private @Nullable Boolean batteryLow;
|
||||
@SerializedName("STANDBY")
|
||||
private @Nullable Boolean standby;
|
||||
@SerializedName("HEAT_ON")
|
||||
private @Nullable Boolean heating;
|
||||
@SerializedName("PREHEAT_ACTIVE")
|
||||
private @Nullable Boolean preHeat;
|
||||
@SerializedName("TIMER_ON")
|
||||
private @Nullable Boolean timerOn;
|
||||
@SerializedName("OFFLINE")
|
||||
private @Nullable Boolean offline;
|
||||
@SerializedName("MANUAL_OFF")
|
||||
private @Nullable Boolean manualOff;
|
||||
@SerializedName("MANUAL_ON")
|
||||
private @Nullable Boolean manualOn;
|
||||
|
||||
private boolean safeBoolean(@Nullable Boolean value) {
|
||||
return (value == null ? false : value.booleanValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceName() {
|
||||
String deviceName = this.deviceName;
|
||||
return deviceName != null ? deviceName : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getTargetTemperature() {
|
||||
return safeBigDecimal(currentSetTemperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getActualTemperature() {
|
||||
return safeBigDecimal(currentTemperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getFloorTemperature() {
|
||||
return safeBigDecimal(currentFloorTemperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStandby() {
|
||||
return safeBoolean(standby);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeating() {
|
||||
return safeBoolean(heating);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreHeating() {
|
||||
return safeBoolean(preHeat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimerOn() {
|
||||
return safeBoolean(timerOn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offline() {
|
||||
return safeBoolean(offline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stateManual() {
|
||||
return safeBoolean(manualOn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stateAuto() {
|
||||
return safeBoolean(manualOff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWindowOpen() {
|
||||
return safeBoolean(windowOpen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBatteryLow() {
|
||||
return safeBoolean(batteryLow);
|
||||
}
|
||||
}
|
||||
|
||||
public long getTimestampEngineers() {
|
||||
BigDecimal timestampEngineers = this.timestampEngineers;
|
||||
return timestampEngineers != null ? timestampEngineers.longValue() : 0;
|
||||
}
|
||||
|
||||
public long getTimestampSystem() {
|
||||
BigDecimal timestampSystem = this.timestampSystem;
|
||||
return timestampSystem != null ? timestampSystem.longValue() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create wrapper around a JSON string
|
||||
*
|
||||
* @param fromJson the JSON string
|
||||
* @return a NeoHubGetLiveDataResponse wrapper around the JSON string
|
||||
* @throws JsonSyntaxException
|
||||
*
|
||||
*/
|
||||
public static @Nullable NeoHubLiveDeviceData createDeviceData(String fromJson) throws JsonSyntaxException {
|
||||
return GSON.fromJson(fromJson, NeoHubLiveDeviceData.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the device record corresponding to a given device name
|
||||
*
|
||||
* @param deviceName the device name
|
||||
* @return its respective device record
|
||||
*/
|
||||
@Override
|
||||
public @Nullable AbstractRecord getDeviceRecord(String deviceName) {
|
||||
List<LiveDataRecord> deviceRecords = this.deviceRecords;
|
||||
if (deviceRecords != null) {
|
||||
for (AbstractRecord deviceRecord : deviceRecords) {
|
||||
if (deviceName.equals(deviceRecord.getDeviceName())) {
|
||||
return deviceRecord;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the full list of device records
|
||||
*/
|
||||
@Override
|
||||
public @Nullable List<LiveDataRecord> getDevices() {
|
||||
return deviceRecords;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* A wrapper around the JSON response to the JSON READ_DCB and GET_SYSTEM
|
||||
* request
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubReadDcbResponse {
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
@SerializedName("CORF")
|
||||
private @Nullable String degreesCorF;
|
||||
|
||||
/*
|
||||
* note: time-stamps are measured in seconds from 1970-01-01T00:00:00Z
|
||||
*
|
||||
* this time-stamp is the moment of creation of this class instance; it is used
|
||||
* to compare with the system last change time-stamp reported by the hub
|
||||
*/
|
||||
public final long timeStamp = Instant.now().getEpochSecond();
|
||||
|
||||
public Unit<?> getTemperatureUnit() {
|
||||
return "F".equalsIgnoreCase(degreesCorF) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create wrapper around a JSON string
|
||||
*
|
||||
* @param fromJson the JSON string
|
||||
* @return a NeoHubReadDcbResponse wrapper around the JSON string
|
||||
* @throws JsonSyntaxException
|
||||
*
|
||||
*/
|
||||
public static @Nullable NeoHubReadDcbResponse createSystemData(String fromJson) throws JsonSyntaxException {
|
||||
return GSON.fromJson(fromJson, NeoHubReadDcbResponse.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* NeoHubConnector handles the ASCII based communication via TCP between openHAB
|
||||
* and NeoHub
|
||||
*
|
||||
* @author Sebastian Prehn - Initial contribution
|
||||
* @author Andrew Fiddian-Green - Refactoring for openHAB v2.x
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubSocket {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(NeoHubSocket.class);
|
||||
|
||||
/**
|
||||
* Name of host or IP to connect to.
|
||||
*/
|
||||
private final String hostname;
|
||||
|
||||
/**
|
||||
* The port to connect to
|
||||
*/
|
||||
private final int port;
|
||||
|
||||
/**
|
||||
* The socket connect resp. read timeout value
|
||||
*/
|
||||
private final int timeout;
|
||||
|
||||
public NeoHubSocket(final String hostname, final int portNumber, final int timeoutSeconds) {
|
||||
this.hostname = hostname;
|
||||
this.port = portNumber;
|
||||
this.timeout = timeoutSeconds * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* sends the message over the network to the NeoHub and returns its response
|
||||
*
|
||||
* @param requestJson the message to be sent to the NeoHub
|
||||
* @return responseJson received from NeoHub
|
||||
* @throws NeoHubException, IOException
|
||||
*
|
||||
*/
|
||||
public String sendMessage(final String requestJson) throws IOException, NeoHubException {
|
||||
IOException caughtException = null;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
try (Socket socket = new Socket()) {
|
||||
socket.connect(new InetSocketAddress(hostname, port), timeout);
|
||||
socket.setSoTimeout(timeout);
|
||||
|
||||
try (InputStreamReader reader = new InputStreamReader(socket.getInputStream(), US_ASCII);
|
||||
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream(), US_ASCII)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("sending {} characters..", requestJson.length());
|
||||
logger.debug(">> {}", requestJson);
|
||||
}
|
||||
|
||||
writer.write(requestJson);
|
||||
writer.write(0); // NULL terminate the command string
|
||||
writer.flush();
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("sent {} characters..", requestJson.length());
|
||||
}
|
||||
|
||||
int inChar;
|
||||
// NULL termination, end of stream (-1), or newline
|
||||
while (((inChar = reader.read()) > 0) && (inChar != '\n')) {
|
||||
builder.append((char) inChar);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// catch IOExceptions here, and save them to be re-thrown later
|
||||
caughtException = e;
|
||||
}
|
||||
|
||||
String responseJson = builder.toString();
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("received {} characters..", responseJson.length());
|
||||
logger.trace("<< {}", responseJson);
|
||||
} else
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("received {} characters (set log level to TRACE to see full string)..", responseJson.length());
|
||||
logger.debug("<< {} ...", responseJson.substring(0, Math.min(responseJson.length(), 30)));
|
||||
}
|
||||
|
||||
// if any type of Exception was caught above, re-throw it again to the caller
|
||||
if (caughtException != null) {
|
||||
throw caughtException;
|
||||
}
|
||||
|
||||
if (responseJson.isEmpty()) {
|
||||
throw new NeoHubException("empty response string");
|
||||
}
|
||||
|
||||
return responseJson;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
|
||||
/**
|
||||
* The {@link NeoPlugHandler} is the OpenHAB Handler for NeoPlug devices Note:
|
||||
* inherits almost all the functionality of a {@link NeoBaseHandler}
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoPlugHandler extends NeoBaseHandler {
|
||||
|
||||
public NeoPlugHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
// =========== methods of NeoBaseHandler that are overridden ================
|
||||
|
||||
@Override
|
||||
protected String toNeoHubBuildCommandString(String channelId, Command command) {
|
||||
NeoBaseConfiguration config = this.config;
|
||||
if (config != null) {
|
||||
if (command instanceof OnOffType && channelId.equals(CHAN_PLUG_OUTPUT_STATE)) {
|
||||
return String.format(CMD_CODE_TIMER, ((OnOffType) command).toString(), config.deviceNameInHub);
|
||||
}
|
||||
if (command instanceof OnOffType && channelId.equals(CHAN_PLUG_AUTO_MODE)) {
|
||||
return String.format(CMD_CODE_MANUAL, invert((OnOffType) command).toString(), config.deviceNameInHub);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toNeoHubSendCommandSet(String channelId, Command command) {
|
||||
// if this is a manual command, switch to manual mode first..
|
||||
if (channelId.equals(CHAN_PLUG_OUTPUT_STATE) && command instanceof OnOffType) {
|
||||
toNeoHubSendCommand(CHAN_PLUG_AUTO_MODE, OnOffType.from(false));
|
||||
}
|
||||
// send the actual command to the hub
|
||||
toNeoHubSendCommand(channelId, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toOpenHabSendChannelValues(NeoHubAbstractDeviceData.AbstractRecord deviceRecord) {
|
||||
boolean offline = deviceRecord.offline();
|
||||
toOpenHabSendValueDebounced(CHAN_PLUG_AUTO_MODE, OnOffType.from(!deviceRecord.stateManual()), offline);
|
||||
toOpenHabSendValueDebounced(CHAN_PLUG_OUTPUT_STATE, OnOffType.from(deviceRecord.isTimerOn()), offline);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
|
||||
/**
|
||||
* The {@link NeoStatHandler} is the openHAB Handler for NeoStat devices Note:
|
||||
* inherits almost all the functionality of a {@link NeoBaseHandler}
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoStatHandler extends NeoBaseHandler {
|
||||
|
||||
public NeoStatHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toNeoHubBuildCommandString(String channelId, Command command) {
|
||||
NeoBaseConfiguration config = this.config;
|
||||
if (config != null) {
|
||||
if (command instanceof QuantityType<?> && channelId.equals(CHAN_TARGET_TEMP)) {
|
||||
Command doCommand = command;
|
||||
QuantityType<?> temp = ((QuantityType<?>) command).toUnit(getTemperatureUnit());
|
||||
if (temp != null) {
|
||||
doCommand = temp;
|
||||
}
|
||||
return String.format(CMD_CODE_TEMP, ((QuantityType<?>) doCommand).toBigDecimal().toString(),
|
||||
config.deviceNameInHub);
|
||||
}
|
||||
|
||||
if (command instanceof OnOffType && channelId.equals(CHAN_OCC_MODE_PRESENT)) {
|
||||
return String.format(CMD_CODE_AWAY, invert((OnOffType) command).toString(), config.deviceNameInHub);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toOpenHabSendChannelValues(NeoHubAbstractDeviceData.AbstractRecord deviceRecord) {
|
||||
Unit<?> unit = getTemperatureUnit();
|
||||
boolean offline = deviceRecord.offline();
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_TARGET_TEMP, new QuantityType<>(deviceRecord.getTargetTemperature(), unit),
|
||||
offline);
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_ROOM_TEMP, new QuantityType<>(deviceRecord.getActualTemperature(), unit),
|
||||
offline);
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_FLOOR_TEMP, new QuantityType<>(deviceRecord.getFloorTemperature(), unit),
|
||||
offline);
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_OCC_MODE_PRESENT, OnOffType.from(!deviceRecord.isStandby()), offline);
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_STAT_OUTPUT_STATE,
|
||||
(deviceRecord.isHeating() || deviceRecord.isPreHeating() ? new StringType(VAL_HEATING)
|
||||
: new StringType(VAL_OFF)),
|
||||
offline);
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_BATTERY_LOW_ALARM, OnOffType.from(deviceRecord.isBatteryLow()), offline);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
/**
|
||||
* The {@link NeoTemperatureSensorHandler} is the OpenHAB Handler for NeoTemperatureSensor devices
|
||||
*
|
||||
* Note: inherits almost all the functionality of a {@link NeoBaseHandler}
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoTemperatureSensorHandler extends NeoBaseHandler {
|
||||
|
||||
public NeoTemperatureSensorHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
// =========== methods of NeoBaseHandler that are overridden ================
|
||||
|
||||
@Override
|
||||
protected void toOpenHabSendChannelValues(NeoHubAbstractDeviceData.AbstractRecord deviceRecord) {
|
||||
boolean offline = deviceRecord.offline();
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_TEMPERATURE_SENSOR,
|
||||
new QuantityType<>(deviceRecord.getActualTemperature(), getTemperatureUnit()), offline);
|
||||
|
||||
toOpenHabSendValueDebounced(CHAN_BATTERY_LOW_ALARM, OnOffType.from(deviceRecord.isBatteryLow()), offline);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* A custom class that wraps a boolean; we need this because newer versions of
|
||||
* NeoHub have broken JSON for some boolean values so we can't use the standard
|
||||
* deserializer, and thus have to use a custom one
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeohubBool {
|
||||
public boolean value;
|
||||
|
||||
public NeohubBool(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.internal;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
/**
|
||||
* A custom deserializer for NeohubBool; we need this because newer versions of
|
||||
* NeoHub have broken JSON for some boolean values so we can't use the standard
|
||||
* deserializer, and thus have to use a custom one
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeohubBoolDeserializer implements JsonDeserializer<NeohubBool> {
|
||||
|
||||
@Override
|
||||
public NeohubBool deserialize(@Nullable JsonElement json, @Nullable Type typeOfT,
|
||||
@Nullable JsonDeserializationContext context) throws JsonParseException {
|
||||
if (json != null) {
|
||||
JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
|
||||
if (jsonPrimitive.isBoolean()) {
|
||||
return new NeohubBool(jsonPrimitive.getAsBoolean());
|
||||
} else if (jsonPrimitive.isNumber()) {
|
||||
return new NeohubBool(jsonPrimitive.getAsNumber().intValue() != 0);
|
||||
}
|
||||
}
|
||||
return new NeohubBool(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="neohub" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>NeoHub Binding</name>
|
||||
<description>This is the binding for Heatmiser NeoHub devices</description>
|
||||
<author>Andrew Fiddian-Green</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,310 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="neohub"
|
||||
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">
|
||||
|
||||
<bridge-type id="neohub">
|
||||
|
||||
<label>NeoHub</label>
|
||||
<description>Heatmiser NeoHub bridge to NeoStat and NeoPlug devices</description>
|
||||
|
||||
<channels>
|
||||
<channel typeId="meshNetworkQoS" id="meshNetworkQoS"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="vendor">Heatmiser</property>
|
||||
<property name="modelId">NeoHub</property>
|
||||
</properties>
|
||||
|
||||
<config-description>
|
||||
<parameter name="hostName" type="text" required="true">
|
||||
<label>Host Name</label>
|
||||
<context>network-address</context>
|
||||
<description>Host name (IP address) of the NeoHub</description>
|
||||
</parameter>
|
||||
|
||||
<parameter name="portNumber" type="integer" required="false">
|
||||
<label>Port Number</label>
|
||||
<description>Port number of the NeoHub</description>
|
||||
<default>4242</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
|
||||
<parameter name="pollingInterval" type="integer" min="4" max="60" required="false" unit="s">
|
||||
<label>Polling Interval</label>
|
||||
<description>Time (seconds) between polling the NeoHub (min=4, max/default=60)</description>
|
||||
<default>60</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
|
||||
<parameter name="socketTimeout" type="integer" min="5" max="20" required="false" unit="s">
|
||||
<label>Socket Timeout</label>
|
||||
<description>Time (seconds) to wait for connections to the Hub (min/default=5, max=20)</description>
|
||||
<default>5</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
|
||||
<parameter name="preferLegacyApi" type="boolean" required="false">
|
||||
<label>Prefer Legacy API</label>
|
||||
<description>Use the legacy API instead of the new API (if available)</description>
|
||||
<default>false</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</bridge-type>
|
||||
|
||||
<thing-type id="neostat">
|
||||
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="neohub"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Heatmiser NeoStat</label>
|
||||
<description>Heatmiser Neo Smart Thermostat</description>
|
||||
|
||||
<channels>
|
||||
<channel id="roomTemperature" typeId="temperature">
|
||||
<label>Room Temperature</label>
|
||||
<description>Actual room temperature</description>
|
||||
</channel>
|
||||
|
||||
<channel id="targetTemperature" typeId="targetTemperature"/>
|
||||
|
||||
<channel id="floorTemperature" typeId="temperature">
|
||||
<label>Floor Temperature</label>
|
||||
<description>Actual floor temperature</description>
|
||||
</channel>
|
||||
|
||||
<channel id="thermostatOutputState" typeId="thermostatOutputState"/>
|
||||
<channel id="occupancyModePresent" typeId="occupancyModePresent"/>
|
||||
<channel id="batteryLowAlarm" typeId="system.low-battery"/>
|
||||
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="vendor">Heatmiser</property>
|
||||
<property name="modelId">NeoStat</property>
|
||||
</properties>
|
||||
<representation-property>deviceNameInHub</representation-property>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceNameInHub" type="text" required="true">
|
||||
<label>Device Name</label>
|
||||
<description>Device Name that identifies the NeoStat device in the NeoHub and Heatmiser App</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="neoplug">
|
||||
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="neohub"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Heatmiser NeoPlug</label>
|
||||
<description>Heatmiser Neo Smart Plug</description>
|
||||
|
||||
<channels>
|
||||
<channel id="plugOutputState" typeId="plugOutputState"/>
|
||||
<channel id="plugAutoMode" typeId="plugAutoMode"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="vendor">Heatmiser</property>
|
||||
<property name="modelId">NeoPlug</property>
|
||||
</properties>
|
||||
<representation-property>deviceNameInHub</representation-property>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceNameInHub" type="text" required="true">
|
||||
<label>Device Name</label>
|
||||
<description>Device Name that identifies the NeoPlug device in the NeoHub and Heatmiser App</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="neocontact">
|
||||
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="neohub"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Heatmiser Contact Sensor</label>
|
||||
<description>Heatmiser (wireless) Window or Door Contact</description>
|
||||
|
||||
<channels>
|
||||
<channel id="contactState" typeId="contactState"/>
|
||||
<channel id="batteryLowAlarm" typeId="system.low-battery">
|
||||
<label>Battery Low Alarm</label>
|
||||
<description>ON if the device has a low battery</description>
|
||||
</channel>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="vendor">Heatmiser</property>
|
||||
<property name="modelId">Contact Sensor</property>
|
||||
</properties>
|
||||
<representation-property>deviceNameInHub</representation-property>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceNameInHub" type="text" required="true">
|
||||
<label>Device Name</label>
|
||||
<description>Device Name that identifies the Contact in the NeoHub and Heatmiser App</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="neotemperaturesensor">
|
||||
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="neohub"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Heatmiser Wireless Air Sensor</label>
|
||||
<description>Heatmiser (wireless) Temperature Sensor</description>
|
||||
|
||||
<channels>
|
||||
<channel id="sensorTemperature" typeId="temperature">
|
||||
<label>Temperature</label>
|
||||
<description>Measured temperature value (Read-Only)</description>
|
||||
</channel>
|
||||
|
||||
<channel id="batteryLowAlarm" typeId="system.low-battery">
|
||||
<label>Battery Low Alarm</label>
|
||||
<description>ON if the device has a low battery</description>
|
||||
</channel>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="vendor">Heatmiser</property>
|
||||
<property name="modelId">Wireless Air Sensor</property>
|
||||
</properties>
|
||||
<representation-property>deviceNameInHub</representation-property>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceNameInHub" type="text" required="true">
|
||||
<label>Device Name</label>
|
||||
<description>Device Name that identifies the Temperature Sensor in the NeoHub and Heatmiser App</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="temperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>Measured temperature value (Read-Only)</description>
|
||||
<category>temperature</category>
|
||||
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||
<config-description>
|
||||
<parameter name="holdOnlineState" type="boolean" required="false">
|
||||
<label>Hold Online State</label>
|
||||
<description>If the device loses its RF mesh connection, hold the last known state display value</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="targetTemperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Target Temperature</label>
|
||||
<description>Target temperature setting of the room</description>
|
||||
<category>temperature</category>
|
||||
<state readOnly="false" pattern="%.1f %unit%" step="1"/>
|
||||
<config-description>
|
||||
<parameter name="holdOnlineState" type="boolean" required="false">
|
||||
<label>Hold Online State</label>
|
||||
<description>If the device loses its RF mesh connection, hold the last known state display value</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="thermostatOutputState">
|
||||
<item-type>String</item-type>
|
||||
<label>Thermostat Output State</label>
|
||||
<description>Status of whether the thermostat is Off, or calling for Heat</description>
|
||||
<category>fire</category>
|
||||
<state readOnly="true"/>
|
||||
<config-description>
|
||||
<parameter name="holdOnlineState" type="boolean" required="false">
|
||||
<label>Hold Online State</label>
|
||||
<description>If the device loses its RF mesh connection, hold the last known state display value</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="occupancyModePresent">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Occupancy Mode Present</label>
|
||||
<description>The Thermostat is in the Present Occupancy Mode (Off=Absent, On=Present)</description>
|
||||
<category>presence</category>
|
||||
<state readOnly="false"/>
|
||||
<config-description>
|
||||
<parameter name="holdOnlineState" type="boolean" required="false">
|
||||
<label>Hold Online State</label>
|
||||
<description>If the device loses its RF mesh connection, hold the last known state display value</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="plugAutoMode">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Plug Auto Mode</label>
|
||||
<description>The Plug is in Automatic Mode (Off=Manual, On=Automatic)</description>
|
||||
<category>energy</category>
|
||||
<state readOnly="false"/>
|
||||
<config-description>
|
||||
<parameter name="holdOnlineState" type="boolean" required="false">
|
||||
<label>Hold Online State</label>
|
||||
<description>If the device loses its RF mesh connection, hold the last known state display value</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="plugOutputState">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Plug Output State</label>
|
||||
<description>The state of the Plug switch, Off or On</description>
|
||||
<state readOnly="false"/>
|
||||
<config-description>
|
||||
<parameter name="holdOnlineState" type="boolean" required="false">
|
||||
<label>Hold Online State</label>
|
||||
<description>If the device loses its RF mesh connection, hold the last known state display value</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="contactState">
|
||||
<item-type>Contact</item-type>
|
||||
<label>Contact State</label>
|
||||
<description>The state of the contact</description>
|
||||
<category>window</category>
|
||||
<state readOnly="true"/>
|
||||
<config-description>
|
||||
<parameter name="holdOnlineState" type="boolean" required="false">
|
||||
<label>Hold Online State</label>
|
||||
<description>If the device loses its RF mesh connection, hold the last known state display value</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="meshNetworkQoS">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Mesh Network QoS</label>
|
||||
<description>Quality of Service: percentage of configured devices currently connected to the RF mesh network</description>
|
||||
<state readOnly="true" pattern="%.0f %%"></state>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,399 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neohub.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData;
|
||||
import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData.AbstractRecord;
|
||||
import org.openhab.binding.neohub.internal.NeoHubGetEngineersData;
|
||||
import org.openhab.binding.neohub.internal.NeoHubInfoResponse;
|
||||
import org.openhab.binding.neohub.internal.NeoHubInfoResponse.InfoRecord;
|
||||
import org.openhab.binding.neohub.internal.NeoHubLiveDeviceData;
|
||||
import org.openhab.binding.neohub.internal.NeoHubReadDcbResponse;
|
||||
import org.openhab.binding.neohub.internal.NeoHubSocket;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
|
||||
/**
|
||||
* The {@link NeoHubTestData} class defines common constants, which are used
|
||||
* across the whole binding.
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NeoHubTestData {
|
||||
|
||||
/*
|
||||
* Load the test JSON payload string from a file
|
||||
*/
|
||||
private String load(String fileName) {
|
||||
try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName));
|
||||
BufferedReader reader = new BufferedReader(file)) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
builder.append(line).append("\n");
|
||||
}
|
||||
return builder.toString();
|
||||
} catch (IOException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test an INFO JSON response string as produced by older firmware versions
|
||||
*/
|
||||
@Test
|
||||
public void testInfoJsonOld() {
|
||||
// load INFO JSON response string in old JSON format
|
||||
NeoHubAbstractDeviceData infoResponse = NeoHubInfoResponse.createDeviceData(load("info_old"));
|
||||
assertNotNull(infoResponse);
|
||||
|
||||
// missing device
|
||||
AbstractRecord device = infoResponse.getDeviceRecord("Aardvark");
|
||||
assertNull(device);
|
||||
|
||||
// existing type 12 thermostat device
|
||||
device = infoResponse.getDeviceRecord("Dining Room");
|
||||
assertNotNull(device);
|
||||
assertEquals("Dining Room", device.getDeviceName());
|
||||
assertEquals(new BigDecimal("22.0"), device.getTargetTemperature());
|
||||
assertEquals(new BigDecimal("22.2"), device.getActualTemperature());
|
||||
assertEquals(new BigDecimal("23"), device.getFloorTemperature());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(12, ((InfoRecord) device).getDeviceType());
|
||||
assertFalse(device.isStandby());
|
||||
assertFalse(device.isHeating());
|
||||
assertFalse(device.isPreHeating());
|
||||
assertFalse(device.isTimerOn());
|
||||
assertFalse(device.offline());
|
||||
assertFalse(device.stateManual());
|
||||
assertTrue(device.stateAuto());
|
||||
assertFalse(device.isWindowOpen());
|
||||
assertFalse(device.isBatteryLow());
|
||||
|
||||
// existing type 6 plug device (MANUAL OFF)
|
||||
device = infoResponse.getDeviceRecord("Plug South");
|
||||
assertNotNull(device);
|
||||
assertEquals("Plug South", device.getDeviceName());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(6, ((InfoRecord) device).getDeviceType());
|
||||
assertFalse(device.isTimerOn());
|
||||
assertTrue(device.stateManual());
|
||||
|
||||
// existing type 6 plug device (MANUAL ON)
|
||||
device = infoResponse.getDeviceRecord("Plug North");
|
||||
assertNotNull(device);
|
||||
assertEquals("Plug North", device.getDeviceName());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(6, ((InfoRecord) device).getDeviceType());
|
||||
assertTrue(device.isTimerOn());
|
||||
assertTrue(device.stateManual());
|
||||
|
||||
// existing type 6 plug device (AUTO OFF)
|
||||
device = infoResponse.getDeviceRecord("Watering System");
|
||||
assertNotNull(device);
|
||||
assertEquals("Watering System", device.getDeviceName());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(6, ((InfoRecord) device).getDeviceType());
|
||||
assertFalse(device.isTimerOn());
|
||||
assertFalse(device.stateManual());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test an INFO JSON response string as produced by newer firmware versions
|
||||
*/
|
||||
@Test
|
||||
public void testInfoJsonNew() {
|
||||
// load INFO JSON response string in new JSON format
|
||||
NeoHubAbstractDeviceData infoResponse = NeoHubInfoResponse.createDeviceData(load("info_new"));
|
||||
assertNotNull(infoResponse);
|
||||
|
||||
// existing device (new JSON format)
|
||||
AbstractRecord device = infoResponse.getDeviceRecord("Dining Room");
|
||||
assertNotNull(device);
|
||||
assertEquals("Dining Room", device.getDeviceName());
|
||||
assertFalse(device.offline());
|
||||
assertFalse(device.isWindowOpen());
|
||||
|
||||
// existing repeater device
|
||||
device = infoResponse.getDeviceRecord("repeaternode54473");
|
||||
assertNotNull(device);
|
||||
assertEquals("repeaternode54473", device.getDeviceName());
|
||||
assertEquals(new BigDecimal("127"), device.getFloorTemperature());
|
||||
assertEquals(new BigDecimal("255.255"), device.getActualTemperature());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for a READ_DCB JSON string that has valid CORF C response
|
||||
*/
|
||||
@Test
|
||||
public void testReadDcbJson() {
|
||||
// load READ_DCB JSON response string with valid CORF C response
|
||||
NeoHubReadDcbResponse dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_celsius"));
|
||||
assertNotNull(dcbResponse);
|
||||
assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
|
||||
|
||||
// load READ_DCB JSON response string with valid CORF F response
|
||||
dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_fahrenheit"));
|
||||
assertNotNull(dcbResponse);
|
||||
assertEquals(ImperialUnits.FAHRENHEIT, dcbResponse.getTemperatureUnit());
|
||||
|
||||
// load READ_DCB JSON response string with missing CORF element
|
||||
dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_corf_missing"));
|
||||
assertNotNull(dcbResponse);
|
||||
assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
|
||||
|
||||
// load READ_DCB JSON response string where CORF element is an empty string
|
||||
dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_corf_empty"));
|
||||
assertNotNull(dcbResponse);
|
||||
assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test an INFO JSON string that has a door contact and a temperature sensor
|
||||
*/
|
||||
@Test
|
||||
public void testInfoJsonWithSensors() {
|
||||
/*
|
||||
* load an INFO JSON response string that has a closed door contact and a
|
||||
* temperature sensor
|
||||
*/
|
||||
// save("info_sensors_closed", NEOHUB_JSON_TEST_STRING_INFO_SENSORS_CLOSED);
|
||||
NeoHubAbstractDeviceData infoResponse = NeoHubInfoResponse.createDeviceData(load("info_sensors_closed"));
|
||||
assertNotNull(infoResponse);
|
||||
|
||||
// existing contact device type 5 (CLOSED)
|
||||
AbstractRecord device = infoResponse.getDeviceRecord("Back Door");
|
||||
assertNotNull(device);
|
||||
assertEquals("Back Door", device.getDeviceName());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(5, ((InfoRecord) device).getDeviceType());
|
||||
assertFalse(device.isWindowOpen());
|
||||
assertFalse(device.isBatteryLow());
|
||||
|
||||
// existing temperature sensor type 14
|
||||
device = infoResponse.getDeviceRecord("Master Bedroom");
|
||||
assertNotNull(device);
|
||||
assertEquals("Master Bedroom", device.getDeviceName());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(14, ((InfoRecord) device).getDeviceType());
|
||||
assertEquals(new BigDecimal("19.5"), device.getActualTemperature());
|
||||
|
||||
// existing thermostat type 1
|
||||
device = infoResponse.getDeviceRecord("Living Room Floor");
|
||||
assertNotNull(device);
|
||||
assertEquals("Living Room Floor", device.getDeviceName());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(1, ((InfoRecord) device).getDeviceType());
|
||||
assertEquals(new BigDecimal("19.8"), device.getActualTemperature());
|
||||
|
||||
// load an INFO JSON response string that has an open door contact
|
||||
// save("info_sensors_open", NEOHUB_JSON_TEST_STRING_INFO_SENSORS_OPEN);
|
||||
infoResponse = NeoHubInfoResponse.createDeviceData(load("info_sensors_open"));
|
||||
assertNotNull(infoResponse);
|
||||
|
||||
// existing contact device type 5 (OPEN)
|
||||
device = infoResponse.getDeviceRecord("Back Door");
|
||||
assertNotNull(device);
|
||||
assertEquals("Back Door", device.getDeviceName());
|
||||
assertTrue(device instanceof InfoRecord);
|
||||
assertEquals(5, ((InfoRecord) device).getDeviceType());
|
||||
assertTrue(device.isWindowOpen());
|
||||
assertTrue(device.isBatteryLow());
|
||||
}
|
||||
|
||||
/*
|
||||
* From NeoHub rev2.6 onwards the READ_DCB command is "deprecated" so we can
|
||||
* also test the replacement GET_SYSTEM command (valid CORF response)
|
||||
*/
|
||||
@Test
|
||||
public void testGetSystemJson() {
|
||||
// load GET_SYSTEM JSON response string
|
||||
NeoHubReadDcbResponse dcbResponse;
|
||||
dcbResponse = NeoHubReadDcbResponse.createSystemData(load("system"));
|
||||
assertNotNull(dcbResponse);
|
||||
assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
|
||||
}
|
||||
|
||||
/*
|
||||
* From NeoHub rev2.6 onwards the INFO command is "deprecated" so we must test
|
||||
* the replacement GET_LIVE_DATA command
|
||||
*/
|
||||
@Test
|
||||
public void testGetLiveDataJson() {
|
||||
// load GET_LIVE_DATA JSON response string
|
||||
NeoHubLiveDeviceData liveDataResponse = NeoHubLiveDeviceData.createDeviceData(load("live_data"));
|
||||
assertNotNull(liveDataResponse);
|
||||
|
||||
// test the time stamps
|
||||
assertEquals(1588494785, liveDataResponse.getTimestampEngineers());
|
||||
assertEquals(0, liveDataResponse.getTimestampSystem());
|
||||
|
||||
// missing device
|
||||
AbstractRecord device = liveDataResponse.getDeviceRecord("Aardvark");
|
||||
assertNull(device);
|
||||
|
||||
// test an existing thermostat device
|
||||
device = liveDataResponse.getDeviceRecord("Dining Room");
|
||||
assertNotNull(device);
|
||||
assertEquals("Dining Room", device.getDeviceName());
|
||||
assertEquals(new BigDecimal("22.0"), device.getTargetTemperature());
|
||||
assertEquals(new BigDecimal("22.2"), device.getActualTemperature());
|
||||
assertEquals(new BigDecimal("20.50"), device.getFloorTemperature());
|
||||
assertFalse(device.isStandby());
|
||||
assertFalse(device.isHeating());
|
||||
assertFalse(device.isPreHeating());
|
||||
assertFalse(device.isTimerOn());
|
||||
assertFalse(device.offline());
|
||||
assertFalse(device.stateManual());
|
||||
assertTrue(device.stateAuto());
|
||||
assertFalse(device.isWindowOpen());
|
||||
assertFalse(device.isBatteryLow());
|
||||
|
||||
// test a plug device (MANUAL OFF)
|
||||
device = liveDataResponse.getDeviceRecord("Living Room South");
|
||||
assertNotNull(device);
|
||||
assertEquals("Living Room South", device.getDeviceName());
|
||||
assertFalse(device.isTimerOn());
|
||||
assertTrue(device.stateManual());
|
||||
|
||||
// test a plug device (MANUAL ON)
|
||||
device = liveDataResponse.getDeviceRecord("Living Room North");
|
||||
assertNotNull(device);
|
||||
assertEquals("Living Room North", device.getDeviceName());
|
||||
assertTrue(device.isTimerOn());
|
||||
assertTrue(device.stateManual());
|
||||
|
||||
// test a plug device (AUTO OFF)
|
||||
device = liveDataResponse.getDeviceRecord("Green Wall Watering");
|
||||
assertNotNull(device);
|
||||
assertEquals("Green Wall Watering", device.getDeviceName());
|
||||
assertFalse(device.isTimerOn());
|
||||
assertFalse(device.stateManual());
|
||||
|
||||
// test a device that is offline
|
||||
device = liveDataResponse.getDeviceRecord("Shower Room");
|
||||
assertNotNull(device);
|
||||
assertEquals("Shower Room", device.getDeviceName());
|
||||
assertTrue(device.offline());
|
||||
|
||||
// test a device with a low battery
|
||||
device = liveDataResponse.getDeviceRecord("Conservatory");
|
||||
assertNotNull(device);
|
||||
assertEquals("Conservatory", device.getDeviceName());
|
||||
assertTrue(device.isBatteryLow());
|
||||
|
||||
// test a device with an open window alarm
|
||||
device = liveDataResponse.getDeviceRecord("Door Contact");
|
||||
assertNotNull(device);
|
||||
assertEquals("Door Contact", device.getDeviceName());
|
||||
assertTrue(device.isWindowOpen());
|
||||
|
||||
// test a wireless temperature sensor
|
||||
device = liveDataResponse.getDeviceRecord("Room Sensor");
|
||||
assertNotNull(device);
|
||||
assertEquals("Room Sensor", device.getDeviceName());
|
||||
assertEquals(new BigDecimal("21.5"), device.getActualTemperature());
|
||||
|
||||
// test a repeater node
|
||||
device = liveDataResponse.getDeviceRecord("repeaternode54473");
|
||||
assertNotNull(device);
|
||||
assertEquals("repeaternode54473", device.getDeviceName());
|
||||
assertTrue(MATCHER_HEATMISER_REPEATER.matcher(device.getDeviceName()).matches());
|
||||
}
|
||||
|
||||
/*
|
||||
* From NeoHub rev2.6 onwards the INFO command is "deprecated" and the DEVICE_ID
|
||||
* element is not returned in the GET_LIVE_DATA call so we must test the
|
||||
* replacement GET_ENGINEERS command
|
||||
*/
|
||||
@Test
|
||||
public void testGetEngineersJson() {
|
||||
// load GET_ENGINEERS JSON response string
|
||||
NeoHubGetEngineersData engResponse = NeoHubGetEngineersData.createEngineersData(load("engineers"));
|
||||
assertNotNull(engResponse);
|
||||
|
||||
// test device ID (type 12 thermostat device)
|
||||
assertEquals(12, engResponse.getDeviceType("Dining Room"));
|
||||
|
||||
// test device ID (type 6 plug device)
|
||||
assertEquals(6, engResponse.getDeviceType("Living Room South"));
|
||||
}
|
||||
|
||||
/*
|
||||
* send JSON request to the socket and retrieve JSON response
|
||||
*/
|
||||
private String testCommunicationInner(String requestJson) {
|
||||
NeoHubSocket socket = new NeoHubSocket("192.168.1.109", 4242, 5);
|
||||
String responseJson = "";
|
||||
try {
|
||||
responseJson = socket.sendMessage(requestJson);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
return responseJson;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the communications
|
||||
*/
|
||||
@Test
|
||||
public void testCommunications() {
|
||||
String responseJson = testCommunicationInner(CMD_CODE_INFO);
|
||||
assertFalse(responseJson.isEmpty());
|
||||
|
||||
responseJson = testCommunicationInner(CMD_CODE_READ_DCB);
|
||||
assertFalse(responseJson.isEmpty());
|
||||
|
||||
NeoHubReadDcbResponse dcbResponse = NeoHubReadDcbResponse.createSystemData(responseJson);
|
||||
assertNotNull(dcbResponse);
|
||||
|
||||
long timeStamp = dcbResponse.timeStamp;
|
||||
assertEquals(Instant.now().getEpochSecond(), timeStamp, 1);
|
||||
|
||||
responseJson = testCommunicationInner(CMD_CODE_GET_LIVE_DATA);
|
||||
assertFalse(responseJson.isEmpty());
|
||||
|
||||
NeoHubLiveDeviceData liveDataResponse = NeoHubLiveDeviceData.createDeviceData(responseJson);
|
||||
assertNotNull(liveDataResponse);
|
||||
|
||||
assertTrue(timeStamp > liveDataResponse.getTimestampEngineers());
|
||||
assertTrue(timeStamp > liveDataResponse.getTimestampSystem());
|
||||
|
||||
responseJson = testCommunicationInner(CMD_CODE_GET_ENGINEERS);
|
||||
assertFalse(responseJson.isEmpty());
|
||||
|
||||
responseJson = testCommunicationInner(CMD_CODE_GET_SYSTEM);
|
||||
assertFalse(responseJson.isEmpty());
|
||||
|
||||
responseJson = testCommunicationInner(String.format(CMD_CODE_TEMP, "20", "Hallway"));
|
||||
assertFalse(responseJson.isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"AIR_ALT_DELAY": 60,
|
||||
"AIR_ALT_DELAY_END": 6,
|
||||
"AIR_ALT_DELAY_START": 23,
|
||||
"ALT_TIMER_FORMAT": 1,
|
||||
"AWAY": false,
|
||||
"BOOTTIME": 1587842223,
|
||||
"CLOSE_DELAY": null,
|
||||
"COOLBOX": "heating",
|
||||
"COOLBOX_PRESENT": 0,
|
||||
"CORF": "C",
|
||||
"DATE": "Apr 30",
|
||||
"DEVICE_ID": "NeoHub",
|
||||
"DSTAUTO": true,
|
||||
"DSTON": true,
|
||||
"EXTENDED_HISTORY": "off",
|
||||
"Firmware version": 2134,
|
||||
"GDEVLIST": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
],
|
||||
"GLOBAL_SYSTEM_TYPE": "HeatOnly",
|
||||
"HEATING_LEVELS": 4,
|
||||
"HEATORCOOL": "HEAT",
|
||||
"Homekit": true,
|
||||
"LAST_RECONNECT": 191959,
|
||||
"LAST_RECONNECT_TIME": 1588034182,
|
||||
"NTP": "Running",
|
||||
"OPEN_DELAY": null,
|
||||
"PARTITION COUNT": "4",
|
||||
"PROGFORMAT": 1,
|
||||
"SET_GLOBAL_HC_MODE": "heating",
|
||||
"TIME": "16:24:35",
|
||||
"TIMEZONE": 0.0,
|
||||
"UPTIME": 418052,
|
||||
"ZIGBEE_CHANNEL": "15"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"AIR_ALT_DELAY": 60,
|
||||
"AIR_ALT_DELAY_END": 6,
|
||||
"AIR_ALT_DELAY_START": 23,
|
||||
"ALT_TIMER_FORMAT": 1,
|
||||
"AWAY": false,
|
||||
"BOOTTIME": 1587842223,
|
||||
"CLOSE_DELAY": null,
|
||||
"COOLBOX": "heating",
|
||||
"COOLBOX_PRESENT": 0,
|
||||
"CORF": "",
|
||||
"DATE": "Apr 30",
|
||||
"DEVICE_ID": "NeoHub",
|
||||
"DSTAUTO": true,
|
||||
"DSTON": true,
|
||||
"EXTENDED_HISTORY": "off",
|
||||
"Firmware version": 2134,
|
||||
"GDEVLIST": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
],
|
||||
"GLOBAL_SYSTEM_TYPE": "HeatOnly",
|
||||
"HEATING_LEVELS": 4,
|
||||
"HEATORCOOL": "HEAT",
|
||||
"Homekit": true,
|
||||
"LAST_RECONNECT": 191959,
|
||||
"LAST_RECONNECT_TIME": 1588034182,
|
||||
"NTP": "Running",
|
||||
"OPEN_DELAY": null,
|
||||
"PARTITION COUNT": "4",
|
||||
"PROGFORMAT": 1,
|
||||
"SET_GLOBAL_HC_MODE": "heating",
|
||||
"TIME": "16:24:35",
|
||||
"TIMEZONE": 0.0,
|
||||
"UPTIME": 418052,
|
||||
"ZIGBEE_CHANNEL": "15"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"AIR_ALT_DELAY": 60,
|
||||
"AIR_ALT_DELAY_END": 6,
|
||||
"AIR_ALT_DELAY_START": 23,
|
||||
"ALT_TIMER_FORMAT": 1,
|
||||
"AWAY": false,
|
||||
"BOOTTIME": 1587842223,
|
||||
"CLOSE_DELAY": null,
|
||||
"COOLBOX": "heating",
|
||||
"COOLBOX_PRESENT": 0,
|
||||
"DATE": "Apr 30",
|
||||
"DEVICE_ID": "NeoHub",
|
||||
"DSTAUTO": true,
|
||||
"DSTON": true,
|
||||
"EXTENDED_HISTORY": "off",
|
||||
"Firmware version": 2134,
|
||||
"GDEVLIST": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
],
|
||||
"GLOBAL_SYSTEM_TYPE": "HeatOnly",
|
||||
"HEATING_LEVELS": 4,
|
||||
"HEATORCOOL": "HEAT",
|
||||
"Homekit": true,
|
||||
"LAST_RECONNECT": 191959,
|
||||
"LAST_RECONNECT_TIME": 1588034182,
|
||||
"NTP": "Running",
|
||||
"OPEN_DELAY": null,
|
||||
"PARTITION COUNT": "4",
|
||||
"PROGFORMAT": 1,
|
||||
"SET_GLOBAL_HC_MODE": "heating",
|
||||
"TIME": "16:24:35",
|
||||
"TIMEZONE": 0.0,
|
||||
"UPTIME": 418052,
|
||||
"ZIGBEE_CHANNEL": "15"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"AIR_ALT_DELAY": 60,
|
||||
"AIR_ALT_DELAY_END": 6,
|
||||
"AIR_ALT_DELAY_START": 23,
|
||||
"ALT_TIMER_FORMAT": 1,
|
||||
"AWAY": false,
|
||||
"BOOTTIME": 1587842223,
|
||||
"CLOSE_DELAY": null,
|
||||
"COOLBOX": "heating",
|
||||
"COOLBOX_PRESENT": 0,
|
||||
"CORF": "F",
|
||||
"DATE": "Apr 30",
|
||||
"DEVICE_ID": "NeoHub",
|
||||
"DSTAUTO": true,
|
||||
"DSTON": true,
|
||||
"EXTENDED_HISTORY": "off",
|
||||
"Firmware version": 2134,
|
||||
"GDEVLIST": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
],
|
||||
"GLOBAL_SYSTEM_TYPE": "HeatOnly",
|
||||
"HEATING_LEVELS": 4,
|
||||
"HEATORCOOL": "HEAT",
|
||||
"Homekit": true,
|
||||
"LAST_RECONNECT": 191959,
|
||||
"LAST_RECONNECT_TIME": 1588034182,
|
||||
"NTP": "Running",
|
||||
"OPEN_DELAY": null,
|
||||
"PARTITION COUNT": "4",
|
||||
"PROGFORMAT": 1,
|
||||
"SET_GLOBAL_HC_MODE": "heating",
|
||||
"TIME": "16:24:35",
|
||||
"TIMEZONE": 0.0,
|
||||
"UPTIME": 418052,
|
||||
"ZIGBEE_CHANNEL": "15"
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"Conservatory": {
|
||||
"DEADBAND": 2,
|
||||
"DEVICE_ID": 3,
|
||||
"DEVICE_TYPE": 12,
|
||||
"FLOOR_LIMIT": 38,
|
||||
"FROST_TEMP": 12,
|
||||
"MAX_PREHEAT": 2,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 24,
|
||||
"SWITCHING DIFFERENTIAL": 1,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493839,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Dining Room": {
|
||||
"DEADBAND": 2,
|
||||
"DEVICE_ID": 1,
|
||||
"DEVICE_TYPE": 12,
|
||||
"FLOOR_LIMIT": 37,
|
||||
"FROST_TEMP": 12,
|
||||
"MAX_PREHEAT": 2,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 24,
|
||||
"SWITCHING DIFFERENTIAL": 1,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493858,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Door Contact": {
|
||||
"DEADBAND": 0,
|
||||
"DEVICE_ID": 11,
|
||||
"DEVICE_TYPE": 5,
|
||||
"FLOOR_LIMIT": 0,
|
||||
"FROST_TEMP": 0,
|
||||
"MAX_PREHEAT": 0,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 0,
|
||||
"SWITCHING DIFFERENTIAL": 0,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588700958,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": true
|
||||
},
|
||||
"Green Wall Watering": {
|
||||
"DEADBAND": 0,
|
||||
"DEVICE_ID": 10,
|
||||
"DEVICE_TYPE": 6,
|
||||
"FLOOR_LIMIT": 0,
|
||||
"FROST_TEMP": 0,
|
||||
"MAX_PREHEAT": 0,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 79,
|
||||
"SWITCHING DIFFERENTIAL": 0,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588494897,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Hallway": {
|
||||
"DEADBAND": 2,
|
||||
"DEVICE_ID": 6,
|
||||
"DEVICE_TYPE": 12,
|
||||
"FLOOR_LIMIT": 37,
|
||||
"FROST_TEMP": 12,
|
||||
"MAX_PREHEAT": 2,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 24,
|
||||
"SWITCHING DIFFERENTIAL": 1,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493838,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Kitchen": {
|
||||
"DEADBAND": 2,
|
||||
"DEVICE_ID": 5,
|
||||
"DEVICE_TYPE": 12,
|
||||
"FLOOR_LIMIT": 37,
|
||||
"FROST_TEMP": 12,
|
||||
"MAX_PREHEAT": 2,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 24,
|
||||
"SWITCHING DIFFERENTIAL": 1,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493861,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Living Room": {
|
||||
"DEADBAND": 2,
|
||||
"DEVICE_ID": 4,
|
||||
"DEVICE_TYPE": 12,
|
||||
"FLOOR_LIMIT": 37,
|
||||
"FROST_TEMP": 12,
|
||||
"MAX_PREHEAT": 2,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 24,
|
||||
"SWITCHING DIFFERENTIAL": 1,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493838,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Living Room North": {
|
||||
"DEADBAND": 0,
|
||||
"DEVICE_ID": 9,
|
||||
"DEVICE_TYPE": 6,
|
||||
"FLOOR_LIMIT": 0,
|
||||
"FROST_TEMP": 0,
|
||||
"MAX_PREHEAT": 0,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 79,
|
||||
"SWITCHING DIFFERENTIAL": 0,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493846,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Living Room South": {
|
||||
"DEADBAND": 0,
|
||||
"DEVICE_ID": 8,
|
||||
"DEVICE_TYPE": 6,
|
||||
"FLOOR_LIMIT": 0,
|
||||
"FROST_TEMP": 0,
|
||||
"MAX_PREHEAT": 0,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 79,
|
||||
"SWITCHING DIFFERENTIAL": 0,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493846,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Shed Heating": {
|
||||
"DEADBAND": 2,
|
||||
"DEVICE_ID": 7,
|
||||
"DEVICE_TYPE": 12,
|
||||
"FLOOR_LIMIT": 28,
|
||||
"FROST_TEMP": 9,
|
||||
"MAX_PREHEAT": 0,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 24,
|
||||
"SWITCHING DIFFERENTIAL": 1,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493854,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
},
|
||||
"Shower Room": {
|
||||
"DEADBAND": 2,
|
||||
"DEVICE_ID": 2,
|
||||
"DEVICE_TYPE": 12,
|
||||
"FLOOR_LIMIT": 28,
|
||||
"FROST_TEMP": 12,
|
||||
"MAX_PREHEAT": 2,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PUMP_DELAY": 0,
|
||||
"RF_SENSOR_MODE": "self",
|
||||
"STAT_FAILSAFE": 0,
|
||||
"STAT_VERSION": 24,
|
||||
"SWITCHING DIFFERENTIAL": 1,
|
||||
"SWITCH_DELAY": 0,
|
||||
"SYSTEM_TYPE": 0,
|
||||
"TIMESTAMP": 1588493860,
|
||||
"USER_LIMIT": 0,
|
||||
"WINDOW_SWITCH_OPEN": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,730 @@
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 21,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "24.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "24.0",
|
||||
"MIN_TEMPERATURE": "21.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "3 days 23:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "3:24",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 24,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Dining Room"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "22.9",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 23,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "26.0",
|
||||
"MIN_TEMPERATURE": "23.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "3 days 23:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "REMOTE_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 24,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Shower Room"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 23,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "25.7",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 16,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "26.0",
|
||||
"MIN_TEMPERATURE": "21.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "3 days 23:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 24,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Conservatory"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 27,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "25.7",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "26.0",
|
||||
"MIN_TEMPERATURE": "21.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "3 days 23:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "3:24",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 24,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Living Room"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 19,
|
||||
"CURRENT_SET_TEMPERATURE": "21.0",
|
||||
"CURRENT_TEMPERATURE": "23.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "24.0",
|
||||
"MIN_TEMPERATURE": "20.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "3 days 23:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 24,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Kitchen"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 19,
|
||||
"CURRENT_SET_TEMPERATURE": "20.0",
|
||||
"CURRENT_TEMPERATURE": "21.7",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "23.0",
|
||||
"MIN_TEMPERATURE": "21.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "3 days 22:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 24,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Hallway"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "9.0",
|
||||
"CURRENT_TEMPERATURE": "19.4",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 9,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "22.0",
|
||||
"MIN_TEMPERATURE": "15.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "4 days 08:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 5,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 24,
|
||||
"WRITE_COUNT": 1,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Shed Heating"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "255.255",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 6,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 1,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "255.255",
|
||||
"MIN_TEMPERATURE": "255.255",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_ON": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 79,
|
||||
"WRITE_COUNT": 11,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Living Room South"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "255.255",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 6,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "255.255",
|
||||
"MIN_TEMPERATURE": "255.255",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_ON": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": true,
|
||||
"TIME_CLOCK_OVERIDE_BIT": true,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 79,
|
||||
"WRITE_COUNT": 192,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Living Room North"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "255.255",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 6,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 1,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "255.255",
|
||||
"MIN_TEMPERATURE": "255.255",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 79,
|
||||
"WRITE_COUNT": 57,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Green Wall Watering"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "255.255",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 10,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "255.255",
|
||||
"MIN_TEMPERATURE": "255.255",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "5DAY/2DAY",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 69,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "repeaternode54473"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,664 @@
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 23,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "22.2",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "22.0",
|
||||
"MIN_TEMPERATURE": "21.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "6 days 23:00",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "2:42",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 20,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Dining Room"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "22.6",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 23,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "24.0",
|
||||
"MIN_TEMPERATURE": "23.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "6 days 23:00",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "REMOTE_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 20,
|
||||
"WRITE_COUNT": 4,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Shower Room"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 26,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "23.3",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 16,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "25.0",
|
||||
"MIN_TEMPERATURE": "20.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "6 days 23:00",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "3:48",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 20,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Conservatory"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 28,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "22.6",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "24.0",
|
||||
"MIN_TEMPERATURE": "19.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "6 days 23:00",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "3:16",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 20,
|
||||
"WRITE_COUNT": 2,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Living Room"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 23,
|
||||
"CURRENT_SET_TEMPERATURE": "22.0",
|
||||
"CURRENT_TEMPERATURE": "23.6",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "23.0",
|
||||
"MIN_TEMPERATURE": "20.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "6 days 23:00",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "2:08",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 20,
|
||||
"WRITE_COUNT": 6,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Kitchen"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 17,
|
||||
"CURRENT_SET_TEMPERATURE": "20.0",
|
||||
"CURRENT_TEMPERATURE": "20.1",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 21,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "21.0",
|
||||
"MIN_TEMPERATURE": "20.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "7 days 00:00",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AND_FLOOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 20,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Hallway"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 23,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "10.0",
|
||||
"CURRENT_TEMPERATURE": "17.3",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 12,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 10,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "19.0",
|
||||
"MIN_TEMPERATURE": "16.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "7 days 08:00",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 5,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 20,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Shed"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "255.255",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 6,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 1,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "255.255",
|
||||
"MIN_TEMPERATURE": "255.255",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_ON": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 79,
|
||||
"WRITE_COUNT": 11,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Plug South"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "255.255",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 6,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "255.255",
|
||||
"MIN_TEMPERATURE": "255.255",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_ON": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": true,
|
||||
"TIME_CLOCK_OVERIDE_BIT": true,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 79,
|
||||
"WRITE_COUNT": 7,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Plug North"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 127,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "255.255",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 6,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 1,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "255.255",
|
||||
"MIN_TEMPERATURE": "255.255",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": false,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "24HOURSFIXED",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 79,
|
||||
"WRITE_COUNT": 28,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Watering System"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,466 @@
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 20,
|
||||
"CURRENT_SET_TEMPERATURE": "20.0",
|
||||
"CURRENT_TEMPERATURE": "19.8",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 1,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 12,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "20.0",
|
||||
"MIN_TEMPERATURE": "19.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "5 days 19:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "5:13",
|
||||
"PROGRAM_MODE": "5DAY/2DAY",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "FLOOR_SENSOR_ONLY",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 108,
|
||||
"WRITE_COUNT": 89,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Living Room Floor"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "19.5",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 14,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Master Bedroom"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 22,
|
||||
"CURRENT_SET_TEMPERATURE": "12.0",
|
||||
"CURRENT_TEMPERATURE": "21.5",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 1,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 12,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "1717",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "23.0",
|
||||
"MIN_TEMPERATURE": "22.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "5 days 23:55",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "5DAY/2DAY",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "FLOOR_SENSOR_ONLY",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 108,
|
||||
"WRITE_COUNT": 26,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Bathroom Floor"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 22,
|
||||
"CURRENT_SET_TEMPERATURE": "12.0",
|
||||
"CURRENT_TEMPERATURE": "21.6",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 1,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 24,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "23.0",
|
||||
"MIN_TEMPERATURE": "21.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "5 days 22:30",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "1:02",
|
||||
"PROGRAM_MODE": "5DAY/2DAY",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "FLOOR_SENSOR_ONLY",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 108,
|
||||
"WRITE_COUNT": 27,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Ensuite Floor"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "20.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 14,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Nursery"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "0.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 5,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Back Door"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "0.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 5,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Nursery Window"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,466 @@
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 20,
|
||||
"CURRENT_SET_TEMPERATURE": "7.0",
|
||||
"CURRENT_TEMPERATURE": "19.8",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 1,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 12,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "20.0",
|
||||
"MIN_TEMPERATURE": "19.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "255 days 255:255",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "5:13",
|
||||
"PROGRAM_MODE": "5DAY/2DAY",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "FLOOR_SENSOR_ONLY",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": true,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 108,
|
||||
"WRITE_COUNT": 90,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Living Room Floor"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "19.5",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 14,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Master Bedroom"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 22,
|
||||
"CURRENT_SET_TEMPERATURE": "12.0",
|
||||
"CURRENT_TEMPERATURE": "21.6",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 1,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 12,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "1717",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "23.0",
|
||||
"MIN_TEMPERATURE": "22.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "5 days 23:55",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "255:255",
|
||||
"PROGRAM_MODE": "5DAY/2DAY",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "FLOOR_SENSOR_ONLY",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 108,
|
||||
"WRITE_COUNT": 26,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Bathroom Floor"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 22,
|
||||
"CURRENT_SET_TEMPERATURE": "12.0",
|
||||
"CURRENT_TEMPERATURE": "21.6",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 1,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 24,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "23.0",
|
||||
"MIN_TEMPERATURE": "21.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "5 days 22:30",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "1:02",
|
||||
"PROGRAM_MODE": "5DAY/2DAY",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "FLOOR_SENSOR_ONLY",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 108,
|
||||
"WRITE_COUNT": 27,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": true,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Ensuite Floor"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": false,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "20.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 14,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": false,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"THERMOSTAT": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Nursery"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": true,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "0.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 5,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": true,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Back Door"
|
||||
},
|
||||
{
|
||||
"AWAY": false,
|
||||
"COOLING": false,
|
||||
"COOLING_ENABLED": false,
|
||||
"COOLING_TEMPERATURE_IN_WHOLE_DEGREES": 0,
|
||||
"COOL_INP": true,
|
||||
"COUNT_DOWN_TIME": "0:00",
|
||||
"CRADLE_PAIRED_TO_REMOTE_SENSOR": false,
|
||||
"CRADLE_PAIRED_TO_STAT": false,
|
||||
"CURRENT_FLOOR_TEMPERATURE": 0,
|
||||
"CURRENT_SET_TEMPERATURE": "0.0",
|
||||
"CURRENT_TEMPERATURE": "0.0",
|
||||
"DEMAND": false,
|
||||
"DEVICE_TYPE": 5,
|
||||
"ENABLE_BOILER": false,
|
||||
"ENABLE_COOLING": false,
|
||||
"ENABLE_PUMP": false,
|
||||
"ENABLE_VALVE": false,
|
||||
"ENABLE_ZONE": false,
|
||||
"FAILSAFE_STATE": false,
|
||||
"FAIL_SAFE_ENABLED": false,
|
||||
"FLOOR_LIMIT": false,
|
||||
"FULL/PARTIAL_LOCK_AVAILABLE": false,
|
||||
"HEAT/COOL_MODE": false,
|
||||
"HEATING": false,
|
||||
"HOLD_TEMPERATURE": 0,
|
||||
"HOLD_TIME": "0:00",
|
||||
"HOLIDAY": false,
|
||||
"HOLIDAY_DAYS": 0,
|
||||
"HUMIDITY": 0,
|
||||
"LOCK": false,
|
||||
"LOCK_PIN_NUMBER": "0000",
|
||||
"LOW_BATTERY": true,
|
||||
"MAX_TEMPERATURE": "0.0",
|
||||
"MIN_TEMPERATURE": "0.0",
|
||||
"MODULATION_LEVEL": 0,
|
||||
"NEXT_ON_TIME": "0 days 00:00",
|
||||
"OFFLINE": 0,
|
||||
"OUPUT_DELAY": false,
|
||||
"OUTPUT_DELAY": 0,
|
||||
"PREHEAT": false,
|
||||
"PREHEAT_TIME": "0:00",
|
||||
"PROGRAM_MODE": "NONPROGRAMMABLE",
|
||||
"PUMP_DELAY": false,
|
||||
"RADIATORS_OR_UNDERFLOOR": false,
|
||||
"SENSOR_SELECTION": "BUILT_IN_AIR_SENSOR",
|
||||
"SET_COUNTDOWN_TIME": 0,
|
||||
"STANDBY": false,
|
||||
"STAT_MODE": {
|
||||
"4_HEAT_LEVELS": true,
|
||||
"MANUAL_OFF": true,
|
||||
"TIMECLOCK": true
|
||||
},
|
||||
"TEMPERATURE_FORMAT": false,
|
||||
"TEMP_HOLD": false,
|
||||
"TIMECLOCK_MODE": false,
|
||||
"TIMER": false,
|
||||
"TIME_CLOCK_OVERIDE_BIT": false,
|
||||
"ULTRA_VERSION": 0,
|
||||
"VERSION_NUMBER": 0,
|
||||
"WRITE_COUNT": 0,
|
||||
"ZONE_1PAIRED_TO_MULTILINK": false,
|
||||
"ZONE_1_OR_2": false,
|
||||
"ZONE_2_PAIRED_TO_MULTILINK": false,
|
||||
"device": "Nursery Window"
|
||||
}
|
||||
]
|
||||
}
|
||||
1805
bundles/org.openhab.binding.neohub/src/test/resources/live_data.json
Normal file
1805
bundles/org.openhab.binding.neohub/src/test/resources/live_data.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"ALT_TIMER_FORMAT": 1,
|
||||
"CORF": "C",
|
||||
"DEVICE_ID": "NeoHub",
|
||||
"DST_AUTO": true,
|
||||
"DST_ON": true,
|
||||
"EXTENDED_HISTORY": "off",
|
||||
"FORMAT": 1,
|
||||
"GDEVLIST": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
],
|
||||
"GLOBAL_HC_MODE": "heating",
|
||||
"GLOBAL_SYSTEM_TYPE": "HeatOnly",
|
||||
"HEATING_LEVELS": 4,
|
||||
"HUB_TYPE": 2,
|
||||
"HUB_VERSION": 2134,
|
||||
"NTP_ON": "Running",
|
||||
"PARTITION": "4",
|
||||
"TIMESTAMP": 0,
|
||||
"TIMEZONESTR": null,
|
||||
"TIME_ZONE": 0.0,
|
||||
"UTC": 1588513535
|
||||
}
|
||||
Reference in New Issue
Block a user