added migrated 2.x add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer
2020-09-21 01:58:32 +02:00
parent bbf1a7fd29
commit 6df6783b60
11662 changed files with 1302875 additions and 11 deletions

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.verisure-${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-verisure" description="Verisure Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<feature>openhab-transport-serial</feature>
<bundle dependency="true">mvn:org.jsoup/jsoup/1.8.3</bundle>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.verisure/${project.version}</bundle>
</feature>
</features>

View File

@@ -0,0 +1,41 @@
/**
* 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.verisure.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.dto.VerisureThingDTO;
/**
* The {@link DeviceStatusListener} is notified when a device status has changed
* or a device has been removed or added.
*
* @author Jarle Hjortland - Initial contribution
* @author Jan Gustafsson - Updated after code review comments
*
*/
@NonNullByDefault
public interface DeviceStatusListener<T extends VerisureThingDTO> {
/**
* This method is called whenever the state of the given device has changed.
*
* @param thing
* The thing that was changed.
*/
void onDeviceStateChanged(T thing);
/**
* This method returns the thing's class
*/
public Class<T> getVerisureThingClass();
}

View File

@@ -0,0 +1,165 @@
/**
* 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.verisure.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link VerisureBinding} class defines common constants, which are
* used across the whole binding.
*
* @author l3rum - Initial contribution
* @author Jan Gustafsson - Furher development
*/
@NonNullByDefault
public class VerisureBindingConstants {
public static final String BINDING_ID = "verisure";
// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge");
public static final ThingTypeUID THING_TYPE_ALARM = new ThingTypeUID(BINDING_ID, "alarm");
public static final ThingTypeUID THING_TYPE_SMARTPLUG = new ThingTypeUID(BINDING_ID, "smartPlug");
public static final ThingTypeUID THING_TYPE_SMOKEDETECTOR = new ThingTypeUID(BINDING_ID, "smokeDetector");
public static final ThingTypeUID THING_TYPE_WATERDETECTOR = new ThingTypeUID(BINDING_ID, "waterDetector");
public static final ThingTypeUID THING_TYPE_SIREN = new ThingTypeUID(BINDING_ID, "siren");
public static final ThingTypeUID THING_TYPE_DOORWINDOW = new ThingTypeUID(BINDING_ID, "doorWindowSensor");
public static final ThingTypeUID THING_TYPE_USERPRESENCE = new ThingTypeUID(BINDING_ID, "userPresence");
public static final ThingTypeUID THING_TYPE_SMARTLOCK = new ThingTypeUID(BINDING_ID, "smartLock");
public static final ThingTypeUID THING_TYPE_BROADBAND_CONNECTION = new ThingTypeUID(BINDING_ID,
"broadbandConnection");
public static final ThingTypeUID THING_TYPE_NIGHT_CONTROL = new ThingTypeUID(BINDING_ID, "nightControl");
public static final ThingTypeUID THING_TYPE_MICE_DETECTION = new ThingTypeUID(BINDING_ID, "miceDetection");
public static final ThingTypeUID THING_TYPE_EVENT_LOG = new ThingTypeUID(BINDING_ID, "eventLog");
public static final ThingTypeUID THING_TYPE_GATEWAY = new ThingTypeUID(BINDING_ID, "gateway");
// List of all Channel ids
public static final String CHANNEL_NUMERIC_STATUS = "numericStatus";
public static final String CHANNEL_TEMPERATURE = "temperature";
public static final String CHANNEL_HUMIDITY = "humidity";
public static final String CHANNEL_HUMIDITY_ENABLED = "humidityEnabled";
public static final String CHANNEL_LOCATION = "location";
public static final String CHANNEL_STATUS = "status";
public static final String CHANNEL_CONNECTED = "connected";
public static final String CHANNEL_STATE = "state";
public static final String CHANNEL_LABEL = "label";
public static final String CHANNEL_USER_NAME = "userName";
public static final String CHANNEL_WEBACCOUNT = "webAccount";
public static final String CHANNEL_USER_LOCATION_STATUS = "userLocationStatus";
public static final String CHANNEL_USER_DEVICE_NAME = "userDeviceName";
public static final String CHANNEL_SMARTLOCK_VOLUME = "smartLockVolume";
public static final String CHANNEL_SMARTLOCK_VOICE_LEVEL = "smartLockVoiceLevel";
public static final String CHANNEL_SMARTLOCK_TRIGGER_CHANNEL = "smartLockTriggerChannel";
public static final String CHANNEL_AUTO_RELOCK = "autoRelock";
public static final String CHANNEL_SMARTPLUG_STATUS = "smartPlugStatus";
public static final String CHANNEL_SMARTPLUG_TRIGGER_CHANNEL = "smartPlugTriggerChannel";
public static final String CHANNEL_ALARM_STATUS = "alarmStatus";
public static final String CHANNEL_ALARM_TRIGGER_CHANNEL = "alarmTriggerChannel";
public static final String CHANNEL_SMARTLOCK_STATUS = "smartLockStatus";
public static final String CHANNEL_CHANGED_BY_USER = "changedByUser";
public static final String CHANNEL_CHANGED_VIA = "changedVia";
public static final String CHANNEL_TIMESTAMP = "timestamp";
public static final String CHANNEL_TEMPERATURE_TIMESTAMP = "temperatureTimestamp";
public static final String CHANNEL_HAZARDOUS = "hazardous";
public static final String CHANNEL_MOTOR_JAM = "motorJam";
public static final String CHANNEL_INSTALLATION_NAME = "installationName";
public static final String CHANNEL_INSTALLATION_ID = "installationId";
public static final String CHANNEL_COUNT_LATEST_DETECTION = "countLatestDetection";
public static final String CHANNEL_COUNT_LAST_24_HOURS = "countLast24Hours";
public static final String CHANNEL_DURATION_LATEST_DETECTION = "durationLatestDetection";
public static final String CHANNEL_DURATION_LAST_24_HOURS = "durationLast24Hours";
public static final String CHANNEL_LAST_EVENT_LOCATION = "lastEventLocation";
public static final String CHANNEL_LAST_EVENT_ID = "lastEventId";
public static final String CHANNEL_LAST_EVENT_DEVICE_ID = "lastEventDeviceId";
public static final String CHANNEL_LAST_EVENT_DEVICE_TYPE = "lastEventDeviceType";
public static final String CHANNEL_LAST_EVENT_TYPE = "lastEventType";
public static final String CHANNEL_LAST_EVENT_CATEGORY = "lastEventCategory";
public static final String CHANNEL_LAST_EVENT_TIME = "lastEventTime";
public static final String CHANNEL_LAST_EVENT_USER_NAME = "lastEventUserName";
public static final String CHANNEL_EVENT_LOG = "eventLog";
public static final String CHANNEL_STATUS_GSM_OVER_UDP = "statusGSMOverUDP";
public static final String CHANNEL_STATUS_GSM_OVER_SMS = "statusGSMOverSMS";
public static final String CHANNEL_STATUS_GPRS_OVER_UDP = "statusGPRSOverUDP";
public static final String CHANNEL_STATUS_ETH_OVER_UDP = "statusETHOverUDP";
public static final String CHANNEL_TEST_TIME_GSM_OVER_UDP = "testTimeGSMOverUDP";
public static final String CHANNEL_TEST_TIME_GSM_OVER_SMS = "testTimeGSMOverSMS";
public static final String CHANNEL_TEST_TIME_GPRS_OVER_UDP = "testTimeGPRSOverUDP";
public static final String CHANNEL_TEST_TIME_ETH_OVER_UDP = "testTimeETHOverUDP";
public static final String CHANNEL_GATEWAY_MODEL = "model";
public static final String CHANNEL_SMOKE_DETECTION_TRIGGER_CHANNEL = "smokeDetectionTriggerChannel";
public static final String CHANNEL_MICE_DETECTION_TRIGGER_CHANNEL = "miceDetectionTriggerChannel";
public static final String CHANNEL_WATER_DETECTION_TRIGGER_CHANNEL = "waterDetectionTriggerChannel";
public static final String CHANNEL_SIREN_TRIGGER_CHANNEL = "sirenTriggerChannel";
public static final String CHANNEL_NIGHT_CONTROL_TRIGGER_CHANNEL = "nightControlTriggerChannel";
public static final String CHANNEL_DOOR_WINDOW_TRIGGER_CHANNEL = "doorWindowTriggerChannel";
public static final String CHANNEL_GATEWAY_TRIGGER_CHANNEL = "gatewayTriggerChannel";
// Trigger channel events
public static final String TRIGGER_EVENT_LOCK = "LOCK";
public static final String TRIGGER_EVENT_UNLOCK = "UNLOCK";
public static final String TRIGGER_EVENT_LOCK_FAILURE = "LOCK_FAILURE";
public static final String TRIGGER_EVENT_ARM = "ARM";
public static final String TRIGGER_EVENT_DISARM = "DISARM";
public static final String TRIGGER_EVENT_FIRE = "FIRE";
public static final String TRIGGER_EVENT_INSTRUSION = "INTRUSION";
public static final String TRIGGER_EVENT_WATER = "WATER";
public static final String TRIGGER_EVENT_MICE = "MICE";
public static final String TRIGGER_EVENT_BATTERY_LOW = "BATTERY_LOW";
public static final String TRIGGER_EVENT_BATTERY_RESTORED = "BATTERY_RESTORED";
public static final String TRIGGER_EVENT_COM_FAILURE = "COM_FAILURE";
public static final String TRIGGER_EVENT_COM_RESTORED = "COM_RESTORED";
public static final String TRIGGER_EVENT_COM_TEST = "COM_TEST";
public static final String TRIGGER_EVENT_SABOTAGE_ALARM = "SABOTAGE_ALARM";
public static final String TRIGGER_EVENT_SABOTAGE_RESTORED = "SABOTAGE_RESTORED";
public static final String TRIGGER_EVENT_DOORWINDOW_OPENED = "DOORWINDOW_OPENED";
public static final String TRIGGER_EVENT_DOORWINDOW_CLOSED = "DOORWINDOW_CLOSED";
public static final String TRIGGER_EVENT_LOCATION_HOME = "LOCATION_HOME";
public static final String TRIGGER_EVENT_LOCATION_AWAY = "LOCATION_AWAY";
// REST URI constants
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
public static final String BASEURL = "https://mypages.verisure.com";
public static final String LOGON_SUF = BASEURL + "/j_spring_security_check?locale=en_GB";
public static final String ALARM_COMMAND = BASEURL + "/remotecontrol/armstatechange.cmd";
public static final String SMARTLOCK_LOCK_COMMAND = BASEURL + "/remotecontrol/lockunlock.cmd";
public static final String SMARTLOCK_SET_COMMAND = BASEURL + "/overview/setdoorlock.cmd";
public static final String SMARTLOCK_AUTORELOCK_COMMAND = BASEURL + "/settings/setautorelock.cmd";
public static final String SMARTLOCK_VOLUME_COMMAND = BASEURL + "/settings/setvolume.cmd";
public static final String SMARTPLUG_COMMAND = BASEURL + "/settings/smartplug/onoffplug.cmd";
public static final String START_REDIRECT = "/uk/start.html";
public static final String START_SUF = BASEURL + START_REDIRECT;
// GraphQL constants
public static final String STATUS = BASEURL + "/uk/status";
public static final String SETTINGS = BASEURL + "/uk/settings.html?giid=";
public static final String SET_INSTALLATION = BASEURL + "/setinstallation?giid=";
public static final String BASEURL_API = "https://m-api02.verisure.com";
public static final String START_GRAPHQL = "/graphql";
public static final String AUTH_TOKEN = "/auth/token";
public static final String AUTH_LOGIN = "/auth/login";
public static final String ALARMSTATUS_PATH = "/remotecontrol";
public static final String SMARTLOCK_PATH = "/overview/doorlock/";
public static final String DOORWINDOW_PATH = "/settings/doorwindow";
public static final String USERTRACKING_PATH = "/overview/usertrackingcontacts";
public static final String CLIMATEDEVICE_PATH = "/overview/climatedevice";
public static final String SMARTPLUG_PATH = "/settings/smartplug";
public static final String ETHERNETSTATUS_PATH = "/overview/ethernetstatus";
public static final String VACATIONMODE_PATH = "/overview/vacationmode";
public static final String TEMPERATURE_CONTROL_PATH = "/overview/temperaturecontrol";
public static final String MOUSEDETECTION_PATH = "/overview/mousedetection";
public static final String CAMERA_PATH = "/overview/camera";
}

View File

@@ -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.verisure.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* Configuration class for VerisureBridgeHandler bridge used to connect to the
* Verisure MyPage.
*
* @author Jarle Hjortland - Initial contribution
*/
@NonNullByDefault
public class VerisureBridgeConfiguration {
public @Nullable String username;
public @Nullable String password;
public int refresh;
public @Nullable String pin;
}

View File

@@ -0,0 +1,127 @@
/**
* 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.verisure.internal;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.verisure.internal.handler.VerisureAlarmThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureBridgeHandler;
import org.openhab.binding.verisure.internal.handler.VerisureBroadbandConnectionThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureClimateDeviceThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureDoorWindowThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureEventLogThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureGatewayThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureMiceDetectionThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureSmartLockThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureSmartPlugThingHandler;
import org.openhab.binding.verisure.internal.handler.VerisureUserPresenceThingHandler;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link VerisureHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @author Jarle Hjortland - Initial contribution
* @author Jan Gustafsson - Further development
*/
@NonNullByDefault
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.verisure")
public class VerisureHandlerFactory extends BaseThingHandlerFactory {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<ThingTypeUID>();
static {
SUPPORTED_THING_TYPES.addAll(VerisureBridgeHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureAlarmThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureSmartLockThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureSmartPlugThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureClimateDeviceThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureBroadbandConnectionThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureDoorWindowThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureUserPresenceThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureMiceDetectionThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureEventLogThingHandler.SUPPORTED_THING_TYPES);
SUPPORTED_THING_TYPES.addAll(VerisureGatewayThingHandler.SUPPORTED_THING_TYPES);
}
private final Logger logger = LoggerFactory.getLogger(VerisureHandlerFactory.class);
private final HttpClient httpClient;
@Activate
public VerisureHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
this.httpClient = httpClientFactory.getCommonHttpClient();
}
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
}
@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
logger.debug("createHandler this: {}", thing);
final ThingHandler thingHandler;
if (VerisureBridgeHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureBridgeHandler");
thingHandler = new VerisureBridgeHandler((Bridge) thing, httpClient);
} else if (VerisureAlarmThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureAlarmThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureAlarmThingHandler(thing);
} else if (VerisureSmartLockThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureSmartLockThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureSmartLockThingHandler(thing);
} else if (VerisureSmartPlugThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureSmartPlugThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureSmartPlugThingHandler(thing);
} else if (VerisureClimateDeviceThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureClimateDeviceThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureClimateDeviceThingHandler(thing);
} else if (VerisureBroadbandConnectionThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureBroadbandConnectionThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureBroadbandConnectionThingHandler(thing);
} else if (VerisureDoorWindowThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureDoorWindowThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureDoorWindowThingHandler(thing);
} else if (VerisureUserPresenceThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureUserPresenceThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureUserPresenceThingHandler(thing);
} else if (VerisureMiceDetectionThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureMiceDetectionThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureMiceDetectionThingHandler(thing);
} else if (VerisureEventLogThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureEventLogThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureEventLogThingHandler(thing);
} else if (VerisureGatewayThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("Create VerisureGatewayThingHandler {}", thing.getThingTypeUID());
thingHandler = new VerisureGatewayThingHandler(thing);
} else {
logger.debug("Not possible to create thing handler for thing {}", thing);
thingHandler = null;
}
return thingHandler;
}
}

View File

@@ -0,0 +1,47 @@
/**
* 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.verisure.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* Configuration class for VerisureThingHandler.
*
*
* @author Jan Gustafsson - Initial contribution
*/
@NonNullByDefault
public class VerisureThingConfiguration {
public static final String DEVICE_ID_LABEL = "deviceId";
private String deviceId = "";
private int numberOfEvents;
private int eventTriggerDelay;
public String getDeviceId() {
// Make sure device id is normalized, i.e. replace all non character/digits with empty string
return normalizeDeviceId(deviceId);
}
public static String normalizeDeviceId(String unnormalizedDeviceId) {
return unnormalizedDeviceId.replaceAll("[^a-zA-Z0-9]+", "");
}
public int getNumberOfEvents() {
return numberOfEvents;
}
public int getEventTriggerDelay() {
return eventTriggerDelay;
}
}

View File

@@ -0,0 +1,129 @@
/**
* 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.verisure.internal.discovery;
import java.util.Collection;
import java.util.Collections;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.verisure.internal.VerisureHandlerFactory;
import org.openhab.binding.verisure.internal.VerisureSession;
import org.openhab.binding.verisure.internal.VerisureThingConfiguration;
import org.openhab.binding.verisure.internal.dto.VerisureThingDTO;
import org.openhab.binding.verisure.internal.handler.VerisureBridgeHandler;
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.config.discovery.DiscoveryService;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The discovery service, notified by a listener on the VerisureSession.
*
* @author Jarle Hjortland - Initial contribution
* @author Jan Gustafsson - Further development
*
*/
@NonNullByDefault
public class VerisureThingDiscoveryService extends AbstractDiscoveryService
implements DiscoveryService, ThingHandlerService {
private static final int SEARCH_TIME_SECONDS = 60;
private final Logger logger = LoggerFactory.getLogger(VerisureThingDiscoveryService.class);
private @NonNullByDefault({}) VerisureBridgeHandler verisureBridgeHandler;
private @NonNullByDefault({}) ThingUID bridgeUID;
public VerisureThingDiscoveryService() {
super(VerisureHandlerFactory.SUPPORTED_THING_TYPES, SEARCH_TIME_SECONDS);
}
@Override
public void startScan() {
logger.debug("VerisureThingDiscoveryService:startScan");
removeOlderResults(getTimestampOfLastScan());
if (verisureBridgeHandler != null) {
VerisureSession session = verisureBridgeHandler.getSession();
if (session != null) {
Collection<VerisureThingDTO> verisureThings = session.getVerisureThings();
verisureThings.stream().forEach(thing -> {
logger.debug("Discovered thing: {}", thing);
onThingAddedInternal(thing);
});
}
}
}
private void onThingAddedInternal(VerisureThingDTO thing) {
logger.debug("VerisureThingDiscoveryService:OnThingAddedInternal");
ThingUID thingUID = getThingUID(thing);
String deviceId = thing.getDeviceId();
if (thingUID != null) {
if (verisureBridgeHandler != null) {
String label = "Device Id: " + deviceId;
if (thing.getLocation() != null) {
label += ", Location: " + thing.getLocation();
}
if (thing.getSiteName() != null) {
label += ", Site name: " + thing.getSiteName();
}
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID)
.withLabel(label).withProperty(VerisureThingConfiguration.DEVICE_ID_LABEL, deviceId)
.withRepresentationProperty(deviceId).build();
logger.debug("thinguid: {}, bridge {}, label {}", thingUID, bridgeUID, deviceId);
thingDiscovered(discoveryResult);
}
} else {
logger.debug("Discovered unsupported thing of type '{}' with deviceId {}", thing.getClass(), deviceId);
}
}
private @Nullable ThingUID getThingUID(VerisureThingDTO thing) {
ThingUID thingUID = null;
if (verisureBridgeHandler != null) {
String deviceId = thing.getDeviceId();
// Make sure device id is normalized, i.e. replace all non character/digits with empty string
deviceId = VerisureThingConfiguration.normalizeDeviceId(deviceId);
thingUID = new ThingUID(thing.getThingTypeUID(), bridgeUID, deviceId);
}
return thingUID;
}
@Override
public void activate() {
super.activate(Collections.singletonMap(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY, true));
}
@Override
public void deactivate() {
super.deactivate();
}
@Override
public void setThingHandler(@Nullable ThingHandler handler) {
if (handler instanceof VerisureBridgeHandler) {
verisureBridgeHandler = (VerisureBridgeHandler) handler;
bridgeUID = verisureBridgeHandler.getUID();
}
}
@Override
public @Nullable ThingHandler getThingHandler() {
return verisureBridgeHandler;
}
}

View File

@@ -0,0 +1,213 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_ALARM;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
/**
* The alarms of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureAlarmsDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_ALARM;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return true;
}
public static class ArmState {
private @Nullable String type;
private @Nullable String statusType;
private @Nullable String date;
private @Nullable String name;
private @Nullable String changedVia;
private boolean allowedForFirstLine;
private boolean allowed;
private List<Object> errorCodes = new ArrayList<>();
private @Nullable String typename;
public @Nullable String getType() {
return type;
}
public @Nullable String getStatusType() {
return statusType;
}
public void setStatusType(@Nullable String statusType) {
this.statusType = statusType;
}
public @Nullable String getDate() {
return date;
}
public @Nullable String getName() {
return name;
}
public @Nullable String getChangedVia() {
return changedVia;
}
public boolean getAllowedForFirstLine() {
return allowedForFirstLine;
}
public boolean getAllowed() {
return allowed;
}
public List<Object> getErrorCodes() {
return errorCodes;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (allowed ? 1231 : 1237);
result = prime * result + (allowedForFirstLine ? 1231 : 1237);
String localChangedVia = changedVia;
result = prime * result + ((localChangedVia == null) ? 0 : localChangedVia.hashCode());
String localDate = date;
result = prime * result + ((localDate == null) ? 0 : localDate.hashCode());
result = prime * result + errorCodes.hashCode();
String localName = name;
result = prime * result + ((localName == null) ? 0 : localName.hashCode());
String localStatusType = statusType;
result = prime * result + ((localStatusType == null) ? 0 : localStatusType.hashCode());
String localType = type;
result = prime * result + ((localType == null) ? 0 : localType.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ArmState other = (ArmState) obj;
if (allowed != other.allowed) {
return false;
}
if (allowedForFirstLine != other.allowedForFirstLine) {
return false;
}
String localChangedVia = changedVia;
if (localChangedVia == null) {
if (other.changedVia != null) {
return false;
}
} else if (!localChangedVia.equals(other.changedVia)) {
return false;
}
String localdate = date;
if (localdate == null) {
if (other.date != null) {
return false;
}
} else if (!localdate.equals(other.date)) {
return false;
}
if (!errorCodes.equals(other.errorCodes)) {
return false;
}
String localName = name;
if (localName == null) {
if (other.name != null) {
return false;
}
} else if (!localName.equals(other.name)) {
return false;
}
String localStatusType = statusType;
if (localStatusType == null) {
if (other.statusType != null) {
return false;
}
} else if (!localStatusType.equals(other.statusType)) {
return false;
}
String localType = type;
if (localType == null) {
if (other.type != null) {
return false;
}
} else if (!localType.equals(other.type)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "ArmState [type=" + type + ", statusType=" + statusType + ", date=" + date + ", name=" + name
+ ", changedVia=" + changedVia + ", allowedForFirstLine=" + allowedForFirstLine + ", allowed="
+ allowed + ", errorCodes=" + errorCodes + ", typename=" + typename + "]";
}
}
}

View File

@@ -0,0 +1,571 @@
/**
* 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.verisure.internal.dto;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.verisure.internal.VerisureThingConfiguration;
import org.openhab.binding.verisure.internal.dto.VerisureAlarmsDTO.ArmState;
import org.openhab.binding.verisure.internal.dto.VerisureBroadbandConnectionsDTO.Broadband;
import org.openhab.binding.verisure.internal.dto.VerisureClimatesDTO.Climate;
import org.openhab.binding.verisure.internal.dto.VerisureDoorWindowsDTO.DoorWindow;
import org.openhab.binding.verisure.internal.dto.VerisureEventLogDTO.EventLog;
import org.openhab.binding.verisure.internal.dto.VerisureGatewayDTO.CommunicationState;
import org.openhab.binding.verisure.internal.dto.VerisureMiceDetectionDTO.Mouse;
import org.openhab.binding.verisure.internal.dto.VerisureSmartLocksDTO.Doorlock;
import org.openhab.binding.verisure.internal.dto.VerisureSmartPlugsDTO.Smartplug;
import org.openhab.binding.verisure.internal.dto.VerisureUserPresencesDTO.UserTracking;
import org.openhab.core.thing.ThingTypeUID;
import com.google.gson.annotations.SerializedName;
/**
* A base JSON thing for other Verisure things to inherit from.
*
* @author Jarle Hjortland - Initial contribution
*
*/
@NonNullByDefault
public abstract class VerisureBaseThingDTO implements VerisureThingDTO {
protected String deviceId = "";
protected @Nullable String name;
protected @Nullable String location;
protected @Nullable String status;
protected @Nullable String siteName;
protected BigDecimal siteId = BigDecimal.ZERO;
protected Data data = new Data();
public @Nullable String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public @Nullable String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getDeviceId() {
return deviceId;
}
@Override
public void setDeviceId(String deviceId) {
// Make sure device id is normalized
this.deviceId = VerisureThingConfiguration.normalizeDeviceId(deviceId);
}
@Override
public @Nullable String getLocation() {
return location;
}
public void setLocation(@Nullable String location) {
this.location = location;
}
@Override
public @Nullable String getSiteName() {
return siteName;
}
@Override
public void setSiteName(@Nullable String siteName) {
this.siteName = siteName;
}
@Override
public BigDecimal getSiteId() {
return siteId;
}
@Override
public void setSiteId(BigDecimal siteId) {
this.siteId = siteId;
}
@Override
public abstract ThingTypeUID getThingTypeUID();
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + data.hashCode();
result = prime * result + deviceId.hashCode();
String localLocation = location;
result = prime * result + ((localLocation == null) ? 0 : localLocation.hashCode());
String localName = name;
result = prime * result + ((localName == null) ? 0 : localName.hashCode());
result = prime * result + siteId.hashCode();
String localSiteName = siteName;
result = prime * result + ((localSiteName == null) ? 0 : localSiteName.hashCode());
String localStatus = status;
result = prime * result + ((localStatus == null) ? 0 : localStatus.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VerisureBaseThingDTO other = (VerisureBaseThingDTO) obj;
if (!data.equals(other.data)) {
return false;
}
if (!deviceId.equals(other.deviceId)) {
return false;
}
String localLocation = location;
if (localLocation == null) {
if (other.location != null) {
return false;
}
} else if (!localLocation.equals(other.location)) {
return false;
}
String localName = name;
if (localName == null) {
if (other.name != null) {
return false;
}
} else if (!localName.equals(other.name)) {
return false;
}
if (!siteId.equals(other.siteId)) {
return false;
}
String localSiteName = siteName;
if (localSiteName == null) {
if (other.siteName != null) {
return false;
}
} else if (!localSiteName.equals(other.siteName)) {
return false;
}
String localStatus = status;
if (localStatus == null) {
if (other.status != null) {
return false;
}
} else if (!localStatus.equals(other.status)) {
return false;
}
return true;
}
@Override
public String toString() {
return "VerisureBaseThingDTO [deviceId=" + deviceId + ", name=" + name + ", location=" + location + ", status="
+ status + ", siteName=" + siteName + ", siteId=" + siteId + ", data=" + data + "]";
}
public static class Data {
private Installation installation = new Installation();
public Installation getInstallation() {
return installation;
}
public void setInstallation(Installation installation) {
this.installation = installation;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + installation.hashCode();
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Data other = (Data) obj;
if (!installation.equals(other.installation)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Data [installation=" + installation + "]";
}
}
public static class Installation {
private ArmState armState = new ArmState();
private Broadband broadband = new Broadband();
private EventLog eventLog = new EventLog();
private List<Climate> climates = new ArrayList<>();
private List<DoorWindow> doorWindows = new ArrayList<>();
private List<CommunicationState> communicationState = new ArrayList<>();
private List<Mouse> mice = new ArrayList<>();
private List<Doorlock> doorlocks = new ArrayList<>();
private List<Smartplug> smartplugs = new ArrayList<>();
private List<UserTracking> userTrackings = new ArrayList<>();
@SerializedName("__typename")
private @Nullable String typename;
public ArmState getArmState() {
return armState;
}
public Broadband getBroadband() {
return broadband;
}
public List<Climate> getClimates() {
return climates;
}
public void setClimates(List<Climate> climates) {
this.climates = climates;
}
public List<DoorWindow> getDoorWindows() {
return doorWindows;
}
public void setDoorWindows(List<DoorWindow> doorWindows) {
this.doorWindows = doorWindows;
}
public EventLog getEventLog() {
return eventLog;
}
public List<CommunicationState> getCommunicationState() {
return communicationState;
}
public List<Mouse> getMice() {
return mice;
}
public void setMice(List<Mouse> mice) {
this.mice = mice;
}
public List<Doorlock> getDoorlocks() {
return doorlocks;
}
public void setDoorlocks(List<Doorlock> doorlocks) {
this.doorlocks = doorlocks;
}
public List<Smartplug> getSmartplugs() {
return smartplugs;
}
public void setSmartplugs(List<Smartplug> smartplugs) {
this.smartplugs = smartplugs;
}
public List<UserTracking> getUserTrackings() {
return userTrackings;
}
public void setUserTrackings(List<UserTracking> userTrackings) {
this.userTrackings = userTrackings;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + armState.hashCode();
result = prime * result + broadband.hashCode();
result = prime * result + climates.hashCode();
result = prime * result + communicationState.hashCode();
result = prime * result + doorWindows.hashCode();
result = prime * result + doorlocks.hashCode();
result = prime * result + eventLog.hashCode();
result = prime * result + mice.hashCode();
result = prime * result + smartplugs.hashCode();
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
result = prime * result + userTrackings.hashCode();
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Installation other = (Installation) obj;
if (!armState.equals(other.armState)) {
return false;
}
if (!broadband.equals(other.broadband)) {
return false;
}
if (!climates.equals(other.climates)) {
return false;
}
if (!communicationState.equals(other.communicationState)) {
return false;
}
if (!doorWindows.equals(other.doorWindows)) {
return false;
}
if (!doorlocks.equals(other.doorlocks)) {
return false;
}
if (!eventLog.equals(other.eventLog)) {
return false;
}
if (!mice.equals(other.mice)) {
return false;
}
if (!smartplugs.equals(other.smartplugs)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
if (!userTrackings.equals(other.userTrackings)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Installation [armState=" + armState + ", broadband=" + broadband + ", eventLog=" + eventLog
+ ", climates=" + climates + ", doorWindows=" + doorWindows + ", communicationState="
+ communicationState + ", mice=" + mice + ", doorlocks=" + doorlocks + ", smartplugs=" + smartplugs
+ ", userTrackings=" + userTrackings + ", typename=" + typename + "]";
}
}
public static class Device {
private @Nullable String deviceLabel;
private @Nullable String area;
private Gui gui = new Gui();
@SerializedName("__typename")
private @Nullable String typename;
public @Nullable String getDeviceLabel() {
return deviceLabel;
}
public @Nullable String getArea() {
return area;
}
public Gui getGui() {
return gui;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localArea = area;
result = prime * result + ((localArea == null) ? 0 : localArea.hashCode());
String localDeviceLabel = deviceLabel;
result = prime * result + ((localDeviceLabel == null) ? 0 : localDeviceLabel.hashCode());
result = prime * result + gui.hashCode();
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Device other = (Device) obj;
String localArea = area;
if (localArea == null) {
if (other.area != null) {
return false;
}
} else if (!localArea.equals(other.area)) {
return false;
}
String localDeviceLabel = deviceLabel;
if (localDeviceLabel == null) {
if (other.deviceLabel != null) {
return false;
}
} else if (!localDeviceLabel.equals(other.deviceLabel)) {
return false;
}
if (!gui.equals(other.gui)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Device [deviceLabel=" + deviceLabel + ", area=" + area + ", gui=" + gui + ", typename=" + typename
+ "]";
}
}
public static class Gui {
private @Nullable String label;
private @Nullable String support;
@SerializedName("__typename")
private @Nullable String typename;
public @Nullable String getLabel() {
return label;
}
public @Nullable String getSupport() {
return support;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localLabel = label;
result = prime * result + ((localLabel == null) ? 0 : localLabel.hashCode());
String localSupport = support;
result = prime * result + ((localSupport == null) ? 0 : localSupport.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Gui other = (Gui) obj;
String localLabel = label;
if (localLabel == null) {
if (other.label != null) {
return false;
}
} else if (!localLabel.equals(other.label)) {
return false;
}
String localSupport = support;
if (localSupport == null) {
if (other.support != null) {
return false;
}
} else if (!localSupport.equals(other.support)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Gui [label=" + label + ", support=" + support + ", typename=" + typename + "]";
}
}
}

View File

@@ -0,0 +1,130 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_BROADBAND_CONNECTION;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
import com.google.gson.annotations.SerializedName;
/**
* The broadband connections of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureBroadbandConnectionsDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_BROADBAND_CONNECTION;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return true;
}
public static class Broadband {
private @Nullable String testDate;
private boolean isBroadbandConnected;
@SerializedName("__typename")
private @Nullable String typename;
public @Nullable String getTestDate() {
return testDate;
}
public boolean isBroadbandConnected() {
return isBroadbandConnected;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (isBroadbandConnected ? 1231 : 1237);
String localTestDate = testDate;
result = prime * result + ((localTestDate == null) ? 0 : localTestDate.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Broadband other = (Broadband) obj;
if (isBroadbandConnected != other.isBroadbandConnected) {
return false;
}
String localTestDate = testDate;
if (localTestDate == null) {
if (other.testDate != null) {
return false;
}
} else if (!localTestDate.equals(other.testDate)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Broadband [testDate=" + testDate + ", isBroadbandConnected=" + isBroadbandConnected + ", typename="
+ typename + "]";
}
}
}

View File

@@ -0,0 +1,187 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
import com.google.gson.annotations.SerializedName;
/**
* The climate devices of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureClimatesDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
String type = getData().getInstallation().getClimates().get(0).getDevice().getGui().getLabel();
if ("SMOKE".equals(type)) {
return THING_TYPE_SMOKEDETECTOR;
} else if ("WATER".equals(type)) {
return THING_TYPE_WATERDETECTOR;
} else if ("HOMEPAD".equals(type)) {
return THING_TYPE_NIGHT_CONTROL;
} else if ("SIREN".equals(type)) {
return THING_TYPE_SIREN;
} else {
return THING_TYPE_SMOKEDETECTOR;
}
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return true;
}
public static class Climate {
private Device device = new Device();
private boolean humidityEnabled;
private @Nullable String humidityTimestamp;
private double humidityValue;
private @Nullable String temperatureTimestamp;
private double temperatureValue;
@SerializedName("__typename")
private @Nullable String typename;
public Device getDevice() {
return device;
}
public boolean isHumidityEnabled() {
return humidityEnabled;
}
public @Nullable String getHumidityTimestamp() {
return humidityTimestamp;
}
public double getHumidityValue() {
return humidityValue;
}
public @Nullable String getTemperatureTimestamp() {
return temperatureTimestamp;
}
public double getTemperatureValue() {
return temperatureValue;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + device.hashCode();
result = prime * result + (humidityEnabled ? 1231 : 1237);
String localHumidityTimestamp = humidityTimestamp;
result = prime * result + ((localHumidityTimestamp == null) ? 0 : localHumidityTimestamp.hashCode());
long temp;
temp = Double.doubleToLongBits(humidityValue);
result = prime * result + (int) (temp ^ (temp >>> 32));
String localTemperatureTimestamp = temperatureTimestamp;
result = prime * result + ((localTemperatureTimestamp == null) ? 0 : localTemperatureTimestamp.hashCode());
temp = Double.doubleToLongBits(temperatureValue);
result = prime * result + (int) (temp ^ (temp >>> 32));
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Climate other = (Climate) obj;
if (!device.equals(other.device)) {
return false;
}
if (humidityEnabled != other.humidityEnabled) {
return false;
}
String localHumidityTimestamp = humidityTimestamp;
if (localHumidityTimestamp == null) {
if (other.humidityTimestamp != null) {
return false;
}
} else if (!localHumidityTimestamp.equals(other.humidityTimestamp)) {
return false;
}
if (Double.doubleToLongBits(humidityValue) != Double.doubleToLongBits(other.humidityValue)) {
return false;
}
String localTemperatureTimestamp = temperatureTimestamp;
if (localTemperatureTimestamp == null) {
if (other.temperatureTimestamp != null) {
return false;
}
} else if (!localTemperatureTimestamp.equals(other.temperatureTimestamp)) {
return false;
}
if (Double.doubleToLongBits(temperatureValue) != Double.doubleToLongBits(other.temperatureValue)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Climate [device=" + device + ", humidityEnabled=" + humidityEnabled + ", humidityTimestamp="
+ humidityTimestamp + ", humidityValue=" + humidityValue + ", temperatureTimestamp="
+ temperatureTimestamp + ", temperatureValue=" + temperatureValue + ", typename=" + typename + "]";
}
}
}

View File

@@ -0,0 +1,169 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_DOORWINDOW;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
import com.google.gson.annotations.SerializedName;
/**
* The door and window devices of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureDoorWindowsDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_DOORWINDOW;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return true;
}
public static class DoorWindow {
private Device device = new Device();
private @Nullable String type;
private @Nullable String state;
private boolean wired;
private @Nullable String reportTime;
@SerializedName("__typename")
private @Nullable String typename;
public Device getDevice() {
return device;
}
public @Nullable String getType() {
return type;
}
public @Nullable String getState() {
return state;
}
public boolean getWired() {
return wired;
}
public @Nullable String getReportTime() {
return reportTime;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + device.hashCode();
String localReportTime = reportTime;
result = prime * result + ((localReportTime == null) ? 0 : localReportTime.hashCode());
String localState = state;
result = prime * result + ((localState == null) ? 0 : localState.hashCode());
String localType = type;
result = prime * result + ((localType == null) ? 0 : localType.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
result = prime * result + (wired ? 1231 : 1237);
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DoorWindow other = (DoorWindow) obj;
if (!device.equals(other.device)) {
return false;
}
String localReportTime = reportTime;
if (localReportTime == null) {
if (other.reportTime != null) {
return false;
}
} else if (!localReportTime.equals(other.reportTime)) {
return false;
}
String localState = state;
if (localState == null) {
if (other.state != null) {
return false;
}
} else if (!localState.equals(other.state)) {
return false;
}
String localType = type;
if (localType == null) {
if (other.type != null) {
return false;
}
} else if (!localType.equals(other.type)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
if (wired != other.wired) {
return false;
}
return true;
}
@Override
public String toString() {
return "DoorWindow [device=" + device + ", type=" + type + ", state=" + state + ", wired=" + wired
+ ", reportTime=" + reportTime + ", typename=" + typename + "]";
}
}
}

View File

@@ -0,0 +1,347 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_EVENT_LOG;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
/**
* The event log of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureEventLogDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_EVENT_LOG;
}
public static class EventLog {
private boolean moreDataAvailable;
private List<PagedList> pagedList = new ArrayList<>();
private @Nullable String typename;
public boolean isMoreDataAvailable() {
return moreDataAvailable;
}
public List<PagedList> getPagedList() {
return pagedList;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (moreDataAvailable ? 1231 : 1237);
result = prime * result + pagedList.hashCode();
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
EventLog other = (EventLog) obj;
if (moreDataAvailable != other.moreDataAvailable) {
return false;
}
if (!pagedList.equals(other.pagedList)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "EventLog [moreDataAvailable=" + moreDataAvailable + ", pagedList=" + pagedList + ", typename="
+ typename + "]";
}
}
public static class PagedList {
private @Nullable Device device = new Device();
private @Nullable String gatewayArea;
private @Nullable String eventType;
private @Nullable String eventCategory;
private @Nullable String eventSource;
private @Nullable String eventId;
private @Nullable String eventTime;
private @Nullable String userName;
private @Nullable String armState;
private @Nullable String userType;
private @Nullable String climateValue;
private @Nullable String sensorType;
private @Nullable String eventCount;
private @Nullable String typename;
public @Nullable Device getDevice() {
return device;
}
public @Nullable String getGatewayArea() {
return gatewayArea;
}
public @Nullable String getEventType() {
return eventType;
}
public @Nullable String getEventCategory() {
return eventCategory;
}
public @Nullable String getEventSource() {
return eventSource;
}
public @Nullable String getEventId() {
return eventId;
}
public @Nullable String getEventTime() {
return eventTime;
}
public @Nullable String getUserName() {
return userName;
}
public @Nullable String getArmState() {
return armState;
}
public @Nullable String getUserType() {
return userType;
}
public @Nullable String getClimateValue() {
return climateValue;
}
public @Nullable String getSensorType() {
return sensorType;
}
public @Nullable String getEventCount() {
return eventCount;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localArmState = armState;
result = prime * result + ((localArmState == null) ? 0 : localArmState.hashCode());
String localClimateValue = climateValue;
result = prime * result + ((localClimateValue == null) ? 0 : localClimateValue.hashCode());
Device localDevice = device;
result = prime * result + ((localDevice == null) ? 0 : localDevice.hashCode());
String localEventCategory = eventCategory;
result = prime * result + ((localEventCategory == null) ? 0 : localEventCategory.hashCode());
String localEventCount = eventCount;
result = prime * result + ((localEventCount == null) ? 0 : localEventCount.hashCode());
String localEventId = eventId;
result = prime * result + ((localEventId == null) ? 0 : localEventId.hashCode());
String localEventSource = eventSource;
result = prime * result + ((localEventSource == null) ? 0 : localEventSource.hashCode());
String localEventTime = eventTime;
result = prime * result + ((localEventTime == null) ? 0 : localEventTime.hashCode());
String localEventType = eventType;
result = prime * result + ((localEventType == null) ? 0 : localEventType.hashCode());
String localGatewayArea = gatewayArea;
result = prime * result + ((localGatewayArea == null) ? 0 : localGatewayArea.hashCode());
String localSensorType = sensorType;
result = prime * result + ((localSensorType == null) ? 0 : localSensorType.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
String localUserName = userName;
result = prime * result + ((localUserName == null) ? 0 : localUserName.hashCode());
String localUserType = userType;
result = prime * result + ((localUserType == null) ? 0 : localUserType.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PagedList other = (PagedList) obj;
String localArmState = armState;
if (localArmState == null) {
if (other.armState != null) {
return false;
}
} else if (!localArmState.equals(other.armState)) {
return false;
}
String localClimateValue = climateValue;
if (localClimateValue == null) {
if (other.climateValue != null) {
return false;
}
} else if (!localClimateValue.equals(other.climateValue)) {
return false;
}
Device localDevice = device;
if (localDevice == null) {
if (other.device != null) {
return false;
}
} else if (!localDevice.equals(other.device)) {
return false;
}
String localEventCategory = eventCategory;
if (localEventCategory == null) {
if (other.eventCategory != null) {
return false;
}
} else if (!localEventCategory.equals(other.eventCategory)) {
return false;
}
String localEventCount = eventCount;
if (localEventCount == null) {
if (other.eventCount != null) {
return false;
}
} else if (!localEventCount.equals(other.eventCount)) {
return false;
}
String localEventId = eventId;
if (localEventId == null) {
if (other.eventId != null) {
return false;
}
} else if (!localEventId.equals(other.eventId)) {
return false;
}
String localEventSource = eventSource;
if (localEventSource == null) {
if (other.eventSource != null) {
return false;
}
} else if (!localEventSource.equals(other.eventSource)) {
return false;
}
String localEventTime = eventTime;
if (localEventTime == null) {
if (other.eventTime != null) {
return false;
}
} else if (!localEventTime.equals(other.eventTime)) {
return false;
}
String localEventType = eventType;
if (localEventType == null) {
if (other.eventType != null) {
return false;
}
} else if (!localEventType.equals(other.eventType)) {
return false;
}
String localGatewayArea = gatewayArea;
if (localGatewayArea == null) {
if (other.gatewayArea != null) {
return false;
}
} else if (!localGatewayArea.equals(other.gatewayArea)) {
return false;
}
String localSensorType = sensorType;
if (localSensorType == null) {
if (other.sensorType != null) {
return false;
}
} else if (!localSensorType.equals(other.sensorType)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
String localUserName = userName;
if (localUserName == null) {
if (other.userName != null) {
return false;
}
} else if (!localUserName.equals(other.userName)) {
return false;
}
String localUserType = userType;
if (localUserType == null) {
if (other.userType != null) {
return false;
}
} else if (!localUserType.equals(other.userType)) {
return false;
}
return true;
}
@Override
public String toString() {
return "PagedList [device=" + device + ", gatewayArea=" + gatewayArea + ", eventType=" + eventType
+ ", eventCategory=" + eventCategory + ", eventSource=" + eventSource + ", eventId=" + eventId
+ ", eventTime=" + eventTime + ", userName=" + userName + ", armState=" + armState + ", userType="
+ userType + ", climateValue=" + climateValue + ", sensorType=" + sensorType + ", eventCount="
+ eventCount + ", typename=" + typename + "]";
}
}
}

View File

@@ -0,0 +1,173 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_GATEWAY;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
/**
* The gateway in the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureGatewayDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_GATEWAY;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return true;
}
public static class CommunicationState {
private @Nullable String hardwareCarrierType;
private @Nullable String result;
private @Nullable String mediaType;
private Device device = new Device();
private @Nullable String testDate;
private @Nullable String typename;
public @Nullable String getHardwareCarrierType() {
return hardwareCarrierType;
}
public @Nullable String getResult() {
return result;
}
public @Nullable String getMediaType() {
return mediaType;
}
public Device getDevice() {
return device;
}
public @Nullable String getTestDate() {
return testDate;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + device.hashCode();
String locaHardwareCarrierType = hardwareCarrierType;
result = prime * result + ((locaHardwareCarrierType == null) ? 0 : locaHardwareCarrierType.hashCode());
String localMediaType = mediaType;
result = prime * result + ((localMediaType == null) ? 0 : localMediaType.hashCode());
String localResult = this.result;
result = prime * result + ((localResult == null) ? 0 : localResult.hashCode());
String localTestDate = testDate;
result = prime * result + ((localTestDate == null) ? 0 : localTestDate.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CommunicationState other = (CommunicationState) obj;
if (!device.equals(other.device)) {
return false;
}
String locaHardwareCarrierType = hardwareCarrierType;
if (locaHardwareCarrierType == null) {
if (other.hardwareCarrierType != null) {
return false;
}
} else if (!locaHardwareCarrierType.equals(other.hardwareCarrierType)) {
return false;
}
String localMediaType = mediaType;
if (localMediaType == null) {
if (other.mediaType != null) {
return false;
}
} else if (!localMediaType.equals(other.mediaType)) {
return false;
}
String localResult = result;
if (localResult == null) {
if (other.result != null) {
return false;
}
} else if (!localResult.equals(other.result)) {
return false;
}
String localTestDate = testDate;
if (localTestDate == null) {
if (other.testDate != null) {
return false;
}
} else if (!localTestDate.equals(other.testDate)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "CommunicationState [hardwareCarrierType=" + hardwareCarrierType + ", result=" + result
+ ", mediaType=" + mediaType + ", device=" + device + ", testDate=" + testDate + ", typename="
+ typename + "]";
}
}
}

View File

@@ -0,0 +1,300 @@
/**
* 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.verisure.internal.dto;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.verisure.internal.dto.VerisureBaseThingDTO.Installation;
import com.google.gson.annotations.SerializedName;
/**
* The installation(s) of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureInstallationsDTO {
private Data data = new Data();
public Data getData() {
return data;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + data.hashCode();
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VerisureInstallationsDTO other = (VerisureInstallationsDTO) obj;
if (!data.equals(other.data)) {
return false;
}
return true;
}
@Override
public String toString() {
return "VerisureInstallationsDTO [data=" + data + "]";
}
public static class Data {
private Installation installation = new Installation();
private Account account = new Account();
public Account getAccount() {
return account;
}
public Installation getInstallation() {
return installation;
}
public void setInstallation(Installation installation) {
this.installation = installation;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + account.hashCode();
result = prime * result + installation.hashCode();
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Data other = (Data) obj;
if (!account.equals(other.account)) {
return false;
}
if (!installation.equals(other.installation)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Data [installation=" + installation + ", account=" + account + "]";
}
}
public static class Account {
@SerializedName("__typename")
private @Nullable String typename;
private List<Owainstallation> owainstallations = new ArrayList<>();
public @Nullable String getTypename() {
return typename;
}
public List<Owainstallation> getOwainstallations() {
return owainstallations;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + owainstallations.hashCode();
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Account other = (Account) obj;
if (!owainstallations.equals(other.owainstallations)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Account [typename=" + typename + ", owainstallations=" + owainstallations + "]";
}
}
public static class Owainstallation {
@SerializedName("__typename")
private @Nullable String typename;
private @Nullable String alias;
private @Nullable String dealerId;
private @Nullable String giid;
private @Nullable String subsidiary;
private @Nullable String type;
public @Nullable String getTypename() {
return typename;
}
public @Nullable String getAlias() {
return alias;
}
public @Nullable String getDealerId() {
return dealerId;
}
public @Nullable String getGiid() {
return giid;
}
public @Nullable String getSubsidiary() {
return subsidiary;
}
public @Nullable String getType() {
return type;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localAlias = alias;
result = prime * result + ((localAlias == null) ? 0 : localAlias.hashCode());
String localDealerId = dealerId;
result = prime * result + ((localDealerId == null) ? 0 : localDealerId.hashCode());
String localGiid = giid;
result = prime * result + ((localGiid == null) ? 0 : localGiid.hashCode());
String localSubsidiary = subsidiary;
result = prime * result + ((localSubsidiary == null) ? 0 : localSubsidiary.hashCode());
String localType = type;
result = prime * result + ((localType == null) ? 0 : localType.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Owainstallation other = (Owainstallation) obj;
String localAlias = alias;
if (localAlias == null) {
if (other.alias != null) {
return false;
}
} else if (!localAlias.equals(other.alias)) {
return false;
}
String localDealerId = dealerId;
if (localDealerId == null) {
if (other.dealerId != null) {
return false;
}
} else if (!localDealerId.equals(other.dealerId)) {
return false;
}
String localGiid = giid;
if (localGiid == null) {
if (other.giid != null) {
return false;
}
} else if (!localGiid.equals(other.giid)) {
return false;
}
String localSubsidiary = subsidiary;
if (localSubsidiary == null) {
if (other.subsidiary != null) {
return false;
}
} else if (!localSubsidiary.equals(other.subsidiary)) {
return false;
}
String localType = type;
if (localType == null) {
if (other.type != null) {
return false;
}
} else if (!localType.equals(other.type)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Owainstallation [typename=" + typename + ", alias=" + alias + ", dealerId=" + dealerId + ", giid="
+ giid + ", subsidiary=" + subsidiary + ", type=" + type + "]";
}
}
}

View File

@@ -0,0 +1,279 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_MICE_DETECTION;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
/**
* The Mice detection status of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureMiceDetectionDTO extends VerisureBaseThingDTO {
public static final int UNDEFINED = -1;
private double temperatureValue = UNDEFINED;
private @Nullable String temperatureTimestamp;
public double getTemperatureValue() {
return temperatureValue;
}
public void setTemperatureValue(double temperatureValue) {
this.temperatureValue = temperatureValue;
}
public @Nullable String getTemperatureTime() {
return temperatureTimestamp;
}
public void setTemperatureTime(@Nullable String temperatureTimestamp) {
this.temperatureTimestamp = temperatureTimestamp;
}
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_MICE_DETECTION;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
String localTemperatureTimestamp = temperatureTimestamp;
result = prime * result + ((localTemperatureTimestamp == null) ? 0 : localTemperatureTimestamp.hashCode());
long temp;
temp = Double.doubleToLongBits(temperatureValue);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VerisureMiceDetectionDTO other = (VerisureMiceDetectionDTO) obj;
String localTemperatureTimestamp = temperatureTimestamp;
if (localTemperatureTimestamp == null) {
if (other.temperatureTimestamp != null) {
return false;
}
} else if (!localTemperatureTimestamp.equals(other.temperatureTimestamp)) {
return false;
}
if (Double.doubleToLongBits(temperatureValue) != Double.doubleToLongBits(other.temperatureValue)) {
return false;
}
return true;
}
@Override
public String toString() {
return "VerisureMiceDetectionDTO [temperatureValue=" + temperatureValue + ", temperatureTimestamp="
+ temperatureTimestamp + "]";
}
public static class Mouse {
private Device device = new Device();
private @Nullable Object type;
private List<Detection> detections = new ArrayList<>();
private @Nullable String typename;
public Device getDevice() {
return device;
}
public @Nullable Object getType() {
return type;
}
public List<Detection> getDetections() {
return detections;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + detections.hashCode();
result = prime * result + device.hashCode();
Object localType = type;
result = prime * result + ((localType == null) ? 0 : localType.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Mouse other = (Mouse) obj;
if (!detections.equals(other.detections)) {
return false;
}
if (!device.equals(other.device)) {
return false;
}
Object localType = type;
if (localType == null) {
if (other.type != null) {
return false;
}
} else if (!localType.equals(other.type)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Mouse [device=" + device + ", type=" + type + ", detections=" + detections + ", typename="
+ typename + "]";
}
}
public static class Detection {
private int count;
private @Nullable String gatewayTime;
private @Nullable String nodeTime;
private int duration;
private @Nullable String typename;
public int getCount() {
return count;
}
public @Nullable String getGatewayTime() {
return gatewayTime;
}
public @Nullable String getNodeTime() {
return nodeTime;
}
public int getDuration() {
return duration;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + count;
result = prime * result + duration;
String localGatewayTime = gatewayTime;
result = prime * result + ((localGatewayTime == null) ? 0 : localGatewayTime.hashCode());
String localNodeTime = nodeTime;
result = prime * result + ((localNodeTime == null) ? 0 : localNodeTime.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Detection other = (Detection) obj;
if (count != other.count) {
return false;
}
if (duration != other.duration) {
return false;
}
String localGatewayTime = gatewayTime;
if (localGatewayTime == null) {
if (other.gatewayTime != null) {
return false;
}
} else if (!localGatewayTime.equals(other.gatewayTime)) {
return false;
}
String localNodeTime = nodeTime;
if (localNodeTime == null) {
if (other.nodeTime != null) {
return false;
}
} else if (!localNodeTime.equals(other.nodeTime)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Detection [count=" + count + ", gatewayTime=" + gatewayTime + ", nodeTime=" + nodeTime
+ ", duration=" + duration + ", typename=" + typename + "]";
}
}
}

View File

@@ -0,0 +1,185 @@
/**
* 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.verisure.internal.dto;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* The SmartLock state of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureSmartLockDTO {
private boolean autoRelockEnabled;
private @Nullable String deviceLabel;
private DoorLockVolumeSettings doorLockVolumeSettings = new DoorLockVolumeSettings();
public boolean getAutoRelockEnabled() {
return autoRelockEnabled;
}
public @Nullable String getDeviceLabel() {
return deviceLabel;
}
public DoorLockVolumeSettings getDoorLockVolumeSettings() {
return doorLockVolumeSettings;
}
public static class DoorLockVolumeSettings {
private @Nullable String volume;
private @Nullable String voiceLevel;
private @Nullable String active;
private List<String> availableVolumes = new ArrayList<>();
private List<String> availableVoiceLevels = new ArrayList<>();
public @Nullable String getVolume() {
return volume;
}
public @Nullable String getVoiceLevel() {
return voiceLevel;
}
public @Nullable String getActive() {
return active;
}
public List<String> getAvailableVolumes() {
return availableVolumes;
}
public List<String> getAvailableVoiceLevels() {
return availableVoiceLevels;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localActive = active;
result = prime * result + ((localActive == null) ? 0 : localActive.hashCode());
result = prime * result + availableVoiceLevels.hashCode();
result = prime * result + availableVolumes.hashCode();
String localVoiceLevel = voiceLevel;
result = prime * result + ((localVoiceLevel == null) ? 0 : localVoiceLevel.hashCode());
String localVolume = volume;
result = prime * result + ((localVolume == null) ? 0 : localVolume.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DoorLockVolumeSettings other = (DoorLockVolumeSettings) obj;
String localActive = active;
if (localActive == null) {
if (other.active != null) {
return false;
}
} else if (!localActive.equals(other.active)) {
return false;
}
if (!availableVoiceLevels.equals(other.availableVoiceLevels)) {
return false;
}
if (!availableVolumes.equals(other.availableVolumes)) {
return false;
}
String localVoiceLevel = voiceLevel;
if (localVoiceLevel == null) {
if (other.voiceLevel != null) {
return false;
}
} else if (!localVoiceLevel.equals(other.voiceLevel)) {
return false;
}
String localVolume = volume;
if (localVolume == null) {
if (other.volume != null) {
return false;
}
} else if (!localVolume.equals(other.volume)) {
return false;
}
return true;
}
@Override
public String toString() {
return "DoorLockVolumeSettings [volume=" + volume + ", voiceLevel=" + voiceLevel + ", active=" + active
+ ", availableVolumes=" + availableVolumes + ", availableVoiceLevels=" + availableVoiceLevels + "]";
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (autoRelockEnabled ? 1231 : 1237);
String localDeviceLabel = deviceLabel;
result = prime * result + ((localDeviceLabel == null) ? 0 : localDeviceLabel.hashCode());
result = prime * result + doorLockVolumeSettings.hashCode();
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VerisureSmartLockDTO other = (VerisureSmartLockDTO) obj;
if (autoRelockEnabled != other.autoRelockEnabled) {
return false;
}
String localDeviceLabel = deviceLabel;
if (localDeviceLabel == null) {
if (other.deviceLabel != null) {
return false;
}
} else if (!localDeviceLabel.equals(other.deviceLabel)) {
return false;
}
if (!doorLockVolumeSettings.equals(other.doorLockVolumeSettings)) {
return false;
}
return true;
}
@Override
public String toString() {
return "VerisureSmartLockDTO [autoRelockEnabled=" + autoRelockEnabled + ", deviceLabel=" + deviceLabel
+ ", doorLockVolumeSettings=" + doorLockVolumeSettings + "]";
}
}

View File

@@ -0,0 +1,222 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_SMARTLOCK;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
import com.google.gson.annotations.SerializedName;
/**
* The smart locks of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureSmartLocksDTO extends VerisureBaseThingDTO {
private @Nullable VerisureSmartLockDTO smartLockJSON;
public @Nullable VerisureSmartLockDTO getSmartLockJSON() {
return smartLockJSON;
}
public void setSmartLockJSON(@Nullable VerisureSmartLockDTO smartLockJSON) {
this.smartLockJSON = smartLockJSON;
}
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_SMARTLOCK;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
VerisureSmartLockDTO localSmartLockJSON = smartLockJSON;
result = prime * result + ((localSmartLockJSON == null) ? 0 : localSmartLockJSON.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VerisureSmartLocksDTO other = (VerisureSmartLocksDTO) obj;
VerisureSmartLockDTO localSmartLockJSON = smartLockJSON;
if (localSmartLockJSON == null) {
if (other.smartLockJSON != null) {
return false;
}
} else if (!localSmartLockJSON.equals(other.smartLockJSON)) {
return false;
}
return true;
}
@Override
public String toString() {
return "VerisureSmartLocksDTO [smartLockJSON=" + smartLockJSON + "]";
}
public static class Doorlock {
@SerializedName("__typename")
private @Nullable String typename;
private @Nullable String currentLockState;
private @Nullable String eventTime;
private @Nullable String method;
private @Nullable String userString;
private Device device = new Device();
private boolean motorJam;
private boolean secureModeActive;
public @Nullable String getTypename() {
return typename;
}
public @Nullable String getCurrentLockState() {
return currentLockState;
}
public Device getDevice() {
return device;
}
public @Nullable String getEventTime() {
return eventTime;
}
public @Nullable String getMethod() {
return method;
}
public boolean isMotorJam() {
return motorJam;
}
public boolean getSecureModeActive() {
return secureModeActive;
}
public @Nullable String getUserString() {
return userString;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localCurrentLockState = currentLockState;
result = prime * result + ((localCurrentLockState == null) ? 0 : localCurrentLockState.hashCode());
result = prime * result + device.hashCode();
String localEventTime = eventTime;
result = prime * result + ((localEventTime == null) ? 0 : localEventTime.hashCode());
String localMethod = method;
result = prime * result + ((localMethod == null) ? 0 : localMethod.hashCode());
result = prime * result + (motorJam ? 1231 : 1237);
result = prime * result + (secureModeActive ? 1231 : 1237);
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
String localUserString = userString;
result = prime * result + ((localUserString == null) ? 0 : localUserString.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Doorlock other = (Doorlock) obj;
String localCurrentLockState = currentLockState;
if (localCurrentLockState == null) {
if (other.currentLockState != null) {
return false;
}
} else if (!localCurrentLockState.equals(other.currentLockState)) {
return false;
}
if (!device.equals(other.device)) {
return false;
}
String localEventTime = eventTime;
if (localEventTime == null) {
if (other.eventTime != null) {
return false;
}
} else if (!localEventTime.equals(other.eventTime)) {
return false;
}
String localMethod = method;
if (localMethod == null) {
if (other.method != null) {
return false;
}
} else if (!localMethod.equals(other.method)) {
return false;
}
if (motorJam != other.motorJam) {
return false;
}
if (secureModeActive != other.secureModeActive) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
String localUserString = userString;
if (localUserString == null) {
if (other.userString != null) {
return false;
}
} else if (!localUserString.equals(other.userString)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Doorlock [typename=" + typename + ", currentLockState=" + currentLockState + ", eventTime="
+ eventTime + ", method=" + method + ", userString=" + userString + ", device=" + device
+ ", motorJam=" + motorJam + ", secureModeActive=" + secureModeActive + "]";
}
}
}

View File

@@ -0,0 +1,154 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_SMARTPLUG;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
import com.google.gson.annotations.SerializedName;
/**
* The smart plugs of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureSmartPlugsDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_SMARTPLUG;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return true;
}
public static class Smartplug {
private Device device = new Device();
private @Nullable String currentState;
private @Nullable String icon;
private boolean isHazardous;
@SerializedName("__typename")
private @Nullable String typename;
public Device getDevice() {
return device;
}
public @Nullable String getCurrentState() {
return currentState;
}
public @Nullable String getIcon() {
return icon;
}
public boolean isHazardous() {
return isHazardous;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localCurrentState = currentState;
result = prime * result + ((localCurrentState == null) ? 0 : localCurrentState.hashCode());
result = prime * result + device.hashCode();
String localIcon = icon;
result = prime * result + ((localIcon == null) ? 0 : localIcon.hashCode());
result = prime * result + (isHazardous ? 1231 : 1237);
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Smartplug other = (Smartplug) obj;
String localCurrentState = currentState;
if (localCurrentState == null) {
if (other.currentState != null) {
return false;
}
} else if (!localCurrentState.equals(other.currentState)) {
return false;
}
if (!device.equals(other.device)) {
return false;
}
String localIcon = icon;
if (localIcon == null) {
if (other.icon != null) {
return false;
}
} else if (!localIcon.equals(other.icon)) {
return false;
}
if (isHazardous != other.isHazardous) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Smartplug [device=" + device + ", currentState=" + currentState + ", icon=" + icon
+ ", isHazardous=" + isHazardous + ", typename=" + typename + "]";
}
}
}

View File

@@ -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.verisure.internal.dto;
import java.math.BigDecimal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
/**
* The base identifer of all Verisure response objects.
*
* @author Jarle Hjortland - Initial contribution
* @author Jan Gustafsson - Further development
*
*/
@NonNullByDefault
public interface VerisureThingDTO {
String getDeviceId();
void setDeviceId(String deviceId);
@Nullable
String getLocation();
void setSiteName(@Nullable String siteName);
@Nullable
String getSiteName();
void setSiteId(BigDecimal siteId);
BigDecimal getSiteId();
ThingTypeUID getThingTypeUID();
}

View File

@@ -0,0 +1,247 @@
/**
* 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.verisure.internal.dto;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.THING_TYPE_USERPRESENCE;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingTypeUID;
import com.google.gson.annotations.SerializedName;
/**
* The user presences of the Verisure System.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureUserPresencesDTO extends VerisureBaseThingDTO {
@Override
public ThingTypeUID getThingTypeUID() {
return THING_TYPE_USERPRESENCE;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return true;
}
public static class UserTracking {
private boolean isCallingUser;
private @Nullable String webAccount;
private @Nullable String status;
private @Nullable String xbnContactId;
private @Nullable String currentLocationName;
private String deviceId = "";
private @Nullable String name;
private @Nullable String currentLocationTimestamp;
private @Nullable String deviceName;
private @Nullable String currentLocationId;
@SerializedName("__typename")
private @Nullable String typename;
public boolean getIsCallingUser() {
return isCallingUser;
}
public @Nullable String getWebAccount() {
return webAccount;
}
public @Nullable String getStatus() {
return status;
}
public @Nullable String getXbnContactId() {
return xbnContactId;
}
public @Nullable String getCurrentLocationName() {
return currentLocationName;
}
public @Nullable String getDeviceId() {
return deviceId;
}
public @Nullable String getName() {
return name;
}
public @Nullable String getCurrentLocationTimestamp() {
return currentLocationTimestamp;
}
public @Nullable String getDeviceName() {
return deviceName;
}
public @Nullable String getCurrentLocationId() {
return currentLocationId;
}
public @Nullable String getTypename() {
return typename;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String localCurrentLocationId = currentLocationId;
result = prime * result + ((localCurrentLocationId == null) ? 0 : localCurrentLocationId.hashCode());
String localCurrentLocationName = currentLocationName;
result = prime * result + ((localCurrentLocationName == null) ? 0 : localCurrentLocationName.hashCode());
String localCurrentLocationTimestamp = currentLocationTimestamp;
result = prime * result
+ ((localCurrentLocationTimestamp == null) ? 0 : localCurrentLocationTimestamp.hashCode());
result = prime * result + deviceId.hashCode();
String localDeviceName = deviceName;
result = prime * result + ((localDeviceName == null) ? 0 : localDeviceName.hashCode());
result = prime * result + (isCallingUser ? 1231 : 1237);
String localName = name;
result = prime * result + ((localName == null) ? 0 : localName.hashCode());
String localStatus = status;
result = prime * result + ((localStatus == null) ? 0 : localStatus.hashCode());
String localTypeName = typename;
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
String localWebAccount = webAccount;
result = prime * result + ((localWebAccount == null) ? 0 : localWebAccount.hashCode());
String localXbnContactId = xbnContactId;
result = prime * result + ((localXbnContactId == null) ? 0 : localXbnContactId.hashCode());
return result;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
UserTracking other = (UserTracking) obj;
String localCurrentLocationId = currentLocationId;
if (localCurrentLocationId == null) {
if (other.currentLocationId != null) {
return false;
}
} else if (!localCurrentLocationId.equals(other.currentLocationId)) {
return false;
}
String localCurrentLocationName = currentLocationName;
if (localCurrentLocationName == null) {
if (other.currentLocationName != null) {
return false;
}
} else if (!localCurrentLocationName.equals(other.currentLocationName)) {
return false;
}
String localCurrentLocationTimestamp = currentLocationTimestamp;
if (localCurrentLocationTimestamp == null) {
if (other.currentLocationTimestamp != null) {
return false;
}
} else if (!localCurrentLocationTimestamp.equals(other.currentLocationTimestamp)) {
return false;
}
if (!deviceId.equals(other.deviceId)) {
return false;
}
String localDeviceName = deviceName;
if (localDeviceName == null) {
if (other.deviceName != null) {
return false;
}
} else if (!localDeviceName.equals(other.deviceName)) {
return false;
}
if (isCallingUser != other.isCallingUser) {
return false;
}
String localName = name;
if (localName == null) {
if (other.name != null) {
return false;
}
} else if (!localName.equals(other.name)) {
return false;
}
String localStatus = status;
if (localStatus == null) {
if (other.status != null) {
return false;
}
} else if (!localStatus.equals(other.status)) {
return false;
}
String localTypeName = typename;
if (localTypeName == null) {
if (other.typename != null) {
return false;
}
} else if (!localTypeName.equals(other.typename)) {
return false;
}
String localWebAccount = webAccount;
if (localWebAccount == null) {
if (other.webAccount != null) {
return false;
}
} else if (!localWebAccount.equals(other.webAccount)) {
return false;
}
String localXbnContactId = xbnContactId;
if (localXbnContactId == null) {
if (other.xbnContactId != null) {
return false;
}
} else if (!localXbnContactId.equals(other.xbnContactId)) {
return false;
}
return true;
}
@Override
public String toString() {
return "UserTracking [isCallingUser=" + isCallingUser + ", webAccount=" + webAccount + ", status=" + status
+ ", xbnContactId=" + xbnContactId + ", currentLocationName=" + currentLocationName + ", deviceId="
+ deviceId + ", name=" + name + ", currentLocationTimestamp=" + currentLocationTimestamp
+ ", deviceName=" + deviceName + ", currentLocationId=" + currentLocationId + ", typename="
+ typename + "]";
}
}
}

View File

@@ -0,0 +1,213 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.verisure.internal.VerisureSession;
import org.openhab.binding.verisure.internal.dto.VerisureAlarmsDTO;
import org.openhab.binding.verisure.internal.dto.VerisureAlarmsDTO.ArmState;
import org.openhab.core.library.types.StringType;
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.ThingTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the Alarm Device thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureAlarmThingHandler extends VerisureThingHandler<VerisureAlarmsDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_ALARM);
private static final int REFRESH_DELAY_SECONDS = 10;
public VerisureAlarmThingHandler(Thing thing) {
super(thing);
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("handleCommand, channel: {}, command: {}", channelUID, command);
if (command instanceof RefreshType) {
super.handleCommand(channelUID, command);
} else if (channelUID.getId().equals(CHANNEL_ALARM_STATUS)) {
handleAlarmState(command);
scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
} else {
logger.warn("Unknown command! {}", command);
}
}
private void handleAlarmState(Command command) {
String deviceId = config.getDeviceId();
VerisureSession session = getSession();
if (session != null) {
VerisureAlarmsDTO alarm = session.getVerisureThing(deviceId, getVerisureThingClass());
if (alarm != null) {
BigDecimal installationId = alarm.getSiteId();
String pinCode = session.getPinCode(installationId);
if (pinCode != null) {
String url = START_GRAPHQL;
String operation, state = "";
switch (command.toString()) {
case "DISARMED":
operation = "disarm";
state = "armStateDisarm";
break;
case "ARMED_HOME":
operation = "armHome";
state = "armStateArmHome";
break;
case "ARMED_AWAY":
operation = "armAway";
state = "armStateArmAway";
break;
default:
logger.warn("Unknown alarm command: {}", command);
return;
}
ArrayList<AlarmDTO> list = new ArrayList<>();
AlarmDTO alarmJSON = new AlarmDTO();
VariablesDTO variables = new VariablesDTO();
variables.setCode(pinCode);
variables.setGiid(installationId.toString());
alarmJSON.setVariables(variables);
alarmJSON.setOperationName(operation);
String query = "mutation " + operation + "($giid: String!, $code: String!) {\n " + state
+ "(giid: $giid, code: $code)\n}\n";
alarmJSON.setQuery(query);
list.add(alarmJSON);
String queryQLAlarmSetState = gson.toJson(list);
logger.debug("Trying to set alarm state to {} with URL {} and data {}", operation, url,
queryQLAlarmSetState);
int httpResultCode = session.sendCommand(url, queryQLAlarmSetState, installationId);
if (httpResultCode == HttpStatus.OK_200) {
logger.debug("Alarm status successfully changed!");
} else {
logger.warn("Could not send command, HTTP result code: {}", httpResultCode);
}
} else {
logger.warn("PIN code is not configured! Mandatory to control Alarm!");
}
}
}
}
@Override
public Class<VerisureAlarmsDTO> getVerisureThingClass() {
return VerisureAlarmsDTO.class;
}
@Override
public synchronized void update(VerisureAlarmsDTO thing) {
updateAlarmState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateAlarmState(VerisureAlarmsDTO alarmsJSON) {
ArmState armState = alarmsJSON.getData().getInstallation().getArmState();
String alarmStatus = armState.getStatusType();
if (alarmStatus != null) {
getThing().getChannels().stream().map(Channel::getUID)
.filter(channelUID -> isLinked(channelUID) && !channelUID.getId().equals("timestamp"))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), armState);
updateState(channelUID, state);
});
updateTimeStamp(armState.getDate());
updateInstallationChannels(alarmsJSON);
} else {
logger.warn("Alarm status is null!");
}
}
public State getValue(String channelId, ArmState armState) {
switch (channelId) {
case CHANNEL_ALARM_STATUS:
return new StringType(armState.getStatusType());
case CHANNEL_CHANGED_BY_USER:
return new StringType(armState.getName());
case CHANNEL_CHANGED_VIA:
return new StringType(armState.getChangedVia());
}
return UnDefType.UNDEF;
}
private static class AlarmDTO {
@SuppressWarnings("unused")
private @Nullable String operationName;
@SuppressWarnings("unused")
private VariablesDTO variables = new VariablesDTO();
@SuppressWarnings("unused")
private @Nullable String query;
public void setOperationName(String operationName) {
this.operationName = operationName;
}
public void setVariables(VariablesDTO variables) {
this.variables = variables;
}
public void setQuery(String query) {
this.query = query;
}
}
private static class VariablesDTO {
@SuppressWarnings("unused")
private @Nullable String giid;
@SuppressWarnings("unused")
private @Nullable String code;
public void setGiid(String giid) {
this.giid = giid;
}
public void setCode(String code) {
this.code = code;
}
}
@Override
public void updateTriggerChannel(String event) {
logger.debug("ThingHandler trigger event {}", event);
triggerChannel(CHANNEL_SMARTLOCK_TRIGGER_CHANNEL, event);
}
}

View File

@@ -0,0 +1,266 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.verisure.internal.DeviceStatusListener;
import org.openhab.binding.verisure.internal.VerisureBridgeConfiguration;
import org.openhab.binding.verisure.internal.VerisureSession;
import org.openhab.binding.verisure.internal.discovery.VerisureThingDiscoveryService;
import org.openhab.binding.verisure.internal.dto.VerisureThingDTO;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.BaseBridgeHandler;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link VerisureBridgeHandler} is responsible for handling commands, which are
* sent to one of the channels.
*
* @author l3rum - Initial contribution
* @author Jan Gustafsson - Furher development
*/
@NonNullByDefault
public class VerisureBridgeHandler extends BaseBridgeHandler {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_BRIDGE);
private static final int REFRESH_DELAY_SECONDS = 30;
private final Logger logger = LoggerFactory.getLogger(VerisureBridgeHandler.class);
private final ReentrantLock immediateRefreshJobLock = new ReentrantLock();
private final HttpClient httpClient;
private String authstring = "";
private @Nullable String pinCode;
private static int REFRESH_SEC = 600;
private @Nullable ScheduledFuture<?> refreshJob;
private @Nullable ScheduledFuture<?> immediateRefreshJob;
private @Nullable VerisureSession session;
public VerisureBridgeHandler(Bridge bridge, HttpClient httpClient) {
super(bridge);
this.httpClient = httpClient;
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("VerisureBridgeHandler Handle command {} on channelUID: {}", command, channelUID);
if (command instanceof RefreshType) {
if (channelUID.getId().equals(CHANNEL_STATUS) && channelUID.getThingUID().equals(getThing().getUID())) {
logger.debug("Refresh command on status channel {} will trigger instant refresh", channelUID);
scheduleImmediateRefresh(0);
} else {
logger.debug("Refresh command on channel {} will trigger refresh in {} seconds", channelUID,
REFRESH_DELAY_SECONDS);
scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
}
} else {
logger.warn("unknown command! {}", command);
}
}
public @Nullable VerisureSession getSession() {
return session;
}
public @Nullable ThingUID getUID() {
return getThing().getUID();
}
@Override
public void initialize() {
logger.debug("Initializing Verisure Binding");
VerisureBridgeConfiguration config = getConfigAs(VerisureBridgeConfiguration.class);
REFRESH_SEC = config.refresh;
this.pinCode = config.pin;
if (config.username == null || config.password == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"Configuration of username and password is mandatory");
} else if (REFRESH_SEC < 0) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Refresh time cannot negative!");
} else {
try {
authstring = "j_username=" + config.username + "&j_password="
+ URLEncoder.encode(config.password, StandardCharsets.UTF_8.toString())
+ "&spring-security-redirect=" + START_REDIRECT;
scheduler.execute(() -> {
if (session == null) {
logger.debug("Session is null, let's create a new one");
session = new VerisureSession(this.httpClient);
}
VerisureSession session = this.session;
updateStatus(ThingStatus.UNKNOWN);
if (session != null) {
if (!session.initialize(authstring, pinCode, config.username)) {
logger.warn("Failed to initialize bridge, please check your credentials!");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_REGISTERING_ERROR,
"Failed to login to Verisure, please check your credentials!");
return;
}
startAutomaticRefresh();
}
});
} catch (RuntimeException | UnsupportedEncodingException e) {
logger.warn("Failed to initialize: {}", e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
}
}
@Override
public void dispose() {
logger.debug("Handler disposed.");
stopAutomaticRefresh();
stopImmediateRefresh();
session = null;
}
public <T extends VerisureThingDTO> boolean registerObjectStatusListener(
DeviceStatusListener<T> deviceStatusListener) {
VerisureSession mySession = session;
if (mySession != null) {
logger.debug("registerObjectStatusListener for listener {}", deviceStatusListener);
return mySession.registerDeviceStatusListener(deviceStatusListener);
}
return false;
}
public <T extends VerisureThingDTO> boolean unregisterObjectStatusListener(
DeviceStatusListener<T> deviceStatusListener) {
VerisureSession mySession = session;
if (mySession != null) {
logger.debug("unregisterObjectStatusListener for listener {}", deviceStatusListener);
return mySession.unregisterDeviceStatusListener(deviceStatusListener);
}
return false;
}
@Override
public Collection<Class<? extends ThingHandlerService>> getServices() {
return Collections.singleton(VerisureThingDiscoveryService.class);
}
private void refreshAndUpdateStatus() {
logger.debug("Refresh and update status!");
VerisureSession session = this.session;
if (session != null) {
boolean success = session.refresh();
if (success) {
updateStatus(ThingStatus.ONLINE);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
}
}
}
void scheduleImmediateRefresh(int refreshDelay) {
logger.debug("VerisureBridgeHandler - scheduleImmediateRefresh");
immediateRefreshJobLock.lock();
ScheduledFuture<?> refreshJob = this.refreshJob;
ScheduledFuture<?> immediateRefreshJob = this.immediateRefreshJob;
try {
// We schedule in 10 sec, to avoid multiple updates
if (refreshJob != null) {
logger.debug("Current remaining delay {} for refresh job {}", refreshJob.getDelay(TimeUnit.SECONDS),
refreshJob);
if (immediateRefreshJob != null) {
logger.debug("Current remaining delay {} for immediate refresh job {}",
immediateRefreshJob.getDelay(TimeUnit.SECONDS), immediateRefreshJob);
}
if (refreshJob.getDelay(TimeUnit.SECONDS) > refreshDelay) {
if (immediateRefreshJob == null || immediateRefreshJob.getDelay(TimeUnit.SECONDS) <= 0) {
if (immediateRefreshJob != null) {
logger.debug("Current remaining delay {} for immediate refresh job {}",
immediateRefreshJob.getDelay(TimeUnit.SECONDS), immediateRefreshJob);
}
// Note we are using getDelay() instead of isDone() as we want to allow Things to schedule a
// refresh if their status is pending. As the status update happens inside the
// refreshAndUpdateStatus
// execution the isDone() will return false and would not allow the rescheduling of the task.
this.immediateRefreshJob = scheduler.schedule(this::refreshAndUpdateStatus, refreshDelay,
TimeUnit.SECONDS);
logger.debug("Scheduling new immediate refresh job {}", immediateRefreshJob);
}
}
}
} catch (RejectedExecutionException e) {
logger.warn("Immediate refresh job cannot be scheduled!");
} finally {
immediateRefreshJobLock.unlock();
}
}
private void startAutomaticRefresh() {
ScheduledFuture<?> refreshJob = this.refreshJob;
logger.debug("Start automatic refresh {}", refreshJob);
if (refreshJob == null || refreshJob.isCancelled()) {
try {
this.refreshJob = scheduler.scheduleWithFixedDelay(this::refreshAndUpdateStatus, 0, REFRESH_SEC,
TimeUnit.SECONDS);
logger.debug("Scheduling at fixed delay refreshjob {}", this.refreshJob);
} catch (RejectedExecutionException e) {
logger.warn("Automatic refresh job cannot be started!");
}
}
}
private void stopAutomaticRefresh() {
ScheduledFuture<?> refreshJob = this.refreshJob;
logger.debug("Stop automatic refresh for job {}", refreshJob);
if (refreshJob != null) {
refreshJob.cancel(true);
this.refreshJob = null;
}
}
private void stopImmediateRefresh() {
immediateRefreshJobLock.lock();
ScheduledFuture<?> immediateRefreshJob = this.immediateRefreshJob;
try {
logger.debug("Stop immediate refresh for job {}", immediateRefreshJob);
if (immediateRefreshJob != null) {
immediateRefreshJob.cancel(true);
this.immediateRefreshJob = null;
}
} catch (RejectedExecutionException e) {
logger.warn("Immediate refresh job cannot be scheduled!");
} finally {
immediateRefreshJobLock.unlock();
}
}
}

View File

@@ -0,0 +1,69 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.util.Collections;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.dto.VerisureBroadbandConnectionsDTO;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
/**
* Handler for the Broadband COnnection thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureBroadbandConnectionThingHandler extends VerisureThingHandler<VerisureBroadbandConnectionsDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections
.singleton(THING_TYPE_BROADBAND_CONNECTION);
public VerisureBroadbandConnectionThingHandler(Thing thing) {
super(thing);
}
@Override
public Class<VerisureBroadbandConnectionsDTO> getVerisureThingClass() {
return VerisureBroadbandConnectionsDTO.class;
}
@Override
public synchronized void update(VerisureBroadbandConnectionsDTO thing) {
updateBroadbandConnection(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateBroadbandConnection(VerisureBroadbandConnectionsDTO vbcJSON) {
String testDate = vbcJSON.getData().getInstallation().getBroadband().getTestDate();
if (testDate != null) {
updateTimeStamp(testDate);
ChannelUID cuid = new ChannelUID(getThing().getUID(), CHANNEL_CONNECTED);
boolean broadbandConnected = vbcJSON.getData().getInstallation().getBroadband().isBroadbandConnected();
updateState(cuid, OnOffType.from(broadbandConnected));
updateInstallationChannels(vbcJSON);
}
}
@Override
public void updateTriggerChannel(String event) {
}
}

View File

@@ -0,0 +1,109 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.util.HashSet;
import java.util.Set;
import javax.measure.quantity.Dimensionless;
import javax.measure.quantity.Temperature;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.dto.VerisureClimatesDTO;
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.library.unit.SIUnits;
import org.openhab.core.library.unit.SmartHomeUnits;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for all Climate Device thing types that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureClimateDeviceThingHandler extends VerisureThingHandler<VerisureClimatesDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<ThingTypeUID>();
static {
SUPPORTED_THING_TYPES.add(THING_TYPE_SMOKEDETECTOR);
SUPPORTED_THING_TYPES.add(THING_TYPE_WATERDETECTOR);
SUPPORTED_THING_TYPES.add(THING_TYPE_SIREN);
SUPPORTED_THING_TYPES.add(THING_TYPE_NIGHT_CONTROL);
}
public VerisureClimateDeviceThingHandler(Thing thing) {
super(thing);
}
@Override
public Class<VerisureClimatesDTO> getVerisureThingClass() {
return VerisureClimatesDTO.class;
}
@Override
public synchronized void update(VerisureClimatesDTO thing) {
updateClimateDeviceState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateClimateDeviceState(VerisureClimatesDTO climateJSON) {
getThing().getChannels().stream().map(Channel::getUID)
.filter(channelUID -> isLinked(channelUID) && !channelUID.getId().equals("timestamp"))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), climateJSON);
updateState(channelUID, state);
});
String timeStamp = climateJSON.getData().getInstallation().getClimates().get(0).getTemperatureTimestamp();
if (timeStamp != null) {
updateTimeStamp(timeStamp);
}
updateInstallationChannels(climateJSON);
}
public State getValue(String channelId, VerisureClimatesDTO climateJSON) {
switch (channelId) {
case CHANNEL_TEMPERATURE:
double temperature = climateJSON.getData().getInstallation().getClimates().get(0).getTemperatureValue();
return new QuantityType<Temperature>(temperature, SIUnits.CELSIUS);
case CHANNEL_HUMIDITY:
if (climateJSON.getData().getInstallation().getClimates().get(0).isHumidityEnabled()) {
double humidity = climateJSON.getData().getInstallation().getClimates().get(0).getHumidityValue();
return new QuantityType<Dimensionless>(humidity, SmartHomeUnits.PERCENT);
}
case CHANNEL_HUMIDITY_ENABLED:
boolean humidityEnabled = climateJSON.getData().getInstallation().getClimates().get(0)
.isHumidityEnabled();
return OnOffType.from(humidityEnabled);
case CHANNEL_LOCATION:
String location = climateJSON.getLocation();
return location != null ? new StringType(location) : UnDefType.NULL;
}
return UnDefType.UNDEF;
}
@Override
public void updateTriggerChannel(String event) {
logger.debug("ClimateThingHandler trigger event {}", event);
triggerChannel(CHANNEL_SMOKE_DETECTION_TRIGGER_CHANNEL, event);
}
}

View File

@@ -0,0 +1,94 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.dto.VerisureDoorWindowsDTO;
import org.openhab.binding.verisure.internal.dto.VerisureDoorWindowsDTO.DoorWindow;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the Smart Lock Device thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureDoorWindowThingHandler extends VerisureThingHandler<VerisureDoorWindowsDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_DOORWINDOW);
public VerisureDoorWindowThingHandler(Thing thing) {
super(thing);
}
@Override
public Class<VerisureDoorWindowsDTO> getVerisureThingClass() {
return VerisureDoorWindowsDTO.class;
}
@Override
public synchronized void update(VerisureDoorWindowsDTO thing) {
updateDoorWindowState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateDoorWindowState(VerisureDoorWindowsDTO doorWindowJSON) {
List<DoorWindow> doorWindowList = doorWindowJSON.getData().getInstallation().getDoorWindows();
if (!doorWindowList.isEmpty()) {
DoorWindow doorWindow = doorWindowList.get(0);
getThing().getChannels().stream().map(Channel::getUID)
.filter(channelUID -> isLinked(channelUID) && !channelUID.getId().equals("timestamp"))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), doorWindow);
updateState(channelUID, state);
});
updateTimeStamp(doorWindow.getReportTime());
updateInstallationChannels(doorWindowJSON);
} else {
logger.debug("DoorWindow list is empty!");
}
}
public State getValue(String channelId, DoorWindow doorWindow) {
switch (channelId) {
case CHANNEL_STATE:
return "OPEN".equals(doorWindow.getState()) ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
case CHANNEL_LOCATION:
String location = doorWindow.getDevice().getArea();
return location != null ? new StringType(location) : UnDefType.UNDEF;
}
return UnDefType.UNDEF;
}
@Override
public void updateTriggerChannel(String event) {
logger.debug("DoorWindowThingHandler trigger event {}", event);
triggerChannel(CHANNEL_DOOR_WINDOW_TRIGGER_CHANNEL, event);
}
}

View File

@@ -0,0 +1,174 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.VerisureSession;
import org.openhab.binding.verisure.internal.VerisureThingConfiguration;
import org.openhab.binding.verisure.internal.dto.VerisureBaseThingDTO.Device;
import org.openhab.binding.verisure.internal.dto.VerisureEventLogDTO;
import org.openhab.binding.verisure.internal.dto.VerisureEventLogDTO.EventLog;
import org.openhab.binding.verisure.internal.dto.VerisureEventLogDTO.PagedList;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the Event Log thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureEventLogThingHandler extends VerisureThingHandler<VerisureEventLogDTO> {
private BigDecimal lastEventId = BigDecimal.ZERO;
private long lastEventTime = 0;
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_EVENT_LOG);
public VerisureEventLogThingHandler(Thing thing) {
super(thing);
}
@Override
public Class<VerisureEventLogDTO> getVerisureThingClass() {
return VerisureEventLogDTO.class;
}
@Override
public synchronized void update(VerisureEventLogDTO thing) {
updateEventLogState(thing);
updateStatus(ThingStatus.ONLINE);
}
@Override
public void initialize() {
logger.debug("initialize on thing: {}", thing);
VerisureSession session = getSession();
config = getConfigAs(VerisureThingConfiguration.class);
if (session != null) {
logger.debug("Set number of events to fetch from API to {} for thing {}", config.getNumberOfEvents(),
thing);
session.setNumberOfEvents(config.getNumberOfEvents());
}
super.initialize();
}
private void updateEventLogState(VerisureEventLogDTO eventLogJSON) {
EventLog eventLog = eventLogJSON.getData().getInstallation().getEventLog();
if (eventLog.getPagedList().size() > 0) {
getThing().getChannels().stream().map(Channel::getUID).filter(channelUID -> isLinked(channelUID))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), eventLogJSON, eventLog);
updateState(channelUID, state);
});
updateInstallationChannels(eventLogJSON);
String eventTime = eventLogJSON.getData().getInstallation().getEventLog().getPagedList().get(0)
.getEventTime();
if (eventTime != null) {
updateTimeStamp(eventTime, CHANNEL_LAST_EVENT_TIME);
lastEventTime = ZonedDateTime.parse(eventTime).toEpochSecond();
}
} else {
logger.debug("Empty event log.");
}
}
public State getValue(String channelId, VerisureEventLogDTO verisureEventLog, EventLog eventLog) {
Device device = eventLog.getPagedList().get(0).getDevice();
switch (channelId) {
case CHANNEL_LAST_EVENT_LOCATION:
return device != null && device.getArea() != null ? new StringType(device.getArea()) : UnDefType.NULL;
case CHANNEL_LAST_EVENT_DEVICE_ID:
return device != null && device.getDeviceLabel() != null ? new StringType(device.getDeviceLabel())
: UnDefType.NULL;
case CHANNEL_LAST_EVENT_ID:
String eventId = eventLog.getPagedList().get(0).getEventId();
if (eventId != null) {
if (eventId.contains("-")) {
eventId = eventId.replace("-", "");
lastEventId = new BigDecimal(new BigInteger(eventId, 16));
} else {
lastEventId = new BigDecimal(eventId);
}
return new DecimalType(lastEventId);
} else {
return UnDefType.NULL;
}
case CHANNEL_LAST_EVENT_TIME:
if (lastEventTime != 0) {
triggerEventChannels(eventLog);
}
case CHANNEL_LAST_EVENT_DEVICE_TYPE:
return device != null && device.getGui().getLabel() != null ? new StringType(device.getGui().getLabel())
: UnDefType.NULL;
case CHANNEL_LAST_EVENT_TYPE:
String lastEventType = eventLog.getPagedList().get(0).getEventType();
return lastEventType != null ? new StringType(lastEventType) : UnDefType.NULL;
case CHANNEL_LAST_EVENT_CATEGORY:
String lastEventCategory = eventLog.getPagedList().get(0).getEventCategory();
return lastEventCategory != null ? new StringType(lastEventCategory) : UnDefType.NULL;
case CHANNEL_LAST_EVENT_USER_NAME:
String lastEventUserName = eventLog.getPagedList().get(0).getUserName();
return lastEventUserName != null ? new StringType(lastEventUserName) : UnDefType.NULL;
case CHANNEL_EVENT_LOG:
String eventLogJSON = gson.toJson(eventLog);
return eventLogJSON != null ? new StringType(eventLogJSON) : UnDefType.NULL;
}
return UnDefType.UNDEF;
}
private void triggerEventChannels(EventLog eventLog) {
List<PagedList> newEventList = eventLog.getPagedList().stream().collect(Collectors.toList());
Collections.reverse(newEventList);
ArrayList<Event> events = new ArrayList<>();
for (PagedList newEvent : newEventList) {
long eventTime = ZonedDateTime.parse(newEvent.getEventTime()).toEpochSecond();
logger.trace("Event time: {} Last Event time: {}", eventTime, lastEventTime);
if (eventTime > lastEventTime) {
logger.debug("Create event {} for event time {}", newEvent.getEventType(), eventTime);
Event event;
Device device = newEvent.getDevice();
if (device != null) {
event = new Event(device.getDeviceLabel(), newEvent.getEventType(), newEvent.getEventCategory());
} else {
event = new Event("NA", newEvent.getEventType(), newEvent.getEventCategory());
}
events.add(event);
}
}
updateTriggerChannel(events);
}
@Override
public void updateTriggerChannel(String event) {
}
}

View File

@@ -0,0 +1,106 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.dto.VerisureGatewayDTO;
import org.openhab.binding.verisure.internal.dto.VerisureGatewayDTO.CommunicationState;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the Gateway thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureGatewayThingHandler extends VerisureThingHandler<VerisureGatewayDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_GATEWAY);
public VerisureGatewayThingHandler(Thing thing) {
super(thing);
}
@Override
public Class<VerisureGatewayDTO> getVerisureThingClass() {
return VerisureGatewayDTO.class;
}
@Override
public synchronized void update(VerisureGatewayDTO thing) {
updateGatewayState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateGatewayState(VerisureGatewayDTO gatewayJSON) {
List<CommunicationState> communicationStateList = gatewayJSON.getData().getInstallation()
.getCommunicationState();
if (!communicationStateList.isEmpty()) {
communicationStateList.forEach(communicationState -> {
getThing().getChannels().stream().map(Channel::getUID).filter(channelUID -> isLinked(channelUID))
.forEach(channelUID -> {
if (!channelUID.getId().contains("testTime")) {
State state = getValue(channelUID.getId(), gatewayJSON, communicationState);
updateState(channelUID, state);
} else {
String timestamp = communicationState.getTestDate();
if (timestamp != null && channelUID.toString()
.contains(communicationState.getHardwareCarrierType())) {
updateTimeStamp(timestamp, channelUID);
}
}
});
});
updateInstallationChannels(gatewayJSON);
} else {
logger.debug("Empty communication state list.");
}
}
public State getValue(String channelId, VerisureGatewayDTO verisureGateway, CommunicationState communicationState) {
switch (channelId) {
case CHANNEL_STATUS_GSM_OVER_UDP:
case CHANNEL_STATUS_GSM_OVER_SMS:
case CHANNEL_STATUS_GPRS_OVER_UDP:
case CHANNEL_STATUS_ETH_OVER_UDP:
String state = communicationState.getResult();
return state != null ? new StringType(state) : UnDefType.NULL;
case CHANNEL_GATEWAY_MODEL:
String model = communicationState.getDevice().getGui().getLabel();
return model != null ? new StringType(model) : UnDefType.NULL;
case CHANNEL_LOCATION:
String location = communicationState.getDevice().getArea();
return location != null ? new StringType(location) : UnDefType.NULL;
}
return UnDefType.UNDEF;
}
@Override
public void updateTriggerChannel(String event) {
logger.debug("GatewayThingHandler trigger event {}", event);
triggerChannel(CHANNEL_GATEWAY_TRIGGER_CHANNEL, event);
}
}

View File

@@ -0,0 +1,130 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.measure.quantity.Temperature;
import javax.measure.quantity.Time;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.dto.VerisureMiceDetectionDTO;
import org.openhab.binding.verisure.internal.dto.VerisureMiceDetectionDTO.Detection;
import org.openhab.binding.verisure.internal.dto.VerisureMiceDetectionDTO.Mouse;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.SmartHomeUnits;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the Mice Detection thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureMiceDetectionThingHandler extends VerisureThingHandler<VerisureMiceDetectionDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_MICE_DETECTION);
public VerisureMiceDetectionThingHandler(Thing thing) {
super(thing);
}
@Override
public Class<VerisureMiceDetectionDTO> getVerisureThingClass() {
return VerisureMiceDetectionDTO.class;
}
@Override
public synchronized void update(VerisureMiceDetectionDTO thing) {
updateMiceDetectionState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateMiceDetectionState(VerisureMiceDetectionDTO miceDetectionJSON) {
List<Mouse> miceList = miceDetectionJSON.getData().getInstallation().getMice();
if (!miceList.isEmpty()) {
Mouse mouse = miceList.get(0);
getThing().getChannels().stream().map(Channel::getUID).filter(channelUID -> isLinked(channelUID)
&& !channelUID.getId().equals("timestamp") && !channelUID.getId().equals("temperatureTimestamp"))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), miceDetectionJSON, mouse);
updateState(channelUID, state);
});
if (mouse.getDetections().size() != 0) {
updateTimeStamp(mouse.getDetections().get(0).getNodeTime());
}
updateTimeStamp(miceDetectionJSON.getTemperatureTime(), CHANNEL_TEMPERATURE_TIMESTAMP);
updateInstallationChannels(miceDetectionJSON);
} else {
logger.debug("MiceList is empty!");
}
}
public State getValue(String channelId, VerisureMiceDetectionDTO miceDetectionJSON, Mouse mouse) {
switch (channelId) {
case CHANNEL_COUNT_LATEST_DETECTION:
if (mouse.getDetections().size() == 0) {
return new DecimalType(0);
} else {
return new DecimalType(mouse.getDetections().get(0).getCount());
}
case CHANNEL_COUNT_LAST_24_HOURS:
if (mouse.getDetections().size() == 0) {
return new DecimalType(0);
} else {
return new DecimalType(mouse.getDetections().stream().mapToInt(Detection::getCount).sum());
}
case CHANNEL_DURATION_LATEST_DETECTION:
if (mouse.getDetections().size() == 0) {
return new QuantityType<Time>(0, SmartHomeUnits.SECOND);
} else {
return new QuantityType<Time>(mouse.getDetections().get(0).getDuration(), SmartHomeUnits.SECOND);
}
case CHANNEL_DURATION_LAST_24_HOURS:
if (mouse.getDetections().size() == 0) {
return new QuantityType<Time>(0, SmartHomeUnits.SECOND);
} else {
return new QuantityType<Time>(mouse.getDetections().stream().mapToInt(Detection::getDuration).sum(),
SmartHomeUnits.SECOND);
}
case CHANNEL_LOCATION:
String location = mouse.getDevice().getArea();
return location != null ? new StringType(location) : UnDefType.NULL;
case CHANNEL_TEMPERATURE:
double temperature = miceDetectionJSON.getTemperatureValue();
return temperature != VerisureMiceDetectionDTO.UNDEFINED
? new QuantityType<Temperature>(temperature, SIUnits.CELSIUS)
: UnDefType.UNDEF;
}
return UnDefType.UNDEF;
}
@Override
public void updateTriggerChannel(String event) {
logger.debug("MiceThingHandler trigger event {}", event);
triggerChannel(CHANNEL_MICE_DETECTION_TRIGGER_CHANNEL, event);
}
}

View File

@@ -0,0 +1,379 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.verisure.internal.VerisureSession;
import org.openhab.binding.verisure.internal.dto.VerisureSmartLockDTO;
import org.openhab.binding.verisure.internal.dto.VerisureSmartLockDTO.DoorLockVolumeSettings;
import org.openhab.binding.verisure.internal.dto.VerisureSmartLocksDTO;
import org.openhab.binding.verisure.internal.dto.VerisureSmartLocksDTO.Doorlock;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.StringType;
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.ThingTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the Smart Lock Device thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureSmartLockThingHandler extends VerisureThingHandler<VerisureSmartLocksDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_SMARTLOCK);
private static final int REFRESH_DELAY_SECONDS = 10;
public VerisureSmartLockThingHandler(Thing thing) {
super(thing);
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("handleCommand, channel: {}, command: {}", channelUID, command);
if (command instanceof RefreshType) {
super.handleCommand(channelUID, command);
return;
} else if (channelUID.getId().equals(CHANNEL_SMARTLOCK_STATUS)) {
handleSmartLockState(command);
} else if (channelUID.getId().equals(CHANNEL_AUTO_RELOCK)) {
handleAutoRelock(command);
} else if (channelUID.getId().equals(CHANNEL_SMARTLOCK_VOLUME)) {
handleSmartLockVolumeAndVoiceLevel(command, true);
} else if (channelUID.getId().equals(CHANNEL_SMARTLOCK_VOICE_LEVEL)) {
handleSmartLockVolumeAndVoiceLevel(command, false);
} else {
logger.warn("Unknown command! {}", command);
return;
}
scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
}
private void handleSmartLockState(Command command) {
String deviceId = config.getDeviceId();
VerisureSession session = getSession();
if (session != null) {
VerisureSmartLocksDTO smartLock = session.getVerisureThing(deviceId, getVerisureThingClass());
if (smartLock != null) {
BigDecimal installationId = smartLock.getSiteId();
String pinCode = session.getPinCode(installationId);
if (pinCode != null) {
String url = START_GRAPHQL;
String operation;
if (command == OnOffType.OFF) {
operation = "DoorUnlock";
} else if (command == OnOffType.ON) {
operation = "DoorLock";
} else {
logger.debug("Unknown command! {}", command);
return;
}
ArrayList<SmartLockDTO> list = new ArrayList<>();
SmartLockDTO smartLockJSON = new SmartLockDTO();
VariablesDTO variables = new VariablesDTO();
InputDTO input = new InputDTO();
variables.setDeviceLabel(deviceId);
variables.setGiid(installationId.toString());
input.setCode(pinCode);
variables.setInput(input);
smartLockJSON.setOperationName(operation);
smartLockJSON.setVariables(variables);
String query = "mutation " + operation
+ "($giid: String!, $deviceLabel: String!, $input: LockDoorInput!) {\n " + operation
+ "(giid: $giid, deviceLabel: $deviceLabel, input: $input)\n}\n";
smartLockJSON.setQuery(query);
list.add(smartLockJSON);
String queryQLSmartLockSetState = gson.toJson(list);
logger.debug("Trying to set SmartLock state to {} with URL {} and data {}", operation, url,
queryQLSmartLockSetState);
int httpResultCode = session.sendCommand(url, queryQLSmartLockSetState, installationId);
if (httpResultCode == HttpStatus.OK_200) {
logger.debug("SmartLock status successfully changed!");
} else {
logger.warn("Failed to send command, HTTP result code {}", httpResultCode);
}
} else {
logger.warn("PIN code is not configured! It is mandatory to control SmartLock!");
}
}
}
}
private void handeAutoRelockResult(String url, String data, BigDecimal installationId, Command command) {
logger.debug("Trying to set Auto Relock {} with URL {} and data {}", command.toString(), url, data);
VerisureSession session = getSession();
if (session != null) {
int httpResultCode = session.sendCommand(url, data, installationId);
if (httpResultCode == HttpStatus.OK_200) {
logger.debug("AutoRelock sucessfully changed to {}", command.toString());
} else {
logger.warn("Failed to send command, HTTP result code {}", httpResultCode);
}
}
}
private void handleAutoRelock(Command command) {
String deviceId = config.getDeviceId();
VerisureSession session = getSession();
if (session != null) {
VerisureSmartLocksDTO smartLock = session.getVerisureThing(deviceId, getVerisureThingClass());
if (smartLock != null) {
BigDecimal installationId = smartLock.getSiteId();
try {
String csrf = session.getCsrfToken(installationId);
StringBuilder sb = new StringBuilder(deviceId);
sb.insert(4, "+");
String data;
String url = SMARTLOCK_AUTORELOCK_COMMAND;
if (command == OnOffType.ON) {
data = "enabledDoorLocks=" + sb.toString()
+ "&doorLockDevices%5B0%5D.autoRelockEnabled=true&_doorLockDevices%5B0%5D.autoRelockEnabled=on&_csrf="
+ csrf;
handeAutoRelockResult(url, data, installationId, command);
} else if (command == OnOffType.OFF) {
data = "enabledDoorLocks=&doorLockDevices%5B0%5D.autoRelockEnabled=true&_doorLockDevices%5B0%5D.autoRelockEnabled=on&_csrf="
+ csrf;
handeAutoRelockResult(url, data, installationId, command);
} else {
logger.warn("Unknown command! {}", command);
}
} catch (ExecutionException | InterruptedException | TimeoutException e) {
logger.debug("Failed to handle auto-relock {}", e.getMessage());
}
}
}
}
private boolean isSettingAllowed(List<String> allowedSettings, String setting) {
return allowedSettings.contains(setting);
}
private void handleSmartLockVolumeAndVoiceLevel(Command command, boolean setVolume) {
String deviceId = config.getDeviceId();
VerisureSession session = getSession();
if (session != null) {
VerisureSmartLocksDTO smartLocks = session.getVerisureThing(deviceId, getVerisureThingClass());
if (smartLocks != null) {
VerisureSmartLockDTO smartLock = smartLocks.getSmartLockJSON();
if (smartLock != null) {
DoorLockVolumeSettings volumeSettings = smartLock.getDoorLockVolumeSettings();
String volume;
String voiceLevel;
if (setVolume) {
List<String> availableVolumes = volumeSettings.getAvailableVolumes();
if (isSettingAllowed(availableVolumes, command.toString())) {
volume = command.toString();
voiceLevel = volumeSettings.getVoiceLevel();
} else {
logger.warn("Failed to change volume, setting not allowed {}", command.toString());
return;
}
} else {
List<String> availableVoiceLevels = volumeSettings.getAvailableVoiceLevels();
if (isSettingAllowed(availableVoiceLevels, command.toString())) {
volume = volumeSettings.getVolume();
voiceLevel = command.toString();
} else {
logger.warn("Failed to change voice level, setting not allowed {}", command.toString());
return;
}
BigDecimal installationId = smartLocks.getSiteId();
try {
String csrf = session.getCsrfToken(installationId);
String url = SMARTLOCK_VOLUME_COMMAND;
String data = "keypad.volume=MEDIUM&keypad.beepOnKeypress=true&_keypad.beepOnKeypress=on&siren.volume=MEDIUM&voiceDevice.volume=MEDIUM&doorLock.volume="
+ volume + "&doorLock.voiceLevel=" + voiceLevel
+ "&_devices%5B0%5D.on=on&devices%5B1%5D.on=true&_devices%5B1%5D.on=on&devices%5B2%5D.on=true&_devices%5B2%5D.on=on&_devices%5B3%5D.on=on&_keypad.keypadsPlayChime=on&_siren.sirensPlayChime=on&_csrf="
+ csrf;
logger.debug("Trying to set SmartLock volume with URL {} and data {}", url, data);
int httpResultCode = session.sendCommand(url, data, installationId);
if (httpResultCode == HttpStatus.OK_200) {
logger.debug("SmartLock volume sucessfully changed!");
} else {
logger.warn("Failed to send command, HTTP result code {}", httpResultCode);
}
} catch (ExecutionException | InterruptedException | TimeoutException e) {
logger.warn("Failed to get CSRF token {}", e.getMessage());
}
}
}
}
}
}
@Override
public Class<VerisureSmartLocksDTO> getVerisureThingClass() {
return VerisureSmartLocksDTO.class;
}
@Override
public synchronized void update(VerisureSmartLocksDTO thing) {
updateSmartLockState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateSmartLockState(VerisureSmartLocksDTO smartLocksJSON) {
List<Doorlock> doorLockList = smartLocksJSON.getData().getInstallation().getDoorlocks();
if (!doorLockList.isEmpty()) {
Doorlock doorlock = doorLockList.get(0);
String smartLockStatus = doorlock.getCurrentLockState();
VerisureSmartLockDTO smartLockJSON = smartLocksJSON.getSmartLockJSON();
if (smartLockStatus != null) {
getThing().getChannels().stream().map(Channel::getUID)
.filter(channelUID -> isLinked(channelUID) && !channelUID.getId().equals("timestamp"))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), doorlock, smartLockStatus, smartLockJSON);
updateState(channelUID, state);
});
updateTimeStamp(doorlock.getEventTime());
updateInstallationChannels(smartLocksJSON);
} else {
logger.debug("Smart lock status {} or smartLockJSON {} is null!", smartLockStatus, smartLockJSON);
}
} else {
logger.debug("DoorLock list is empty!");
}
}
public State getValue(String channelId, Doorlock doorlock, String smartLockStatus,
@Nullable VerisureSmartLockDTO smartLockJSON) {
switch (channelId) {
case CHANNEL_SMARTLOCK_STATUS:
if ("LOCKED".equals(smartLockStatus)) {
return OnOffType.ON;
} else if ("UNLOCKED".equals(smartLockStatus)) {
return OnOffType.OFF;
} else if ("PENDING".equals(smartLockStatus)) {
// Schedule another refresh.
logger.debug("Issuing another immediate refresh since status is still PENDING ...");
this.scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
}
break;
case CHANNEL_CHANGED_BY_USER:
String user = doorlock.getUserString();
return user != null ? new StringType(user) : UnDefType.NULL;
case CHANNEL_CHANGED_VIA:
String method = doorlock.getMethod();
return method != null ? new StringType(method) : UnDefType.NULL;
case CHANNEL_MOTOR_JAM:
return OnOffType.from(doorlock.isMotorJam());
case CHANNEL_LOCATION:
String location = doorlock.getDevice().getArea();
return location != null ? new StringType(location) : UnDefType.NULL;
case CHANNEL_AUTO_RELOCK:
if (smartLockJSON != null) {
return OnOffType.from(smartLockJSON.getAutoRelockEnabled());
} else {
return UnDefType.NULL;
}
case CHANNEL_SMARTLOCK_VOLUME:
if (smartLockJSON != null) {
return new StringType(smartLockJSON.getDoorLockVolumeSettings().getVolume());
} else {
return UnDefType.NULL;
}
case CHANNEL_SMARTLOCK_VOICE_LEVEL:
if (smartLockJSON != null) {
return new StringType(smartLockJSON.getDoorLockVolumeSettings().getVoiceLevel());
} else {
return UnDefType.NULL;
}
}
return UnDefType.UNDEF;
}
private static class SmartLockDTO {
@SuppressWarnings("unused")
private @Nullable String operationName;
@SuppressWarnings("unused")
private VariablesDTO variables = new VariablesDTO();
@SuppressWarnings("unused")
private @Nullable String query;
public void setOperationName(String operationName) {
this.operationName = operationName;
}
public void setVariables(VariablesDTO variables) {
this.variables = variables;
}
public void setQuery(String query) {
this.query = query;
}
}
private static class VariablesDTO {
@SuppressWarnings("unused")
private @Nullable String giid;
@SuppressWarnings("unused")
private @Nullable String deviceLabel;
@SuppressWarnings("unused")
private InputDTO input = new InputDTO();
public void setGiid(String giid) {
this.giid = giid;
}
public void setDeviceLabel(String deviceLabel) {
this.deviceLabel = deviceLabel;
}
public void setInput(InputDTO input) {
this.input = input;
}
}
private static class InputDTO {
@SuppressWarnings("unused")
private @Nullable String code;
public void setCode(String code) {
this.code = code;
}
}
@Override
public void updateTriggerChannel(String event) {
logger.debug("SmartLockThingHandler trigger event {}", event);
triggerChannel(CHANNEL_SMARTLOCK_TRIGGER_CHANNEL, event);
}
}

View File

@@ -0,0 +1,218 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.verisure.internal.VerisureSession;
import org.openhab.binding.verisure.internal.dto.VerisureSmartPlugsDTO;
import org.openhab.binding.verisure.internal.dto.VerisureSmartPlugsDTO.Smartplug;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.StringType;
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.ThingTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the Smart Plug Device thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureSmartPlugThingHandler extends VerisureThingHandler<VerisureSmartPlugsDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_SMARTPLUG);
private static final int REFRESH_DELAY_SECONDS = 10;
public VerisureSmartPlugThingHandler(Thing thing) {
super(thing);
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("handleCommand, channel: {}, command: {}", channelUID, command);
if (command instanceof RefreshType) {
super.handleCommand(channelUID, command);
} else if (channelUID.getId().equals(CHANNEL_SMARTPLUG_STATUS)) {
handleSmartPlugState(command);
scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
} else {
logger.warn("Unknown command! {}", command);
}
}
private void handleSmartPlugState(Command command) {
String deviceId = config.getDeviceId();
VerisureSession session = getSession();
if (session != null) {
VerisureSmartPlugsDTO smartPlug = session.getVerisureThing(deviceId, getVerisureThingClass());
if (smartPlug != null) {
BigDecimal installationId = smartPlug.getSiteId();
String url = START_GRAPHQL;
String operation;
boolean isOperation;
if (command == OnOffType.OFF) {
operation = "false";
isOperation = false;
} else if (command == OnOffType.ON) {
operation = "true";
isOperation = true;
} else {
logger.debug("Unknown command! {}", command);
return;
}
String query = "mutation UpdateState($giid: String!, $deviceLabel: String!, $state: Boolean!) {\n SmartPlugSetState(giid: $giid, input: [{deviceLabel: $deviceLabel, state: $state}])\n}\n";
ArrayList<SmartPlugDTO> list = new ArrayList<>();
SmartPlugDTO smartPlugJSON = new SmartPlugDTO();
VariablesDTO variables = new VariablesDTO();
variables.setDeviceLabel(deviceId);
variables.setGiid(installationId.toString());
variables.setState(isOperation);
smartPlugJSON.setOperationName("UpdateState");
smartPlugJSON.setVariables(variables);
smartPlugJSON.setQuery(query);
list.add(smartPlugJSON);
String queryQLSmartPlugSetState = gson.toJson(list);
logger.debug("Trying to set SmartPlug state to {} with URL {} and data {}", operation, url,
queryQLSmartPlugSetState);
int httpResultCode = session.sendCommand(url, queryQLSmartPlugSetState, installationId);
if (httpResultCode == HttpStatus.OK_200) {
logger.debug("Smartplug state successfully changed!");
} else {
logger.warn("Failed to send command, HTTP result code {}", httpResultCode);
}
}
}
}
@Override
public Class<VerisureSmartPlugsDTO> getVerisureThingClass() {
return VerisureSmartPlugsDTO.class;
}
@Override
public synchronized void update(VerisureSmartPlugsDTO thing) {
updateSmartPlugState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateSmartPlugState(VerisureSmartPlugsDTO smartPlugJSON) {
List<Smartplug> smartPlugList = smartPlugJSON.getData().getInstallation().getSmartplugs();
if (!smartPlugList.isEmpty()) {
Smartplug smartplug = smartPlugList.get(0);
String smartPlugStatus = smartplug.getCurrentState();
if (smartPlugStatus != null) {
getThing().getChannels().stream().map(Channel::getUID)
.filter(channelUID -> isLinked(channelUID) && !channelUID.getId().equals("timestamp"))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), smartplug, smartPlugStatus);
updateState(channelUID, state);
});
updateInstallationChannels(smartPlugJSON);
}
} else {
logger.debug("SmartPlugList is empty!");
}
}
public State getValue(String channelId, Smartplug smartplug, String smartPlugStatus) {
switch (channelId) {
case CHANNEL_SMARTPLUG_STATUS:
if ("ON".equals(smartPlugStatus)) {
return OnOffType.ON;
} else if ("OFF".equals(smartPlugStatus)) {
return OnOffType.OFF;
} else if ("PENDING".equals(smartPlugStatus)) {
// Schedule another refresh.
logger.debug("Issuing another immediate refresh since status is still PENDING ...");
this.scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
}
break;
case CHANNEL_LOCATION:
String location = smartplug.getDevice().getArea();
return location != null ? new StringType(location) : UnDefType.NULL;
case CHANNEL_HAZARDOUS:
return OnOffType.from(smartplug.isHazardous());
}
return UnDefType.UNDEF;
}
private static class SmartPlugDTO {
@SuppressWarnings("unused")
private @Nullable String operationName;
@SuppressWarnings("unused")
private VariablesDTO variables = new VariablesDTO();
@SuppressWarnings("unused")
private @Nullable String query;
public void setOperationName(String operationName) {
this.operationName = operationName;
}
public void setVariables(VariablesDTO variables) {
this.variables = variables;
}
public void setQuery(String query) {
this.query = query;
}
}
private static class VariablesDTO {
@SuppressWarnings("unused")
private @Nullable String giid;
@SuppressWarnings("unused")
private @Nullable String deviceLabel;
@SuppressWarnings("unused")
private boolean state;
public void setGiid(String giid) {
this.giid = giid;
}
public void setDeviceLabel(String deviceLabel) {
this.deviceLabel = deviceLabel;
}
public void setState(boolean state) {
this.state = state;
}
}
@Override
public void updateTriggerChannel(String event) {
logger.debug("SmartPlugThingHandler trigger event {}", event);
triggerChannel(CHANNEL_SMARTPLUG_TRIGGER_CHANNEL, event);
}
}

View File

@@ -0,0 +1,354 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.math.BigDecimal;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.verisure.internal.DeviceStatusListener;
import org.openhab.binding.verisure.internal.VerisureSession;
import org.openhab.binding.verisure.internal.VerisureThingConfiguration;
import org.openhab.binding.verisure.internal.dto.VerisureThingDTO;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType;
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.ThingStatusInfo;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
/**
* Base class and handler for some of the different thing types that Verisure provides.
*
* @author Jarle Hjortland - Initial contribution
* @author Jan Gustafsson - Further development
*
*/
@NonNullByDefault
public abstract class VerisureThingHandler<T extends VerisureThingDTO> extends BaseThingHandler
implements DeviceStatusListener<T> {
protected final Logger logger = LoggerFactory.getLogger(VerisureThingHandler.class);
protected final Gson gson = new Gson();
protected VerisureThingConfiguration config = new VerisureThingConfiguration();
public VerisureThingHandler(Thing thing) {
super(thing);
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("VerisureThingHandler handleCommand, channel: {}, command: {}", channelUID, command);
if (command instanceof RefreshType) {
Bridge bridge = getBridge();
if (bridge != null) {
BridgeHandler bridgeHandler = bridge.getHandler();
if (bridgeHandler != null) {
bridgeHandler.handleCommand(channelUID, command);
String deviceId = config.getDeviceId();
VerisureSession session = getSession();
if (session != null) {
@Nullable
T thing = session.getVerisureThing(deviceId, getVerisureThingClass());
if (thing != null) {
update(thing);
} else {
logger.trace("Thing is null!");
}
} else {
logger.debug("Session is null!");
}
} else {
logger.debug("BridgeHandler is null!");
}
} else {
logger.warn("Bridge is null!");
}
} else {
logger.warn("Unknown command! {}", command);
}
}
@Override
public void initialize() {
// Do not go online
config = getConfigAs(VerisureThingConfiguration.class);
// Set status to UNKNOWN and let background task set correct status
updateStatus(ThingStatus.UNKNOWN);
Bridge bridge = getBridge();
if (bridge != null) {
this.bridgeStatusChanged(bridge.getStatusInfo());
}
}
@Override
public void dispose() {
logger.debug("dispose on thing: {}", thing);
VerisureSession session = getSession();
if (session != null) {
session.unregisterDeviceStatusListener(this);
session.removeVerisureThingHandler(config.getDeviceId());
}
}
@Override
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
VerisureSession session = getSession();
if (session != null) {
String deviceId = config.getDeviceId();
@Nullable
T thing = session.getVerisureThing(deviceId, getVerisureThingClass());
if (thing != null) {
update(thing);
} else {
logger.warn("Please check that you have configured correct deviceId for thing!");
}
session.registerDeviceStatusListener(this);
session.setVerisureThingHandler(this, config.getDeviceId());
}
}
super.bridgeStatusChanged(bridgeStatusInfo);
}
@Override
public void onDeviceStateChanged(T thing) {
String deviceId = thing.getDeviceId();
// Make sure device id is normalized
if (config.getDeviceId().equalsIgnoreCase((VerisureThingConfiguration.normalizeDeviceId(deviceId)))) {
update(thing);
}
}
public abstract void update(T thing);
public abstract void updateTriggerChannel(String event);
protected void updateInstallationChannels(T thing) {
BigDecimal siteId = thing.getSiteId();
updateState(CHANNEL_INSTALLATION_ID, new DecimalType(siteId.longValue()));
updateState(CHANNEL_INSTALLATION_NAME, new StringType(thing.getSiteName()));
}
protected void updateTriggerChannel(ArrayList<Event> newEvents) {
VerisureSession session = getSession();
int delay = 1;
for (Event newEvent : newEvents) {
String deviceId = newEvent.getDeviceId();
String eventType = newEvent.getEventType();
String eventCategory = newEvent.getEventCategory();
logger.debug("Trigger event type {}, event category {} for thing {}", eventType, eventCategory, deviceId);
if (session != null && eventType != null && deviceId != null) {
String deviceIdTransformed = VerisureThingConfiguration.normalizeDeviceId(deviceId);
@Nullable
T thing = session.getVerisureThing(deviceIdTransformed);
if (thing != null) {
logger.debug("Trigger event {} on deviceId {} on thing {}", eventType, deviceIdTransformed, thing);
VerisureThingHandler<?> vth = session.getVerisureThinghandler(deviceIdTransformed);
if (vth == null) {
logger.debug("No VerisureThingHandler found for thing {}", thing);
return;
}
String eventTranslation = "UNKNOWN_EVENT_TYPE";
switch (eventType) {
case "BA":
eventTranslation = TRIGGER_EVENT_INSTRUSION;
break;
case "FA":
eventTranslation = TRIGGER_EVENT_FIRE;
break;
case "XT":
eventTranslation = TRIGGER_EVENT_BATTERY_LOW;
break;
case "XR":
eventTranslation = TRIGGER_EVENT_BATTERY_RESTORED;
break;
case "SB":
case "BP":
eventTranslation = TRIGGER_EVENT_COM_TEST;
break;
case "YC":
eventTranslation = TRIGGER_EVENT_COM_FAILURE;
break;
case "YK":
eventTranslation = TRIGGER_EVENT_COM_RESTORED;
break;
case "TA":
eventTranslation = TRIGGER_EVENT_SABOTAGE_ALARM;
break;
case "TR":
eventTranslation = TRIGGER_EVENT_SABOTAGE_RESTORED;
break;
case "CO":
case "CL":
case "CT":
eventTranslation = TRIGGER_EVENT_ARM;
break;
case "OP":
case "OO":
case "OT":
case "OH":
eventTranslation = TRIGGER_EVENT_DISARM;
break;
case "LM":
case "LO":
case "LC":
case "LD":
eventTranslation = TRIGGER_EVENT_LOCK;
break;
case "FK":
eventTranslation = TRIGGER_EVENT_LOCK_FAILURE;
break;
case "UA":
case "DC":
case "DO":
case "DK":
eventTranslation = TRIGGER_EVENT_UNLOCK;
break;
case "WA":
eventTranslation = TRIGGER_EVENT_WATER;
break;
case "IA":
eventTranslation = TRIGGER_EVENT_MICE;
break;
case "DOORWINDOW_STATE_CHANGE_OPENED":
eventTranslation = TRIGGER_EVENT_DOORWINDOW_OPENED;
break;
case "DOORWINDOW_STATE_CHANGE_CLOSED":
eventTranslation = TRIGGER_EVENT_DOORWINDOW_CLOSED;
break;
case "LOCATION_HOME":
eventTranslation = TRIGGER_EVENT_LOCATION_HOME;
break;
case "LOCATION_AWAY":
eventTranslation = TRIGGER_EVENT_LOCATION_AWAY;
break;
default:
logger.debug("Unhandled event type: {}, event category: {}", eventType, eventCategory);
}
logger.debug("Schedule vth {} and event {} with delay {}", vth, eventTranslation, delay);
scheduler.schedule(new EventTrigger(vth, eventTranslation), delay, TimeUnit.MILLISECONDS);
delay = delay + config.getEventTriggerDelay();
} else {
logger.debug("Thing is null!");
}
}
}
}
protected void updateTimeStamp(@Nullable String lastUpdatedTimeStamp) {
updateTimeStamp(lastUpdatedTimeStamp, CHANNEL_TIMESTAMP);
}
protected void updateTimeStamp(@Nullable String lastUpdatedTimeStamp, ChannelUID cuid) {
if (lastUpdatedTimeStamp != null) {
try {
logger.trace("Parsing date {} for channel {}", lastUpdatedTimeStamp, cuid);
ZonedDateTime zdt = ZonedDateTime.parse(lastUpdatedTimeStamp);
ZonedDateTime zdtLocal = zdt.withZoneSameInstant(ZoneId.systemDefault());
logger.trace("Parsing datetime successful. Using date. {}", new DateTimeType(zdtLocal));
updateState(cuid, new DateTimeType(zdtLocal));
} catch (IllegalArgumentException e) {
logger.warn("Parsing date failed: {}.", e.getMessage(), e);
}
} else {
logger.debug("Timestamp is null!");
}
}
protected void updateTimeStamp(@Nullable String lastUpdatedTimeStamp, String channel) {
ChannelUID cuid = new ChannelUID(getThing().getUID(), channel);
updateTimeStamp(lastUpdatedTimeStamp, cuid);
}
protected @Nullable VerisureSession getSession() {
Bridge bridge = getBridge();
if (bridge != null) {
VerisureBridgeHandler vbh = (VerisureBridgeHandler) bridge.getHandler();
if (vbh != null) {
return vbh.getSession();
}
}
return null;
}
protected void scheduleImmediateRefresh(int refreshDelay) {
logger.debug("scheduleImmediateRefresh on thing: {}", thing);
Bridge bridge = getBridge();
if (bridge != null && bridge.getHandler() != null) {
VerisureBridgeHandler vbh = (VerisureBridgeHandler) bridge.getHandler();
if (vbh != null) {
vbh.scheduleImmediateRefresh(refreshDelay);
}
}
}
private class EventTrigger implements Runnable {
private @Nullable VerisureThingHandler<?> vth;
private @Nullable String event;
public EventTrigger(@Nullable VerisureThingHandler<?> vth, @Nullable String event) {
this.vth = vth;
this.event = event;
}
@Override
public void run() {
logger.debug("Trigger Event {} on {} at time {}", event, vth, ZonedDateTime.now());
String localEvent = event;
if (vth != null && localEvent != null) {
vth.updateTriggerChannel(localEvent);
}
}
}
protected class Event {
private @Nullable String deviceId;
private @Nullable String eventType;
private @Nullable String eventCategory;
public Event(@Nullable String deviceId, @Nullable String eventType, @Nullable String eventCategory) {
this.deviceId = deviceId;
this.eventType = eventType;
this.eventCategory = eventCategory;
}
public @Nullable String getDeviceId() {
return deviceId;
}
public @Nullable String getEventType() {
return eventType;
}
public @Nullable String getEventCategory() {
return eventCategory;
}
}
}

View File

@@ -0,0 +1,101 @@
/**
* 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.verisure.internal.handler;
import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.verisure.internal.dto.VerisureUserPresencesDTO;
import org.openhab.binding.verisure.internal.dto.VerisureUserPresencesDTO.UserTracking;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
/**
* Handler for the User Presence Device thing type that Verisure provides.
*
* @author Jan Gustafsson - Initial contribution
*
*/
@NonNullByDefault
public class VerisureUserPresenceThingHandler extends VerisureThingHandler<VerisureUserPresencesDTO> {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_USERPRESENCE);
public VerisureUserPresenceThingHandler(Thing thing) {
super(thing);
}
@Override
public Class<VerisureUserPresencesDTO> getVerisureThingClass() {
return VerisureUserPresencesDTO.class;
}
@Override
public synchronized void update(VerisureUserPresencesDTO thing) {
updateUserPresenceState(thing);
updateStatus(ThingStatus.ONLINE);
}
private void updateUserPresenceState(VerisureUserPresencesDTO userPresenceJSON) {
List<UserTracking> userTrackingList = userPresenceJSON.getData().getInstallation().getUserTrackings();
if (!userTrackingList.isEmpty()) {
UserTracking userTracking = userTrackingList.get(0);
getThing().getChannels().stream().map(Channel::getUID)
.filter(channelUID -> isLinked(channelUID) && !channelUID.getId().equals("timestamp"))
.forEach(channelUID -> {
State state = getValue(channelUID.getId(), userTracking);
updateState(channelUID, state);
});
updateTimeStamp(userTracking.getCurrentLocationTimestamp());
updateInstallationChannels(userPresenceJSON);
} else {
logger.debug("UserTrackingList is empty!");
}
}
public State getValue(String channelId, UserTracking userTracking) {
switch (channelId) {
case CHANNEL_USER_NAME:
String name = userTracking.getName();
return name != null ? new StringType(name) : UnDefType.NULL;
case CHANNEL_USER_LOCATION_STATUS:
String currentLocation = userTracking.getCurrentLocationName();
return currentLocation != null ? new StringType(currentLocation)
: new StringType(userTracking.getCurrentLocationId());
case CHANNEL_STATUS:
String status = userTracking.getStatus();
return status != null ? new StringType(status) : UnDefType.NULL;
case CHANNEL_WEBACCOUNT:
String webAccount = userTracking.getWebAccount();
return webAccount != null ? new StringType(webAccount) : UnDefType.NULL;
case CHANNEL_USER_DEVICE_NAME:
String deviceName = userTracking.getDeviceName();
return deviceName != null ? new StringType(deviceName) : UnDefType.NULL;
}
return UnDefType.UNDEF;
}
@Override
public void updateTriggerChannel(String event) {
}
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="verisure" 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>Verisure Binding</name>
<description>This is the binding for Verisure Alarm System.</description>
<author>Jan Gustafsson</author>
</binding:binding>

View File

@@ -0,0 +1,804 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="verisure"
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="bridge">
<label>Verisure Bridge</label>
<description>This bridge represents the http://mypages.verisure.com web page connector.</description>
<channels>
<channel id="status" typeId="status"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<config-description>
<parameter name="username" type="text" required="true">
<label>Username</label>
<description>The username used to login to http://mypage.verisure.com.</description>
</parameter>
<parameter name="password" type="text" required="true">
<label>Password</label>
<context>password</context>
<description>The password used to login to http://mypage.verisure.com.</description>
</parameter>
<parameter name="refresh" type="integer" min="10" unit="s">
<label>Refresh Interval</label>
<description>Specifies the refresh interval in seconds.</description>
<default>600</default>
</parameter>
<parameter name="pin" type="text">
<label>Pin Code</label>
<description>The username's pin code to arm/disarm alarm and lock/unlock door. Comma separated in case of many
installations.</description>
<context>password</context>
</parameter>
</config-description>
</bridge-type>
<thing-type id="alarm">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Alarm</label>
<description>A Verisure Alarm.</description>
<channels>
<channel id="changedByUser" typeId="changedByUser"/>
<channel id="changedVia" typeId="changedVia"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="alarmStatus" typeId="alarmStatus"/>
<channel id="alarmTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Unique Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="smartLock">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Yale Doorman SmartLock</label>
<description>Integrated Yale Doorman SmartLock.</description>
<channels>
<channel id="changedByUser" typeId="changedByUser"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="changedVia" typeId="changedVia"/>
<channel id="motorJam" typeId="motorJam"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="smartLockStatus" typeId="smartLockStatus"/>
<channel id="autoRelock" typeId="autoRelock"/>
<channel id="smartLockVolume" typeId="smartLockVolume"/>
<channel id="smartLockVoiceLevel" typeId="smartLockVoiceLevel"/>
<channel id="smartLockTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Verisure Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="smartPlug">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure SmartPlug</label>
<description>A Verisure SmartPlug in your system.</description>
<channels>
<channel id="hazardous" typeId="hazardous"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="smartPlugStatus" typeId="smartPlugStatus"/>
<channel id="smartPlugTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Verisure Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="smokeDetector">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Smoke Detector</label>
<description>A climate device in a Smoke detector.</description>
<channels>
<channel id="temperature" typeId="temperature"/>
<channel id="humidityEnabled" typeId="humidityEnabled"/>
<channel id="humidity" typeId="humidity"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="smokeDetectorTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Verisure Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="waterDetector">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Water Detector</label>
<description>A climate device in a Water detector.</description>
<channels>
<channel id="temperature" typeId="temperature"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="waterDetectorTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Verisure Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="siren">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Siren</label>
<description>A climate device in a Siren.</description>
<channels>
<channel id="temperature" typeId="temperature"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="sirenTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Verisure Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="nightControl">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Night Control</label>
<description>A climate device in a Night Control.</description>
<channels>
<channel id="temperature" typeId="temperature"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="nightControlTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Verisure Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="doorWindowSensor">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Door or Window Sensor</label>
<description>A Verisure door or window sensor in your system.</description>
<channels>
<channel id="state" typeId="state"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="doorWindowTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Verisure Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="userPresence">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure User Presence</label>
<description>Verisure Presence information about your configured and active Verisure users.</description>
<channels>
<channel id="userName" typeId="userName"/>
<channel id="webAccount" typeId="webAccount"/>
<channel id="userLocationStatus" typeId="userLocationStatus"/>
<channel id="userDeviceName" typeId="userDeviceName"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Unique Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="broadbandConnection">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Broadband Connection</label>
<description>Status of the Verisure broadband connection.</description>
<channels>
<channel id="timestamp" typeId="timestamp"/>
<channel id="connected" typeId="connected"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Unique Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="miceDetection">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Mice Detection</label>
<description>Status of the Verisure mice detection.</description>
<channels>
<channel id="countLatestDetection" typeId="countLatestDetection"/>
<channel id="countLast24Hours" typeId="countLast24Hours"/>
<channel id="durationLatestDetection" typeId="durationLatestDetection"/>
<channel id="durationLast24Hours" typeId="durationLast24Hours"/>
<channel id="timestamp" typeId="timestamp"/>
<channel id="temperature" typeId="temperature"/>
<channel id="temperatureTimestamp" typeId="timestamp"/>
<channel id="location" typeId="location"/>
<channel id="installationName" typeId="installationName"/>
<channel id="installationId" typeId="installationId"/>
<channel id="miceDetectionTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Unique Id.</description>
</parameter>
</config-description>
</thing-type>
<thing-type id="eventLog">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Event Log</label>
<description>Contents of the Verisure event log.</description>
<channels>
<channel id="lastEventId" typeId="lastEventId"/>
<channel id="lastEventLocation" typeId="location"/>
<channel id="lastEventDeviceId" typeId="lastEventDeviceId"/>
<channel id="lastEventDeviceType" typeId="lastEventDeviceType"/>
<channel id="lastEventType" typeId="lastEventType"/>
<channel id="lastEventCategory" typeId="lastEventCategory"/>
<channel id="lastEventTime" typeId="timestamp"/>
<channel id="lastEventUserName" typeId="lastEventUserName"/>
<channel id="eventLog" typeId="eventLog"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Unique Id.</description>
</parameter>
<parameter name="numberOfEvents" type="integer">
<label>Number of Events</label>
<description>Number of events to fetch each poll.</description>
<default>15</default>
</parameter>
<parameter name="eventTriggerDelay" type="integer">
<label>Event Trigger Delay</label>
<description>Specifies the event trigger delay in milliseconds.</description>
<default>2000</default>
</parameter>
</config-description>
</thing-type>
<thing-type id="gateway">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Verisure Gateway</label>
<description>Communication status for the Verisure Gateway.</description>
<channels>
<channel id="statusGSMOverUDP" typeId="communicationTestResult"/>
<channel id="testTimeGSMOverUDP" typeId="timestamp"/>
<channel id="statusGSMOverSMS" typeId="communicationTestResult"/>
<channel id="testTimeGSMOverSMS" typeId="timestamp"/>
<channel id="statusGPRSOverUDP" typeId="communicationTestResult"/>
<channel id="testTimeGPRSOverUDP" typeId="timestamp"/>
<channel id="statusETHOverUDP" typeId="communicationTestResult"/>
<channel id="testTimeETHOverUDP" typeId="timestamp"/>
<channel id="location" typeId="location"/>
<channel id="model" typeId="model"/>
<channel id="gatewayTriggerChannel" typeId="triggerChannel"/>
</channels>
<properties>
<property name="vendor">Verisure</property>
</properties>
<representation-property>deviceId</representation-property>
<config-description>
<parameter name="deviceId" type="text" required="true">
<label>Device Id</label>
<description>Unique Id.</description>
</parameter>
</config-description>
</thing-type>
<channel-type id="triggerChannel">
<kind>trigger</kind>
<label>Trigger Channel</label>
<event>
<options>
<option value="LOCK">Lock SmartLock</option>
<option value="UNLOCK">Unlock SmartLock</option>
<option value="LOCK_FAILURE">Lock SmartLock failure</option>
<option value="ARM">Arm alarm</option>
<option value="DISARM">Disarm alarm</option>
<option value="FIRE">Smoke/Fire alarm</option>
<option value="WATER">Water alarm</option>
<option value="MICE">Mice alarm</option>
<option value="BATTERY_LOW">Battery low</option>
<option value="BATTERY_RESTORED">Battery low</option>
<option value="COM_FAILURE">Communication failure</option>
<option value="COM_RESTORED">Communication restored</option>
<option value="COM_TEST">Communication test</option>
<option value="SABOTAGE_ALARM">Sabotage alarm</option>
<option value="SABOTAGE_RESTORED">Sabotage alarm restored</option>
<option value="DOORWINDOW_OPENED">Door/Window opened</option>
<option value="DOORWINDOW_CLOSED">Door/Window closed</option>
<option value="LOCATION_AWAY">Location away</option>
<option value="LOCATION_HOME">Location away</option>
</options>
</event>
</channel-type>
<channel-type id="status">
<item-type>String</item-type>
<label>Current Status</label>
<description>Information on current status.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="userName">
<item-type>String</item-type>
<label>User Name</label>
<description>Name of the user.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="webAccount">
<item-type>String</item-type>
<label>User Email</label>
<description>The User's Email address.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="userLocationStatus">
<item-type>String</item-type>
<label>User Location Status</label>
<description>Information on user location status (HOME/AWAY).</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="userDeviceName">
<item-type>String</item-type>
<label>User Device Name</label>
<description>Information on user device name.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="numericStatus">
<item-type>Number</item-type>
<label>Current Numeric Status</label>
<description>Information about current numeric status.</description>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="timestamp">
<item-type>DateTime</item-type>
<label>TimeStamp</label>
<description>Date and time of last event change.</description>
<state readOnly="true" pattern="%1$tY-%1$tm-%1$td %1$tH:%1$tM"/>
</channel-type>
<channel-type id="changedByUser">
<item-type>String</item-type>
<label>Operated By</label>
<description>User who did the last change.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="changedVia">
<item-type>String</item-type>
<label>Changed via</label>
<description>Method used to change status.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="motorJam">
<item-type>Switch</item-type>
<label>SmartLock Motor Jam</label>
<description>Tells if the SmartLock motor has jammed.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="alarmStatus">
<item-type>String</item-type>
<label>Alarm Status</label>
<description>Verisure alarm status.</description>
<state>
<options>
<option value="DISARMED">DISARMED</option>
<option value="ARMED_HOME">ARMED HOME</option>
<option value="ARMED_AWAY">ARMED AWAY</option>
</options>
</state>
</channel-type>
<channel-type id="smartLockStatus">
<item-type>Switch</item-type>
<label>SmartLock Status</label>
<description>Verisure smart lock status.</description>
</channel-type>
<channel-type id="autoRelock">
<item-type>Switch</item-type>
<label>SmartLock Auto Re-lock</label>
<description>Verisure smart lock auto re-lock status.</description>
</channel-type>
<channel-type id="smartLockVolume">
<item-type>String</item-type>
<label>SmartLock Volume</label>
<description>Verisure smart lock volume status.</description>
<state>
<options>
<option value="SILENCE">SILENCE</option>
<option value="LOW">LOW</option>
<option value="HIGH">HIGH</option>
</options>
</state>
</channel-type>
<channel-type id="smartLockVoiceLevel">
<item-type>String</item-type>
<label>SmartLock Voice Level Setting</label>
<description>Verisure smart lock voice level status.</description>
<state>
<options>
<option value="ESSENTIAL">ESSENTIAL</option>
<option value="NORMAL">NORMAL</option>
</options>
</state>
</channel-type>
<channel-type id="smartPlugStatus">
<item-type>Switch</item-type>
<label>SmartPlug Status</label>
<description>Verisure smart plug status.</description>
</channel-type>
<channel-type id="connected">
<item-type>Switch</item-type>
<label>Broadband Connection Status</label>
<description>Verisure broadband connection status.</description>
</channel-type>
<channel-type id="state">
<item-type>Contact</item-type>
<label>Door/Window State</label>
<description>Is door/window opened or closed. (OPEN/CLOSED)</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="temperature">
<item-type>Number:Temperature</item-type>
<label>Temperature</label>
<description>Current temperature.</description>
<category>Temperature</category>
<state readOnly="true" pattern="%.1f °C"/>
</channel-type>
<channel-type id="humidity">
<item-type>Number:Dimensionless</item-type>
<label>Humidity</label>
<description>Current humidity in %.</description>
<category>Humidity</category>
<state readOnly="true" min="0" max="100" pattern="%d %%"/>
</channel-type>
<channel-type id="humidityEnabled">
<item-type>Switch</item-type>
<label>Humidity Enabled</label>
<description>Is Climate device capable of reporting humidity.</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="label">
<item-type>String</item-type>
<label>Label</label>
<description>The name of the door/window.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="location">
<item-type>String</item-type>
<label>Location</label>
<description>The location of the device.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="hazardous">
<item-type>Switch</item-type>
<label>Hazardous</label>
<description>Is Verisure smart plug configured as hazardous.</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="installationName">
<item-type>String</item-type>
<label>Installation Site Name</label>
<description>Name of the installation site.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="installationId">
<item-type>Number</item-type>
<label>Installation Site Id</label>
<description>ID of the installation site.</description>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="countLatestDetection">
<item-type>Number</item-type>
<label>Mouse Count Latest Detection</label>
<description>Mouse count latest detection during last 24 hours.</description>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="countLast24Hours">
<item-type>Number</item-type>
<label>Mouse Count Last 24 Hours</label>
<description>Mouse count last 24 hours.</description>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="durationLatestDetection">
<item-type>Number:Time</item-type>
<label>Duration Last Detection</label>
<description>Duration last detection.</description>
<state readOnly="true" pattern="%d s"/>
</channel-type>
<channel-type id="durationLast24Hours">
<item-type>Number:Time</item-type>
<label>Duration Last 24 Hours</label>
<description>Duration last 24 hours.</description>
<state readOnly="true" pattern="%d s"/>
</channel-type>
<channel-type id="lastEventType">
<item-type>String</item-type>
<label>Last Event Type</label>
<description>The last event's type in the event log.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="lastEventCategory">
<item-type>String</item-type>
<label>Last Event Category</label>
<description>The last event's category in the event log.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="lastEventId">
<item-type>Number</item-type>
<label>Last Event Id</label>
<description>The last event's id in the event log.</description>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="lastEventDeviceId">
<item-type>String</item-type>
<label>Last Event Device Id</label>
<description>The last event's device id in the event log.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="lastEventDeviceType">
<item-type>String</item-type>
<label>Last Event Device Type</label>
<description>The last event's device type in the event log.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="lastEventUserName">
<item-type>String</item-type>
<label>Last Event User Name</label>
<description>The last event's user name in the event log.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="eventLog">
<item-type>String</item-type>
<label>Verisure Event Log</label>
<description>Verisure event log as a JSON array.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="communicationTestResult">
<item-type>String</item-type>
<label>Verisure GW Communication Test Result</label>
<description>Verisure Gateway communication test result.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
<channel-type id="model">
<item-type>String</item-type>
<label>Verisure GW Model</label>
<description>Verisure Gateway model.</description>
<state readOnly="true" pattern="%s"/>
</channel-type>
</thing:thing-descriptions>