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,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.openhab.binding.verisure</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,20 @@
This content is produced and maintained by the openHAB project.
* Project home: https://www.openhab.org
== Declared Project Licenses
This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.
== Source Code
https://github.com/openhab/openhab2-addons
== Third-party Content
jsoup
* License: MIT License
* Project: https://jsoup.org/
* Source: https://github.com/jhy/jsoup

View File

@@ -0,0 +1,585 @@
# Verisure Binding
This is an openHAB binding for Verisure Alarm System, by Securitas Direct.
This binding uses the rest API behind the Verisure My Pages:
https://mypages.verisure.com/login.html.
Be aware that Verisure don't approve if you update to often, I have gotten no complaints running with a 10 minutes update interval, but officially you should use 30 minutes.
## Supported Things
This binding supports the following thing types:
- Bridge
- Alarm
- Smoke Detector (climate)
- Water Detector (climate)
- Siren (climate)
- Night Control
- Yaleman SmartLock
- SmartPlug
- Door/Window Status
- User Presence Status
- Broadband Connection Status
- Mice Detection Status (incl. climate)
- Event Log
- Gateway
## Binding Configuration
You will have to configure the bridge with username and password, these must be the same credentials as used when logging into https://mypages.verisure.com.
You must also configure your pin-code(s) to be able to lock/unlock the SmartLock(s) and arm/unarm the Alarm(s).
**NOTE:** To be able to have full control over all SmartLock functionality, the user has to have Administrator rights.
## Discovery
After the configuration of the Verisure Bridge all of the available Sensors, Alarms, SmartPlugs, SmartLocks, Climate and Mice Detection devices will be discovered and placed as things in the inbox.
## Thing Configuration
Only the bridge require manual configuration. The devices and sensors can be added by hand, or you can let the discovery mechanism automatically find all of your Verisure things.
## Enable Debugging
To enable DEBUG logging for the binding, login to Karaf console and enter:
`openhab> log:set DEBUG org.openhab.binding.verisure`
## Supported Things and Channels
### Verisure Bridge
#### Configuration Options
* `username` - The username used to connect to http://mypage.verisure.com
* The user has to have Administrator rights to have full SmartLock functionality
* `password` - The password used to connect to http://mypage.verisure.com
* `refresh` - Specifies the refresh interval in seconds
* `pin` - The username's pin code to arm/disarm alarm and lock/unlock door. In the case of more than one installation and different pin-codes, use a comma separated string where pin-code matches order of installations. The installation order can be found using DEBUG log settings.
* Two installations where the first listed installation uses a 6 digit pin-code and second listed installation uses a 4 digit pin-code: 123456,1234
If you define the bridge in a things-file the bridge type id is defined as `bridge`, e.g.:
`Bridge verisure:bridge:myverisureBridge verisure:bridge:myverisure`
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|-----------------|-----------|-------------------------------------------------------------------------------------------------|
| status | String | This channel can be used to trigger an instant refresh by sending a RefreshType.REFRESH command.|
### Verisure Alarm
#### Configuration Options
* `deviceId` - Device Id
* Since Alarm lacks a Verisure ID, the following naming convention is used for alarm on installation ID 123456789: 'alarm123456789'. Installation ID can be found using DEBUG log settings
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|---------------------|-----------|-------------------------------------------------------------------------------------------|
| changedByUser | String | This channel reports the user that last changed the state of the alarm. |
| changedVia | String | This channel reports the method used to change the status. |
| timestamp | DateTime | This channel reports the last time the alarm status was changed. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| alarmStatus | String | This channel is used to arm/disarm the alarm. Available alarm status are "DISARMED", "ARMED_HOME" and "ARMED_AWAY".|
| alarmTriggerChannel | trigger | This is a trigger channel that receives events.|
### Verisure Yaleman SmartLock
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or My Pages)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|-------------------------|-----------|----------------------------------------------------------------------------------------------------------|
| changedByUser | String | This channel reports the user that last changed the state of the alarm. |
| timestamp | DateTime | This channel reports the last time the alarm status was changed. |
| changedVia | String | This channel reports the method used to change the status. |
| motorJam | Switch | This channel reports if the SmartLock motor has jammed. |
| location | String | This channel reports the location of the device. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| smartLockStatus | Switch | This channel is used to lock/unlock. |
| autoRelock | Switch | This channel is used to configure auto-lock functionality. Only supported for users with Administrator rights. |
| smartLockVolume | String | This channel is used to set the volume level. Available volume settings are "SILENCE", "LOW" and "HIGH". Only supported for users with Administrator rights.|
| smartLockVoiceLevel | String | This channel is used to set the voice level. Available voice level settings are "ESSENTIAL" and "NORMAL". Only supported for users with Administrator rights.|
| smartLockTriggerChannel | trigger | This is a trigger channel that receives events. |
### Verisure SmartPlug
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or My Pages or on the sensor itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|-------------------------|-----------|-------------------------------------------------------------------|
| hazardous | Switch | This channel reports if the smart plug is configured as hazardous.|
| location | String | This channel reports the location of the device. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| smartPlugStatus | Switch | This channel is used to turn smart plug on/off. |
| smartPlugTriggerChannel | trigger | This is a trigger channel that receives events. |
### Verisure Smoke Detector
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or on the sensor itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|-----------------------------|-----------------------|-----------------------------------------------------------------------------|
| temperature | Number:Temperature | This channel reports the current temperature. |
| humidity | Number | This channel reports the current humidity in percentage. |
| humidityEnabled | Switch | This channel reports if the Climate is device capable of reporting humidity.|
| timestamp | DateTime | This channel reports the last time this sensor was updated. |
| location | String | This channel reports the location of the device. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| smokeDetectorTriggerChannel | trigger | This is a trigger channel that receives events.|
### Verisure Water Detector
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or My Pages or on the sensor itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|-----------------------------|-----------------------|--------------------------------------------------------------|
| temperature | Number:Temperature | This channel reports the current temperature. |
| timestamp | DateTime | This channel reports the last time this sensor was updated. |
| location | String | This channel reports the location of the device. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| waterDetectorTriggerChannel | trigger | This is a trigger channel that receives events. |
### Verisure Siren
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or My Pages or on the sensor itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|---------------------|-----------------------|------------------------------------------------------------|
| temperature | Number:Temperature | This channel reports the current temperature. |
| timestamp | DateTime | This channel reports the last time this sensor was updated.|
| location | String | This channel reports the location. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| sirenTriggerChannel | trigger | This is a trigger channel that receives events. |
### Verisure Night Control
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or My Pages or on the sensor itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|----------------------------|-----------------------|------------------------------------------------------------|
| temperature | Number:Temperature | This channel reports the current temperature. |
| timestamp | DateTime | This channel reports the last time this sensor was updated.|
| location | String | This channel reports the location. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| nightControlTriggerChannel | trigger | This is a trigger channel that receives events. |
### Verisure DoorWindow Sensor
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or My Pages or on the sensor itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|--------------------------|-----------|-----------------------------------------------------------------------------|
| state | Contact | This channel reports the if the door/window is open or closed (OPEN/CLOSED).|
| timestamp | DateTime | This channel reports the last time this sensor was updated. |
| location | String | This channel reports the location of the device. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| doorWindowTriggerChannel | trigger | This is a trigger channel that receives events. |
### Verisure User Presence
#### Configuration Options
* `deviceId` - Device Id
* Since User presence lacks a Verisure ID, it is constructed from the user's email address, where the '@' sign is removed, and the site id. The following naming convention is used for User presence on site id 123456789 for a user with email address test@gmail.com: 'uptestgmailcom123456789'. Installation ID can be found using DEBUG log settings.
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|--------------------|-----------|-------------------------------------------------------------------------|
| userLocationStatus | String | This channel reports the user presence status (HOME/AWAY). |
| timestamp | DateTime | This channel reports the last time the User Presence status was changed.|
| userName | String | This channel reports the user's name. |
| webAccount | String | This channel reports the user's email address. |
| userDeviceName | String | This channel reports the name of the user device. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
### Verisure Broadband Connection
#### Configuration Options
* `deviceId` - Device Id
* Since Broadband connection lacks a Verisure ID, the following naming convention is used for Broadband connection on site id 123456789: 'bc123456789'. Installation ID can be found using DEBUG log settings.
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|-----------------|-----------|--------------------------------------------------------------------------------|
| connected | String | This channel reports the broadband connection status (true means connected). |
| timestamp | DateTime | This channel reports the last time the Broadband connection status was checked.|
| installationName| String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
### Verisure Mice Detection
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 5A4C35FT (Note: Verisure ID, found in the Verisure App or My Pages or on the sensor itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|-----------------------------|--------------------|-------------------------------------------------------------------------------------|
| countLatestDetection | Number | This channel reports the number of mice counts the latest detection during last 24. |
| countLast24Hours | Number | This channel reports the total number of mice counts the last 24h. |
| durationLatestDetection | Number:Time | This channel reports the detection duration in min of latest detection. |
| durationLast24Hours | Number:Time | This channel reports the total detection duration in min for the last 24 hours. |
| timestamp | DateTime | This channel reports time for the last mouse detection. |
| temperature | Number:Temperature | This channel reports the current temperature. |
| temperatureTimestamp | DateTime | This channel reports the time for the last temperature reading. |
| location | String | This channel reports the location of the device. |
| installationName | String | This channel reports the installation name. |
| installationId | Number | This channel reports the installation ID. |
| miceDetectionTriggerChannel | trigger | This is a trigger channel that receives events. |
### Verisure Event Log
#### Configuration Options
* `deviceId` - Device Id
* Since Event Log lacks a Verisure ID, the following naming convention is used for Event Log on site id 123456789: 'el123456789'. Installation ID can be found using DEBUG log settings.
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|---------------------|-----------|-------------------------------------------------------------------------|
| lastEventLocation | String | This channel reports location for last event in event log. |
| lastEventDeviceId | String | This channel reports device ID for last event in event log. |
| lastEventDeviceType | String | This channel reports device type for last event in event log. |
| lastEventType | String | This channel reports type for last event in event log. |
| lastEventCategory | String | This channel reports category for last event in event log. |
| lastEventTime | DateTime | This channel reports time for last event in event log. |
| lastEventUserName | String | This channel reports user name for last event in event log. |
| eventLog | String | This channel reports the last 15 events from event log in a JSON array. |
### Verisure Gateway
#### Configuration Options
* `deviceId` - Device Id
* Sensor Id. Example 3B4C35FT (Note: Verisure ID, found in the Verisure App or My Pages or on the Gateway itself)
#### Channels
The following channels are supported:
| Channel Type ID | Item Type | Description |
|---------------------|-----------|----------------------------------------------------------------------|
| model | String | This channel reports gateway model. |
| location | String | This channel reports gateway location. |
| statusGSMOverUDP | String | This channel reports communication status for GSM over UDP. |
| testTimeGSMOverUDP | DateTime | This channel reports last communication test time for GSM over UDP. |
| statusGSMOverSMS | String | This channel reports communication status for GSM over SMS. |
| testTimeGSMOverSMS | DateTime | This channel reports last communication test time for GSM over SMS. |
| statusGPRSOverUDP | String | This channel reports communication status for GPRS over UDP. |
| testTimeGPRSOverUDP | DateTime | This channel reports last communication test time for GPRS over UDP. |
| statusETHOverUDP | String | This channel reports communication status for ETH over UDP. |
| testTimeETHOverUDP | DateTime | This channel reports last communication test time for ETH over UDP. |
## Trigger Events
To be able to get trigger events you need an active Event Log thing, you can either get it via auto-detection or create your own in a things-file.
The following trigger events are defined per thing type:
| Event | Thing Type | Description |
|-------------------|---------------|------------------------------------------------------------|
| LOCK | SmartLock | SmartLock has been locked. |
| UNLOCK | SmartLock | SmartLock has been locked. |
| LOCK_FAILURE | SmartLock | SmartLock has failed to lock/unlock. |
| ARM | Alarm | Alarm has been armed. |
| DISARM | Alarm | Alarm has been disarmed. |
| DOORWINDOW_OPENED | DoorWindow | DoorWindow has detected a door/window that opened. |
| DOORWINDOW_CLOSED | DoorWindow | DoorWindow has detected a door/window that closed. |
| INTRUSION | DoorWindow | DoorWindow has detected an intrusion. |
| FIRE | SmokeDetector | SmokeDetector has detected fire/smoke. |
| WATER | WaterDetector | WaterDetector has detected a water leak. |
| MICE | MiceDetector | WaterMiceDetector has detected a mouse. |
| COM_FAILURE | All | Communication failure detected. |
| COM_RESTORED | All | Communication restored. |
| COM_TEST | All | Communication test. |
| BATTERY_LOW | All | Battery low level detected. |
| BATTERY_RESTORED | All | Battery level restored. |
| SABOTAGE_ALARM | All | Sabotage alarm detected. |
| SABOTAGE_RESTORED | All | Sabotage alarm restored. |
## Example
### Things-file
````
// Bridge configuration
Bridge verisure:bridge:myverisure "Verisure Bridge" [username="x@y.com", password="1234", refresh="600", pin="111111"] {
Thing alarm JannesAlarm "Verisure Alarm" [ deviceId="alarm123456789" ]
Thing smartLock JannesSmartLock "Verisure Entrance Yale Doorman" [ deviceId="3C446NPO" ]
Thing smartPlug JannesSmartPlug "Verisure SmartPlug" [ deviceId="3D7GMANV" ]
Thing waterDetector JannesWaterDetector "Verisure Water Detector" [ deviceId="3WETQRH5" ]
Thing userPresence JannesUserPresence "Verisure User Presence" [ deviceId="uptestgmailcom123456789" ]
Thing eventLog JannesEventLog "Verisure Event Log" [ deviceId="el123456789" ]
Thing gateway JannesGateway "Verisure Gateway" [ deviceId="3AFG5673" ]
}
````
### Items-file
````
Group gVerisureMiceDetection
Group gVerisureEventLog
Group gVerisureGateway
// SmartLock and Alarm
Switch SmartLock "Verisure SmartLock" <lock> [ "Switchable" ] {channel="verisure:smartLock:myverisure:JannesSmartLock:smartLockStatus"}
Switch AutoLock "AutoLock" <lock> [ "Switchable" ] {channel="verisure:smartLock:myverisure:JannesSmartLock:autoRelock"}
String SmartLockVolume "SmartLock Volume" <lock> {channel="verisure:smartLock:myverisure:JannesSmartLock:smartLockVolume"}
DateTime SmartLockLastUpdated "SmartLock Last Updated [%1$tY-%1$tm-%1$td %1$tR]" {channel="verisure:smartLock:myverisure:JannesSmartLock:timestamp"}
String AlarmHome "Alarm Home" <alarm> {channel="verisure:alarm:myverisure:JannesAlarm:alarmStatus"}
DateTime AlarmLastUpdated "Verisure Alarm Last Updated [%1$tY-%1$tm.%1$td %1$tR]" {channel="verisure:alarm:myverisure:JannesAlarm:timestamp"}
String AlarmChangedByUser "Verisure Alarm Changed By User" {channel="verisure:alarm:myverisure:JannesAlarm:changedByUser"}
// SmartPlugs
Switch SmartPlugLamp "SmartPlug" <lock> [ "Switchable" ] {channel="verisure:smartPlug:myverisure:4ED5ZXYC:smartPlugStatus"}
Switch SmartPlugGlavaRouter "SmartPlug Glava Router" <lock> [ "Switchable" ] {channel="verisure:smartPlug:myverisure:JannesSmartPlug:smartPlugStatus"}
// DoorWindow
String DoorWindowLocation "Door Window Location" {channel="verisure:doorWindowSensor:myverisure:1SG5GHGT:location"}
String DoorWindowStatus "Door Window Status" {channel="verisure:doorWindowSensor:myverisure:1SG5GHGT:state"}
// UserPresence
String UserName "User Name" {channel="verisure:userPresence:myverisure:JannesUserPresence:userName"}
String UserLocationEmail "User Location Email" {channel="verisure:userPresence:myverisure:JannesUserPresence:webAccount"}
String UserLocationName "User Location Name" {channel="verisure:userPresence:myverisure:JannesUserPresence:userLocationStatus"}
String UserNameGlava "User Name Glava" {channel="verisure:userPresence:myverisure:userpresencetestgmailcom123456789:userName"}
String UserLocationEmailGlava "User Location Email Glava" {channel="verisure:userPresence:myverisure:userpresencetestgmailcom123456789:webAccount"}
String UserLocationNameGlava "User Location Name Glava" {channel="verisure:userPresence:myverisure:userpresencetestgmailcom1123456789:userLocationStatus"}
// EventLog
String LastEventLocation "Last Event Location" (gVerisureEventLog) {channel="verisure:eventLog:myverisure:JannesEventLog:lastEventLocation"}
String LastEventDeviceId "Last Event Device ID" (gVerisureEventLog) {channel="verisure:eventLog:myverisure:JannesEventLog:lastEventDeviceId"}
String LastEventDeviceType "Last Event Device Type" (gVerisureEventLog) {channel="verisure:eventLog:myverisure:JannesEventLog:lastEventDeviceType"}
String LastEventType "Last Event Type" (gVerisureEventLog) {channel="verisure:eventLog:myverisure:JannesEventLog:lastEventType"}
String LastEventCategory "Last Event Category" (gVerisureEventLog) {channel="verisure:eventLog:myverisure:JannesEventLog:lastEventCategory"}
DateTime LastEventTime "Last Event Time [%1$tY-%1$tm-%1$td %1$tR]" (gVerisureEventLog) {channel="verisure:eventLog:myverisure:JannesEventLog:lastEventTime"}
String LastEventUserName "Last Event User Name" (gVerisureEventLog) {channel="verisure:eventLog:myverisure:JannesEventLog:lastEventUserName"}
String EventLog "Event Log" {channel="verisure:eventLog:myverisure:JannesEventLog:eventLog"}
// Gateway
String VerisureGatewayModel "Gateway Model" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:model"}
String VerisureGatewayLocation "Gateway Location" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:location"}
String VerisureGWStatusGSMOverUDP "Gateway Status GSMOverUDP" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:statusGSMOverUDP"}
DateTime VerisureGWTestTimeGSMOverUDP "Gateway Test Time GSMOverUDP" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:testTimeGSMOverUDP"}
String VerisureGWStatusGSMOverSMS "Gateway Status GSMOverSMS" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:statusGSMOverSMS"}
DateTime VerisureGWTestTimeGSMOverSMS "Gateway Test Time GSMOverSMS" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:testTimeGSMOverSMS"}
String VerisureGWStatusGPRSOverUDP "Gateway Status GPRSOverUDP" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:statusGPRSOverUDP"}
DateTime VerisureGWTestTimeGPRSOverUDP "Gateway Test Time GPRSOverUDP" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:testTimeGPRSOverUDP"}
String VerisureGWStatusETHOverUDP "Gateway Status ETHOverUDP" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:statusETHOverUDP"}
DateTime VerisureGWTestTimeETHOverUDP "Gateway Test Time ETHOverUDP" (gVerisureGateway) {channel="verisure:gateway:myverisure:JannesGateway:testTimeETHOverUDP"}
// Broadband Connection
String CurrentBBStatus "Broadband Connection Status" {channel="verisure:broadbandConnection:myverisure:bc123456789:connected"}
// Verisure Mice Detection
Number MouseCountLastDetection "Mouse Count Last Detection" (gVerisureMiceDetection) {channel="verisure:miceDetection:myverisure:2CFZH80U:countLatestDetection"}
Number MouseCountLast24Hours "Mouse Count Last 24 Hours" (gVerisureMiceDetection) {channel="verisure:miceDetection:myverisure:2CFZH80U:countLast24Hours"}
DateTime MouseLastDetectionTime "Mouse Last Detection Time [%1$tY-%1$tm-%1$td %1$tR]" (gVerisureMiceDetection) {channel="verisure:miceDetection:myverisure:2CFZH80U:timestamp"}
Number MouseDurationLastDetection "Mouse Duration Last Detection" (gVerisureMiceDetection) {channel="verisure:miceDetection:myverisure:2CFZH80U:durationLatestDetection"}
Number MouseDurationLast24Hours "Mouse Duration Last 24 Hours" (gVerisureMiceDetection) {channel="verisure:miceDetection:myverisure:2CFZH80U:durationLast24Hours"}
Number MouseDetectionTemperature "Mouse Detection Temperature [%.1f C]" <temperature> (gTemperaturesVerisure, gVerisureMiceDetection) ["CurrentTemperature"] {channel="verisure:miceDetection:myverisure:2CFZH80U:temperature"}
DateTime MouseDetectionTemperatureTime "Mouse Detection Temperature Time [%1$tY-%1$tm-%1$td %1$tR]" (gVerisureMiceDetection) {channel="verisure:miceDetection:myverisure:2CFZH80U:temperatureTimestamp"}
String MouseDetectionLocation "Mouse Detection Location" (gVerisureMiceDetection) {channel="verisure:miceDetection:myverisure:2CFZH80U:location"}
````
### Sitemap
````
Frame label="SmartLock and Alarm" {
Text label="SmartLock and Alarm" icon="groundfloor" {
Frame label="Yale Doorman SmartLock" {
Switch item=SmartLock label="Yale Doorman SmartLock" icon="lock.png"
}
Frame label="Verisure Alarm" {
Switch item=AlarmHome icon="alarm" label="Verisure Alarm" mappings=["DISARMED"="Disarm", "ARMED_HOME"="Arm Home", "ARMED_AWAY"="Arm Away"]
}
Frame label="Yale Doorman SmartLock AutoLock" {
Switch item=AutoLock label="Yale Doorman SmartLock AutoLock" icon="lock.png"
}
Frame label="Yale Doorman SmartLock Volume" {
Switch item=SmartLockVolume icon="lock" label="Yale Doorman SmartLock Volume" mappings=["SILENCE"="Silence", "LOW"="Low", "HIGH"="High"]
}
Text item=AlarmHomeInstallationName label="Alarm Installation [%s]"
Text item=AlarmChangedByUser label="Changed by user [%s]"
Text item=AlarmLastUpdated
Text item=SmartLockStatus label="SmartLock status [%s]"
Text item=SmartLockLastUpdated
Text item=SmartLockOperatedBy label="Changed by user [%s]"
Text item=DoorWindowStatus label="Door State"
Text item=DoorWindowLocation
}
}
Frame label="SmartPlugs" {
Text label="SmartPlugs" icon="attic" {
Frame label="SmartPlug Lamp" {
Switch item=SmartPlugLamp label="Verisure SmartPlug Lamp" icon="smartheater.png"
}
}
}
Frame label="User Presence" {
Text label="User Presence" icon="attic" {
Frame label="User Presence Champinjonvägen" {
Text item=UserName label="User Name [%s]"
Text item=UserLocationEmail label="User Email [%s]"
Text item=UserLocationStatus label="User Location Status [%s]"
}
}
}
Frame label="Broadband Connection" {
Text label="Broadband Connection" icon="attic" {
Frame label="Broadband Connection Champinjonvägen" {
Text item=CurrentBBStatus label="Broadband Connection Status [%s]"
}
}
}
Frame label="Mice Detection" {
Group item=gVerisureMiceDetection label="Verisure Mice Detection"
}
Frame label="Event Log" {
Group item=gVerisureEventLog label="Verisure Event Log"
}
Frame label="Gateway" {
Group item=gVerisureGateway label="Verisure Gateway"
}
````
### Rules
````
import org.openhab.core.types.RefreshType
rule "Handle Refesh of Verisure"
when
Item RefreshVerisure received command
then
var String command = RefreshVerisure.state.toString.toLowerCase
logDebug("RULES","RefreshVerisure Rule command: " + command)
sendCommand(VerisureBridgeStatus, RefreshType.REFRESH)
end
rule "Verisure SmartLock Event Triggers"
when
Channel "verisure:smartLock:myverisure:JannesSmartLock:smartLockTriggerChannel" triggered
then
logInfo("RULES", "A SmartLock trigger event was detected:" + receivedEvent.toString())
end
rule "Verisure Gateway Event Triggers"
when
Channel "verisure:gateway:myverisure:JannesGateway:gatewayTriggerChannel" triggered
then
logInfo("RULES", "A Gateway trigger event was detected:" + receivedEvent.toString())
end
rule "Verisure DoorWindow Event Triggers"
when
Channel "verisure:doorWindowSensor:myverisure:1SG5GHGT:doorWindowTriggerChannel" triggered
then
logInfo("RULES", "A DoorWindow trigger event was detected:" + receivedEvent.toString())
end
````

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>3.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.openhab.binding.verisure</artifactId>
<name>openHAB Add-ons :: Bundles :: Verisure Binding</name>
<dependencies>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

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>