[sleepiq] Rework cloud API and other enhancements (#14180)
Signed-off-by: Mark Hilbush <mark@hilbush.com>
This commit is contained in:
parent
cb07f3e2f0
commit
253b25631f
|
@ -301,7 +301,7 @@
|
||||||
/bundles/org.openhab.binding.siemensrds/ @andrewfg
|
/bundles/org.openhab.binding.siemensrds/ @andrewfg
|
||||||
/bundles/org.openhab.binding.silvercrestwifisocket/ @jmvaz
|
/bundles/org.openhab.binding.silvercrestwifisocket/ @jmvaz
|
||||||
/bundles/org.openhab.binding.sinope/ @chaton78
|
/bundles/org.openhab.binding.sinope/ @chaton78
|
||||||
/bundles/org.openhab.binding.sleepiq/ @syphr42
|
/bundles/org.openhab.binding.sleepiq/ @syphr42 @mhilbush
|
||||||
/bundles/org.openhab.binding.smaenergymeter/ @monnimeter
|
/bundles/org.openhab.binding.smaenergymeter/ @monnimeter
|
||||||
/bundles/org.openhab.binding.smartmeter/ @msteigenberger
|
/bundles/org.openhab.binding.smartmeter/ @msteigenberger
|
||||||
/bundles/org.openhab.binding.smartthings/ @BobRak
|
/bundles/org.openhab.binding.smartthings/ @BobRak
|
||||||
|
|
|
@ -31,13 +31,11 @@ The binding requires no special configuration.
|
||||||
The bridge requires a username and a password.
|
The bridge requires a username and a password.
|
||||||
Optionally, you can also specify a polling interval.
|
Optionally, you can also specify a polling interval.
|
||||||
|
|
||||||
To enable verbose logging of HTTP requests and responses regarding the cloud service, enable DEBUG level logging on ```SleepIQCloudHandler```.
|
|
||||||
|
|
||||||
| Configuration Parameter | Type | Description | Default |
|
| Configuration Parameter | Type | Description | Default |
|
||||||
|-------------------------|---------|--------------------------------------------------------|---------|
|
|-------------------------|---------|--------------------------------------------------------|---------|
|
||||||
| username | text | Username of a registered SleepIQ account owner | |
|
| username | text | Username of a registered SleepIQ account owner | |
|
||||||
| password | text | Password of a registered SleepIQ account owner | |
|
| password | text | Password of a registered SleepIQ account owner | |
|
||||||
| pollingInterval | integer | Seconds between fetching values from the cloud service | 60 |
|
| pollingInterval | integer | Seconds between fetching values from the cloud service | 120 |
|
||||||
|
|
||||||
### Dual-Chamber Bed (Thing ID: "dualBed")
|
### Dual-Chamber Bed (Thing ID: "dualBed")
|
||||||
|
|
||||||
|
@ -50,7 +48,7 @@ Each bed requires a bed ID as defined by the SleepIQ service.
|
||||||
### Sample Thing Configuration
|
### Sample Thing Configuration
|
||||||
|
|
||||||
```java
|
```java
|
||||||
Bridge sleepiq:cloud:1 [ username="mail@example.com", password="password", pollingInterval=60, logging=false ]
|
Bridge sleepiq:cloud:1 [ username="mail@example.com", password="password", pollingInterval=120 ]
|
||||||
{
|
{
|
||||||
Thing dualBed master [ bedId="-9999999999999999999" ]
|
Thing dualBed master [ bedId="-9999999999999999999" ]
|
||||||
Thing dualBed guest [ bedId="-8888888888888888888" ]
|
Thing dualBed guest [ bedId="-8888888888888888888" ]
|
||||||
|
@ -68,33 +66,65 @@ Bridge sleepiq:cloud:1 [ username="mail@example.com", password="password", polli
|
||||||
|
|
||||||
### Chamber Channel Group
|
### Chamber Channel Group
|
||||||
|
|
||||||
All channels within this group are read-only.
|
All channels within this group are read-only, except for the sleepNumber and privacyMode channels.
|
||||||
|
|
||||||
| Channel ID | Item Type | Description |
|
| Channel ID | Item Type | Description |
|
||||||
|----------------------|-----------|---------------------------------------------------------------------------------------------------------------------|
|
|-----------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------|
|
||||||
| inBed | Switch | The presence of a person or object on the chamber |
|
| inBed | Switch | The presence of a person or object on the chamber |
|
||||||
| sleepNumber | Number | The Sleep Number setting of the chamber |
|
| sleepNumber | Number | The Sleep Number setting of the chamber. Set the sleep number of the chamber by sending a command to the sleepNumber channel with a value between 5 and 100. The value must be a multiple of 5 |
|
||||||
|
|
||||||
|
| sleepGoalMinutes | Number:Time | The person's sleep goal in minutes |
|
||||||
| pressure | Number | The current pressure inside the chamber |
|
| pressure | Number | The current pressure inside the chamber |
|
||||||
|
| privacyMode | Switch | Enable or disable privacy mode |
|
||||||
| lastLink | String | The amount of time that has passed since a connection was made from the chamber to the cloud service (D d HH:MM:SS) |
|
| lastLink | String | The amount of time that has passed since a connection was made from the chamber to the cloud service (D d HH:MM:SS) |
|
||||||
| alertId | Number | Identifier for an alert condition with the chamber |
|
| alertId | Number | Identifier for an alert condition with the chamber |
|
||||||
| alertDetailedMessage | String | A detailed message describing an alert condition with the chamber |
|
| alertDetailedMessage | String | A detailed message describing an alert condition with the chamber |
|
||||||
|
| todaySleepIQ | Number | The Sleep IQ score for the current day |
|
||||||
|
| todayAverageHeartRate | Number | The average heart rate for the current day |
|
||||||
|
| todayAverageRespirationRate | Number | The average respiration rate for the current day |
|
||||||
|
| todayMessage | String | A description of the sleep quality for the current day |
|
||||||
|
| todaySleepDurationSeconds | Number:Time | The duration of sleep for the current day |
|
||||||
|
| monthlySleepIQ | Number | The average Sleep IQ score for the current month |
|
||||||
|
| monthlyAverageHeartRate | Number | The average heart rate for the current month |
|
||||||
|
| monthlyAverageRespirationRate | Number | The average respiration rate for the current month |
|
||||||
|
|
||||||
## Items
|
## Items
|
||||||
|
|
||||||
Here is a sample item configuration:
|
Here is a sample item configuration:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
Switch MasterBedroom_SleepIQ_InBed_Alice "In Bed [%s]" { channel="sleepiq:dualBed:1:master:left#inBed" }
|
Switch MasterBR_SleepIQ_InBed_Alice "In Bed [%s]" { channel="sleepiq:dualBed:1:master:left#inBed" }
|
||||||
Number MasterBedroom_SleepIQ_SleepNumber_Alice "Sleep Number [%s]" { channel="sleepiq:dualBed:1:master:left#sleepNumber" }
|
Number MasterBR_SleepIQ_SleepNumber_Alice "Sleep Number [%s]" { channel="sleepiq:dualBed:1:master:left#sleepNumber" }
|
||||||
Number MasterBedroom_SleepIQ_Pressure_Alice "Pressure [%s]" { channel="sleepiq:dualBed:1:master:left#pressure" }
|
Number:Time MasterBR_SleepIQ_SleepGoal_Alice "Sleep Goal [%d min]" { channel="sleepiq:dualBed:1:master:left#sleepGoalMinutes"
|
||||||
String MasterBedroom_SleepIQ_LastLink_Alice "Last Update [%s]" { channel="sleepiq:dualBed:1:master:left#lastLink" }
|
Number MasterBR_SleepIQ_Pressure_Alice "Pressure [%s]" { channel="sleepiq:dualBed:1:master:left#pressure" }
|
||||||
Number MasterBedroom_SleepIQ_AlertId_Alice "Alert ID [%s]" { channel="sleepiq:dualBed:1:master:left#alertId" }
|
Switch MasterBR_SleepIQ_PrivacyMode_Alice "Privacy Mode [%s]" { channel="sleepiq:dualBed:1:master:left#privacyMode" }
|
||||||
String MasterBedroom_SleepIQ_AlertMessage_Alice "Alert Message [%s]" { channel="sleepiq:dualBed:1:master:left#alertDetailedMessage" }
|
String MasterBR_SleepIQ_LastLink_Alice "Last Update [%s]" { channel="sleepiq:dualBed:1:master:left#lastLink" }
|
||||||
|
Number MasterBR_SleepIQ_AlertId_Alice "Alert ID [%s]" { channel="sleepiq:dualBed:1:master:left#alertId" }
|
||||||
|
String MasterBR_SleepIQ_AlertMessage_Alice "Alert Message [%s]" { channel="sleepiq:dualBed:1:master:left#alertDetailedMessage" }
|
||||||
|
Number MasterBR_SleepIQ_DailySleepIQ_Alice "Daily Sleep IQ [%.0f]" { channel="sleepiq:dualBed:1:master:left#todaySleepIQ" }
|
||||||
|
Number MasterBR_SleepIQ_DailyHeartRate_Alice "Daily Heart Rate [%.0f]" { channel="sleepiq:dualBed:1:master:left#todayAverageHeartRate" }
|
||||||
|
Number MasterBR_SleepIQ_DailyRespRate_Alice "Daily Respiration Rate [%.0f]" { channel="sleepiq:dualBed:1:master:left#todayAverageRespirationRate"}
|
||||||
|
String MasterBR_SleepIQ_DailyMessage_Alice "Daily Message [%s]" { channel="sleepiq:dualBed:1:master:left#todayMessage"}
|
||||||
|
Number MasterBR_SleepIQ_DailyDuration_Alice "Daily Sleep Duration [%.0f]" { channel="sleepiq:dualBed:1:master:left#todaySleepDurationSeconds"}
|
||||||
|
Number:Time MasterBR_SleepIQ_MonthlySleepIQ_Alice "Monthly Sleep IQ [%d s]" { channel="sleepiq:dualBed:1:master:left#monthlySleepIQ"}
|
||||||
|
Number MasterBR_SleepIQ_MonthlyHeartRate_Alice "Monthly Heart Rate [%.0f]" { channel="sleepiq:dualBed:1:master:left#monthlyAverageHeartRate"}
|
||||||
|
Number MasterBR_SleepIQ_MonthlyRespRate_Alice "Monthly Respiration Rate [%.0f]" { channel="sleepiq:dualBed:1:master:left#monthlyAverageRespirationRate"}
|
||||||
|
|
||||||
Switch MasterBedroom_SleepIQ_InBed_Bob "In Bed [%s]" { channel="sleepiq:dualBed:1:master:right#inBed" }
|
|
||||||
Number MasterBedroom_SleepIQ_SleepNumber_Bob "Sleep Number [%s]" { channel="sleepiq:dualBed:1:master:right#sleepNumber" }
|
Switch MasterBR_SleepIQ_InBed_Bob "In Bed [%s]" { channel="sleepiq:dualBed:1:master:right#inBed" }
|
||||||
Number MasterBedroom_SleepIQ_Pressure_Bob "Pressure [%s]" { channel="sleepiq:dualBed:1:master:right#pressure" }
|
Number MasterBR_SleepIQ_SleepNumber_Bob "Sleep Number [%s]" { channel="sleepiq:dualBed:1:master:right#sleepNumber" }
|
||||||
String MasterBedroom_SleepIQ_LastLink_Bob "Last Update [%s]" { channel="sleepiq:dualBed:1:master:right#lastLink" }
|
Number MasterBR_SleepIQ_SleepGoal_Alice "Sleep Goal [%d min]" { channel="sleepiq:dualBed:1:master:left#sleepGoalMinutes"
|
||||||
Number MasterBedroom_SleepIQ_AlertId_Bob "Alert ID [%s]" { channel="sleepiq:dualBed:1:master:right#alertId" }
|
Number:Time MasterBR_SleepIQ_Pressure_Bob "Pressure [%s]" { channel="sleepiq:dualBed:1:master:right#pressure" }
|
||||||
String MasterBedroom_SleepIQ_AlertMessage_Bob "Alert Message [%s]" { channel="sleepiq:dualBed:1:master:right#alertDetailedMessage" }
|
Switch MasterBR_SleepIQ_PrivacyMode_Bob "Privacy Mode [%s]" { channel="sleepiq:dualBed:1:master:right#privacyMode" }
|
||||||
|
String MasterBR_SleepIQ_LastLink_Bob "Last Update [%s]" { channel="sleepiq:dualBed:1:master:right#lastLink" }
|
||||||
|
Number MasterBR_SleepIQ_AlertId_Bob "Alert ID [%s]" { channel="sleepiq:dualBed:1:master:right#alertId" }
|
||||||
|
String MasterBR_SleepIQ_AlertMessage_Bob "Alert Message [%s]" { channel="sleepiq:dualBed:1:master:right#alertDetailedMessage" }
|
||||||
|
Number MasterBR_SleepIQ_DailySleepIQ_Bob "Daily Sleep IQ [%.0f]" { channel="sleepiq:dualBed:1:master:right#todaySleepIQ" }
|
||||||
|
Number MasterBR_SleepIQ_DailyHeartRate_Bob "Daily Heart Rate [%.0f]" { channel="sleepiq:dualBed:1:master:right#todayAverageHeartRate" }
|
||||||
|
Number MasterBR_SleepIQ_DailyRespRate_Bob "Daily Respiration Rate [%.0f]" { channel="sleepiq:dualBed:1:master:right#todayAverageRespirationRate"}
|
||||||
|
String MasterBR_SleepIQ_DailyMessage_Bob "Daily Message [%s]" { channel="sleepiq:dualBed:1:master:right#todayMessage"}
|
||||||
|
Number:Time MasterBR_SleepIQ_DailyDuration_Bob "Daily Sleep Duration [%d s]" { channel="sleepiq:dualBed:1:master:right#todaySleepDurationSeconds"}
|
||||||
|
Number MasterBR_SleepIQ_MonthlySleepIQ_Bob "Monthly Sleep IQ [%.0f]" { channel="sleepiq:dualBed:1:master:right#monthlySleepIQ"}
|
||||||
|
Number MasterBR_SleepIQ_MonthlyHeartRate_Bob "Monthly Heart Rate [%.0f]" { channel="sleepiq:dualBed:1:master:right#monthlyAverageHeartRate"}
|
||||||
|
Number MasterBR_SleepIQ_MonthlyRespRate_Bob "Monthly Respiration Rate [%.0f]" { channel="sleepiq:dualBed:1:master:right#monthlyAverageRespirationRate"}
|
||||||
```
|
```
|
||||||
|
|
|
@ -14,51 +14,4 @@
|
||||||
|
|
||||||
<name>openHAB Add-ons :: Bundles :: SleepIQ Binding</name>
|
<name>openHAB Add-ons :: Bundles :: SleepIQ Binding</name>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<dep.noembedding>provider-gson</dep.noembedding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.12</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>build-helper-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>add-source</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>generate-sources</phase>
|
|
||||||
<configuration>
|
|
||||||
<sources>
|
|
||||||
<source>src/3rdparty/java</source>
|
|
||||||
</sources>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>add-test-source</id>
|
|
||||||
<phase>generate-sources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>add-test-source</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<sources>
|
|
||||||
<source>src/3rdparty/test</source>
|
|
||||||
</sources>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Failure;
|
|
||||||
|
|
||||||
public class BedNotFoundException extends SleepIQException
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public BedNotFoundException(Failure failure)
|
|
||||||
{
|
|
||||||
super(failure);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Failure;
|
|
||||||
|
|
||||||
public class LoginException extends SleepIQException
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public LoginException(Failure failure)
|
|
||||||
{
|
|
||||||
super(failure);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.impl.SleepIQImpl;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.FamilyStatus;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.LoginInfo;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.PauseMode;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Sleeper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface is the main API to access the SleepIQ system.
|
|
||||||
*
|
|
||||||
* @author Gregory Moyer
|
|
||||||
*/
|
|
||||||
public interface SleepIQ {
|
|
||||||
/**
|
|
||||||
* Login to the {@link Configuration configured} account. This method is not
|
|
||||||
* required to be called before other methods because all methods must
|
|
||||||
* ensure login before acting. However, when the only desired action is to
|
|
||||||
* login and not retrieve other data, this method is the most efficient
|
|
||||||
* option.
|
|
||||||
*
|
|
||||||
* @return basic information about the logged in user
|
|
||||||
* @throws UnauthorizedException
|
|
||||||
* if the credentials provided are not valid
|
|
||||||
* @throws LoginException
|
|
||||||
* if the login request fails for any reason other than bad
|
|
||||||
* credentials (including missing credentials)
|
|
||||||
*/
|
|
||||||
public LoginInfo login() throws LoginException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of beds connected to the account.
|
|
||||||
*
|
|
||||||
* @return the list of beds
|
|
||||||
*/
|
|
||||||
public List<Bed> getBeds();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of people registered to this account for beds or bed positions
|
|
||||||
* (left or right side).
|
|
||||||
*
|
|
||||||
* @return the list of sleepers
|
|
||||||
*/
|
|
||||||
public List<Sleeper> getSleepers();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of all beds and all air chambers registered to this
|
|
||||||
* account.
|
|
||||||
*
|
|
||||||
* @return the complete status of beds on the account
|
|
||||||
*/
|
|
||||||
public FamilyStatus getFamilyStatus();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of "pause mode" (disabling SleepIQ data upload) for a
|
|
||||||
* specific bed. A bed in pause mode will send no information to the SleepIQ
|
|
||||||
* cloud services. For example, if a sleeper is in bed and disables SleepIQ
|
|
||||||
* (enables pause mode), the service will continue to report that the bed is
|
|
||||||
* occupied even after the sleeper exits the bed until pause mode is
|
|
||||||
* disabled.
|
|
||||||
*
|
|
||||||
* @param bedId
|
|
||||||
* the unique identifier of the bed to query
|
|
||||||
* @return the status of pause mode for the specified bed
|
|
||||||
* @throws BedNotFoundException
|
|
||||||
* if the bed identifier was not found on the account
|
|
||||||
*/
|
|
||||||
public PauseMode getPauseMode(String bedId) throws BedNotFoundException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a default implementation instance of this interface. Each call to
|
|
||||||
* this method will create a new object.
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* the configuration to use for the new instance
|
|
||||||
* @return a concrete implementation of this interface
|
|
||||||
*/
|
|
||||||
public static SleepIQ create(Configuration config, ClientBuilder clientBuilder) {
|
|
||||||
return new SleepIQImpl(config, clientBuilder);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Failure;
|
|
||||||
|
|
||||||
public class SleepIQException extends Exception
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private final Failure failure;
|
|
||||||
|
|
||||||
public SleepIQException(Failure failure)
|
|
||||||
{
|
|
||||||
super(failure.getError().getMessage());
|
|
||||||
this.failure = failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Failure getFailure()
|
|
||||||
{
|
|
||||||
return failure;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Failure;
|
|
||||||
|
|
||||||
public class UnauthorizedException extends LoginException
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public UnauthorizedException(Failure failure)
|
|
||||||
{
|
|
||||||
super(failure);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,355 +0,0 @@
|
||||||
/*
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the terms of either the GNU
|
|
||||||
* General Public License Version 2 only ("GPL") or the Common Development
|
|
||||||
* and Distribution License("CDDL") (collectively, the "License"). You
|
|
||||||
* may not use this file except in compliance with the License. You can
|
|
||||||
* obtain a copy of the License at
|
|
||||||
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
|
|
||||||
* or packager/legal/LICENSE.txt. See the License for the specific
|
|
||||||
* language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* When distributing the software, include this License Header Notice in each
|
|
||||||
* file and include the License file at packager/legal/LICENSE.txt.
|
|
||||||
*
|
|
||||||
* GPL Classpath Exception:
|
|
||||||
* Oracle designates this particular file as subject to the "Classpath"
|
|
||||||
* exception as provided by Oracle in the GPL Version 2 section of the License
|
|
||||||
* file that accompanied this code.
|
|
||||||
*
|
|
||||||
* Modifications:
|
|
||||||
* If applicable, add the following below the License Header, with the fields
|
|
||||||
* enclosed by brackets [] replaced by your own identifying information:
|
|
||||||
* "Portions Copyright [year] [name of copyright owner]"
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* If you wish your version of this file to be governed by only the CDDL or
|
|
||||||
* only the GPL Version 2, indicate your decision by adding "[Contributor]
|
|
||||||
* elects to include this software in this distribution under the [CDDL or GPL
|
|
||||||
* Version 2] license." If you don't indicate a single choice of license, a
|
|
||||||
* recipient has the option to distribute your version of this file under
|
|
||||||
* either the CDDL, the GPL Version 2 or to extend the choice of license to
|
|
||||||
* its licensees as provided above. However, if you add GPL Version 2 code
|
|
||||||
* and therefore, elected the GPL Version 2 license, then the option applies
|
|
||||||
* only if the new code is made subject to such option by the copyright
|
|
||||||
* holder.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.filter;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.FilterOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.annotation.Priority;
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.client.ClientRequestContext;
|
|
||||||
import javax.ws.rs.client.ClientRequestFilter;
|
|
||||||
import javax.ws.rs.client.ClientResponseContext;
|
|
||||||
import javax.ws.rs.client.ClientResponseFilter;
|
|
||||||
import javax.ws.rs.container.ContainerRequestContext;
|
|
||||||
import javax.ws.rs.container.ContainerRequestFilter;
|
|
||||||
import javax.ws.rs.container.ContainerResponseContext;
|
|
||||||
import javax.ws.rs.container.ContainerResponseFilter;
|
|
||||||
import javax.ws.rs.container.PreMatching;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
|
||||||
import javax.ws.rs.ext.WriterInterceptor;
|
|
||||||
import javax.ws.rs.ext.WriterInterceptorContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Universal logging filter.
|
|
||||||
* <p/>
|
|
||||||
* Can be used on client or server side. Has the highest priority.
|
|
||||||
*
|
|
||||||
* @author Pavel Bucek (pavel.bucek at oracle.com)
|
|
||||||
* @author Martin Matula
|
|
||||||
*/
|
|
||||||
@PreMatching
|
|
||||||
@Priority(Integer.MIN_VALUE)
|
|
||||||
public final class LoggingFilter implements ContainerRequestFilter, ClientRequestFilter, ContainerResponseFilter,
|
|
||||||
ClientResponseFilter, WriterInterceptor {
|
|
||||||
|
|
||||||
public static final Charset UTF8 = Charset.forName("UTF-8");
|
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(LoggingFilter.class.getName());
|
|
||||||
private static final String NOTIFICATION_PREFIX = "* ";
|
|
||||||
private static final String REQUEST_PREFIX = "> ";
|
|
||||||
private static final String RESPONSE_PREFIX = "< ";
|
|
||||||
private static final String ENTITY_LOGGER_PROPERTY = LoggingFilter.class.getName() + ".entityLogger";
|
|
||||||
private static final String LOGGING_ID_PROPERTY = LoggingFilter.class.getName() + ".id";
|
|
||||||
|
|
||||||
private static final Comparator<Map.Entry<String, List<String>>> COMPARATOR = new Comparator<Map.Entry<String, List<String>>>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(final Map.Entry<String, List<String>> o1, final Map.Entry<String, List<String>> o2) {
|
|
||||||
return o1.getKey().compareToIgnoreCase(o2.getKey());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final int DEFAULT_MAX_ENTITY_SIZE = 8 * 1024;
|
|
||||||
|
|
||||||
//
|
|
||||||
private final Logger logger;
|
|
||||||
private final AtomicLong _id = new AtomicLong(0);
|
|
||||||
private final boolean printEntity;
|
|
||||||
private final int maxEntitySize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a logging filter logging the request and response to a default JDK
|
|
||||||
* logger, named as the fully qualified class name of this class. Entity
|
|
||||||
* logging is turned off by default.
|
|
||||||
*/
|
|
||||||
public LoggingFilter() {
|
|
||||||
this(LOGGER, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a logging filter with custom logger and custom settings of entity
|
|
||||||
* logging.
|
|
||||||
*
|
|
||||||
* @param logger the logger to log requests and responses.
|
|
||||||
* @param printEntity if true, entity will be logged as well up to the default maxEntitySize, which is 8KB
|
|
||||||
*/
|
|
||||||
public LoggingFilter(final Logger logger, final boolean printEntity) {
|
|
||||||
this.logger = logger;
|
|
||||||
this.printEntity = printEntity;
|
|
||||||
this.maxEntitySize = DEFAULT_MAX_ENTITY_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a logging filter with custom logger and entity logging turned on, but potentially limiting the size
|
|
||||||
* of entity to be buffered and logged.
|
|
||||||
*
|
|
||||||
* @param logger the logger to log requests and responses.
|
|
||||||
* @param maxEntitySize maximum number of entity bytes to be logged (and buffered) - if the entity is larger,
|
|
||||||
* logging filter will print (and buffer in memory) only the specified number of bytes
|
|
||||||
* and print "...more..." string at the end. Negative values are interpreted as zero.
|
|
||||||
*/
|
|
||||||
public LoggingFilter(final Logger logger, final int maxEntitySize) {
|
|
||||||
this.logger = logger;
|
|
||||||
this.printEntity = true;
|
|
||||||
this.maxEntitySize = Math.max(0, maxEntitySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void log(final StringBuilder b) {
|
|
||||||
if (logger != null) {
|
|
||||||
logger.info(b.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private StringBuilder prefixId(final StringBuilder b, final long id) {
|
|
||||||
b.append(Long.toString(id)).append(" ");
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printRequestLine(final StringBuilder b, final String note, final long id, final String method,
|
|
||||||
final URI uri) {
|
|
||||||
prefixId(b, id).append(NOTIFICATION_PREFIX).append(note).append(" on thread ")
|
|
||||||
.append(Thread.currentThread().getName()).append("\n");
|
|
||||||
prefixId(b, id).append(REQUEST_PREFIX).append(method).append(" ").append(uri.toASCIIString()).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printResponseLine(final StringBuilder b, final String note, final long id, final int status) {
|
|
||||||
prefixId(b, id).append(NOTIFICATION_PREFIX).append(note).append(" on thread ")
|
|
||||||
.append(Thread.currentThread().getName()).append("\n");
|
|
||||||
prefixId(b, id).append(RESPONSE_PREFIX).append(Integer.toString(status)).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printPrefixedHeaders(final StringBuilder b, final long id, final String prefix,
|
|
||||||
final MultivaluedMap<String, String> headers) {
|
|
||||||
for (final Map.Entry<String, List<String>> headerEntry : getSortedHeaders(headers.entrySet())) {
|
|
||||||
final List<?> val = headerEntry.getValue();
|
|
||||||
final String header = headerEntry.getKey();
|
|
||||||
|
|
||||||
if (val.size() == 1) {
|
|
||||||
prefixId(b, id).append(prefix).append(header).append(": ").append(val.get(0)).append("\n");
|
|
||||||
} else {
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
boolean add = false;
|
|
||||||
for (final Object s : val) {
|
|
||||||
if (add) {
|
|
||||||
sb.append(',');
|
|
||||||
}
|
|
||||||
add = true;
|
|
||||||
sb.append(s);
|
|
||||||
}
|
|
||||||
prefixId(b, id).append(prefix).append(header).append(": ").append(sb.toString()).append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Map.Entry<String, List<String>>> getSortedHeaders(final Set<Map.Entry<String, List<String>>> headers) {
|
|
||||||
final TreeSet<Map.Entry<String, List<String>>> sortedHeaders = new TreeSet<Map.Entry<String, List<String>>>(
|
|
||||||
COMPARATOR);
|
|
||||||
sortedHeaders.addAll(headers);
|
|
||||||
return sortedHeaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
private InputStream logInboundEntity(final StringBuilder b, InputStream stream, final Charset charset)
|
|
||||||
throws IOException {
|
|
||||||
if (!stream.markSupported()) {
|
|
||||||
stream = new BufferedInputStream(stream);
|
|
||||||
}
|
|
||||||
stream.mark(maxEntitySize + 1);
|
|
||||||
final byte[] entity = new byte[maxEntitySize + 1];
|
|
||||||
final int entitySize = stream.read(entity);
|
|
||||||
b.append(new String(entity, 0, Math.min(entitySize, maxEntitySize), charset));
|
|
||||||
if (entitySize > maxEntitySize) {
|
|
||||||
b.append("...more...");
|
|
||||||
}
|
|
||||||
b.append('\n');
|
|
||||||
stream.reset();
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void filter(final ClientRequestContext context) throws IOException {
|
|
||||||
final long id = _id.incrementAndGet();
|
|
||||||
context.setProperty(LOGGING_ID_PROPERTY, id);
|
|
||||||
|
|
||||||
final StringBuilder b = new StringBuilder();
|
|
||||||
|
|
||||||
printRequestLine(b, "Sending client request", id, context.getMethod(), context.getUri());
|
|
||||||
printPrefixedHeaders(b, id, REQUEST_PREFIX, context.getStringHeaders());
|
|
||||||
|
|
||||||
if (printEntity && context.hasEntity()) {
|
|
||||||
final OutputStream stream = new LoggingStream(b, context.getEntityStream());
|
|
||||||
context.setEntityStream(stream);
|
|
||||||
context.setProperty(ENTITY_LOGGER_PROPERTY, stream);
|
|
||||||
// not calling log(b) here - it will be called by the interceptor
|
|
||||||
} else {
|
|
||||||
log(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext)
|
|
||||||
throws IOException {
|
|
||||||
final Object requestId = requestContext.getProperty(LOGGING_ID_PROPERTY);
|
|
||||||
final long id = requestId != null ? (Long) requestId : _id.incrementAndGet();
|
|
||||||
|
|
||||||
final StringBuilder b = new StringBuilder();
|
|
||||||
|
|
||||||
printResponseLine(b, "Client response received", id, responseContext.getStatus());
|
|
||||||
printPrefixedHeaders(b, id, RESPONSE_PREFIX, responseContext.getHeaders());
|
|
||||||
|
|
||||||
if (printEntity && responseContext.hasEntity()) {
|
|
||||||
responseContext.setEntityStream(
|
|
||||||
logInboundEntity(b, responseContext.getEntityStream(), getCharset(responseContext.getMediaType())));
|
|
||||||
}
|
|
||||||
|
|
||||||
log(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void filter(final ContainerRequestContext context) throws IOException {
|
|
||||||
final long id = _id.incrementAndGet();
|
|
||||||
context.setProperty(LOGGING_ID_PROPERTY, id);
|
|
||||||
|
|
||||||
final StringBuilder b = new StringBuilder();
|
|
||||||
|
|
||||||
printRequestLine(b, "Server has received a request", id, context.getMethod(),
|
|
||||||
context.getUriInfo().getRequestUri());
|
|
||||||
printPrefixedHeaders(b, id, REQUEST_PREFIX, context.getHeaders());
|
|
||||||
|
|
||||||
if (printEntity && context.hasEntity()) {
|
|
||||||
context.setEntityStream(logInboundEntity(b, context.getEntityStream(), getCharset(context.getMediaType())));
|
|
||||||
}
|
|
||||||
|
|
||||||
log(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext)
|
|
||||||
throws IOException {
|
|
||||||
final Object requestId = requestContext.getProperty(LOGGING_ID_PROPERTY);
|
|
||||||
final long id = requestId != null ? (Long) requestId : _id.incrementAndGet();
|
|
||||||
|
|
||||||
final StringBuilder b = new StringBuilder();
|
|
||||||
|
|
||||||
printResponseLine(b, "Server responded with a response", id, responseContext.getStatus());
|
|
||||||
printPrefixedHeaders(b, id, RESPONSE_PREFIX, responseContext.getStringHeaders());
|
|
||||||
|
|
||||||
if (printEntity && responseContext.hasEntity()) {
|
|
||||||
final OutputStream stream = new LoggingStream(b, responseContext.getEntityStream());
|
|
||||||
responseContext.setEntityStream(stream);
|
|
||||||
requestContext.setProperty(ENTITY_LOGGER_PROPERTY, stream);
|
|
||||||
// not calling log(b) here - it will be called by the interceptor
|
|
||||||
} else {
|
|
||||||
log(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void aroundWriteTo(final WriterInterceptorContext writerInterceptorContext)
|
|
||||||
throws IOException, WebApplicationException {
|
|
||||||
final LoggingStream stream = (LoggingStream) writerInterceptorContext.getProperty(ENTITY_LOGGER_PROPERTY);
|
|
||||||
writerInterceptorContext.proceed();
|
|
||||||
if (stream != null) {
|
|
||||||
log(stream.getStringBuilder(getCharset(writerInterceptorContext.getMediaType())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LoggingStream extends FilterOutputStream {
|
|
||||||
|
|
||||||
private final StringBuilder b;
|
|
||||||
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
LoggingStream(final StringBuilder b, final OutputStream inner) {
|
|
||||||
super(inner);
|
|
||||||
|
|
||||||
this.b = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder getStringBuilder(final Charset charset) {
|
|
||||||
// write entity to the builder
|
|
||||||
final byte[] entity = baos.toByteArray();
|
|
||||||
|
|
||||||
b.append(new String(entity, 0, Math.min(entity.length, maxEntitySize), charset));
|
|
||||||
if (entity.length > maxEntitySize) {
|
|
||||||
b.append("...more...");
|
|
||||||
}
|
|
||||||
b.append('\n');
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(final int i) throws IOException {
|
|
||||||
if (baos.size() <= maxEntitySize) {
|
|
||||||
baos.write(i);
|
|
||||||
}
|
|
||||||
out.write(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the character set from a media type.
|
|
||||||
* <p>
|
|
||||||
* The character set is obtained from the media type parameter "charset".
|
|
||||||
* If the parameter is not present the {@link #UTF8} charset is utilized.
|
|
||||||
*
|
|
||||||
* @param m the media type.
|
|
||||||
* @return the character set.
|
|
||||||
*/
|
|
||||||
public static Charset getCharset(MediaType m) {
|
|
||||||
String name = (m == null) ? null : m.getParameters().get(MediaType.CHARSET_PARAMETER);
|
|
||||||
return (name == null) ? UTF8 : Charset.forName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl;
|
|
||||||
|
|
||||||
import javax.ws.rs.client.Client;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
public abstract class AbstractClient
|
|
||||||
{
|
|
||||||
private volatile Client client;
|
|
||||||
private volatile Gson gson;
|
|
||||||
|
|
||||||
protected Client getClient()
|
|
||||||
{
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
client = createClient();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Gson getGson()
|
|
||||||
{
|
|
||||||
if (gson == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (gson == null)
|
|
||||||
{
|
|
||||||
gson = createGson();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gson;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Client createClient();
|
|
||||||
|
|
||||||
protected Gson createGson()
|
|
||||||
{
|
|
||||||
return GsonGenerator.create();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl;
|
|
||||||
|
|
||||||
public class Endpoints
|
|
||||||
{
|
|
||||||
private static final String LOGIN = "login";
|
|
||||||
private static final String BED = "bed";
|
|
||||||
private static final String SLEEPER = "sleeper";
|
|
||||||
private static final String FAMILY_STATUS = "familyStatus";
|
|
||||||
private static final String PAUSE_MODE = "pauseMode";
|
|
||||||
|
|
||||||
public static String login()
|
|
||||||
{
|
|
||||||
return LOGIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String bed()
|
|
||||||
{
|
|
||||||
return BED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sleeper()
|
|
||||||
{
|
|
||||||
return SLEEPER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String familyStatus()
|
|
||||||
{
|
|
||||||
return FAMILY_STATUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String pauseMode()
|
|
||||||
{
|
|
||||||
return PAUSE_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
private Endpoints() {}
|
|
||||||
// @formatter:on
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.impl.typeadapters.JSR310TypeAdapters;
|
|
||||||
import org.openhab.binding.sleepiq.api.impl.typeadapters.TimeSinceTypeAdapter;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.TimeSince;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
|
|
||||||
public class GsonGenerator
|
|
||||||
{
|
|
||||||
public static Gson create()
|
|
||||||
{
|
|
||||||
return create(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Gson create(boolean prettyPrint)
|
|
||||||
{
|
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
|
|
||||||
// add Java 8 Time API support
|
|
||||||
JSR310TypeAdapters.registerJSR310TypeAdapters(builder);
|
|
||||||
|
|
||||||
builder.registerTypeAdapter(TimeSince.class, new TimeSinceTypeAdapter());
|
|
||||||
|
|
||||||
if (prettyPrint)
|
|
||||||
{
|
|
||||||
builder.setPrettyPrinting();
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
private GsonGenerator() {}
|
|
||||||
// @formatter:on
|
|
||||||
}
|
|
|
@ -1,204 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.ws.rs.client.Client;
|
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
|
||||||
import javax.ws.rs.client.ClientRequestContext;
|
|
||||||
import javax.ws.rs.client.ClientRequestFilter;
|
|
||||||
import javax.ws.rs.client.Entity;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.Response.Status;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.BedNotFoundException;
|
|
||||||
import org.openhab.binding.sleepiq.api.Configuration;
|
|
||||||
import org.openhab.binding.sleepiq.api.LoginException;
|
|
||||||
import org.openhab.binding.sleepiq.api.SleepIQ;
|
|
||||||
import org.openhab.binding.sleepiq.api.UnauthorizedException;
|
|
||||||
import org.openhab.binding.sleepiq.api.filter.LoggingFilter;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.BedsResponse;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Failure;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.FamilyStatus;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.LoginInfo;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.LoginRequest;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.PauseMode;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Sleeper;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.SleepersResponse;
|
|
||||||
import org.openhab.binding.sleepiq.internal.GsonProvider;
|
|
||||||
|
|
||||||
public class SleepIQImpl extends AbstractClient implements SleepIQ {
|
|
||||||
protected static final String PARAM_KEY = "_k";
|
|
||||||
|
|
||||||
protected static final String DATA_BED_ID = "bedId";
|
|
||||||
|
|
||||||
protected final Configuration config;
|
|
||||||
|
|
||||||
private volatile LoginInfo loginInfo;
|
|
||||||
|
|
||||||
private final ClientBuilder clientBuilder;
|
|
||||||
|
|
||||||
public SleepIQImpl(Configuration config, ClientBuilder clientBuilder) {
|
|
||||||
this.config = config;
|
|
||||||
this.clientBuilder = clientBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoginInfo login() throws LoginException {
|
|
||||||
if (loginInfo == null) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (loginInfo == null) {
|
|
||||||
Response response = getClient().target(config.getBaseUri()).path(Endpoints.login())
|
|
||||||
.request(MediaType.APPLICATION_JSON_TYPE).put(Entity.json(new LoginRequest()
|
|
||||||
.withLogin(config.getUsername()).withPassword(config.getPassword())));
|
|
||||||
|
|
||||||
if (isUnauthorized(response)) {
|
|
||||||
throw new UnauthorizedException(response.readEntity(Failure.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
|
|
||||||
throw new LoginException(response.readEntity(Failure.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the received cookies to all future requests
|
|
||||||
getClient().register(new ClientRequestFilter() {
|
|
||||||
@Override
|
|
||||||
public void filter(ClientRequestContext requestContext) throws IOException {
|
|
||||||
List<Object> cookies = response.getCookies().values().stream()
|
|
||||||
.map(newCookie -> newCookie.toCookie()).collect(Collectors.toList());
|
|
||||||
requestContext.getHeaders().put("Cookie", cookies);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
loginInfo = response.readEntity(LoginInfo.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return loginInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Bed> getBeds() {
|
|
||||||
return getSessionResponse(this::getBedsResponse).readEntity(BedsResponse.class).getBeds();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Response getBedsResponse(Map<String, Object> data) throws LoginException {
|
|
||||||
LoginInfo login = login();
|
|
||||||
return getClient().target(config.getBaseUri()).path(Endpoints.bed()).queryParam(PARAM_KEY, login.getKey())
|
|
||||||
.request(MediaType.APPLICATION_JSON_TYPE).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Sleeper> getSleepers() {
|
|
||||||
return getSessionResponse(this::getSleepersResponse).readEntity(SleepersResponse.class).getSleepers();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Response getSleepersResponse(Map<String, Object> data) throws LoginException {
|
|
||||||
LoginInfo login = login();
|
|
||||||
return getClient().target(config.getBaseUri()).path(Endpoints.sleeper()).queryParam(PARAM_KEY, login.getKey())
|
|
||||||
.request(MediaType.APPLICATION_JSON_TYPE).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FamilyStatus getFamilyStatus() {
|
|
||||||
return getSessionResponse(this::getFamilyStatusResponse).readEntity(FamilyStatus.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Response getFamilyStatusResponse(Map<String, Object> data) throws LoginException {
|
|
||||||
LoginInfo login = login();
|
|
||||||
return getClient().target(config.getBaseUri()).path(Endpoints.bed()).path(Endpoints.familyStatus())
|
|
||||||
.queryParam(PARAM_KEY, login.getKey()).request(MediaType.APPLICATION_JSON_TYPE).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PauseMode getPauseMode(String bedId) throws BedNotFoundException {
|
|
||||||
Map<String, Object> data = new HashMap<>();
|
|
||||||
data.put(DATA_BED_ID, bedId);
|
|
||||||
|
|
||||||
Response response = getSessionResponse(this::getPauseModeResponse, data);
|
|
||||||
|
|
||||||
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
|
|
||||||
throw new BedNotFoundException(response.readEntity(Failure.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.readEntity(PauseMode.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Response getPauseModeResponse(Map<String, Object> data) throws LoginException {
|
|
||||||
LoginInfo login = login();
|
|
||||||
return getClient().target(config.getBaseUri()).path(Endpoints.bed()).path(data.get(DATA_BED_ID).toString())
|
|
||||||
.path(Endpoints.pauseMode()).queryParam(PARAM_KEY, login.getKey())
|
|
||||||
.request(MediaType.APPLICATION_JSON_TYPE).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isUnauthorized(Response response) {
|
|
||||||
return Status.UNAUTHORIZED.getStatusCode() == response.getStatusInfo().getStatusCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized void resetLogin() {
|
|
||||||
loginInfo = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Response getSessionResponse(Request request) {
|
|
||||||
return getSessionResponse(request, Collections.emptyMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Response getSessionResponse(Request request, Map<String, Object> data) {
|
|
||||||
try {
|
|
||||||
Response response = request.execute(data);
|
|
||||||
|
|
||||||
if (isUnauthorized(response)) {
|
|
||||||
// session timed out
|
|
||||||
response.close();
|
|
||||||
resetLogin();
|
|
||||||
response = request.execute(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
} catch (LoginException e) {
|
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Client createClient() {
|
|
||||||
// setup Gson (de)serialization
|
|
||||||
GsonProvider<Object> gsonProvider = new GsonProvider<>(getGson());
|
|
||||||
clientBuilder.register(gsonProvider);
|
|
||||||
|
|
||||||
// turn on logging if requested
|
|
||||||
if (config.isLogging()) {
|
|
||||||
clientBuilder.register(new LoggingFilter(Logger.getLogger(SleepIQImpl.class.getName()), true));
|
|
||||||
}
|
|
||||||
|
|
||||||
return clientBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public static interface Request {
|
|
||||||
public Response execute(Map<String, Object> data) throws LoginException;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract type adapter for jsr310 date-time types.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
abstract class DateTimeTypeAdapter<T> extends TemporalTypeAdapter<T> {
|
|
||||||
|
|
||||||
DateTimeTypeAdapter(Function<String, T> parseFunction) {
|
|
||||||
super(parseFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String preProcess(String in) {
|
|
||||||
if (in.endsWith("+0000")) {
|
|
||||||
return in.substring(0, in.length()-5) + "Z";
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link Duration} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class DurationTypeAdapter extends TemporalTypeAdapter<Duration> {
|
|
||||||
|
|
||||||
public DurationTypeAdapter() {
|
|
||||||
super(Duration::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link Instant} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class InstantTypeAdapter extends DateTimeTypeAdapter<Instant> {
|
|
||||||
|
|
||||||
public InstantTypeAdapter() {
|
|
||||||
super(Instant::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
|
|
||||||
import java.time.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper methods to register JSR310 type adapters.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class JSR310TypeAdapters {
|
|
||||||
|
|
||||||
private JSR310TypeAdapters() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerDurationTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(Duration.class, new DurationTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerInstantTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(Instant.class, new InstantTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerLocalDateTimeTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerLocalDateTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerLocalTimeTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(LocalTime.class, new LocalTimeTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerMonthDayTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(MonthDay.class, new MonthDayTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerOffsetDateTimeTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerOffsetTimeTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(OffsetTime.class, new OffsetTimeTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerPeriodTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(Period.class, new PeriodTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerYearMonthTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(YearMonth.class, new YearMonthTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerYearTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(Year.class, new YearTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GsonBuilder registerZonedDateTimeTypeAdapter(GsonBuilder gsonBuilder) {
|
|
||||||
return gsonBuilder.registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to register all the available JSR310 adapters at once.
|
|
||||||
* @param gsonBuilder the gsonBuilder on which all the JSR310 adapters must be registered.
|
|
||||||
* @return the gsonBuilder with the JSR310 adapters registered.
|
|
||||||
*/
|
|
||||||
public static GsonBuilder registerJSR310TypeAdapters(GsonBuilder gsonBuilder) {
|
|
||||||
registerDurationTypeAdapter(gsonBuilder);
|
|
||||||
registerInstantTypeAdapter(gsonBuilder);
|
|
||||||
registerLocalDateTimeTypeAdapter(gsonBuilder);
|
|
||||||
registerLocalDateTypeAdapter(gsonBuilder);
|
|
||||||
registerLocalTimeTypeAdapter(gsonBuilder);
|
|
||||||
registerMonthDayTypeAdapter(gsonBuilder);
|
|
||||||
registerOffsetDateTimeTypeAdapter(gsonBuilder);
|
|
||||||
registerOffsetTimeTypeAdapter(gsonBuilder);
|
|
||||||
registerPeriodTypeAdapter(gsonBuilder);
|
|
||||||
registerYearMonthTypeAdapter(gsonBuilder);
|
|
||||||
registerYearTypeAdapter(gsonBuilder);
|
|
||||||
registerZonedDateTimeTypeAdapter(gsonBuilder);
|
|
||||||
|
|
||||||
return gsonBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link LocalDateTime} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class LocalDateTimeTypeAdapter extends DateTimeTypeAdapter<LocalDateTime> {
|
|
||||||
|
|
||||||
public LocalDateTimeTypeAdapter() {
|
|
||||||
super(LocalDateTime::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link LocalDate} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class LocalDateTypeAdapter extends TemporalTypeAdapter<LocalDate> {
|
|
||||||
|
|
||||||
public LocalDateTypeAdapter() {
|
|
||||||
super(LocalDate::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.LocalTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link LocalTime} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class LocalTimeTypeAdapter extends TemporalTypeAdapter<LocalTime> {
|
|
||||||
|
|
||||||
public LocalTimeTypeAdapter() {
|
|
||||||
super(LocalTime::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.MonthDay;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link MonthDay} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class MonthDayTypeAdapter extends TemporalTypeAdapter<MonthDay> {
|
|
||||||
|
|
||||||
public MonthDayTypeAdapter() {
|
|
||||||
super(MonthDay::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.OffsetDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link OffsetDateTime} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class OffsetDateTimeTypeAdapter extends DateTimeTypeAdapter<OffsetDateTime> {
|
|
||||||
|
|
||||||
public OffsetDateTimeTypeAdapter() {
|
|
||||||
super(OffsetDateTime::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.OffsetTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link OffsetTime} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class OffsetTimeTypeAdapter extends TemporalTypeAdapter<OffsetTime> {
|
|
||||||
|
|
||||||
public OffsetTimeTypeAdapter() {
|
|
||||||
super(OffsetTime::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.Period;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link Period} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class PeriodTypeAdapter extends TemporalTypeAdapter<Period> {
|
|
||||||
|
|
||||||
public PeriodTypeAdapter() {
|
|
||||||
super(Period::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.model.TimeSince;
|
|
||||||
|
|
||||||
public class TimeSinceTypeAdapter extends TemporalTypeAdapter<TimeSince>
|
|
||||||
{
|
|
||||||
public TimeSinceTypeAdapter()
|
|
||||||
{
|
|
||||||
super(TimeSince::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.YearMonth;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link YearMonth} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class YearMonthTypeAdapter extends TemporalTypeAdapter<YearMonth> {
|
|
||||||
|
|
||||||
public YearMonthTypeAdapter() {
|
|
||||||
super(YearMonth::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.Year;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link Year} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class YearTypeAdapter extends TemporalTypeAdapter<Year> {
|
|
||||||
|
|
||||||
public YearTypeAdapter() {
|
|
||||||
super(Year::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type adapter for jsr310 {@link ZonedDateTime} class.
|
|
||||||
*
|
|
||||||
* @author Christophe Bornet
|
|
||||||
*/
|
|
||||||
public class ZonedDateTimeTypeAdapter extends DateTimeTypeAdapter<ZonedDateTime> {
|
|
||||||
|
|
||||||
public ZonedDateTimeTypeAdapter() {
|
|
||||||
super(ZonedDateTime::parse);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
public class BedStatus
|
|
||||||
{
|
|
||||||
private Long status;
|
|
||||||
private String bedId;
|
|
||||||
private BedSideStatus leftSide;
|
|
||||||
private BedSideStatus rightSide;
|
|
||||||
|
|
||||||
public Long getStatus()
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(Long status)
|
|
||||||
{
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BedStatus withStatus(Long status)
|
|
||||||
{
|
|
||||||
setStatus(status);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBedId()
|
|
||||||
{
|
|
||||||
return bedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBedId(String bedId)
|
|
||||||
{
|
|
||||||
this.bedId = bedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BedStatus withBedId(String bedId)
|
|
||||||
{
|
|
||||||
setBedId(bedId);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BedSideStatus getLeftSide()
|
|
||||||
{
|
|
||||||
return leftSide;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLeftSide(BedSideStatus leftSide)
|
|
||||||
{
|
|
||||||
this.leftSide = leftSide;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BedStatus withLeftSide(BedSideStatus leftSide)
|
|
||||||
{
|
|
||||||
setLeftSide(leftSide);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BedSideStatus getRightSide()
|
|
||||||
{
|
|
||||||
return rightSide;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRightSide(BedSideStatus rightSide)
|
|
||||||
{
|
|
||||||
this.rightSide = rightSide;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BedStatus withRightSide(BedSideStatus rightSide)
|
|
||||||
{
|
|
||||||
setRightSide(rightSide);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((bedId == null) ? 0 : bedId.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof BedStatus))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BedStatus other = (BedStatus)obj;
|
|
||||||
if (bedId == null)
|
|
||||||
{
|
|
||||||
if (other.bedId != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!bedId.equals(other.bedId))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("BedStatus [status=");
|
|
||||||
builder.append(status);
|
|
||||||
builder.append(", bedId=");
|
|
||||||
builder.append(bedId);
|
|
||||||
builder.append(", leftSide=");
|
|
||||||
builder.append(leftSide);
|
|
||||||
builder.append(", rightSide=");
|
|
||||||
builder.append(rightSide);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class BedsResponse
|
|
||||||
{
|
|
||||||
private List<Bed> beds;
|
|
||||||
|
|
||||||
public List<Bed> getBeds()
|
|
||||||
{
|
|
||||||
return beds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeds(List<Bed> beds)
|
|
||||||
{
|
|
||||||
this.beds = beds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BedsResponse withBeds(List<Bed> beds)
|
|
||||||
{
|
|
||||||
setBeds(beds);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((beds == null) ? 0 : beds.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof BedsResponse))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BedsResponse other = (BedsResponse)obj;
|
|
||||||
if (beds == null)
|
|
||||||
{
|
|
||||||
if (other.beds != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!beds.equals(other.beds))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("BedsResponse [beds=");
|
|
||||||
builder.append(beds);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
public class Error
|
|
||||||
{
|
|
||||||
@SerializedName("Code")
|
|
||||||
private Long code;
|
|
||||||
@SerializedName("Message")
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
public Long getCode()
|
|
||||||
{
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCode(Long code)
|
|
||||||
{
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Error withCode(Long code)
|
|
||||||
{
|
|
||||||
setCode(code);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage()
|
|
||||||
{
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessage(String message)
|
|
||||||
{
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Error withMessage(String message)
|
|
||||||
{
|
|
||||||
setMessage(message);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((code == null) ? 0 : code.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof Error))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Error other = (Error)obj;
|
|
||||||
if (code == null)
|
|
||||||
{
|
|
||||||
if (other.code != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!code.equals(other.code))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("Error [code=");
|
|
||||||
builder.append(code);
|
|
||||||
builder.append(", message=");
|
|
||||||
builder.append(message);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
public class Failure
|
|
||||||
{
|
|
||||||
@SerializedName("Error")
|
|
||||||
private Error error;
|
|
||||||
|
|
||||||
public Error getError()
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setError(Error error)
|
|
||||||
{
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Failure withError(Error error)
|
|
||||||
{
|
|
||||||
setError(error);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((error == null) ? 0 : error.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof Failure))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Failure other = (Failure)obj;
|
|
||||||
if (error == null)
|
|
||||||
{
|
|
||||||
if (other.error != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!error.equals(other.error))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("Failure [error=");
|
|
||||||
builder.append(error);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class FamilyStatus
|
|
||||||
{
|
|
||||||
private List<BedStatus> beds;
|
|
||||||
|
|
||||||
public List<BedStatus> getBeds()
|
|
||||||
{
|
|
||||||
return beds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeds(List<BedStatus> beds)
|
|
||||||
{
|
|
||||||
this.beds = beds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FamilyStatus withBeds(List<BedStatus> beds)
|
|
||||||
{
|
|
||||||
setBeds(beds);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((beds == null) ? 0 : beds.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof FamilyStatus))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
FamilyStatus other = (FamilyStatus)obj;
|
|
||||||
if (beds == null)
|
|
||||||
{
|
|
||||||
if (other.beds != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!beds.equals(other.beds))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("FamilyStatus [beds=");
|
|
||||||
builder.append(beds);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
public class LoginRequest
|
|
||||||
{
|
|
||||||
private String login;
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
public String getLogin()
|
|
||||||
{
|
|
||||||
return login;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLogin(String login)
|
|
||||||
{
|
|
||||||
this.login = login;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoginRequest withLogin(String login)
|
|
||||||
{
|
|
||||||
setLogin(login);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword()
|
|
||||||
{
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password)
|
|
||||||
{
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoginRequest withPassword(String password)
|
|
||||||
{
|
|
||||||
setPassword(password);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((login == null) ? 0 : login.hashCode());
|
|
||||||
result = prime * result + ((password == null) ? 0 : password.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof LoginRequest))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LoginRequest other = (LoginRequest)obj;
|
|
||||||
if (login == null)
|
|
||||||
{
|
|
||||||
if (other.login != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!login.equals(other.login))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (password == null)
|
|
||||||
{
|
|
||||||
if (other.password != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!password.equals(other.password))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("LoginRequest [login=");
|
|
||||||
builder.append(login);
|
|
||||||
builder.append(", password=");
|
|
||||||
builder.append(password);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
public class PauseMode
|
|
||||||
{
|
|
||||||
private String accountId;
|
|
||||||
private String bedId;
|
|
||||||
private String pauseMode;
|
|
||||||
|
|
||||||
public String getAccountId()
|
|
||||||
{
|
|
||||||
return accountId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccountId(String accountId)
|
|
||||||
{
|
|
||||||
this.accountId = accountId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PauseMode withAccountId(String accountId)
|
|
||||||
{
|
|
||||||
setAccountId(accountId);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBedId()
|
|
||||||
{
|
|
||||||
return bedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBedId(String bedId)
|
|
||||||
{
|
|
||||||
this.bedId = bedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PauseMode withBedId(String bedId)
|
|
||||||
{
|
|
||||||
setBedId(bedId);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPauseMode()
|
|
||||||
{
|
|
||||||
return pauseMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPauseMode(String pauseMode)
|
|
||||||
{
|
|
||||||
this.pauseMode = pauseMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PauseMode withPauseMode(String pauseMode)
|
|
||||||
{
|
|
||||||
setPauseMode(pauseMode);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((accountId == null) ? 0 : accountId.hashCode());
|
|
||||||
result = prime * result + ((bedId == null) ? 0 : bedId.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof PauseMode))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
PauseMode other = (PauseMode)obj;
|
|
||||||
if (accountId == null)
|
|
||||||
{
|
|
||||||
if (other.accountId != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!accountId.equals(other.accountId))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bedId == null)
|
|
||||||
{
|
|
||||||
if (other.bedId != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!bedId.equals(other.bedId))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("PauseMode [accountId=");
|
|
||||||
builder.append(accountId);
|
|
||||||
builder.append(", bedId=");
|
|
||||||
builder.append(bedId);
|
|
||||||
builder.append(", pauseMode=");
|
|
||||||
builder.append(pauseMode);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SleepersResponse
|
|
||||||
{
|
|
||||||
private List<Sleeper> sleepers;
|
|
||||||
|
|
||||||
public List<Sleeper> getSleepers()
|
|
||||||
{
|
|
||||||
return sleepers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSleepers(List<Sleeper> sleepers)
|
|
||||||
{
|
|
||||||
this.sleepers = sleepers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SleepersResponse withSleepers(List<Sleeper> sleepers)
|
|
||||||
{
|
|
||||||
setSleepers(sleepers);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((sleepers == null) ? 0 : sleepers.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof SleepersResponse))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SleepersResponse other = (SleepersResponse)obj;
|
|
||||||
if (sleepers == null)
|
|
||||||
{
|
|
||||||
if (other.sleepers != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!sleepers.equals(other.sleepers))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("SleepersResponse [sleepers=");
|
|
||||||
builder.append(sleepers);
|
|
||||||
builder.append("]");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
public class FamilyStatusTest extends AbstractTest {
|
|
||||||
private static Gson gson;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSerializeAllFields() throws Exception {
|
|
||||||
FamilyStatus familyStatus = new FamilyStatus().withBeds(Arrays.asList(new BedStatus().withStatus(1L)));
|
|
||||||
assertEquals(readJson("family-status.json"), gson.toJson(familyStatus));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeserializeAllFields() throws Exception {
|
|
||||||
try (FileReader reader = new FileReader(getTestDataFile("family-status.json"))) {
|
|
||||||
FamilyStatus familyStatus = gson.fromJson(reader, FamilyStatus.class);
|
|
||||||
|
|
||||||
List<BedStatus> beds = familyStatus.getBeds();
|
|
||||||
assertNotNull(beds);
|
|
||||||
assertEquals(1, beds.size());
|
|
||||||
assertEquals(Long.valueOf(1L), beds.get(0).getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 Gregory Moyer
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import java.io.FileReader;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
public class PauseModeTest extends AbstractTest {
|
|
||||||
private static Gson gson;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSerializeAllFields() throws Exception {
|
|
||||||
PauseMode pauseMode = new PauseMode().withAccountId("-8888888888888888888").withBedId("-9999999999999999999")
|
|
||||||
.withPauseMode("off");
|
|
||||||
assertEquals(readJson("pause-mode.json"), gson.toJson(pauseMode));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeserializeAllFields() throws Exception {
|
|
||||||
try (FileReader reader = new FileReader(getTestDataFile("pause-mode.json"))) {
|
|
||||||
PauseMode pauseMode = gson.fromJson(reader, PauseMode.class);
|
|
||||||
assertEquals("-8888888888888888888", pauseMode.getAccountId());
|
|
||||||
assertEquals("-9999999999999999999", pauseMode.getBedId());
|
|
||||||
assertEquals("off", pauseMode.getPauseMode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010-2023 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.sleepiq.internal;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
|
||||||
import javax.ws.rs.ext.MessageBodyReader;
|
|
||||||
import javax.ws.rs.ext.MessageBodyWriter;
|
|
||||||
import javax.ws.rs.ext.Provider;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON reader/writer for Jersey using GSON.
|
|
||||||
*
|
|
||||||
* @author Simon Kaufmann - Initial contribution
|
|
||||||
*
|
|
||||||
* @param <T>
|
|
||||||
*/
|
|
||||||
@Provider
|
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public class GsonProvider<T> implements MessageBodyReader<T>, MessageBodyWriter<T> {
|
|
||||||
|
|
||||||
private final Gson gson;
|
|
||||||
|
|
||||||
public GsonProvider(Gson gson) {
|
|
||||||
this.gson = gson;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSize(T t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(T object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
|
|
||||||
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
|
|
||||||
throws IOException, WebApplicationException {
|
|
||||||
try (OutputStream stream = entityStream) {
|
|
||||||
entityStream.write(gson.toJson(object).getBytes(StandardCharsets.UTF_8));
|
|
||||||
entityStream.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType,
|
|
||||||
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
|
|
||||||
throws IOException, WebApplicationException {
|
|
||||||
try (InputStreamReader reader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) {
|
|
||||||
return gson.fromJson(reader, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -31,34 +31,60 @@ public class SleepIQBindingConstants {
|
||||||
public static final ThingTypeUID THING_TYPE_CLOUD = new ThingTypeUID(BINDING_ID, "cloud");
|
public static final ThingTypeUID THING_TYPE_CLOUD = new ThingTypeUID(BINDING_ID, "cloud");
|
||||||
|
|
||||||
// generic thing types
|
// generic thing types
|
||||||
// public static final ThingTypeUID THING_TYPE_SINGLE_BED = new ThingTypeUID(BINDING_ID, "singleBed");
|
|
||||||
public static final ThingTypeUID THING_TYPE_DUAL_BED = new ThingTypeUID(BINDING_ID, "dualBed");
|
public static final ThingTypeUID THING_TYPE_DUAL_BED = new ThingTypeUID(BINDING_ID, "dualBed");
|
||||||
|
|
||||||
// List of all Channel ids
|
// List of all Channel ids
|
||||||
// public static final String CHANNEL_BED_IN_BED = "bed#inBed";
|
|
||||||
public static final String CHANNEL_LEFT_IN_BED = "left#inBed";
|
public static final String CHANNEL_LEFT_IN_BED = "left#inBed";
|
||||||
public static final String CHANNEL_RIGHT_IN_BED = "right#inBed";
|
public static final String CHANNEL_RIGHT_IN_BED = "right#inBed";
|
||||||
|
|
||||||
// public static final String CHANNEL_BED_SLEEP_NUMBER = "bed#sleepNumber";
|
|
||||||
public static final String CHANNEL_LEFT_SLEEP_NUMBER = "left#sleepNumber";
|
public static final String CHANNEL_LEFT_SLEEP_NUMBER = "left#sleepNumber";
|
||||||
public static final String CHANNEL_RIGHT_SLEEP_NUMBER = "right#sleepNumber";
|
public static final String CHANNEL_RIGHT_SLEEP_NUMBER = "right#sleepNumber";
|
||||||
|
|
||||||
// public static final String CHANNEL_BED_PRESSURE = "bed#pressure";
|
|
||||||
public static final String CHANNEL_LEFT_PRESSURE = "left#pressure";
|
public static final String CHANNEL_LEFT_PRESSURE = "left#pressure";
|
||||||
public static final String CHANNEL_RIGHT_PRESSURE = "right#pressure";
|
public static final String CHANNEL_RIGHT_PRESSURE = "right#pressure";
|
||||||
|
|
||||||
// public static final String CHANNEL_BED_LAST_LINK = "bed#lastLink";
|
|
||||||
public static final String CHANNEL_LEFT_LAST_LINK = "left#lastLink";
|
public static final String CHANNEL_LEFT_LAST_LINK = "left#lastLink";
|
||||||
public static final String CHANNEL_RIGHT_LAST_LINK = "right#lastLink";
|
public static final String CHANNEL_RIGHT_LAST_LINK = "right#lastLink";
|
||||||
|
|
||||||
// public static final String CHANNEL_BED_ALERT_ID = "bed#alertId";
|
|
||||||
public static final String CHANNEL_LEFT_ALERT_ID = "left#alertId";
|
public static final String CHANNEL_LEFT_ALERT_ID = "left#alertId";
|
||||||
public static final String CHANNEL_RIGHT_ALERT_ID = "right#alertId";
|
public static final String CHANNEL_RIGHT_ALERT_ID = "right#alertId";
|
||||||
|
|
||||||
// public static final String CHANNEL_BED_ALERT_DETAILED_MESSAGE = "bed#alertDetailedMessage";
|
|
||||||
public static final String CHANNEL_LEFT_ALERT_DETAILED_MESSAGE = "left#alertDetailedMessage";
|
public static final String CHANNEL_LEFT_ALERT_DETAILED_MESSAGE = "left#alertDetailedMessage";
|
||||||
public static final String CHANNEL_RIGHT_ALERT_DETAILED_MESSAGE = "right#alertDetailedMessage";
|
public static final String CHANNEL_RIGHT_ALERT_DETAILED_MESSAGE = "right#alertDetailedMessage";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_FIRST_NAME = "left#firstName";
|
||||||
|
public static final String CHANNEL_RIGHT_FIRST_NAME = "right#firstName";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_SLEEP_GOAL_MINUTES = "left#sleepGoalMinutes";
|
||||||
|
public static final String CHANNEL_RIGHT_SLEEP_GOAL_MINUTES = "right#sleepGoalMinutes";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_PRIVACY_MODE = "left#privacyMode";
|
||||||
|
public static final String CHANNEL_RIGHT_PRIVACY_MODE = "right#privacyMode";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_TODAY_SLEEP_IQ = "left#todaySleepIQ";
|
||||||
|
public static final String CHANNEL_RIGHT_TODAY_SLEEP_IQ = "right#todaySleepIQ";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_TODAY_AVG_HEART_RATE = "left#todayAverageHeartRate";
|
||||||
|
public static final String CHANNEL_RIGHT_TODAY_AVG_HEART_RATE = "right#todayAverageHeartRate";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_TODAY_AVG_RESPIRATION_RATE = "left#todayAverageRespirationRate";
|
||||||
|
public static final String CHANNEL_RIGHT_TODAY_AVG_RESPIRATION_RATE = "right#todayAverageRespirationRate";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_TODAY_MESSAGE = "left#todayMessage";
|
||||||
|
public static final String CHANNEL_RIGHT_TODAY_MESSAGE = "right#todayMessage";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_TODAY_SLEEP_DURATION_SECONDS = "left#todaySleepDurationSeconds";
|
||||||
|
public static final String CHANNEL_RIGHT_TODAY_SLEEP_DURATION_SECONDS = "right#todaySleepDurationSeconds";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_MONTHLY_SLEEP_IQ = "left#monthlySleepIQ";
|
||||||
|
public static final String CHANNEL_RIGHT_MONTHLY_SLEEP_IQ = "right#monthlySleepIQ";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_MONTHLY_AVG_HEART_RATE = "left#monthlyAverageHeartRate";
|
||||||
|
public static final String CHANNEL_RIGHT_MONTHLY_AVG_HEART_RATE = "right#monthlyAverageHeartRate";
|
||||||
|
|
||||||
|
public static final String CHANNEL_LEFT_MONTHLY_AVG_RESPIRATION_RATE = "left#monthlyAverageRespirationRate";
|
||||||
|
public static final String CHANNEL_RIGHT_MONTHLY_AVG_RESPIRATION_RATE = "right#monthlyAverageRespirationRate";
|
||||||
|
|
||||||
// List of non-standard Properties
|
// List of non-standard Properties
|
||||||
public static final String PROPERTY_BASE = "base";
|
public static final String PROPERTY_BASE = "base";
|
||||||
public static final String PROPERTY_KIDS_BED = "kidsBed";
|
public static final String PROPERTY_KIDS_BED = "kidsBed";
|
||||||
|
@ -67,8 +93,4 @@ public class SleepIQBindingConstants {
|
||||||
public static final String PROPERTY_PURCHASE_DATE = "purchaseDate";
|
public static final String PROPERTY_PURCHASE_DATE = "purchaseDate";
|
||||||
public static final String PROPERTY_SIZE = "size";
|
public static final String PROPERTY_SIZE = "size";
|
||||||
public static final String PROPERTY_SKU = "sku";
|
public static final String PROPERTY_SKU = "sku";
|
||||||
|
|
||||||
private SleepIQBindingConstants() {
|
|
||||||
// utility class
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,15 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.internal;
|
package org.openhab.binding.sleepiq.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link SleepIQConfigStatusMessage} defines the keys to be used for configuration status messages.
|
* The {@link SleepIQConfigStatusMessage} defines the keys to be used for configuration status messages.
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer - Initial contribution
|
* @author Gregory Moyer - Initial contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public interface SleepIQConfigStatusMessage {
|
public interface SleepIQConfigStatusMessage {
|
||||||
public static final String USERNAME_MISSING = "missing-username-configuration";
|
public static final String USERNAME_MISSING = "missing-username-configuration";
|
||||||
public static final String PASSWORD_MISSING = "missing-password-configuration";
|
public static final String PASSWORD_MISSING = "missing-password-configuration";
|
||||||
|
|
|
@ -20,12 +20,14 @@ import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.openhab.binding.sleepiq.internal.discovery.SleepIQBedDiscoveryService;
|
import org.openhab.binding.sleepiq.internal.discovery.SleepIQBedDiscoveryService;
|
||||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQCloudHandler;
|
import org.openhab.binding.sleepiq.internal.handler.SleepIQCloudHandler;
|
||||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQDualBedHandler;
|
import org.openhab.binding.sleepiq.internal.handler.SleepIQDualBedHandler;
|
||||||
import org.openhab.core.config.discovery.DiscoveryService;
|
import org.openhab.core.config.discovery.DiscoveryService;
|
||||||
|
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||||
import org.openhab.core.thing.Bridge;
|
import org.openhab.core.thing.Bridge;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
import org.openhab.core.thing.ThingTypeUID;
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
@ -45,6 +47,7 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer - Initial contribution
|
* @author Gregory Moyer - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.sleepiq")
|
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.sleepiq")
|
||||||
public class SleepIQHandlerFactory extends BaseThingHandlerFactory {
|
public class SleepIQHandlerFactory extends BaseThingHandlerFactory {
|
||||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections
|
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections
|
||||||
|
@ -53,13 +56,13 @@ public class SleepIQHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(SleepIQHandlerFactory.class);
|
private final Logger logger = LoggerFactory.getLogger(SleepIQHandlerFactory.class);
|
||||||
|
|
||||||
private final ClientBuilder clientBuilder;
|
private final HttpClient httpClient;
|
||||||
|
|
||||||
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceReg = new HashMap<>();
|
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceReg = new HashMap<>();
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
public SleepIQHandlerFactory(@Reference ClientBuilder clientBuilder) {
|
public SleepIQHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||||
this.clientBuilder = clientBuilder;
|
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,26 +71,23 @@ public class SleepIQHandlerFactory extends BaseThingHandlerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ThingHandler createHandler(final Thing thing) {
|
protected @Nullable ThingHandler createHandler(final Thing thing) {
|
||||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
|
|
||||||
if (SleepIQCloudHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
|
if (SleepIQCloudHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
|
||||||
logger.debug("Creating SleepIQ cloud thing handler");
|
logger.debug("Creating SleepIQ cloud thing handler");
|
||||||
SleepIQCloudHandler cloudHandler = new SleepIQCloudHandler((Bridge) thing, clientBuilder);
|
SleepIQCloudHandler cloudHandler = new SleepIQCloudHandler((Bridge) thing, httpClient);
|
||||||
registerBedDiscoveryService(cloudHandler);
|
registerBedDiscoveryService(cloudHandler);
|
||||||
return cloudHandler;
|
return cloudHandler;
|
||||||
} else if (SleepIQDualBedHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
|
} else if (SleepIQDualBedHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
|
||||||
logger.debug("Creating SleepIQ dual bed thing handler");
|
logger.debug("Creating SleepIQ dual bed thing handler");
|
||||||
return new SleepIQDualBedHandler(thing);
|
return new SleepIQDualBedHandler(thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void removeHandler(final ThingHandler thingHandler) {
|
protected void removeHandler(final ThingHandler thingHandler) {
|
||||||
logger.debug("Removing SleepIQ thing handler");
|
logger.debug("Removing SleepIQ thing handler");
|
||||||
|
|
||||||
if (thingHandler instanceof SleepIQCloudHandler) {
|
if (thingHandler instanceof SleepIQCloudHandler) {
|
||||||
unregisterBedDiscoveryService((SleepIQCloudHandler) thingHandler);
|
unregisterBedDiscoveryService((SleepIQCloudHandler) thingHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BedNotFoundException} is thrown when a bedId is missing or invalid.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class BedNotFoundException extends SleepIQException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public BedNotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link CommunicationException} is thrown when there's an error communicating with
|
||||||
|
* the sleepiq service.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class CommunicationException extends SleepIQException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public CommunicationException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,34 +1,32 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api;
|
package org.openhab.binding.sleepiq.internal.api;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents configuration parameters for using {@link SleepIQ}.
|
* This class represents configuration parameters for using {@link SleepIQ}.
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer
|
* @author Gregory Moyer - Initial contribution
|
||||||
*/
|
*/
|
||||||
public class Configuration
|
@NonNullByDefault
|
||||||
{
|
public class Configuration {
|
||||||
private String username;
|
private String username = "";
|
||||||
private String password;
|
private String password = "";
|
||||||
|
|
||||||
private URI baseUri = URI.create("https://api.sleepiq.sleepnumber.com/rest");
|
private URI baseUri = URI.create("https://api.sleepiq.sleepnumber.com");
|
||||||
|
|
||||||
private boolean logging = false;
|
private boolean logging = false;
|
||||||
|
|
||||||
|
@ -37,8 +35,7 @@ public class Configuration
|
||||||
*
|
*
|
||||||
* @return the username
|
* @return the username
|
||||||
*/
|
*/
|
||||||
public String getUsername()
|
public String getUsername() {
|
||||||
{
|
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +46,7 @@ public class Configuration
|
||||||
* @param username
|
* @param username
|
||||||
* the value to set
|
* the value to set
|
||||||
*/
|
*/
|
||||||
public void setUsername(String username)
|
public void setUsername(String username) {
|
||||||
{
|
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +58,7 @@ public class Configuration
|
||||||
* the value to set
|
* the value to set
|
||||||
* @return this configuration instance
|
* @return this configuration instance
|
||||||
*/
|
*/
|
||||||
public Configuration withUsername(String username)
|
public Configuration withUsername(String username) {
|
||||||
{
|
|
||||||
setUsername(username);
|
setUsername(username);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -73,8 +68,7 @@ public class Configuration
|
||||||
*
|
*
|
||||||
* @return the password
|
* @return the password
|
||||||
*/
|
*/
|
||||||
public String getPassword()
|
public String getPassword() {
|
||||||
{
|
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +79,7 @@ public class Configuration
|
||||||
* @param password
|
* @param password
|
||||||
* the value to set
|
* the value to set
|
||||||
*/
|
*/
|
||||||
public void setPassword(String password)
|
public void setPassword(String password) {
|
||||||
{
|
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,8 +91,7 @@ public class Configuration
|
||||||
* the value to set
|
* the value to set
|
||||||
* @return this configuration instance
|
* @return this configuration instance
|
||||||
*/
|
*/
|
||||||
public Configuration withPassword(String password)
|
public Configuration withPassword(String password) {
|
||||||
{
|
|
||||||
setPassword(password);
|
setPassword(password);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -109,8 +101,7 @@ public class Configuration
|
||||||
*
|
*
|
||||||
* @return the base URI
|
* @return the base URI
|
||||||
*/
|
*/
|
||||||
public URI getBaseUri()
|
public URI getBaseUri() {
|
||||||
{
|
|
||||||
return baseUri;
|
return baseUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,8 +112,7 @@ public class Configuration
|
||||||
* @param baseUri
|
* @param baseUri
|
||||||
* the value to set
|
* the value to set
|
||||||
*/
|
*/
|
||||||
public void setBaseUri(URI baseUri)
|
public void setBaseUri(URI baseUri) {
|
||||||
{
|
|
||||||
this.baseUri = baseUri;
|
this.baseUri = baseUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,8 +124,7 @@ public class Configuration
|
||||||
* the value to set
|
* the value to set
|
||||||
* @return this configuration instance
|
* @return this configuration instance
|
||||||
*/
|
*/
|
||||||
public Configuration withBaseUri(URI baseUri)
|
public Configuration withBaseUri(URI baseUri) {
|
||||||
{
|
|
||||||
setBaseUri(baseUri);
|
setBaseUri(baseUri);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -145,8 +134,7 @@ public class Configuration
|
||||||
*
|
*
|
||||||
* @return the logging flag
|
* @return the logging flag
|
||||||
*/
|
*/
|
||||||
public boolean isLogging()
|
public boolean isLogging() {
|
||||||
{
|
|
||||||
return logging;
|
return logging;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +146,7 @@ public class Configuration
|
||||||
* @param logging
|
* @param logging
|
||||||
* the value to set
|
* the value to set
|
||||||
*/
|
*/
|
||||||
public void setLogging(boolean logging)
|
public void setLogging(boolean logging) {
|
||||||
{
|
|
||||||
this.logging = logging;
|
this.logging = logging;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,8 +159,7 @@ public class Configuration
|
||||||
* the value to set
|
* the value to set
|
||||||
* @return this configuration instance
|
* @return this configuration instance
|
||||||
*/
|
*/
|
||||||
public Configuration withLogging(boolean logging)
|
public Configuration withLogging(boolean logging) {
|
||||||
{
|
|
||||||
setLogging(logging);
|
setLogging(logging);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link LoginException} is thrown when there's a failure to log
|
||||||
|
* into the sleepiq service.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class LoginException extends SleepIQException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public LoginException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link LoginException} is thrown when a badly formatted response is
|
||||||
|
* received from the sleepiq service.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class ResponseFormatException extends SleepIQException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public ResponseFormatException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Bed;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.FamilyStatusResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.LoginInfo;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.PauseModeResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepDataResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Sleeper;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.SleepDataInterval;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.SleepIQImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface is the main API to access the SleepIQ system.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public interface SleepIQ {
|
||||||
|
/**
|
||||||
|
* Login to the {@link Configuration configured} account. This method is not
|
||||||
|
* required to be called before other methods because all methods must
|
||||||
|
* ensure login before acting. However, when the only desired action is to
|
||||||
|
* login and not retrieve other data, this method is the most efficient
|
||||||
|
* option.
|
||||||
|
*
|
||||||
|
* @return basic information about the logged in user
|
||||||
|
* @throws UnauthorizedException
|
||||||
|
* if the credentials provided are not valid
|
||||||
|
* @throws LoginException
|
||||||
|
* if the login request fails for any reason other than bad
|
||||||
|
* credentials (including missing credentials)
|
||||||
|
*/
|
||||||
|
public @Nullable LoginInfo login() throws LoginException, UnauthorizedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of beds connected to the account.
|
||||||
|
*
|
||||||
|
* @return the list of beds
|
||||||
|
* @throws LoginException
|
||||||
|
* if the login request fails for any reason other than bad
|
||||||
|
* credentials (including missing credentials)
|
||||||
|
* @throws SleepIQException
|
||||||
|
*/
|
||||||
|
public List<Bed> getBeds() throws LoginException, SleepIQException, BedNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of sleepers registered to this account for beds or bed positions
|
||||||
|
* (left or right side).
|
||||||
|
*
|
||||||
|
* @return the list of sleepers
|
||||||
|
* @throws LoginException
|
||||||
|
* @throws SleepIQException
|
||||||
|
*/
|
||||||
|
public List<Sleeper> getSleepers() throws LoginException, SleepIQException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status of all beds and all air chambers registered to this
|
||||||
|
* account.
|
||||||
|
*
|
||||||
|
* @return the complete status of beds on the account
|
||||||
|
* @throws LoginException
|
||||||
|
* @throws SleepIQException
|
||||||
|
*/
|
||||||
|
public FamilyStatusResponse getFamilyStatus() throws LoginException, SleepIQException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Sleep Data for a sleeper registered to this account.
|
||||||
|
*
|
||||||
|
* @param sleeperId the sleeper Id to query
|
||||||
|
* @param interval The time period for which data is to be queried
|
||||||
|
* @return the Sleep Data
|
||||||
|
* @throws BedNotFoundException
|
||||||
|
* if the bed identifier was not found on the account
|
||||||
|
* @throws LoginException
|
||||||
|
* @throws SleepIQException
|
||||||
|
*/
|
||||||
|
public SleepDataResponse getSleepData(String sleeperId, SleepDataInterval interval)
|
||||||
|
throws BedNotFoundException, LoginException, SleepIQException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status of "pause mode" (disabling SleepIQ data upload) for a
|
||||||
|
* specific bed. A bed in pause mode will send no information to the SleepIQ
|
||||||
|
* cloud services. For example, if a sleeper is in bed and disables SleepIQ
|
||||||
|
* (enables pause mode), the service will continue to report that the bed is
|
||||||
|
* occupied even after the sleeper exits the bed until pause mode is
|
||||||
|
* disabled.
|
||||||
|
*
|
||||||
|
* @return the status of pause mode for the specified bed
|
||||||
|
* @throws BedNotFoundException
|
||||||
|
* if the bed identifier was not found on the account
|
||||||
|
* @throws LoginException
|
||||||
|
* @throws SleepIQException
|
||||||
|
*/
|
||||||
|
public PauseModeResponse getPauseMode(String bedId) throws BedNotFoundException, LoginException, SleepIQException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sleep number for a chamber of a bed
|
||||||
|
*
|
||||||
|
* @param bedId the unique identifier of the bed
|
||||||
|
* @param side thethe chamber of the bed
|
||||||
|
* @param sleepNumber the new sleep number
|
||||||
|
*
|
||||||
|
* @throws LoginException
|
||||||
|
* @throws SleepIQException
|
||||||
|
*/
|
||||||
|
public void setSleepNumber(String bedId, Side side, int sleepNumber) throws LoginException, SleepIQException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the pause (privacy) mode for a bed
|
||||||
|
*
|
||||||
|
* @param bedId the unique identifier of the bed
|
||||||
|
*
|
||||||
|
* @throws LoginException
|
||||||
|
* @throws SleepIQException
|
||||||
|
*/
|
||||||
|
public void setPauseMode(String bedId, boolean command) throws LoginException, SleepIQException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a default implementation instance of this interface. Each call to
|
||||||
|
* this method will create a new object.
|
||||||
|
*
|
||||||
|
* @param config the configuration to use for the new instance
|
||||||
|
* @param httpClient handle to the Jetty http client
|
||||||
|
* @return a concrete implementation of this interface
|
||||||
|
*/
|
||||||
|
public static SleepIQ create(Configuration config, HttpClient httpClient) {
|
||||||
|
return new SleepIQImpl(config, httpClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close down the cloud service
|
||||||
|
*/
|
||||||
|
public void shutdown();
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepIQException} is the base exception class from which other
|
||||||
|
* sleepiq exceptions are derived.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class SleepIQException extends Exception {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public SleepIQException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link UnauthorizedException} is thrown when a login to the sleepiq service
|
||||||
|
* is unauthorized to use the API.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class UnauthorizedException extends LoginException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public UnauthorizedException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +1,27 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class Bed
|
/**
|
||||||
{
|
* The {@link Bed} holds the bed response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Bed {
|
||||||
private ZonedDateTime registrationDate;
|
private ZonedDateTime registrationDate;
|
||||||
private String sleeperRightId;
|
private String sleeperRightId;
|
||||||
private String base;
|
private String base;
|
||||||
|
@ -45,345 +46,281 @@ public class Bed
|
||||||
private String zipCode;
|
private String zipCode;
|
||||||
private String reference;
|
private String reference;
|
||||||
|
|
||||||
public ZonedDateTime getRegistrationDate()
|
public ZonedDateTime getRegistrationDate() {
|
||||||
{
|
|
||||||
return registrationDate;
|
return registrationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegistrationDate(ZonedDateTime registrationDate)
|
public void setRegistrationDate(ZonedDateTime registrationDate) {
|
||||||
{
|
|
||||||
this.registrationDate = registrationDate;
|
this.registrationDate = registrationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withRegistrationDate(ZonedDateTime registrationDate)
|
public Bed withRegistrationDate(ZonedDateTime registrationDate) {
|
||||||
{
|
|
||||||
setRegistrationDate(registrationDate);
|
setRegistrationDate(registrationDate);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSleeperRightId()
|
public String getSleeperRightId() {
|
||||||
{
|
|
||||||
return sleeperRightId;
|
return sleeperRightId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSleeperRightId(String sleeperRightId)
|
public void setSleeperRightId(String sleeperRightId) {
|
||||||
{
|
|
||||||
this.sleeperRightId = sleeperRightId;
|
this.sleeperRightId = sleeperRightId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withSleeperRightId(String sleeperRightId)
|
public Bed withSleeperRightId(String sleeperRightId) {
|
||||||
{
|
|
||||||
setSleeperRightId(sleeperRightId);
|
setSleeperRightId(sleeperRightId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBase()
|
public String getBase() {
|
||||||
{
|
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBase(String base)
|
public void setBase(String base) {
|
||||||
{
|
|
||||||
this.base = base;
|
this.base = base;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withBase(String base)
|
public Bed withBase(String base) {
|
||||||
{
|
|
||||||
setBase(base);
|
setBase(base);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getReturnRequestStatus()
|
public Long getReturnRequestStatus() {
|
||||||
{
|
|
||||||
return returnRequestStatus;
|
return returnRequestStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReturnRequestStatus(Long returnRequestStatus)
|
public void setReturnRequestStatus(Long returnRequestStatus) {
|
||||||
{
|
|
||||||
this.returnRequestStatus = returnRequestStatus;
|
this.returnRequestStatus = returnRequestStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withReturnRequestStatus(Long returnRequestStatus)
|
public Bed withReturnRequestStatus(Long returnRequestStatus) {
|
||||||
{
|
|
||||||
setReturnRequestStatus(returnRequestStatus);
|
setReturnRequestStatus(returnRequestStatus);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSize()
|
public String getSize() {
|
||||||
{
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSize(String size)
|
public void setSize(String size) {
|
||||||
{
|
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withSize(String size)
|
public Bed withSize(String size) {
|
||||||
{
|
|
||||||
setSize(size);
|
setSize(size);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName()
|
public String getName() {
|
||||||
{
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name)
|
public void setName(String name) {
|
||||||
{
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withName(String name)
|
public Bed withName(String name) {
|
||||||
{
|
|
||||||
setName(name);
|
setName(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSerial()
|
public String getSerial() {
|
||||||
{
|
|
||||||
return serial;
|
return serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSerial(String serial)
|
public void setSerial(String serial) {
|
||||||
{
|
|
||||||
this.serial = serial;
|
this.serial = serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withSerial(String serial)
|
public Bed withSerial(String serial) {
|
||||||
{
|
|
||||||
setSerial(serial);
|
setSerial(serial);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isKidsBed()
|
public Boolean isKidsBed() {
|
||||||
{
|
|
||||||
return kidsBed;
|
return kidsBed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKidsBed(Boolean kidsBed)
|
public void setKidsBed(Boolean kidsBed) {
|
||||||
{
|
|
||||||
this.kidsBed = kidsBed;
|
this.kidsBed = kidsBed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withKidsBed(Boolean kidsBed)
|
public Bed withKidsBed(Boolean kidsBed) {
|
||||||
{
|
|
||||||
setKidsBed(kidsBed);
|
setKidsBed(kidsBed);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isDualSleep()
|
public Boolean isDualSleep() {
|
||||||
{
|
|
||||||
return dualSleep;
|
return dualSleep;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDualSleep(Boolean dualSleep)
|
public void setDualSleep(Boolean dualSleep) {
|
||||||
{
|
|
||||||
this.dualSleep = dualSleep;
|
this.dualSleep = dualSleep;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withDualSleep(Boolean dualSleep)
|
public Bed withDualSleep(Boolean dualSleep) {
|
||||||
{
|
|
||||||
setDualSleep(dualSleep);
|
setDualSleep(dualSleep);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBedId()
|
public String getBedId() {
|
||||||
{
|
|
||||||
return bedId;
|
return bedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBedId(String bedId)
|
public void setBedId(String bedId) {
|
||||||
{
|
|
||||||
this.bedId = bedId;
|
this.bedId = bedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withBedId(String bedId)
|
public Bed withBedId(String bedId) {
|
||||||
{
|
|
||||||
setBedId(bedId);
|
setBedId(bedId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getStatus()
|
public Long getStatus() {
|
||||||
{
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatus(Long status)
|
public void setStatus(Long status) {
|
||||||
{
|
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withStatus(Long status)
|
public Bed withStatus(Long status) {
|
||||||
{
|
|
||||||
setStatus(status);
|
setStatus(status);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSleeperLeftId()
|
public String getSleeperLeftId() {
|
||||||
{
|
|
||||||
return sleeperLeftId;
|
return sleeperLeftId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSleeperLeftId(String sleeperLeftId)
|
public void setSleeperLeftId(String sleeperLeftId) {
|
||||||
{
|
|
||||||
this.sleeperLeftId = sleeperLeftId;
|
this.sleeperLeftId = sleeperLeftId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withSleeperLeftId(String sleeperLeftId)
|
public Bed withSleeperLeftId(String sleeperLeftId) {
|
||||||
{
|
|
||||||
setSleeperLeftId(sleeperLeftId);
|
setSleeperLeftId(sleeperLeftId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVersion()
|
public String getVersion() {
|
||||||
{
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVersion(String version)
|
public void setVersion(String version) {
|
||||||
{
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withVersion(String version)
|
public Bed withVersion(String version) {
|
||||||
{
|
|
||||||
setVersion(version);
|
setVersion(version);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAccountId()
|
public String getAccountId() {
|
||||||
{
|
|
||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccountId(String accountId)
|
public void setAccountId(String accountId) {
|
||||||
{
|
|
||||||
this.accountId = accountId;
|
this.accountId = accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withAccountId(String accountId)
|
public Bed withAccountId(String accountId) {
|
||||||
{
|
|
||||||
setAccountId(accountId);
|
setAccountId(accountId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTimezone()
|
public String getTimezone() {
|
||||||
{
|
|
||||||
return timezone;
|
return timezone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimezone(String timezone)
|
public void setTimezone(String timezone) {
|
||||||
{
|
|
||||||
this.timezone = timezone;
|
this.timezone = timezone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withTimezone(String timezone)
|
public Bed withTimezone(String timezone) {
|
||||||
{
|
|
||||||
setTimezone(timezone);
|
setTimezone(timezone);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getModel()
|
public String getModel() {
|
||||||
{
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModel(String model)
|
public void setModel(String model) {
|
||||||
{
|
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withModel(String model)
|
public Bed withModel(String model) {
|
||||||
{
|
|
||||||
setModel(model);
|
setModel(model);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZonedDateTime getPurchaseDate()
|
public ZonedDateTime getPurchaseDate() {
|
||||||
{
|
|
||||||
return purchaseDate;
|
return purchaseDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPurchaseDate(ZonedDateTime purchaseDate)
|
public void setPurchaseDate(ZonedDateTime purchaseDate) {
|
||||||
{
|
|
||||||
this.purchaseDate = purchaseDate;
|
this.purchaseDate = purchaseDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withPurchaseDate(ZonedDateTime purchaseDate)
|
public Bed withPurchaseDate(ZonedDateTime purchaseDate) {
|
||||||
{
|
|
||||||
setPurchaseDate(purchaseDate);
|
setPurchaseDate(purchaseDate);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMacAddress()
|
public String getMacAddress() {
|
||||||
{
|
|
||||||
return macAddress;
|
return macAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMacAddress(String macAddress)
|
public void setMacAddress(String macAddress) {
|
||||||
{
|
|
||||||
this.macAddress = macAddress;
|
this.macAddress = macAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withMacAddress(String macAddress)
|
public Bed withMacAddress(String macAddress) {
|
||||||
{
|
|
||||||
setMacAddress(macAddress);
|
setMacAddress(macAddress);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSku()
|
public String getSku() {
|
||||||
{
|
|
||||||
return sku;
|
return sku;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSku(String sku)
|
public void setSku(String sku) {
|
||||||
{
|
|
||||||
this.sku = sku;
|
this.sku = sku;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withSku(String sku)
|
public Bed withSku(String sku) {
|
||||||
{
|
|
||||||
setSku(sku);
|
setSku(sku);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getZipCode()
|
public String getZipCode() {
|
||||||
{
|
|
||||||
return zipCode;
|
return zipCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setZipCode(String zipCode)
|
public void setZipCode(String zipCode) {
|
||||||
{
|
|
||||||
this.zipCode = zipCode;
|
this.zipCode = zipCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withZipCode(String zipCode)
|
public Bed withZipCode(String zipCode) {
|
||||||
{
|
|
||||||
setZipCode(zipCode);
|
setZipCode(zipCode);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getReference()
|
public String getReference() {
|
||||||
{
|
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReference(String reference)
|
public void setReference(String reference) {
|
||||||
{
|
|
||||||
this.reference = reference;
|
this.reference = reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bed withReference(String reference)
|
public Bed withReference(String reference) {
|
||||||
{
|
|
||||||
setReference(reference);
|
setReference(reference);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + ((bedId == null) ? 0 : bedId.hashCode());
|
result = prime * result + ((bedId == null) ? 0 : bedId.hashCode());
|
||||||
|
@ -391,38 +328,29 @@ public class Bed
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj) {
|
||||||
{
|
if (this == obj) {
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof Bed))
|
if (!(obj instanceof Bed)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Bed other = (Bed) obj;
|
Bed other = (Bed) obj;
|
||||||
if (bedId == null)
|
if (bedId == null) {
|
||||||
{
|
if (other.bedId != null) {
|
||||||
if (other.bedId != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!bedId.equals(other.bedId)) {
|
||||||
else if (!bedId.equals(other.bedId))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("Bed [registrationDate=");
|
builder.append("Bed [registrationDate=");
|
||||||
builder.append(registrationDate);
|
builder.append(registrationDate);
|
|
@ -1,24 +1,25 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class BedSideStatus
|
/**
|
||||||
{
|
* The {@link BedSideStatus} holds the BedSideStatus response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class BedSideStatus {
|
||||||
@SerializedName("isInBed")
|
@SerializedName("isInBed")
|
||||||
private Boolean inBed;
|
private Boolean inBed;
|
||||||
private String alertDetailedMessage;
|
private String alertDetailedMessage;
|
||||||
|
@ -27,109 +28,89 @@ public class BedSideStatus
|
||||||
private TimeSince lastLink;
|
private TimeSince lastLink;
|
||||||
private Integer pressure; // appears to be in kPa
|
private Integer pressure; // appears to be in kPa
|
||||||
|
|
||||||
public Boolean isInBed()
|
public Boolean isInBed() {
|
||||||
{
|
|
||||||
return inBed;
|
return inBed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInBed(Boolean inBed)
|
public void setInBed(Boolean inBed) {
|
||||||
{
|
|
||||||
this.inBed = inBed;
|
this.inBed = inBed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BedSideStatus withInBed(Boolean inBed)
|
public BedSideStatus withInBed(Boolean inBed) {
|
||||||
{
|
|
||||||
setInBed(inBed);
|
setInBed(inBed);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAlertDetailedMessage()
|
public String getAlertDetailedMessage() {
|
||||||
{
|
|
||||||
return alertDetailedMessage;
|
return alertDetailedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAlertDetailedMessage(String alertDetailedMessage)
|
public void setAlertDetailedMessage(String alertDetailedMessage) {
|
||||||
{
|
|
||||||
this.alertDetailedMessage = alertDetailedMessage;
|
this.alertDetailedMessage = alertDetailedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BedSideStatus withAlertDetailedMessage(String alertDetailedMessage)
|
public BedSideStatus withAlertDetailedMessage(String alertDetailedMessage) {
|
||||||
{
|
|
||||||
setAlertDetailedMessage(alertDetailedMessage);
|
setAlertDetailedMessage(alertDetailedMessage);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getSleepNumber()
|
public Integer getSleepNumber() {
|
||||||
{
|
|
||||||
return sleepNumber;
|
return sleepNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSleepNumber(Integer sleepNumber)
|
public void setSleepNumber(Integer sleepNumber) {
|
||||||
{
|
|
||||||
this.sleepNumber = sleepNumber;
|
this.sleepNumber = sleepNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BedSideStatus withSleepNumber(Integer sleepNumber)
|
public BedSideStatus withSleepNumber(Integer sleepNumber) {
|
||||||
{
|
|
||||||
setSleepNumber(sleepNumber);
|
setSleepNumber(sleepNumber);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getAlertId()
|
public Long getAlertId() {
|
||||||
{
|
|
||||||
return alertId;
|
return alertId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAlertId(Long alertId)
|
public void setAlertId(Long alertId) {
|
||||||
{
|
|
||||||
this.alertId = alertId;
|
this.alertId = alertId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BedSideStatus withAlertId(Long alertId)
|
public BedSideStatus withAlertId(Long alertId) {
|
||||||
{
|
|
||||||
setAlertId(alertId);
|
setAlertId(alertId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeSince getLastLink()
|
public TimeSince getLastLink() {
|
||||||
{
|
|
||||||
return lastLink;
|
return lastLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastLink(TimeSince lastLink)
|
public void setLastLink(TimeSince lastLink) {
|
||||||
{
|
|
||||||
this.lastLink = lastLink;
|
this.lastLink = lastLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BedSideStatus withLastLink(TimeSince lastLink)
|
public BedSideStatus withLastLink(TimeSince lastLink) {
|
||||||
{
|
|
||||||
setLastLink(lastLink);
|
setLastLink(lastLink);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getPressure()
|
public Integer getPressure() {
|
||||||
{
|
|
||||||
return pressure;
|
return pressure;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPressure(Integer pressure)
|
public void setPressure(Integer pressure) {
|
||||||
{
|
|
||||||
this.pressure = pressure;
|
this.pressure = pressure;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BedSideStatus withPressure(Integer pressure)
|
public BedSideStatus withPressure(Integer pressure) {
|
||||||
{
|
|
||||||
setPressure(pressure);
|
setPressure(pressure);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result
|
result = prime * result + ((alertDetailedMessage == null) ? 0 : alertDetailedMessage.hashCode());
|
||||||
+ ((alertDetailedMessage == null) ? 0 : alertDetailedMessage.hashCode());
|
|
||||||
result = prime * result + ((alertId == null) ? 0 : alertId.hashCode());
|
result = prime * result + ((alertId == null) ? 0 : alertId.hashCode());
|
||||||
result = prime * result + ((inBed == null) ? 0 : inBed.hashCode());
|
result = prime * result + ((inBed == null) ? 0 : inBed.hashCode());
|
||||||
result = prime * result + ((lastLink == null) ? 0 : lastLink.hashCode());
|
result = prime * result + ((lastLink == null) ? 0 : lastLink.hashCode());
|
||||||
|
@ -139,93 +120,64 @@ public class BedSideStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj) {
|
||||||
{
|
if (this == obj) {
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof BedSideStatus))
|
if (!(obj instanceof BedSideStatus)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BedSideStatus other = (BedSideStatus) obj;
|
BedSideStatus other = (BedSideStatus) obj;
|
||||||
if (alertDetailedMessage == null)
|
if (alertDetailedMessage == null) {
|
||||||
{
|
if (other.alertDetailedMessage != null) {
|
||||||
if (other.alertDetailedMessage != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!alertDetailedMessage.equals(other.alertDetailedMessage)) {
|
||||||
else if (!alertDetailedMessage.equals(other.alertDetailedMessage))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (alertId == null)
|
if (alertId == null) {
|
||||||
{
|
if (other.alertId != null) {
|
||||||
if (other.alertId != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!alertId.equals(other.alertId)) {
|
||||||
else if (!alertId.equals(other.alertId))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (inBed == null)
|
if (inBed == null) {
|
||||||
{
|
if (other.inBed != null) {
|
||||||
if (other.inBed != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!inBed.equals(other.inBed)) {
|
||||||
else if (!inBed.equals(other.inBed))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (lastLink == null)
|
if (lastLink == null) {
|
||||||
{
|
if (other.lastLink != null) {
|
||||||
if (other.lastLink != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!lastLink.equals(other.lastLink)) {
|
||||||
else if (!lastLink.equals(other.lastLink))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pressure == null)
|
if (pressure == null) {
|
||||||
{
|
if (other.pressure != null) {
|
||||||
if (other.pressure != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!pressure.equals(other.pressure)) {
|
||||||
else if (!pressure.equals(other.pressure))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (sleepNumber == null)
|
if (sleepNumber == null) {
|
||||||
{
|
if (other.sleepNumber != null) {
|
||||||
if (other.sleepNumber != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!sleepNumber.equals(other.sleepNumber)) {
|
||||||
else if (!sleepNumber.equals(other.sleepNumber))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("BedSideStatus [inBed=");
|
builder.append("BedSideStatus [inBed=");
|
||||||
builder.append(inBed);
|
builder.append(inBed);
|
|
@ -0,0 +1,122 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BedStatus} holds the BedStatus response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class BedStatus {
|
||||||
|
private Long status;
|
||||||
|
private String bedId;
|
||||||
|
private BedSideStatus leftSide;
|
||||||
|
private BedSideStatus rightSide;
|
||||||
|
|
||||||
|
public Long getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Long status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BedStatus withStatus(Long status) {
|
||||||
|
setStatus(status);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBedId() {
|
||||||
|
return bedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBedId(String bedId) {
|
||||||
|
this.bedId = bedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BedStatus withBedId(String bedId) {
|
||||||
|
setBedId(bedId);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BedSideStatus getLeftSide() {
|
||||||
|
return leftSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftSide(BedSideStatus leftSide) {
|
||||||
|
this.leftSide = leftSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BedStatus withLeftSide(BedSideStatus leftSide) {
|
||||||
|
setLeftSide(leftSide);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BedSideStatus getRightSide() {
|
||||||
|
return rightSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightSide(BedSideStatus rightSide) {
|
||||||
|
this.rightSide = rightSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BedStatus withRightSide(BedSideStatus rightSide) {
|
||||||
|
setRightSide(rightSide);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((bedId == null) ? 0 : bedId.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof BedStatus)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BedStatus other = (BedStatus) obj;
|
||||||
|
if (bedId == null) {
|
||||||
|
if (other.bedId != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!bedId.equals(other.bedId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("BedStatus [status=");
|
||||||
|
builder.append(status);
|
||||||
|
builder.append(", bedId=");
|
||||||
|
builder.append(bedId);
|
||||||
|
builder.append(", leftSide=");
|
||||||
|
builder.append(leftSide);
|
||||||
|
builder.append(", rightSide=");
|
||||||
|
builder.append(rightSide);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BedsResponse} holds the BedsResponse response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class BedsResponse {
|
||||||
|
private List<Bed> beds;
|
||||||
|
|
||||||
|
public List<Bed> getBeds() {
|
||||||
|
return beds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBeds(List<Bed> beds) {
|
||||||
|
this.beds = beds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BedsResponse withBeds(List<Bed> beds) {
|
||||||
|
setBeds(beds);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((beds == null) ? 0 : beds.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof BedsResponse)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BedsResponse other = (BedsResponse) obj;
|
||||||
|
if (beds == null) {
|
||||||
|
if (other.beds != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!beds.equals(other.beds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("BedsResponse [beds=");
|
||||||
|
builder.append(beds);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Error} holds the Error response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Error {
|
||||||
|
@SerializedName("Code")
|
||||||
|
private Long code;
|
||||||
|
@SerializedName("Message")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public Long getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Long code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Error withCode(Long code) {
|
||||||
|
setCode(code);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Error withMessage(String message) {
|
||||||
|
setMessage(message);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((code == null) ? 0 : code.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof Error)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Error other = (Error) obj;
|
||||||
|
if (code == null) {
|
||||||
|
if (other.code != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!code.equals(other.code)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Error [code=");
|
||||||
|
builder.append(code);
|
||||||
|
builder.append(", message=");
|
||||||
|
builder.append(message);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Failure} holds the Failure response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Failure {
|
||||||
|
@SerializedName("Error")
|
||||||
|
private Error error;
|
||||||
|
|
||||||
|
public Error getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(Error error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Failure withError(Error error) {
|
||||||
|
setError(error);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((error == null) ? 0 : error.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof Failure)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Failure other = (Failure) obj;
|
||||||
|
if (error == null) {
|
||||||
|
if (other.error != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!error.equals(other.error)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Failure [error=");
|
||||||
|
builder.append(error);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FamilyStatusResponse} holds the FamilyStatusResponse response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class FamilyStatusResponse {
|
||||||
|
private List<BedStatus> beds;
|
||||||
|
|
||||||
|
public List<BedStatus> getBeds() {
|
||||||
|
return beds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBeds(List<BedStatus> beds) {
|
||||||
|
this.beds = beds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FamilyStatusResponse withBeds(List<BedStatus> beds) {
|
||||||
|
setBeds(beds);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((beds == null) ? 0 : beds.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof FamilyStatusResponse)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FamilyStatusResponse other = (FamilyStatusResponse) obj;
|
||||||
|
if (beds == null) {
|
||||||
|
if (other.beds != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!beds.equals(other.beds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("FamilyStatus [beds=");
|
||||||
|
builder.append(beds);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,111 +1,96 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
public class LoginInfo
|
/**
|
||||||
{
|
* The {@link LoginInfo} holds the LoginInfo response from the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class LoginInfo {
|
||||||
private String userId;
|
private String userId;
|
||||||
private String key;
|
private String key;
|
||||||
private Long registrationState;
|
private Long registrationState;
|
||||||
private Long edpLoginStatus;
|
private Long edpLoginStatus;
|
||||||
private String edpLoginMessage;
|
private String edpLoginMessage;
|
||||||
|
|
||||||
public String getUserId()
|
public String getUserId() {
|
||||||
{
|
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserId(String userId)
|
public void setUserId(String userId) {
|
||||||
{
|
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginInfo withUserId(String userId)
|
public LoginInfo withUserId(String userId) {
|
||||||
{
|
|
||||||
setUserId(userId);
|
setUserId(userId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKey()
|
public String getKey() {
|
||||||
{
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(String key)
|
public void setKey(String key) {
|
||||||
{
|
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginInfo withKey(String key)
|
public LoginInfo withKey(String key) {
|
||||||
{
|
|
||||||
setKey(key);
|
setKey(key);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getRegistrationState()
|
public Long getRegistrationState() {
|
||||||
{
|
|
||||||
return registrationState;
|
return registrationState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegistrationState(Long registrationState)
|
public void setRegistrationState(Long registrationState) {
|
||||||
{
|
|
||||||
this.registrationState = registrationState;
|
this.registrationState = registrationState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginInfo withRegistrationState(Long registrationState)
|
public LoginInfo withRegistrationState(Long registrationState) {
|
||||||
{
|
|
||||||
setRegistrationState(registrationState);
|
setRegistrationState(registrationState);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getEdpLoginStatus()
|
public Long getEdpLoginStatus() {
|
||||||
{
|
|
||||||
return edpLoginStatus;
|
return edpLoginStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEdpLoginStatus(Long edpLoginStatus)
|
public void setEdpLoginStatus(Long edpLoginStatus) {
|
||||||
{
|
|
||||||
this.edpLoginStatus = edpLoginStatus;
|
this.edpLoginStatus = edpLoginStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginInfo withEdpLoginStatus(Long edpLoginStatus)
|
public LoginInfo withEdpLoginStatus(Long edpLoginStatus) {
|
||||||
{
|
|
||||||
setEdpLoginStatus(edpLoginStatus);
|
setEdpLoginStatus(edpLoginStatus);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEdpLoginMessage()
|
public String getEdpLoginMessage() {
|
||||||
{
|
|
||||||
return edpLoginMessage;
|
return edpLoginMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEdpLoginMessage(String edpLoginMessage)
|
public void setEdpLoginMessage(String edpLoginMessage) {
|
||||||
{
|
|
||||||
this.edpLoginMessage = edpLoginMessage;
|
this.edpLoginMessage = edpLoginMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginInfo withEdpLoginMessage(String edpLoginMessage)
|
public LoginInfo withEdpLoginMessage(String edpLoginMessage) {
|
||||||
{
|
|
||||||
setEdpLoginMessage(edpLoginMessage);
|
setEdpLoginMessage(edpLoginMessage);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
||||||
|
@ -115,53 +100,39 @@ public class LoginInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj) {
|
||||||
{
|
if (this == obj) {
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof LoginInfo))
|
if (!(obj instanceof LoginInfo)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LoginInfo other = (LoginInfo) obj;
|
LoginInfo other = (LoginInfo) obj;
|
||||||
if (key == null)
|
if (key == null) {
|
||||||
{
|
if (other.key != null) {
|
||||||
if (other.key != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!key.equals(other.key)) {
|
||||||
else if (!key.equals(other.key))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!registrationState.equals(other.registrationState))
|
if (!registrationState.equals(other.registrationState)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (userId == null)
|
if (userId == null) {
|
||||||
{
|
if (other.userId != null) {
|
||||||
if (other.userId != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!userId.equals(other.userId)) {
|
||||||
else if (!userId.equals(other.userId))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("LoginInfo [userId=");
|
builder.append("LoginInfo [userId=");
|
||||||
builder.append(userId);
|
builder.append(userId);
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link LoginRequest} holds the Login request sent to the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class LoginRequest {
|
||||||
|
private String login;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public String getLogin() {
|
||||||
|
return login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogin(String login) {
|
||||||
|
this.login = login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginRequest withLogin(String login) {
|
||||||
|
setLogin(login);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginRequest withPassword(String password) {
|
||||||
|
setPassword(password);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((login == null) ? 0 : login.hashCode());
|
||||||
|
result = prime * result + ((password == null) ? 0 : password.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof LoginRequest)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LoginRequest other = (LoginRequest) obj;
|
||||||
|
if (login == null) {
|
||||||
|
if (other.login != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!login.equals(other.login)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (password == null) {
|
||||||
|
if (other.password != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!password.equals(other.password)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("LoginRequest [login=");
|
||||||
|
builder.append(login);
|
||||||
|
builder.append(", password=");
|
||||||
|
builder.append(password);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PauseModeRequest} holds the request to pause the bed data collection.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
public class PauseModeRequest {
|
||||||
|
private String mode;
|
||||||
|
|
||||||
|
public String getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(String mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PauseModeRequest withMode(String mode) {
|
||||||
|
setMode(mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((mode == null) ? 0 : mode.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof PauseModeRequest)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PauseModeRequest other = (PauseModeRequest) obj;
|
||||||
|
if (mode == null) {
|
||||||
|
if (other.mode != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!mode.equals(other.mode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("SleepNumberRequest [mode=");
|
||||||
|
builder.append(mode);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PauseModeResponse} holds the response to the request to pause the bed data collection.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
public class PauseModeResponse {
|
||||||
|
private String accountId;
|
||||||
|
private String bedId;
|
||||||
|
private String pauseMode;
|
||||||
|
|
||||||
|
public String getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountId(String accountId) {
|
||||||
|
this.accountId = accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PauseModeResponse withAccountId(String accountId) {
|
||||||
|
setAccountId(accountId);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBedId() {
|
||||||
|
return bedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBedId(String bedId) {
|
||||||
|
this.bedId = bedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PauseModeResponse withBedId(String bedId) {
|
||||||
|
setBedId(bedId);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPauseMode() {
|
||||||
|
return pauseMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPauseMode(String pauseMode) {
|
||||||
|
this.pauseMode = pauseMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PauseModeResponse withPauseMode(String pauseMode) {
|
||||||
|
setPauseMode(pauseMode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((accountId == null) ? 0 : accountId.hashCode());
|
||||||
|
result = prime * result + ((bedId == null) ? 0 : bedId.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof PauseModeResponse)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PauseModeResponse other = (PauseModeResponse) obj;
|
||||||
|
if (accountId == null) {
|
||||||
|
if (other.accountId != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!accountId.equals(other.accountId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bedId == null) {
|
||||||
|
if (other.bedId != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!bedId.equals(other.bedId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("PauseMode [accountId=");
|
||||||
|
builder.append(accountId);
|
||||||
|
builder.append(", bedId=");
|
||||||
|
builder.append(bedId);
|
||||||
|
builder.append(", pauseMode=");
|
||||||
|
builder.append(pauseMode);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepDataDay} holds the information for a daily sleep session.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
public class SleepDataDay {
|
||||||
|
|
||||||
|
@SerializedName("date")
|
||||||
|
private LocalDate date;
|
||||||
|
|
||||||
|
@SerializedName("message")
|
||||||
|
private String dailyMessage;
|
||||||
|
|
||||||
|
@SerializedName("sessions")
|
||||||
|
private List<SleepDataSession> dailySessions;
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return dailyMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SleepDataSession> getDailySessions() {
|
||||||
|
return dailySessions;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepDataResponse} holds the response to a request for sleep data.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
public class SleepDataResponse {
|
||||||
|
@SerializedName("sleeperId")
|
||||||
|
private String sleeperId;
|
||||||
|
|
||||||
|
@SerializedName("avgSleepIQ")
|
||||||
|
private Integer averageSleepIQ;
|
||||||
|
|
||||||
|
@SerializedName("avgHeartRate")
|
||||||
|
private Integer averageHeartRate;
|
||||||
|
|
||||||
|
@SerializedName("avgRespirationRate")
|
||||||
|
private Integer averageResperationRate;
|
||||||
|
|
||||||
|
@SerializedName("inBed")
|
||||||
|
private Integer totalInBedSeconds;
|
||||||
|
|
||||||
|
@SerializedName("outOfBed")
|
||||||
|
private Integer totalOutOfBedSeconds;
|
||||||
|
|
||||||
|
@SerializedName("restful")
|
||||||
|
private Integer totalRestfulSeconds;
|
||||||
|
|
||||||
|
@SerializedName("restless")
|
||||||
|
private Integer totalRestlessSeconds;
|
||||||
|
|
||||||
|
@SerializedName("sleepData")
|
||||||
|
private List<SleepDataDay> sleepDataDays;
|
||||||
|
|
||||||
|
public String getSleeperId() {
|
||||||
|
return sleeperId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAverageSleepIQ() {
|
||||||
|
return averageSleepIQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAverageHeartRate() {
|
||||||
|
return averageHeartRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAverageRespirationRate() {
|
||||||
|
return averageResperationRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTotalSleepSessionTime() {
|
||||||
|
return totalInBedSeconds + totalOutOfBedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTotalInBedSeconds() {
|
||||||
|
return totalInBedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTotalOutOfBedSeconds() {
|
||||||
|
return totalOutOfBedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTotalRestfulSeconds() {
|
||||||
|
return totalRestfulSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTotalRestlessSeconds() {
|
||||||
|
return totalRestlessSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SleepDataDay> getSleepDataDays() {
|
||||||
|
return sleepDataDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("SleepDataResponse [sleepData=");
|
||||||
|
builder.append("averageSleepIQ=");
|
||||||
|
builder.append(averageSleepIQ);
|
||||||
|
builder.append(", averageHeartRate=");
|
||||||
|
builder.append(averageHeartRate);
|
||||||
|
builder.append(", averageResperationRate=");
|
||||||
|
builder.append(averageResperationRate);
|
||||||
|
builder.append(", totalInBedSeconds=");
|
||||||
|
builder.append(totalInBedSeconds);
|
||||||
|
builder.append(", totalOutOfBedSeconds=");
|
||||||
|
builder.append(totalOutOfBedSeconds);
|
||||||
|
builder.append(", totalRestfulSeconds=");
|
||||||
|
builder.append(totalRestfulSeconds);
|
||||||
|
builder.append(", totalRestlessSeconds=");
|
||||||
|
builder.append(totalRestlessSeconds);
|
||||||
|
builder.append(", totalSleepSessionTime=");
|
||||||
|
builder.append(getTotalSleepSessionTime());
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepDataSession} holds the data for a sleep session.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
public class SleepDataSession {
|
||||||
|
|
||||||
|
@SerializedName("avgSleepIQ")
|
||||||
|
private Integer sessionAverageSleepIQ;
|
||||||
|
|
||||||
|
@SerializedName("avgHeartRate")
|
||||||
|
private Integer sessionAverageHeartRate;
|
||||||
|
|
||||||
|
@SerializedName("avgRespirationRate")
|
||||||
|
private Integer sessionAverageRespirationRate;
|
||||||
|
|
||||||
|
@SerializedName("isFinalized")
|
||||||
|
private boolean sessionIsFinalized;
|
||||||
|
|
||||||
|
@SerializedName("totalSleepSessionTime")
|
||||||
|
private Integer sessionTotalSeconds;
|
||||||
|
|
||||||
|
@SerializedName("inBed")
|
||||||
|
private Integer sessionInBedSeconds;
|
||||||
|
|
||||||
|
@SerializedName("outOfBed")
|
||||||
|
private Integer sessionOutOfBedSeconds;
|
||||||
|
|
||||||
|
@SerializedName("restful")
|
||||||
|
private Integer sessionRestfulSeconds;
|
||||||
|
|
||||||
|
@SerializedName("restless")
|
||||||
|
private Integer sessionRestlessSeconds;
|
||||||
|
|
||||||
|
public Integer getSessionAverageSleepIQ() {
|
||||||
|
return sessionAverageSleepIQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSessionAverageHeartRate() {
|
||||||
|
return sessionAverageHeartRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSessionAverageRespirationRate() {
|
||||||
|
return sessionAverageRespirationRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean sessionIsFinalized() {
|
||||||
|
return sessionIsFinalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSessionTotalSeconds() {
|
||||||
|
return sessionTotalSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSessionInBedSeconds() {
|
||||||
|
return sessionInBedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSessionOutOfBedSeconds() {
|
||||||
|
return sessionOutOfBedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSessionRestfulSeconds() {
|
||||||
|
return sessionRestfulSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSessionRestlessSeconds() {
|
||||||
|
return sessionRestlessSeconds;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepNumberRequest} holds the information used to set the sleep number
|
||||||
|
* for a bed side.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class SleepNumberRequest {
|
||||||
|
private String bedId;
|
||||||
|
private Integer sleepNumber;
|
||||||
|
private Side side;
|
||||||
|
|
||||||
|
public String getBedId() {
|
||||||
|
return bedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBedId(String bedId) {
|
||||||
|
this.bedId = bedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SleepNumberRequest withBedId(String bedId) {
|
||||||
|
setBedId(bedId);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSleepNumber() {
|
||||||
|
return sleepNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSleepNumber(Integer sleepNumber) {
|
||||||
|
this.sleepNumber = sleepNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SleepNumberRequest withSleepNumber(Integer sleepNumber) {
|
||||||
|
setSleepNumber(sleepNumber);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Side getSide() {
|
||||||
|
return side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSide(Side side) {
|
||||||
|
this.side = side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SleepNumberRequest withSide(Side side) {
|
||||||
|
setSide(side);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((bedId == null) ? 0 : bedId.hashCode());
|
||||||
|
result = prime * result + ((sleepNumber == null) ? 0 : sleepNumber.hashCode());
|
||||||
|
result = prime * result + ((side == null) ? 0 : side.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof SleepNumberRequest)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SleepNumberRequest other = (SleepNumberRequest) obj;
|
||||||
|
if (bedId == null) {
|
||||||
|
if (other.bedId != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!bedId.equals(other.bedId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (sleepNumber == null) {
|
||||||
|
if (other.sleepNumber != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (sleepNumber.equals(other.sleepNumber)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (side == null) {
|
||||||
|
if (other.side != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!side.equals(other.side)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("SleepNumberRequest [bedId=");
|
||||||
|
builder.append(bedId);
|
||||||
|
builder.append(", sleepNumber=");
|
||||||
|
builder.append(sleepNumber);
|
||||||
|
builder.append(", side=");
|
||||||
|
builder.append(side);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,24 +1,28 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class Sleeper
|
/**
|
||||||
{
|
* The {@link Sleeper} holds the information about the sleeper that's
|
||||||
|
* associated with a bed side.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class Sleeper {
|
||||||
private String firstName;
|
private String firstName;
|
||||||
private Boolean active;
|
private Boolean active;
|
||||||
private Boolean emailValidated;
|
private Boolean emailValidated;
|
||||||
|
@ -44,379 +48,309 @@ public class Sleeper
|
||||||
private String email;
|
private String email;
|
||||||
private String avatar;
|
private String avatar;
|
||||||
private String lastLogin; // should be ZonedDateTime but provider passes string "null" when missing
|
private String lastLogin; // should be ZonedDateTime but provider passes string "null" when missing
|
||||||
private Integer side; // 0=left; 1=right
|
private Side side; // 0=left; 1=right
|
||||||
|
|
||||||
public String getFirstName()
|
public String getFirstName() {
|
||||||
{
|
|
||||||
return firstName;
|
return firstName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFirstName(String firstName)
|
public void setFirstName(String firstName) {
|
||||||
{
|
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withFirstName(String firstName)
|
public Sleeper withFirstName(String firstName) {
|
||||||
{
|
|
||||||
setFirstName(firstName);
|
setFirstName(firstName);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isActive()
|
public Boolean isActive() {
|
||||||
{
|
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActive(Boolean active)
|
public void setActive(Boolean active) {
|
||||||
{
|
|
||||||
this.active = active;
|
this.active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withActive(Boolean active)
|
public Sleeper withActive(Boolean active) {
|
||||||
{
|
|
||||||
setActive(active);
|
setActive(active);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isEmailValidated()
|
public Boolean isEmailValidated() {
|
||||||
{
|
|
||||||
return emailValidated;
|
return emailValidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmailValidated(Boolean emailValidated)
|
public void setEmailValidated(Boolean emailValidated) {
|
||||||
{
|
|
||||||
this.emailValidated = emailValidated;
|
this.emailValidated = emailValidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withEmailValidated(Boolean emailValidated)
|
public Sleeper withEmailValidated(Boolean emailValidated) {
|
||||||
{
|
|
||||||
setEmailValidated(emailValidated);
|
setEmailValidated(emailValidated);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isChild()
|
public Boolean isChild() {
|
||||||
{
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChild(Boolean child)
|
public void setChild(Boolean child) {
|
||||||
{
|
|
||||||
this.child = child;
|
this.child = child;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withChild(Boolean child)
|
public Sleeper withChild(Boolean child) {
|
||||||
{
|
|
||||||
setChild(child);
|
setChild(child);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBedId()
|
public String getBedId() {
|
||||||
{
|
|
||||||
return bedId;
|
return bedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBedId(String bedId)
|
public void setBedId(String bedId) {
|
||||||
{
|
|
||||||
this.bedId = bedId;
|
this.bedId = bedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withBedId(String bedId)
|
public Sleeper withBedId(String bedId) {
|
||||||
{
|
|
||||||
setBedId(bedId);
|
setBedId(bedId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBirthYear()
|
public String getBirthYear() {
|
||||||
{
|
|
||||||
return birthYear;
|
return birthYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBirthYear(String birthYear)
|
public void setBirthYear(String birthYear) {
|
||||||
{
|
|
||||||
this.birthYear = birthYear;
|
this.birthYear = birthYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withBirthYear(String birthYear)
|
public Sleeper withBirthYear(String birthYear) {
|
||||||
{
|
|
||||||
setBirthYear(birthYear);
|
setBirthYear(birthYear);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getZipCode()
|
public String getZipCode() {
|
||||||
{
|
|
||||||
return zipCode;
|
return zipCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setZipCode(String zipCode)
|
public void setZipCode(String zipCode) {
|
||||||
{
|
|
||||||
this.zipCode = zipCode;
|
this.zipCode = zipCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withZipCode(String zipCode)
|
public Sleeper withZipCode(String zipCode) {
|
||||||
{
|
|
||||||
setZipCode(zipCode);
|
setZipCode(zipCode);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTimezone()
|
public String getTimezone() {
|
||||||
{
|
|
||||||
return timezone;
|
return timezone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimezone(String timezone)
|
public void setTimezone(String timezone) {
|
||||||
{
|
|
||||||
this.timezone = timezone;
|
this.timezone = timezone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withTimezone(String timezone)
|
public Sleeper withTimezone(String timezone) {
|
||||||
{
|
|
||||||
setTimezone(timezone);
|
setTimezone(timezone);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isMale()
|
public Boolean isMale() {
|
||||||
{
|
|
||||||
return male;
|
return male;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMale(Boolean male)
|
public void setMale(Boolean male) {
|
||||||
{
|
|
||||||
this.male = male;
|
this.male = male;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withMale(Boolean male)
|
public Sleeper withMale(Boolean male) {
|
||||||
{
|
|
||||||
setMale(male);
|
setMale(male);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getWeight()
|
public Integer getWeight() {
|
||||||
{
|
|
||||||
return weight;
|
return weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWeight(Integer weight)
|
public void setWeight(Integer weight) {
|
||||||
{
|
|
||||||
this.weight = weight;
|
this.weight = weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withWeight(Integer weight)
|
public Sleeper withWeight(Integer weight) {
|
||||||
{
|
|
||||||
setWeight(weight);
|
setWeight(weight);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDuration()
|
public String getDuration() {
|
||||||
{
|
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDuration(String duration)
|
public void setDuration(String duration) {
|
||||||
{
|
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withDuration(String duration)
|
public Sleeper withDuration(String duration) {
|
||||||
{
|
|
||||||
setDuration(duration);
|
setDuration(duration);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSleeperId()
|
public String getSleeperId() {
|
||||||
{
|
|
||||||
return sleeperId;
|
return sleeperId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSleeperId(String sleeperId)
|
public void setSleeperId(String sleeperId) {
|
||||||
{
|
|
||||||
this.sleeperId = sleeperId;
|
this.sleeperId = sleeperId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withSleeperId(String sleeperId)
|
public Sleeper withSleeperId(String sleeperId) {
|
||||||
{
|
|
||||||
setSleeperId(sleeperId);
|
setSleeperId(sleeperId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getHeight()
|
public Integer getHeight() {
|
||||||
{
|
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeight(Integer height)
|
public void setHeight(Integer height) {
|
||||||
{
|
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withHeight(Integer height)
|
public Sleeper withHeight(Integer height) {
|
||||||
{
|
|
||||||
setHeight(height);
|
setHeight(height);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLicenseVersion()
|
public Long getLicenseVersion() {
|
||||||
{
|
|
||||||
return licenseVersion;
|
return licenseVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLicenseVersion(Long licenseVersion)
|
public void setLicenseVersion(Long licenseVersion) {
|
||||||
{
|
|
||||||
this.licenseVersion = licenseVersion;
|
this.licenseVersion = licenseVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withLicenseVersion(Long licenseVersion)
|
public Sleeper withLicenseVersion(Long licenseVersion) {
|
||||||
{
|
|
||||||
setLicenseVersion(licenseVersion);
|
setLicenseVersion(licenseVersion);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername()
|
public String getUsername() {
|
||||||
{
|
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username)
|
public void setUsername(String username) {
|
||||||
{
|
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withUsername(String username)
|
public Sleeper withUsername(String username) {
|
||||||
{
|
|
||||||
setUsername(username);
|
setUsername(username);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getBirthMonth()
|
public Integer getBirthMonth() {
|
||||||
{
|
|
||||||
return birthMonth;
|
return birthMonth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBirthMonth(Integer birthMonth)
|
public void setBirthMonth(Integer birthMonth) {
|
||||||
{
|
|
||||||
this.birthMonth = birthMonth;
|
this.birthMonth = birthMonth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withBirthMonth(Integer birthMonth)
|
public Sleeper withBirthMonth(Integer birthMonth) {
|
||||||
{
|
|
||||||
setBirthMonth(birthMonth);
|
setBirthMonth(birthMonth);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getSleepGoal()
|
public Integer getSleepGoal() {
|
||||||
{
|
|
||||||
return sleepGoal;
|
return sleepGoal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSleepGoal(Integer sleepGoal)
|
public void setSleepGoal(Integer sleepGoal) {
|
||||||
{
|
|
||||||
this.sleepGoal = sleepGoal;
|
this.sleepGoal = sleepGoal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withSleepGoal(Integer sleepGoal)
|
public Sleeper withSleepGoal(Integer sleepGoal) {
|
||||||
{
|
|
||||||
setSleepGoal(sleepGoal);
|
setSleepGoal(sleepGoal);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isAccountOwner()
|
public Boolean isAccountOwner() {
|
||||||
{
|
|
||||||
return accountOwner;
|
return accountOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccountOwner(Boolean accountOwner)
|
public void setAccountOwner(Boolean accountOwner) {
|
||||||
{
|
|
||||||
this.accountOwner = accountOwner;
|
this.accountOwner = accountOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withAccountOwner(Boolean accountOwner)
|
public Sleeper withAccountOwner(Boolean accountOwner) {
|
||||||
{
|
|
||||||
setAccountOwner(accountOwner);
|
setAccountOwner(accountOwner);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAccountId()
|
public String getAccountId() {
|
||||||
{
|
|
||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccountId(String accountId)
|
public void setAccountId(String accountId) {
|
||||||
{
|
|
||||||
this.accountId = accountId;
|
this.accountId = accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withAccountId(String accountId)
|
public Sleeper withAccountId(String accountId) {
|
||||||
{
|
|
||||||
setAccountId(accountId);
|
setAccountId(accountId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEmail()
|
public String getEmail() {
|
||||||
{
|
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmail(String email)
|
public void setEmail(String email) {
|
||||||
{
|
|
||||||
this.email = email;
|
this.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withEmail(String email)
|
public Sleeper withEmail(String email) {
|
||||||
{
|
|
||||||
setEmail(email);
|
setEmail(email);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAvatar()
|
public String getAvatar() {
|
||||||
{
|
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAvatar(String avatar)
|
public void setAvatar(String avatar) {
|
||||||
{
|
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withAvatar(String avatar)
|
public Sleeper withAvatar(String avatar) {
|
||||||
{
|
|
||||||
setAvatar(avatar);
|
setAvatar(avatar);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLastLogin()
|
public String getLastLogin() {
|
||||||
{
|
|
||||||
return lastLogin;
|
return lastLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastLogin(String lastLogin)
|
public void setLastLogin(String lastLogin) {
|
||||||
{
|
|
||||||
this.lastLogin = lastLogin;
|
this.lastLogin = lastLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withLastLogin(String lastLogin)
|
public Sleeper withLastLogin(String lastLogin) {
|
||||||
{
|
|
||||||
setLastLogin(lastLogin);
|
setLastLogin(lastLogin);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getSide()
|
public Side getSide() {
|
||||||
{
|
|
||||||
return side;
|
return side;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSide(Integer side)
|
public void setSide(Side side) {
|
||||||
{
|
|
||||||
this.side = side;
|
this.side = side;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sleeper withSide(Integer side)
|
public Sleeper withSide(Side side) {
|
||||||
{
|
|
||||||
setSide(side);
|
setSide(side);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + ((sleeperId == null) ? 0 : sleeperId.hashCode());
|
result = prime * result + ((sleeperId == null) ? 0 : sleeperId.hashCode());
|
||||||
|
@ -424,38 +358,29 @@ public class Sleeper
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj) {
|
||||||
{
|
if (this == obj) {
|
||||||
if (this == obj)
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof Sleeper))
|
if (!(obj instanceof Sleeper)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Sleeper other = (Sleeper) obj;
|
Sleeper other = (Sleeper) obj;
|
||||||
if (sleeperId == null)
|
if (sleeperId == null) {
|
||||||
{
|
if (other.sleeperId != null) {
|
||||||
if (other.sleeperId != null)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (!sleeperId.equals(other.sleeperId)) {
|
||||||
else if (!sleeperId.equals(other.sleeperId))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("Sleeper [firstName=");
|
builder.append("Sleeper [firstName=");
|
||||||
builder.append(firstName);
|
builder.append(firstName);
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleeperResponse} holds the information about the sleepers assigned to the bed sides.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
public class SleepersResponse {
|
||||||
|
private List<Sleeper> sleepers;
|
||||||
|
|
||||||
|
public List<Sleeper> getSleepers() {
|
||||||
|
return sleepers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSleepers(List<Sleeper> sleepers) {
|
||||||
|
this.sleepers = sleepers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SleepersResponse withSleepers(List<Sleeper> sleepers) {
|
||||||
|
setSleepers(sleepers);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((sleepers == null) ? 0 : sleepers.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof SleepersResponse)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SleepersResponse other = (SleepersResponse) obj;
|
||||||
|
if (sleepers == null) {
|
||||||
|
if (other.sleepers != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!sleepers.equals(other.sleepers)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("SleepersResponse [sleepers=");
|
||||||
|
builder.append(sleepers);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,16 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.internal.api.dto;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -21,6 +18,11 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link TimeSince} converts from "nn d hh:mm:ss" to Duration
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
public class TimeSince {
|
public class TimeSince {
|
||||||
private static final Pattern PATTERN = Pattern.compile("(([0-9]+) d )?([0-9]{2}):([0-9]{2}):([0-9]{2})",
|
private static final Pattern PATTERN = Pattern.compile("(([0-9]+) d )?([0-9]{2}):([0-9]{2}):([0-9]{2})",
|
||||||
Pattern.CASE_INSENSITIVE);
|
Pattern.CASE_INSENSITIVE);
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.enums;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Side} represents the possible sides of the bed (i.e. left and right).
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum Side {
|
||||||
|
LEFT(0),
|
||||||
|
RIGHT(1);
|
||||||
|
|
||||||
|
private final int side;
|
||||||
|
|
||||||
|
Side(final int side) {
|
||||||
|
this.side = side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value() {
|
||||||
|
return side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Side forValue(int value) {
|
||||||
|
for (Side s : Side.values()) {
|
||||||
|
if (s.side == value) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid side: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Side convertFromGroup(@Nullable String channelGroup) {
|
||||||
|
return "left".equalsIgnoreCase(channelGroup) ? Side.LEFT : Side.RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return side == 0 ? LEFT.name() : RIGHT.name();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.enums;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepDataInterval} represents the time periods that can be
|
||||||
|
* used for sleep data requests.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum SleepDataInterval {
|
||||||
|
DAY("D1"),
|
||||||
|
WEEK("W1"),
|
||||||
|
MONTH("M1");
|
||||||
|
|
||||||
|
private final String interval;
|
||||||
|
|
||||||
|
SleepDataInterval(final String interval) {
|
||||||
|
this.interval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SleepDataInterval forValue(String value) {
|
||||||
|
for (SleepDataInterval s : SleepDataInterval.values()) {
|
||||||
|
if (s.interval.equals(value)) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid sleep data interval: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Endpoints} class contains all endpoints for the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class Endpoints {
|
||||||
|
private static final String LOGIN = "/rest/login";
|
||||||
|
private static final String BED = "/rest/bed";
|
||||||
|
private static final String SLEEPER = "/rest/sleeper";
|
||||||
|
private static final String FAMILY_STATUS = "/rest/bed/familyStatus";
|
||||||
|
private static final String PAUSE_MODE = "/rest/bed/%s/pauseMode";
|
||||||
|
private static final String SLEEP_DATA = "/rest/sleepData";
|
||||||
|
private static final String SET_SLEEP_NUMBER = "/rest/bed/%s/sleepNumber";
|
||||||
|
private static final String SET_PAUSE_MODE = "/rest/bed/%s/pauseMode";
|
||||||
|
|
||||||
|
public static String login() {
|
||||||
|
return LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String bed() {
|
||||||
|
return BED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sleeper() {
|
||||||
|
return SLEEPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String familyStatus() {
|
||||||
|
return FAMILY_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String pauseMode(String bedId) {
|
||||||
|
return String.format(PAUSE_MODE, bedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sleepData() {
|
||||||
|
return SLEEP_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String setSleepNumber(String bedId) {
|
||||||
|
return String.format(SET_SLEEP_NUMBER, bedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String setPauseMode(String bedId) {
|
||||||
|
return String.format(SET_PAUSE_MODE, bedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Endpoints() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepNumberRequest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.TimeSince;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.typeadapters.SideTypeAdapter;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.typeadapters.SleepNumberRequestAdapter;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.typeadapters.TimeSinceTypeAdapter;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.typeadapters.ZonedDateTimeTypeAdapter;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link GsonGenerator} class creates the GSON generator object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class GsonGenerator {
|
||||||
|
public static Gson create() {
|
||||||
|
return create(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Gson create(boolean prettyPrint) {
|
||||||
|
GsonBuilder builder = new GsonBuilder();
|
||||||
|
builder.registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdapter());
|
||||||
|
builder.registerTypeAdapter(TimeSince.class, new TimeSinceTypeAdapter());
|
||||||
|
builder.registerTypeAdapter(SleepNumberRequest.class, new SleepNumberRequestAdapter());
|
||||||
|
builder.registerTypeAdapter(Side.class, new SideTypeAdapter());
|
||||||
|
|
||||||
|
if (prettyPrint) {
|
||||||
|
builder.setPrettyPrinting();
|
||||||
|
}
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GsonGenerator() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,322 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl;
|
||||||
|
|
||||||
|
import java.net.CookieStore;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.eclipse.jetty.client.api.ContentResponse;
|
||||||
|
import org.eclipse.jetty.client.api.Request;
|
||||||
|
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.CommunicationException;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.Configuration;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.LoginException;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.ResponseFormatException;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.SleepIQ;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.UnauthorizedException;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Bed;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedsResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Failure;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.FamilyStatusResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.LoginInfo;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.LoginRequest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.PauseModeResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepDataResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepNumberRequest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Sleeper;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepersResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.SleepDataInterval;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepIQImpl} class handles all interactions with the sleepiq service.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class SleepIQImpl implements SleepIQ {
|
||||||
|
private static final String PARAM_KEY = "_k";
|
||||||
|
private static final String USER_AGENT = "SleepIQ/1593766370 CFNetwork/1185.2 Darwin/20.0.0";
|
||||||
|
|
||||||
|
private static final Gson GSON = GsonGenerator.create(false);
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(SleepIQImpl.class);
|
||||||
|
|
||||||
|
private final HttpClient httpClient;
|
||||||
|
private final CookieStore cookieStore;
|
||||||
|
|
||||||
|
protected final Configuration config;
|
||||||
|
|
||||||
|
private final LoginRequest loginRequest = new LoginRequest();
|
||||||
|
private volatile @Nullable LoginInfo loginInfo;
|
||||||
|
|
||||||
|
public SleepIQImpl(Configuration config, HttpClient httpClient) {
|
||||||
|
this.config = config;
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
cookieStore = httpClient.getCookieStore();
|
||||||
|
loginRequest.setLogin(config.getUsername());
|
||||||
|
loginRequest.setPassword(config.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
|
cookieStore.removeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable LoginInfo login() throws LoginException, UnauthorizedException {
|
||||||
|
logger.trace("SleepIQ: login: loginInfo={}", loginInfo);
|
||||||
|
if (loginInfo == null) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (loginInfo == null) {
|
||||||
|
Request request = httpClient.newRequest(config.getBaseUri()).path(Endpoints.login())
|
||||||
|
.agent(USER_AGENT).header(HttpHeader.CONTENT_TYPE, "application/json")
|
||||||
|
.timeout(10, TimeUnit.SECONDS).method(HttpMethod.PUT)
|
||||||
|
.content(new StringContentProvider(GSON.toJson(loginRequest)), "application/json");
|
||||||
|
logger.trace("SleepIQ: login: request url={}", request.getURI());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ContentResponse response = request.send();
|
||||||
|
logger.debug("SleepIQ: login: status={}, content={}", response.getStatus(),
|
||||||
|
response.getContentAsString());
|
||||||
|
if (isUnauthorized(response)) {
|
||||||
|
Failure failure = GSON.fromJson(response.getContentAsString(), Failure.class);
|
||||||
|
String message = failure != null ? failure.getError().getMessage() : "Login unauthorized";
|
||||||
|
throw new UnauthorizedException(message);
|
||||||
|
}
|
||||||
|
if (isNotOk(response)) {
|
||||||
|
Failure failure = GSON.fromJson(response.getContentAsString(), Failure.class);
|
||||||
|
String message = failure != null ? failure.getError().getMessage() : "Login failed";
|
||||||
|
throw new LoginException(message);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
loginInfo = GSON.fromJson(response.getContentAsString(), LoginInfo.class);
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
throw new LoginException("Failed to parse 'login' response");
|
||||||
|
}
|
||||||
|
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||||
|
logger.info("SleepIQ: login: Login failed message={}", e.getMessage(), e);
|
||||||
|
throw new LoginException("Problem communicating with SleepIQ cloud service");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loginInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Bed> getBeds() throws LoginException, CommunicationException, ResponseFormatException {
|
||||||
|
try {
|
||||||
|
String contentResponse = cloudRequest(Endpoints.bed());
|
||||||
|
BedsResponse response = GSON.fromJson(contentResponse, BedsResponse.class);
|
||||||
|
if (response != null) {
|
||||||
|
return response.getBeds();
|
||||||
|
} else {
|
||||||
|
throw new ResponseFormatException("Failed to get a valid 'beds' response from cloud");
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
throw new ResponseFormatException("Failed to parse 'beds' response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FamilyStatusResponse getFamilyStatus()
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
try {
|
||||||
|
String contentResponse = cloudRequest(Endpoints.familyStatus());
|
||||||
|
FamilyStatusResponse response = GSON.fromJson(contentResponse, FamilyStatusResponse.class);
|
||||||
|
if (response != null) {
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
throw new ResponseFormatException("Failed to get a valid 'familyStatus' response from cloud");
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
throw new ResponseFormatException("Failed to parse 'familyStatus' response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Sleeper> getSleepers() throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
try {
|
||||||
|
String contentResponse = cloudRequest(Endpoints.sleeper());
|
||||||
|
SleepersResponse response = GSON.fromJson(contentResponse, SleepersResponse.class);
|
||||||
|
if (response != null) {
|
||||||
|
return response.getSleepers();
|
||||||
|
} else {
|
||||||
|
throw new ResponseFormatException("Failed to get a valid 'sleepers' response from cloud");
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
throw new ResponseFormatException("Failed to parse 'sleepers' response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PauseModeResponse getPauseMode(String bedId)
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
try {
|
||||||
|
String contentResponse = cloudRequest(Endpoints.pauseMode(bedId));
|
||||||
|
PauseModeResponse response = GSON.fromJson(contentResponse, PauseModeResponse.class);
|
||||||
|
if (response != null) {
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
throw new ResponseFormatException("Failed to get a valid 'pauseMode' response from cloud");
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
throw new ResponseFormatException("Failed to parse 'pauseMode' response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SleepDataResponse getSleepData(String sleeperId, SleepDataInterval interval)
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
try {
|
||||||
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
parameters.put("interval", interval.value());
|
||||||
|
parameters.put("sleeper", sleeperId);
|
||||||
|
parameters.put("includeSlices", "false");
|
||||||
|
parameters.put("date", formatSleepDataDate(ZonedDateTime.now()));
|
||||||
|
String contentResponse = cloudRequest(Endpoints.sleepData(), parameters);
|
||||||
|
SleepDataResponse response = GSON.fromJson(contentResponse, SleepDataResponse.class);
|
||||||
|
if (response != null) {
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
throw new ResponseFormatException("Failed to get a valid 'sleepData' response from cloud");
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
throw new ResponseFormatException("Failed to parse 'sleepData' response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatSleepDataDate(ZonedDateTime zonedDateTime) {
|
||||||
|
return DateTimeFormatter.ofPattern("yyyy-MM-dd").format(zonedDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSleepNumber(String bedId, Side side, int sleepNumber)
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
String body = GSON.toJson(new SleepNumberRequest().withBedId(bedId).withSleepNumber(sleepNumber).withSide(side),
|
||||||
|
SleepNumberRequest.class);
|
||||||
|
logger.debug("SleepIQ: setSleepNumber: Request body={}", body);
|
||||||
|
cloudRequest(Endpoints.setSleepNumber(bedId), null, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPauseMode(String bedId, boolean pauseMode)
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
logger.debug("SleepIQ: setPauseMode: command={}", pauseMode);
|
||||||
|
Map<String, String> requestParameters = new HashMap<>();
|
||||||
|
requestParameters.put("mode", pauseMode ? "on" : "off");
|
||||||
|
cloudRequest(Endpoints.setPauseMode(bedId), requestParameters, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cloudRequest(String endpoint)
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
return cloudRequest(endpoint, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cloudRequest(String endpoint, Map<String, String> parameters)
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
return cloudRequest(endpoint, parameters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cloudRequest(String endpoint, @Nullable Map<String, String> parameters, @Nullable String body)
|
||||||
|
throws LoginException, ResponseFormatException, CommunicationException {
|
||||||
|
logger.debug("SleepIQ: cloudGetRequest: Invoke endpoint={}", endpoint);
|
||||||
|
ContentResponse response = (body == null ? doGet(endpoint, parameters) : doPut(endpoint, parameters, body));
|
||||||
|
if (isUnauthorized(response)) {
|
||||||
|
logger.debug("SleepIQ: cloudGetRequest: UNAUTHORIZED, reset login");
|
||||||
|
// Force new login and try again
|
||||||
|
resetLogin();
|
||||||
|
response = (body == null ? doGet(endpoint, parameters) : doPut(endpoint, parameters, body));
|
||||||
|
}
|
||||||
|
if (isNotOk(response)) {
|
||||||
|
throw new ResponseFormatException(String.format("Cloud API returned error: status=%d, message=%s",
|
||||||
|
response.getStatus(), HttpStatus.getCode(response.getStatus()).getMessage()));
|
||||||
|
}
|
||||||
|
return response.getContentAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContentResponse doGet(String endpoint, @Nullable Map<String, String> parameters)
|
||||||
|
throws CommunicationException, LoginException {
|
||||||
|
LoginInfo login = login();
|
||||||
|
Request request = httpClient.newRequest(config.getBaseUri()).path(endpoint).param(PARAM_KEY, login.getKey())
|
||||||
|
.agent(USER_AGENT).header(HttpHeader.CONTENT_TYPE, "application/json").timeout(10, TimeUnit.SECONDS)
|
||||||
|
.method(HttpMethod.GET);
|
||||||
|
return doRequest(request, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContentResponse doPut(String endpoint, @Nullable Map<String, String> parameters, String body)
|
||||||
|
throws CommunicationException, LoginException {
|
||||||
|
LoginInfo login = login();
|
||||||
|
Request request = httpClient.newRequest(config.getBaseUri()).path(endpoint).param(PARAM_KEY, login.getKey())
|
||||||
|
.agent(USER_AGENT).header(HttpHeader.CONTENT_TYPE, "application/json").timeout(10, TimeUnit.SECONDS)
|
||||||
|
.method(HttpMethod.PUT).content(new StringContentProvider(body), "application/json");
|
||||||
|
return doRequest(request, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContentResponse doRequest(Request request, @Nullable Map<String, String> parameters)
|
||||||
|
throws CommunicationException {
|
||||||
|
try {
|
||||||
|
if (parameters != null) {
|
||||||
|
for (String key : parameters.keySet()) {
|
||||||
|
request.param(key, parameters.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addCookiesToRequest(request);
|
||||||
|
logger.debug("SleepIQ: doPut: request url={}", request.getURI());
|
||||||
|
ContentResponse response = request.send();
|
||||||
|
logger.trace("SleepIQ: doPut: status={} response={}", response.getStatus(), response.getContentAsString());
|
||||||
|
return response;
|
||||||
|
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||||
|
logger.debug("SleepIQ: doPut: Exception message={}", e.getMessage(), e);
|
||||||
|
throw new CommunicationException("Communication error while accessing API: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCookiesToRequest(Request request) {
|
||||||
|
cookieStore.get(config.getBaseUri()).forEach(cookie -> {
|
||||||
|
request.cookie(cookie);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUnauthorized(ContentResponse response) {
|
||||||
|
return response.getStatus() == HttpStatus.Code.UNAUTHORIZED.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNotOk(ContentResponse response) {
|
||||||
|
return response.getStatus() != HttpStatus.Code.OK.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void resetLogin() {
|
||||||
|
logger.debug("SleepIQ: resetLogin: Set loginInfo=null to force login on next transaction");
|
||||||
|
loginInfo = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl.typeadapters;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract type adapter for jsr310 date-time types.
|
||||||
|
*
|
||||||
|
* @author Christophe Bornet - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
abstract class DateTimeTypeAdapter<T> extends TemporalTypeAdapter<T> {
|
||||||
|
|
||||||
|
DateTimeTypeAdapter(Function<String, T> parseFunction) {
|
||||||
|
super(parseFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String preProcess(String in) {
|
||||||
|
if (in.endsWith("+0000")) {
|
||||||
|
return in.substring(0, in.length() - 5) + "Z";
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl.typeadapters;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SideTypeAdapter} converts the Side enum to the format expected by the sleepiq API.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class SideTypeAdapter implements JsonDeserializer<Side>, JsonSerializer<Side> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Side side, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(side.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Side deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2)
|
||||||
|
throws JsonParseException {
|
||||||
|
int key = element.getAsInt();
|
||||||
|
return Side.forValue(key);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl.typeadapters;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepNumberRequest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepNumberRequestAdapter} serializes the request to set the sleep number.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class SleepNumberRequestAdapter implements JsonSerializer<SleepNumberRequest> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(SleepNumberRequest src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
// Sleep number must be >= 5 and <= 100, and be a multiple of 5
|
||||||
|
int sleepNumber = src.getSleepNumber();
|
||||||
|
sleepNumber = Math.min(100, sleepNumber);
|
||||||
|
sleepNumber = Math.max(5, sleepNumber);
|
||||||
|
sleepNumber = 5 * (int) (Math.round(sleepNumber / 5.0));
|
||||||
|
|
||||||
|
JsonObject obj = new JsonObject();
|
||||||
|
obj.addProperty("bedId", src.getBedId());
|
||||||
|
obj.addProperty("sleepNumber", sleepNumber);
|
||||||
|
obj.addProperty("side", src.getSide().equals(Side.LEFT) ? "L" : "R");
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,24 @@
|
||||||
/*
|
/**
|
||||||
* Copyright (C) 2016 Gson Type Adapter Authors.
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
package org.openhab.binding.sleepiq.internal.api.impl.typeadapters;
|
||||||
/*
|
|
||||||
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
|
|
||||||
* and repackaged to avoid the default package.
|
|
||||||
*/
|
|
||||||
package org.openhab.binding.sleepiq.api.impl.typeadapters;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.gson.TypeAdapter;
|
import com.google.gson.TypeAdapter;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.google.gson.stream.JsonToken;
|
import com.google.gson.stream.JsonToken;
|
||||||
|
@ -32,8 +27,9 @@ import com.google.gson.stream.JsonWriter;
|
||||||
/**
|
/**
|
||||||
* Abstract type adapter for jsr310 date-time types.
|
* Abstract type adapter for jsr310 date-time types.
|
||||||
*
|
*
|
||||||
* @author Christophe Bornet
|
* @author Christophe Bornet - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
abstract class TemporalTypeAdapter<T> extends TypeAdapter<T> {
|
abstract class TemporalTypeAdapter<T> extends TypeAdapter<T> {
|
||||||
|
|
||||||
Function<String, T> parseFunction;
|
Function<String, T> parseFunction;
|
||||||
|
@ -44,7 +40,7 @@ abstract class TemporalTypeAdapter<T> extends TypeAdapter<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JsonWriter out, T value) throws IOException {
|
public void write(JsonWriter out, @Nullable T value) throws IOException {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.nullValue();
|
out.nullValue();
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,7 +49,7 @@ abstract class TemporalTypeAdapter<T> extends TypeAdapter<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T read(JsonReader in) throws IOException {
|
public @Nullable T read(JsonReader in) throws IOException {
|
||||||
if (in.peek() == JsonToken.NULL) {
|
if (in.peek() == JsonToken.NULL) {
|
||||||
in.nextNull();
|
in.nextNull();
|
||||||
return null;
|
return null;
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl.typeadapters;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.TimeSince;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link TimeSinceTypeAdapter} handles the parsing of the TimeSince.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class TimeSinceTypeAdapter extends TemporalTypeAdapter<TimeSince> {
|
||||||
|
public TimeSinceTypeAdapter() {
|
||||||
|
super(TimeSince::parse);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.internal.api.impl.typeadapters;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type adapter for jsr310 {@link ZonedDateTime} class.
|
||||||
|
*
|
||||||
|
* @author Christophe Bornet - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class ZonedDateTimeTypeAdapter extends DateTimeTypeAdapter<ZonedDateTime> {
|
||||||
|
|
||||||
|
public ZonedDateTimeTypeAdapter() {
|
||||||
|
super(ZonedDateTime::parse);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,13 +12,17 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.internal.config;
|
package org.openhab.binding.sleepiq.internal.config;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration class for a SleepIQ bed.
|
* Configuration class for a SleepIQ bed.
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer - Initial contribution
|
* @author Gregory Moyer - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SleepIQBedConfiguration {
|
public class SleepIQBedConfiguration {
|
||||||
public static final String BED_ID = "bedId";
|
public static final String BED_ID = "bedId";
|
||||||
|
|
||||||
public String bedId;
|
public @Nullable String bedId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
package org.openhab.binding.sleepiq.internal.discovery;
|
package org.openhab.binding.sleepiq.internal.discovery;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.sleepiq.internal.SleepIQBindingConstants;
|
import org.openhab.binding.sleepiq.internal.SleepIQBindingConstants;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Bed;
|
||||||
import org.openhab.binding.sleepiq.internal.config.SleepIQBedConfiguration;
|
import org.openhab.binding.sleepiq.internal.config.SleepIQBedConfiguration;
|
||||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQCloudHandler;
|
import org.openhab.binding.sleepiq.internal.handler.SleepIQCloudHandler;
|
||||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQDualBedHandler;
|
import org.openhab.binding.sleepiq.internal.handler.SleepIQDualBedHandler;
|
||||||
|
@ -33,6 +35,7 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer - Initial contribution
|
* @author Gregory Moyer - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SleepIQBedDiscoveryService extends AbstractDiscoveryService {
|
public class SleepIQBedDiscoveryService extends AbstractDiscoveryService {
|
||||||
private static final int TIMEOUT = 60;
|
private static final int TIMEOUT = 60;
|
||||||
|
|
||||||
|
@ -59,8 +62,9 @@ public class SleepIQBedDiscoveryService extends AbstractDiscoveryService {
|
||||||
@Override
|
@Override
|
||||||
protected void startScan() {
|
protected void startScan() {
|
||||||
logger.debug("Starting scan for new beds");
|
logger.debug("Starting scan for new beds");
|
||||||
|
List<Bed> beds = cloudHandler.getBeds();
|
||||||
for (Bed bed : cloudHandler.getBeds()) {
|
if (beds != null) {
|
||||||
|
for (Bed bed : beds) {
|
||||||
// only dual chamber beds are supported currently
|
// only dual chamber beds are supported currently
|
||||||
if (!bed.isDualSleep()) {
|
if (!bed.isDualSleep()) {
|
||||||
logger.info("Found a bed that is not dual chamber - currently unsupported");
|
logger.info("Found a bed that is not dual chamber - currently unsupported");
|
||||||
|
@ -77,7 +81,6 @@ public class SleepIQBedDiscoveryService extends AbstractDiscoveryService {
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("New bed found with MAC address {}", bed.getMacAddress());
|
logger.debug("New bed found with MAC address {}", bed.getMacAddress());
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
Map<String, Object> properties = (Map) cloudHandler.updateProperties(bed, new HashMap<>());
|
Map<String, Object> properties = (Map) cloudHandler.updateProperties(bed, new HashMap<>());
|
||||||
properties.put(SleepIQBedConfiguration.BED_ID, bed.getBedId());
|
properties.put(SleepIQBedConfiguration.BED_ID, bed.getBedId());
|
||||||
|
@ -86,7 +89,7 @@ public class SleepIQBedDiscoveryService extends AbstractDiscoveryService {
|
||||||
.withBridge(bridgeUID).withLabel(bed.getName() + " - " + bed.getModel()).build();
|
.withBridge(bridgeUID).withLabel(bed.getName() + " - " + bed.getModel()).build();
|
||||||
thingDiscovered(discoveryResult);
|
thingDiscovered(discoveryResult);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
stopScan();
|
stopScan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,17 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.internal.handler;
|
package org.openhab.binding.sleepiq.internal.handler;
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.SleepIQ;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.sleepiq.api.model.BedStatus;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Sleeper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link BedStatusListener} is notified when a chamber is updated.
|
* The {@link BedStatusListener} is notified when a chamber is updated.
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer - Initial contribution
|
* @author Gregory Moyer - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public interface BedStatusListener {
|
public interface BedStatusListener {
|
||||||
/**
|
/**
|
||||||
* This method will be called whenever a new bed status is received by the cloud handler.
|
* This method will be called whenever a new bed status is received by the cloud handler.
|
||||||
|
@ -27,5 +30,7 @@ public interface BedStatusListener {
|
||||||
* @param cloud the cloud service that can be used to gather additional information
|
* @param cloud the cloud service that can be used to gather additional information
|
||||||
* @param status the status returned from the cloud service
|
* @param status the status returned from the cloud service
|
||||||
*/
|
*/
|
||||||
public void onBedStateChanged(SleepIQ cloud, BedStatus status);
|
public void onBedStateChanged(BedStatus status);
|
||||||
|
|
||||||
|
public void onSleeperChanged(@Nullable Sleeper sleeper);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,19 +25,24 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.sleepiq.api.Configuration;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.openhab.binding.sleepiq.api.LoginException;
|
|
||||||
import org.openhab.binding.sleepiq.api.SleepIQ;
|
|
||||||
import org.openhab.binding.sleepiq.api.UnauthorizedException;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.BedStatus;
|
|
||||||
import org.openhab.binding.sleepiq.api.model.FamilyStatus;
|
|
||||||
import org.openhab.binding.sleepiq.internal.SleepIQBindingConstants;
|
import org.openhab.binding.sleepiq.internal.SleepIQBindingConstants;
|
||||||
import org.openhab.binding.sleepiq.internal.SleepIQConfigStatusMessage;
|
import org.openhab.binding.sleepiq.internal.SleepIQConfigStatusMessage;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.Configuration;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.LoginException;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.SleepIQ;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.SleepIQException;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.UnauthorizedException;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Bed;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.FamilyStatusResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepDataResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Sleeper;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.SleepDataInterval;
|
||||||
import org.openhab.binding.sleepiq.internal.config.SleepIQCloudConfiguration;
|
import org.openhab.binding.sleepiq.internal.config.SleepIQCloudConfiguration;
|
||||||
import org.openhab.core.cache.ExpiringCache;
|
|
||||||
import org.openhab.core.config.core.status.ConfigStatusMessage;
|
import org.openhab.core.config.core.status.ConfigStatusMessage;
|
||||||
import org.openhab.core.thing.Bridge;
|
import org.openhab.core.thing.Bridge;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
@ -56,124 +61,82 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer - Initial contribution
|
* @author Gregory Moyer - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
|
public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
|
||||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections.singleton(THING_TYPE_CLOUD);
|
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections.singleton(THING_TYPE_CLOUD);
|
||||||
|
|
||||||
|
private static final int SLEEPER_POLLING_INTERVAL_HOURS = 12;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(SleepIQCloudHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(SleepIQCloudHandler.class);
|
||||||
|
|
||||||
|
private final HttpClient httpClient;
|
||||||
|
|
||||||
private final List<BedStatusListener> bedStatusListeners = new CopyOnWriteArrayList<>();
|
private final List<BedStatusListener> bedStatusListeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
private ExpiringCache<FamilyStatus> statusCache;
|
private @Nullable ScheduledFuture<?> statusPollingJob;
|
||||||
|
private @Nullable ScheduledFuture<?> sleeperPollingJob;
|
||||||
|
|
||||||
private ScheduledFuture<?> pollingJob;
|
private @Nullable SleepIQ cloud;
|
||||||
|
|
||||||
private SleepIQ cloud;
|
private @Nullable List<Sleeper> sleepers;
|
||||||
|
|
||||||
private ClientBuilder clientBuilder;
|
public SleepIQCloudHandler(final Bridge bridge, HttpClient httpClient) {
|
||||||
|
|
||||||
public SleepIQCloudHandler(final Bridge bridge, ClientBuilder clientBuilder) {
|
|
||||||
super(bridge);
|
super(bridge);
|
||||||
this.clientBuilder = clientBuilder;
|
this.httpClient = httpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
scheduler.execute(() -> {
|
||||||
try {
|
try {
|
||||||
logger.debug("Configuring bed status cache");
|
|
||||||
statusCache = new ExpiringCache<>(TimeUnit.SECONDS.toMillis(getPollingInterval() / 2),
|
|
||||||
() -> cloud.getFamilyStatus());
|
|
||||||
|
|
||||||
createCloudConnection();
|
createCloudConnection();
|
||||||
|
|
||||||
logger.debug("Setting SleepIQ cloud online");
|
|
||||||
updateListenerManagement();
|
updateListenerManagement();
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
} catch (UnauthorizedException e) {
|
} catch (UnauthorizedException e) {
|
||||||
logger.debug("SleepIQ cloud authentication failed", e);
|
logger.debug("CloudHandler: SleepIQ cloud authentication failed", e);
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Invalid SleepIQ credentials");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Invalid SleepIQ credentials");
|
||||||
} catch (LoginException e) {
|
} catch (LoginException e) {
|
||||||
logger.debug("SleepIQ cloud login failed", e);
|
logger.debug("CloudHandler: SleepIQ cloud login failed", e);
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
"SleepIQ cloud login failed: " + e.getMessage());
|
"SleepIQ cloud login failed: " + e.getMessage());
|
||||||
} catch (Exception e) {
|
|
||||||
logger.debug("Unexpected error while communicating with SleepIQ cloud", e);
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
|
||||||
"Unable to connect to SleepIQ cloud: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new SleepIQ cloud service connection. If a connection already exists, it will be lost.
|
|
||||||
*
|
|
||||||
* @param clientBuilder2
|
|
||||||
*
|
|
||||||
* @throws LoginException if there is an error while authenticating to the service
|
|
||||||
*/
|
|
||||||
private void createCloudConnection() throws LoginException {
|
|
||||||
logger.debug("Reading SleepIQ cloud binding configuration");
|
|
||||||
SleepIQCloudConfiguration bindingConfig = getConfigAs(SleepIQCloudConfiguration.class);
|
|
||||||
|
|
||||||
logger.debug("Creating SleepIQ client");
|
|
||||||
Configuration cloudConfig = new Configuration().withUsername(bindingConfig.username)
|
|
||||||
.withPassword(bindingConfig.password).withLogging(logger.isDebugEnabled());
|
|
||||||
cloud = SleepIQ.create(cloudConfig, clientBuilder);
|
|
||||||
|
|
||||||
logger.debug("Authenticating at the SleepIQ cloud service");
|
|
||||||
cloud.login();
|
|
||||||
|
|
||||||
logger.info("Successfully authenticated at the SleepIQ cloud service");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void dispose() {
|
public synchronized void dispose() {
|
||||||
logger.debug("Disposing SleepIQ cloud handler");
|
stopSleeperPollingJob();
|
||||||
|
stopStatusPollingJob();
|
||||||
if (pollingJob != null && !pollingJob.isCancelled()) {
|
if (cloud != null) {
|
||||||
pollingJob.cancel(true);
|
cloud.shutdown();
|
||||||
pollingJob = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCommand(final ChannelUID channelUID, final Command command) {
|
||||||
|
// cloud handler has no channels
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start or stop a background polling job to look for bed status updates based on whether or not there are any
|
* Validate the config from openHAB
|
||||||
* listeners to notify.
|
|
||||||
*/
|
|
||||||
private synchronized void updateListenerManagement() {
|
|
||||||
if (!bedStatusListeners.isEmpty() && (pollingJob == null || pollingJob.isCancelled())) {
|
|
||||||
int pollingInterval = getPollingInterval();
|
|
||||||
pollingJob = scheduler.scheduleWithFixedDelay(this::refreshBedStatus, pollingInterval, pollingInterval,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} else if (bedStatusListeners.isEmpty() && pollingJob != null && !pollingJob.isCancelled()) {
|
|
||||||
pollingJob.cancel(true);
|
|
||||||
pollingJob = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the polling interval for updating bed status.
|
|
||||||
*
|
*
|
||||||
* @return the polling interval in seconds
|
* @return validity status of config parameters
|
||||||
*/
|
*/
|
||||||
private int getPollingInterval() {
|
@Override
|
||||||
return getConfigAs(SleepIQCloudConfiguration.class).pollingInterval;
|
public Collection<ConfigStatusMessage> getConfigStatus() {
|
||||||
|
Collection<ConfigStatusMessage> configStatusMessages = new ArrayList<>();
|
||||||
|
SleepIQCloudConfiguration config = getConfigAs(SleepIQCloudConfiguration.class);
|
||||||
|
String username = config.username;
|
||||||
|
String password = config.password;
|
||||||
|
if (username.isBlank()) {
|
||||||
|
configStatusMessages.add(ConfigStatusMessage.Builder.error(USERNAME)
|
||||||
|
.withMessageKeySuffix(SleepIQConfigStatusMessage.USERNAME_MISSING).withArguments(USERNAME).build());
|
||||||
}
|
}
|
||||||
|
if (password.isBlank()) {
|
||||||
/**
|
configStatusMessages.add(ConfigStatusMessage.Builder.error(PASSWORD)
|
||||||
* Retrieve the latest status on all beds and update all registered listeners.
|
.withMessageKeySuffix(SleepIQConfigStatusMessage.PASSWORD_MISSING).withArguments(PASSWORD).build());
|
||||||
*/
|
|
||||||
public void refreshBedStatus() {
|
|
||||||
try {
|
|
||||||
FamilyStatus status = statusCache.getValue();
|
|
||||||
updateStatus(ThingStatus.ONLINE);
|
|
||||||
|
|
||||||
for (BedStatus bedStatus : status.getBeds()) {
|
|
||||||
bedStatusListeners.stream().forEach(l -> l.onBedStateChanged(cloud, bedStatus));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.debug("Unexpected error while communicating with SleepIQ cloud", e);
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
|
||||||
"Unable to connect to SleepIQ cloud: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
return configStatusMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,13 +145,12 @@ public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
|
||||||
* @param listener the listener to register
|
* @param listener the listener to register
|
||||||
*/
|
*/
|
||||||
public void registerBedStatusListener(final BedStatusListener listener) {
|
public void registerBedStatusListener(final BedStatusListener listener) {
|
||||||
if (listener == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bedStatusListeners.add(listener);
|
bedStatusListeners.add(listener);
|
||||||
|
scheduler.execute(() -> {
|
||||||
|
refreshSleepers();
|
||||||
refreshBedStatus();
|
refreshBedStatus();
|
||||||
updateListenerManagement();
|
updateListenerManagement();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,61 +165,103 @@ public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
|
||||||
if (result) {
|
if (result) {
|
||||||
updateListenerManagement();
|
updateListenerManagement();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleCommand(final ChannelUID channelUID, final Command command) {
|
|
||||||
// cloud handler has no channels
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<ConfigStatusMessage> getConfigStatus() {
|
|
||||||
Collection<ConfigStatusMessage> configStatusMessages = new ArrayList<>();
|
|
||||||
|
|
||||||
SleepIQCloudConfiguration config = getConfigAs(SleepIQCloudConfiguration.class);
|
|
||||||
String username = config.username;
|
|
||||||
String password = config.password;
|
|
||||||
|
|
||||||
if (username.isEmpty()) {
|
|
||||||
configStatusMessages.add(ConfigStatusMessage.Builder.error(USERNAME)
|
|
||||||
.withMessageKeySuffix(SleepIQConfigStatusMessage.USERNAME_MISSING).withArguments(USERNAME).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.isEmpty()) {
|
|
||||||
configStatusMessages.add(ConfigStatusMessage.Builder.error(PASSWORD)
|
|
||||||
.withMessageKeySuffix(SleepIQConfigStatusMessage.PASSWORD_MISSING).withArguments(PASSWORD).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
return configStatusMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of all beds registered to the cloud service account.
|
* Get a list of all beds registered to the cloud service account.
|
||||||
*
|
*
|
||||||
* @return the list of beds (never <code>null</code>)
|
* @return the list of beds or null if unable to get list
|
||||||
*/
|
*/
|
||||||
public List<Bed> getBeds() {
|
public @Nullable List<Bed> getBeds() {
|
||||||
|
try {
|
||||||
return cloud.getBeds();
|
return cloud.getBeds();
|
||||||
|
} catch (SleepIQException e) {
|
||||||
|
logger.debug("CloudHandler: Exception getting list of beds", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link Bed} corresponding to the given identifier.
|
* Get the bed corresponding to the given bed id
|
||||||
*
|
*
|
||||||
* @param bedId the bed identifier
|
* @param bedId the bed identifier
|
||||||
* @return the identified {@link Bed} or <code>null</code> if no such bed exists
|
* @return the identified {@link Bed} or <code>null</code> if no such bed exists
|
||||||
*/
|
*/
|
||||||
public Bed getBed(final String bedId) {
|
public @Nullable Bed getBed(final @Nullable String bedId) {
|
||||||
for (Bed bed : getBeds()) {
|
logger.debug("CloudHandler: Get bed object for bedId={}", bedId);
|
||||||
|
if (bedId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<Bed> beds = getBeds();
|
||||||
|
if (beds != null) {
|
||||||
|
for (Bed bed : beds) {
|
||||||
if (bedId.equals(bed.getBedId())) {
|
if (bedId.equals(bed.getBedId())) {
|
||||||
return bed;
|
return bed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sleeper associated with the bedId and side
|
||||||
|
*
|
||||||
|
* @param bedId the bed identifier
|
||||||
|
* @param side the side of the bed
|
||||||
|
* @return the sleeper or null if sleeper not found
|
||||||
|
*/
|
||||||
|
public @Nullable Sleeper getSleeper(@Nullable String bedId, Side side) {
|
||||||
|
logger.debug("CloudHandler: Get sleeper object for bedId={}, side={}", bedId, side);
|
||||||
|
if (bedId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<Sleeper> localSleepers = sleepers;
|
||||||
|
if (localSleepers != null) {
|
||||||
|
for (Sleeper sleeper : localSleepers) {
|
||||||
|
if (bedId.equals(sleeper.getBedId()) && side.equals(sleeper.getSide())) {
|
||||||
|
return sleeper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sleep number of the specified chamber
|
||||||
|
*
|
||||||
|
* @param bedId the bed identifier
|
||||||
|
* @param sleepNumber the sleep number multiple of 5 between 5 and 100
|
||||||
|
* @param side the chamber to set
|
||||||
|
*/
|
||||||
|
public void setSleepNumber(@Nullable String bedId, Side side, int sleepNumber) {
|
||||||
|
if (bedId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cloud.setSleepNumber(bedId, side, sleepNumber);
|
||||||
|
} catch (SleepIQException e) {
|
||||||
|
logger.debug("CloudHandler: Exception setting sleep number of bed={}", bedId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the pause mode of the specified bed
|
||||||
|
*
|
||||||
|
* @param bedId the bed identifier
|
||||||
|
* @param mode turn pause mode on or off
|
||||||
|
*/
|
||||||
|
public void setPauseMode(@Nullable String bedId, boolean mode) {
|
||||||
|
if (bedId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cloud.setPauseMode(bedId, mode);
|
||||||
|
} catch (SleepIQException e) {
|
||||||
|
logger.debug("CloudHandler: Exception setting pause mode of bed={}", bedId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the given properties with attributes of the given bed. If no properties are given, a new map will be
|
* Update the given properties with attributes of the given bed. If no properties are given, a new map will be
|
||||||
* created.
|
* created.
|
||||||
|
@ -266,8 +270,9 @@ public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
|
||||||
* @param properties the properties to update (this may be <code>null</code>)
|
* @param properties the properties to update (this may be <code>null</code>)
|
||||||
* @return the given map (or a new map if no map was given) with updated/set properties from the supplied bed
|
* @return the given map (or a new map if no map was given) with updated/set properties from the supplied bed
|
||||||
*/
|
*/
|
||||||
public Map<String, String> updateProperties(final Bed bed, Map<String, String> properties) {
|
public Map<String, String> updateProperties(final @Nullable Bed bed, Map<String, String> properties) {
|
||||||
if (bed != null) {
|
if (bed != null) {
|
||||||
|
logger.debug("CloudHandler: Updating bed properties for bed={}", bed.getBedId());
|
||||||
properties.put(Thing.PROPERTY_MODEL_ID, bed.getModel());
|
properties.put(Thing.PROPERTY_MODEL_ID, bed.getModel());
|
||||||
properties.put(SleepIQBindingConstants.PROPERTY_BASE, bed.getBase());
|
properties.put(SleepIQBindingConstants.PROPERTY_BASE, bed.getBase());
|
||||||
if (bed.isKidsBed() != null) {
|
if (bed.isKidsBed() != null) {
|
||||||
|
@ -281,7 +286,146 @@ public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
|
||||||
properties.put(SleepIQBindingConstants.PROPERTY_SIZE, bed.getSize());
|
properties.put(SleepIQBindingConstants.PROPERTY_SIZE, bed.getSize());
|
||||||
properties.put(SleepIQBindingConstants.PROPERTY_SKU, bed.getSku());
|
properties.put(SleepIQBindingConstants.PROPERTY_SKU, bed.getSku());
|
||||||
}
|
}
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the latest status on all beds and update all registered listeners
|
||||||
|
* with bed status, sleepers and sleep data.
|
||||||
|
*/
|
||||||
|
private void refreshBedStatus() {
|
||||||
|
logger.debug("CloudHandler: Refreshing BED STATUS, updating chanels with status, sleepers, and sleep data");
|
||||||
|
try {
|
||||||
|
FamilyStatusResponse familyStatus = cloud.getFamilyStatus();
|
||||||
|
if (familyStatus != null && familyStatus.getBeds() != null) {
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
for (BedStatus bedStatus : familyStatus.getBeds()) {
|
||||||
|
logger.debug("CloudHandler: Informing listeners with bed status for bedId={}",
|
||||||
|
bedStatus.getBedId());
|
||||||
|
bedStatusListeners.stream().forEach(l -> l.onBedStateChanged(bedStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Sleeper> localSleepers = sleepers;
|
||||||
|
if (localSleepers != null) {
|
||||||
|
for (Sleeper sleeper : localSleepers) {
|
||||||
|
logger.debug("CloudHandler: Informing listeners with sleepers for sleeperId={}",
|
||||||
|
sleeper.getSleeperId());
|
||||||
|
bedStatusListeners.stream().forEach(l -> l.onSleeperChanged(sleeper));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (SleepIQException e) {
|
||||||
|
logger.debug("CloudHandler: Exception refreshing bed status", e);
|
||||||
|
}
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Unable to connect to SleepIQ cloud");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the list of sleepers
|
||||||
|
*/
|
||||||
|
private void refreshSleepers() {
|
||||||
|
logger.debug("CloudHandler: Refreshing SLEEPERS");
|
||||||
|
try {
|
||||||
|
sleepers = cloud.getSleepers();
|
||||||
|
} catch (SleepIQException e) {
|
||||||
|
logger.debug("CloudHandler: Exception refreshing list of sleepers", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable SleepDataResponse getDailySleepData(String sleeperId) {
|
||||||
|
return getSleepData(sleeperId, SleepDataInterval.DAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable SleepDataResponse getMonthlySleepData(String sleeperId) {
|
||||||
|
return getSleepData(sleeperId, SleepDataInterval.MONTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable SleepDataResponse getSleepData(String sleeperId, SleepDataInterval interval) {
|
||||||
|
try {
|
||||||
|
return cloud.getSleepData(sleeperId, interval);
|
||||||
|
} catch (SleepIQException e) {
|
||||||
|
logger.debug("CloudHandler: Exception getting sleep data for sleeperId={}", sleeperId, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SleepIQ cloud service connection. If a connection already exists, it will be lost.
|
||||||
|
*
|
||||||
|
* @throws LoginException if there is an error while authenticating to the service
|
||||||
|
*/
|
||||||
|
private void createCloudConnection() throws LoginException {
|
||||||
|
SleepIQCloudConfiguration bindingConfig = getConfigAs(SleepIQCloudConfiguration.class);
|
||||||
|
Configuration cloudConfig = new Configuration().withUsername(bindingConfig.username)
|
||||||
|
.withPassword(bindingConfig.password).withLogging(logger.isTraceEnabled());
|
||||||
|
logger.debug("CloudHandler: Authenticating at the SleepIQ cloud service");
|
||||||
|
cloud = SleepIQ.create(cloudConfig, httpClient);
|
||||||
|
cloud.login();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start or stop the background polling jobs
|
||||||
|
*/
|
||||||
|
private synchronized void updateListenerManagement() {
|
||||||
|
startSleeperPollingJob();
|
||||||
|
startStatusPollingJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start or stop the bed status polling job
|
||||||
|
*/
|
||||||
|
private void startStatusPollingJob() {
|
||||||
|
ScheduledFuture<?> localPollingJob = statusPollingJob;
|
||||||
|
if (!bedStatusListeners.isEmpty() && (localPollingJob == null || localPollingJob.isCancelled())) {
|
||||||
|
int pollingInterval = getStatusPollingIntervalSeconds();
|
||||||
|
logger.debug("CloudHandler: Scheduling bed status polling job every {} seconds", pollingInterval);
|
||||||
|
statusPollingJob = scheduler.scheduleWithFixedDelay(this::refreshBedStatus, pollingInterval,
|
||||||
|
pollingInterval, TimeUnit.SECONDS);
|
||||||
|
} else if (bedStatusListeners.isEmpty()) {
|
||||||
|
stopStatusPollingJob();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the bed status polling job
|
||||||
|
*/
|
||||||
|
private void stopStatusPollingJob() {
|
||||||
|
ScheduledFuture<?> localPollingJob = statusPollingJob;
|
||||||
|
if (localPollingJob != null) {
|
||||||
|
logger.debug("CloudHandler: Canceling bed status polling job");
|
||||||
|
localPollingJob.cancel(true);
|
||||||
|
statusPollingJob = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getStatusPollingIntervalSeconds() {
|
||||||
|
return getConfigAs(SleepIQCloudConfiguration.class).pollingInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start or stop the sleeper polling job
|
||||||
|
*/
|
||||||
|
private void startSleeperPollingJob() {
|
||||||
|
ScheduledFuture<?> localJob = sleeperPollingJob;
|
||||||
|
if (!bedStatusListeners.isEmpty() && (localJob == null || localJob.isCancelled())) {
|
||||||
|
logger.debug("CloudHandler: Scheduling sleeper polling job every {} hours", SLEEPER_POLLING_INTERVAL_HOURS);
|
||||||
|
sleeperPollingJob = scheduler.scheduleWithFixedDelay(this::refreshSleepers, SLEEPER_POLLING_INTERVAL_HOURS,
|
||||||
|
SLEEPER_POLLING_INTERVAL_HOURS, TimeUnit.HOURS);
|
||||||
|
} else if (bedStatusListeners.isEmpty()) {
|
||||||
|
stopSleeperPollingJob();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the sleeper polling job
|
||||||
|
*/
|
||||||
|
private void stopSleeperPollingJob() {
|
||||||
|
ScheduledFuture<?> localJob = sleeperPollingJob;
|
||||||
|
if (localJob != null && !localJob.isCancelled()) {
|
||||||
|
logger.debug("CloudHandler: Canceling sleeper polling job");
|
||||||
|
localJob.cancel(true);
|
||||||
|
sleeperPollingJob = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,22 @@ import static org.openhab.binding.sleepiq.internal.SleepIQBindingConstants.*;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.openhab.binding.sleepiq.api.SleepIQ;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.sleepiq.api.model.BedSideStatus;
|
import org.openhab.binding.sleepiq.internal.api.dto.Bed;
|
||||||
import org.openhab.binding.sleepiq.api.model.BedStatus;
|
import org.openhab.binding.sleepiq.internal.api.dto.BedSideStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepDataResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Sleeper;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
import org.openhab.binding.sleepiq.internal.config.SleepIQBedConfiguration;
|
import org.openhab.binding.sleepiq.internal.config.SleepIQBedConfiguration;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
import org.openhab.core.library.types.DecimalType;
|
||||||
import org.openhab.core.library.types.OnOffType;
|
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.types.StringType;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
import org.openhab.core.thing.Bridge;
|
import org.openhab.core.thing.Bridge;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
|
@ -33,10 +40,10 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.ThingStatusInfo;
|
import org.openhab.core.thing.ThingStatusInfo;
|
||||||
import org.openhab.core.thing.ThingTypeUID;
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
import org.openhab.core.thing.binding.BridgeHandler;
|
|
||||||
import org.openhab.core.thing.binding.ThingHandler;
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.openhab.core.types.RefreshType;
|
import org.openhab.core.types.RefreshType;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -45,12 +52,20 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Gregory Moyer - Initial contribution
|
* @author Gregory Moyer - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SleepIQDualBedHandler extends BaseThingHandler implements BedStatusListener {
|
public class SleepIQDualBedHandler extends BaseThingHandler implements BedStatusListener {
|
||||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections.singleton(THING_TYPE_DUAL_BED);
|
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections.singleton(THING_TYPE_DUAL_BED);
|
||||||
|
|
||||||
|
private static final long GET_SLEEP_DATA_DELAY_MINUTES = 5;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(SleepIQDualBedHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(SleepIQDualBedHandler.class);
|
||||||
|
|
||||||
private volatile String bedId;
|
private volatile @Nullable String bedId;
|
||||||
|
|
||||||
|
private @Nullable Sleeper sleeperLeft;
|
||||||
|
private @Nullable Sleeper sleeperRight;
|
||||||
|
|
||||||
|
private @Nullable BedStatus previousStatus;
|
||||||
|
|
||||||
public SleepIQDualBedHandler(final Thing thing) {
|
public SleepIQDualBedHandler(final Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
|
@ -58,80 +73,113 @@ public class SleepIQDualBedHandler extends BaseThingHandler implements BedStatus
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
logger.debug("Verifying SleepIQ cloud/bridge configuration");
|
|
||||||
|
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
if (bridge == null) {
|
if (bridge == null) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
"No cloud service bridge has been configured");
|
"No cloud service bridge has been configured");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThingHandler handler = bridge.getHandler();
|
ThingHandler handler = bridge.getHandler();
|
||||||
if (!(handler instanceof SleepIQCloudHandler)) {
|
if (!(handler instanceof SleepIQCloudHandler)) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Incorrect bridge thing found");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Incorrect bridge thing found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Reading SleepIQ bed binding configuration");
|
|
||||||
bedId = getConfigAs(SleepIQBedConfiguration.class).bedId;
|
bedId = getConfigAs(SleepIQBedConfiguration.class).bedId;
|
||||||
|
if (bedId == null) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"Bed id not found in configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug("Registering SleepIQ bed status listener");
|
logger.debug("BedHandler: Registering SleepIQ bed status listener for bedId={}", bedId);
|
||||||
SleepIQCloudHandler cloudHandler = (SleepIQCloudHandler) handler;
|
SleepIQCloudHandler cloudHandler = (SleepIQCloudHandler) handler;
|
||||||
cloudHandler.registerBedStatusListener(this);
|
cloudHandler.registerBedStatusListener(this);
|
||||||
|
|
||||||
if (ThingStatus.ONLINE != bridge.getStatus()) {
|
if (ThingStatus.ONLINE != bridge.getStatus()) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||||
} else {
|
} else {
|
||||||
updateProperties();
|
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
scheduler.execute(() -> {
|
||||||
|
updateProperties();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
SleepIQCloudHandler cloudHandler = getCloudHandler();
|
||||||
|
if (cloudHandler != null) {
|
||||||
|
cloudHandler.unregisterBedStatusListener(this);
|
||||||
|
}
|
||||||
|
bedId = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||||
super.bridgeStatusChanged(bridgeStatusInfo);
|
super.bridgeStatusChanged(bridgeStatusInfo);
|
||||||
|
|
||||||
if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
|
if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
|
||||||
updateProperties();
|
updateProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateProperties() {
|
@Override
|
||||||
logger.debug("Updating SleepIQ bed properties for bed {}", bedId);
|
public void handleCommand(final ChannelUID channelUID, final Command command) {
|
||||||
|
if (command == RefreshType.REFRESH) {
|
||||||
SleepIQCloudHandler cloudHandler = (SleepIQCloudHandler) getBridge().getHandler();
|
// Channels will be refreshed automatically by cloud handler
|
||||||
Bed bed = cloudHandler.getBed(bedId);
|
|
||||||
if (bed == null) {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "No bed found with ID " + bedId);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProperties(cloudHandler.updateProperties(bed, editProperties()));
|
switch (channelUID.getId()) {
|
||||||
|
case CHANNEL_LEFT_SLEEP_NUMBER:
|
||||||
|
case CHANNEL_RIGHT_SLEEP_NUMBER:
|
||||||
|
if (command instanceof DecimalType) {
|
||||||
|
Side side = Side.convertFromGroup(channelUID.getGroupId());
|
||||||
|
logger.debug("BedHandler: Set sleepnumber to {} for bedId={}, side={}", command, bedId, side);
|
||||||
|
SleepIQCloudHandler cloudHandler = getCloudHandler();
|
||||||
|
if (cloudHandler != null) {
|
||||||
|
cloudHandler.setSleepNumber(bedId, side, ((DecimalType) command).intValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CHANNEL_LEFT_PRIVACY_MODE:
|
||||||
|
case CHANNEL_RIGHT_PRIVACY_MODE:
|
||||||
|
if (command instanceof OnOffType) {
|
||||||
|
Side side = Side.convertFromGroup(channelUID.getGroupId());
|
||||||
|
logger.debug("BedHandler: Set sleepnumber to {} for bedId={}, side={}", command, bedId, side);
|
||||||
|
SleepIQCloudHandler cloudHandler = getCloudHandler();
|
||||||
|
if (cloudHandler != null) {
|
||||||
|
cloudHandler.setPauseMode(bedId, command == OnOffType.ON ? true : false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void onSleeperChanged(final @Nullable Sleeper sleeper) {
|
||||||
logger.debug("Disposing bed handler for bed {}", bedId);
|
if (sleeper == null || !sleeper.getBedId().equals(bedId)) {
|
||||||
|
|
||||||
Bridge bridge = getBridge();
|
|
||||||
if (bridge != null) {
|
|
||||||
BridgeHandler bridgeHandler = bridge.getHandler();
|
|
||||||
if (bridgeHandler instanceof SleepIQCloudHandler) {
|
|
||||||
((SleepIQCloudHandler) bridgeHandler).unregisterBedStatusListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bedId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBedStateChanged(final SleepIQ cloud, final BedStatus status) {
|
|
||||||
if (!status.getBedId().equals(bedId)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
logger.debug("BedHandler: Updating sleeper information channels for bed={}, side={}", bedId, sleeper.getSide());
|
||||||
|
|
||||||
|
if (sleeper.getSide().equals(Side.LEFT)) {
|
||||||
|
sleeperLeft = sleeper;
|
||||||
|
updateState(CHANNEL_LEFT_FIRST_NAME, new StringType(sleeper.getFirstName()));
|
||||||
|
updateState(CHANNEL_LEFT_SLEEP_GOAL_MINUTES, new QuantityType<>(sleeper.getSleepGoal(), Units.MINUTE));
|
||||||
|
} else {
|
||||||
|
sleeperRight = sleeper;
|
||||||
|
updateState(CHANNEL_RIGHT_FIRST_NAME, new StringType(sleeper.getFirstName()));
|
||||||
|
updateState(CHANNEL_RIGHT_SLEEP_GOAL_MINUTES, new QuantityType<>(sleeper.getSleepGoal(), Units.MINUTE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBedStateChanged(final @Nullable BedStatus status) {
|
||||||
|
if (status == null || !status.getBedId().equals(bedId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.debug("BedHandler: Updating bed status channels for bed {}", bedId);
|
||||||
|
|
||||||
logger.debug("Updating left side status for bed {}", bedId);
|
|
||||||
BedSideStatus left = status.getLeftSide();
|
BedSideStatus left = status.getLeftSide();
|
||||||
updateState(CHANNEL_LEFT_IN_BED, left.isInBed() ? OnOffType.ON : OnOffType.OFF);
|
updateState(CHANNEL_LEFT_IN_BED, left.isInBed() ? OnOffType.ON : OnOffType.OFF);
|
||||||
updateState(CHANNEL_LEFT_SLEEP_NUMBER, new DecimalType(left.getSleepNumber()));
|
updateState(CHANNEL_LEFT_SLEEP_NUMBER, new DecimalType(left.getSleepNumber()));
|
||||||
|
@ -139,8 +187,10 @@ public class SleepIQDualBedHandler extends BaseThingHandler implements BedStatus
|
||||||
updateState(CHANNEL_LEFT_LAST_LINK, new StringType(left.getLastLink().toString()));
|
updateState(CHANNEL_LEFT_LAST_LINK, new StringType(left.getLastLink().toString()));
|
||||||
updateState(CHANNEL_LEFT_ALERT_ID, new DecimalType(left.getAlertId()));
|
updateState(CHANNEL_LEFT_ALERT_ID, new DecimalType(left.getAlertId()));
|
||||||
updateState(CHANNEL_LEFT_ALERT_DETAILED_MESSAGE, new StringType(left.getAlertDetailedMessage()));
|
updateState(CHANNEL_LEFT_ALERT_DETAILED_MESSAGE, new StringType(left.getAlertDetailedMessage()));
|
||||||
|
if (previousStatus != null) {
|
||||||
|
updateSleepDataChannels(previousStatus.getLeftSide(), left, sleeperLeft);
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug("Updating right side status for bed {}", bedId);
|
|
||||||
BedSideStatus right = status.getRightSide();
|
BedSideStatus right = status.getRightSide();
|
||||||
updateState(CHANNEL_RIGHT_IN_BED, right.isInBed() ? OnOffType.ON : OnOffType.OFF);
|
updateState(CHANNEL_RIGHT_IN_BED, right.isInBed() ? OnOffType.ON : OnOffType.OFF);
|
||||||
updateState(CHANNEL_RIGHT_SLEEP_NUMBER, new DecimalType(right.getSleepNumber()));
|
updateState(CHANNEL_RIGHT_SLEEP_NUMBER, new DecimalType(right.getSleepNumber()));
|
||||||
|
@ -148,15 +198,123 @@ public class SleepIQDualBedHandler extends BaseThingHandler implements BedStatus
|
||||||
updateState(CHANNEL_RIGHT_LAST_LINK, new StringType(right.getLastLink().toString()));
|
updateState(CHANNEL_RIGHT_LAST_LINK, new StringType(right.getLastLink().toString()));
|
||||||
updateState(CHANNEL_RIGHT_ALERT_ID, new DecimalType(right.getAlertId()));
|
updateState(CHANNEL_RIGHT_ALERT_ID, new DecimalType(right.getAlertId()));
|
||||||
updateState(CHANNEL_RIGHT_ALERT_DETAILED_MESSAGE, new StringType(right.getAlertDetailedMessage()));
|
updateState(CHANNEL_RIGHT_ALERT_DETAILED_MESSAGE, new StringType(right.getAlertDetailedMessage()));
|
||||||
|
if (previousStatus != null) {
|
||||||
|
updateSleepDataChannels(previousStatus.getRightSide(), right, sleeperRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
previousStatus = status;
|
||||||
public void handleCommand(final ChannelUID channelUID, final Command command) {
|
}
|
||||||
// all channels are read-only
|
|
||||||
|
|
||||||
if (command == RefreshType.REFRESH) {
|
private void updateSleepDataChannels(BedSideStatus previousSideStatus, BedSideStatus currentSideStatus,
|
||||||
SleepIQCloudHandler cloudHandler = (SleepIQCloudHandler) getBridge().getHandler();
|
@Nullable Sleeper sleeper) {
|
||||||
cloudHandler.refreshBedStatus();
|
if (sleeper == null) {
|
||||||
|
logger.debug("BedHandler: Can't update sleep data channels because sleeper is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (previousSideStatus.isInBed() && !currentSideStatus.isInBed()) {
|
||||||
|
logger.debug("BedHandler: Bed status changed from IN BED to OUT OF BED for {}, side {}", bedId,
|
||||||
|
sleeper.getSide());
|
||||||
|
scheduler.schedule(() -> {
|
||||||
|
updateDailySleepDataChannels(sleeper);
|
||||||
|
updateMonthlySleepDataChannels(sleeper);
|
||||||
|
}, GET_SLEEP_DATA_DELAY_MINUTES, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateDailySleepDataChannels(final @Nullable Sleeper sleeper) {
|
||||||
|
SleepIQCloudHandler cloudHandler = getCloudHandler();
|
||||||
|
if (cloudHandler == null || sleeper == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SleepDataResponse sleepData = cloudHandler.getDailySleepData(sleeper.getSleeperId());
|
||||||
|
if (sleepData == null) {
|
||||||
|
logger.debug("BedHandler: Received no daily sleep data for bedId={}, sleeperId={}", sleeper.getBedId(),
|
||||||
|
sleeper.getSleeperId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("BedHandler: UPDATING DAILY SLEEP DATA CHANNELS for bedId={}, sleeperId={}", sleeper.getBedId(),
|
||||||
|
sleeper.getSleeperId());
|
||||||
|
if (sleepData.getSleepDataDays() == null || sleepData.getSleepDataDays().size() != 1) {
|
||||||
|
if (sleeper.getSide().equals(Side.LEFT)) {
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_SLEEP_IQ, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_AVG_HEART_RATE, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_AVG_RESPIRATION_RATE, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_MESSAGE, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_SLEEP_DURATION_SECONDS, UnDefType.UNDEF);
|
||||||
|
} else {
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_SLEEP_IQ, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_AVG_HEART_RATE, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_AVG_RESPIRATION_RATE, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_MESSAGE, UnDefType.UNDEF);
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_SLEEP_DURATION_SECONDS, UnDefType.UNDEF);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (sleeper.getSide().equals(Side.LEFT)) {
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_SLEEP_IQ, new DecimalType(sleepData.getAverageSleepIQ()));
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_AVG_HEART_RATE, new DecimalType(sleepData.getAverageHeartRate()));
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_AVG_RESPIRATION_RATE,
|
||||||
|
new DecimalType(sleepData.getAverageRespirationRate()));
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_MESSAGE, new StringType(sleepData.getSleepDataDays().get(0).getMessage()));
|
||||||
|
updateState(CHANNEL_LEFT_TODAY_SLEEP_DURATION_SECONDS,
|
||||||
|
new QuantityType<>(sleepData.getTotalSleepSessionTime(), Units.SECOND));
|
||||||
|
} else if (sleeper.getSide().equals(Side.RIGHT)) {
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_SLEEP_IQ, new DecimalType(sleepData.getAverageSleepIQ()));
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_AVG_HEART_RATE, new DecimalType(sleepData.getAverageHeartRate()));
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_AVG_RESPIRATION_RATE,
|
||||||
|
new DecimalType(sleepData.getAverageRespirationRate()));
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_MESSAGE, new StringType(sleepData.getSleepDataDays().get(0).getMessage()));
|
||||||
|
updateState(CHANNEL_RIGHT_TODAY_SLEEP_DURATION_SECONDS,
|
||||||
|
new QuantityType<>(sleepData.getTotalSleepSessionTime(), Units.SECOND));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMonthlySleepDataChannels(final @Nullable Sleeper sleeper) {
|
||||||
|
SleepIQCloudHandler cloudHandler = getCloudHandler();
|
||||||
|
if (cloudHandler == null || sleeper == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SleepDataResponse sleepData = cloudHandler.getMonthlySleepData(sleeper.getSleeperId());
|
||||||
|
if (sleepData == null) {
|
||||||
|
logger.debug("BedHandler: Received no monthly sleep data for bedId={}, sleeperId={}", sleeper.getBedId(),
|
||||||
|
sleeper.getSleeperId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("BedHandler: UPDATING MONTHLY SLEEP DATA CHANNELS for bedId={}, sleeperId={}", sleeper.getBedId(),
|
||||||
|
sleeper.getSleeperId());
|
||||||
|
if (sleeper.getSide().equals(Side.LEFT)) {
|
||||||
|
updateState(CHANNEL_LEFT_MONTHLY_SLEEP_IQ, new DecimalType(sleepData.getAverageSleepIQ()));
|
||||||
|
updateState(CHANNEL_LEFT_MONTHLY_AVG_HEART_RATE, new DecimalType(sleepData.getAverageHeartRate()));
|
||||||
|
updateState(CHANNEL_LEFT_MONTHLY_AVG_RESPIRATION_RATE,
|
||||||
|
new DecimalType(sleepData.getAverageRespirationRate()));
|
||||||
|
} else {
|
||||||
|
updateState(CHANNEL_RIGHT_MONTHLY_SLEEP_IQ, new DecimalType(sleepData.getAverageSleepIQ()));
|
||||||
|
updateState(CHANNEL_RIGHT_MONTHLY_AVG_HEART_RATE, new DecimalType(sleepData.getAverageHeartRate()));
|
||||||
|
updateState(CHANNEL_RIGHT_MONTHLY_AVG_RESPIRATION_RATE,
|
||||||
|
new DecimalType(sleepData.getAverageRespirationRate()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateProperties() {
|
||||||
|
logger.debug("BedHandler: Updating bed properties for bedId={}", bedId);
|
||||||
|
SleepIQCloudHandler cloudHandler = getCloudHandler();
|
||||||
|
if (cloudHandler != null) {
|
||||||
|
Bed bed = cloudHandler.getBed(bedId);
|
||||||
|
if (bed == null) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||||
|
"No bed found with ID " + bedId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateProperties(cloudHandler.updateProperties(bed, editProperties()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable SleepIQCloudHandler getCloudHandler() {
|
||||||
|
Bridge bridge = getBridge();
|
||||||
|
if (bridge != null) {
|
||||||
|
return (SleepIQCloudHandler) bridge.getHandler();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
<description>Username of a registered SleepIQ account owner</description>
|
<description>Username of a registered SleepIQ account owner</description>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="password" type="text" required="false">
|
<parameter name="password" type="text" required="false">
|
||||||
<context>password</context>
|
|
||||||
<label>Password</label>
|
<label>Password</label>
|
||||||
<description>Password of a registered SleepIQ account owner</description>
|
<description>Password of a registered SleepIQ account owner</description>
|
||||||
|
<context>password</context>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="pollingInterval" type="integer" min="30" step="30" required="true">
|
<parameter name="pollingInterval" type="integer" min="30" step="30" required="true">
|
||||||
<label>Polling Interval</label>
|
<label>Polling Interval</label>
|
||||||
<description>Seconds between fetching values from the cloud service</description>
|
<description>Seconds between fetching values from the cloud service</description>
|
||||||
<default>60</default>
|
<default>120</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
</config-description>
|
</config-description>
|
||||||
</bridge-type>
|
</bridge-type>
|
||||||
|
@ -86,6 +86,17 @@
|
||||||
<channel id="lastLink" typeId="lastLinkType"/>
|
<channel id="lastLink" typeId="lastLinkType"/>
|
||||||
<channel id="alertId" typeId="alertIdType"/>
|
<channel id="alertId" typeId="alertIdType"/>
|
||||||
<channel id="alertDetailedMessage" typeId="alertDetailedMessageType"/>
|
<channel id="alertDetailedMessage" typeId="alertDetailedMessageType"/>
|
||||||
|
<channel id="firstName" typeId="firstNameType"/>
|
||||||
|
<channel id="sleepGoalMinutes" typeId="sleepGoalMinutesType"/>
|
||||||
|
<channel id="privacyMode" typeId="privacyMode"/>
|
||||||
|
<channel id="todaySleepIQ" typeId="todaySleepIQType"/>
|
||||||
|
<channel id="todayAverageHeartRate" typeId="todayAverageHeartRateType"/>
|
||||||
|
<channel id="todayAverageRespirationRate" typeId="todayAverageRespirationRateType"/>
|
||||||
|
<channel id="todayMessage" typeId="todayMessageType"/>
|
||||||
|
<channel id="todaySleepDurationSeconds" typeId="todaySleepDurationSecondsType"/>
|
||||||
|
<channel id="monthlySleepIQ" typeId="monthlySleepIQType"/>
|
||||||
|
<channel id="monthlyAverageHeartRate" typeId="monthlyAverageHeartRateType"/>
|
||||||
|
<channel id="monthlyAverageRespirationRate" typeId="monthlyAverageRespirationRateType"/>
|
||||||
</channels>
|
</channels>
|
||||||
</channel-group-type>
|
</channel-group-type>
|
||||||
|
|
||||||
|
@ -99,7 +110,7 @@
|
||||||
<item-type>Number</item-type>
|
<item-type>Number</item-type>
|
||||||
<label>Sleep Number</label>
|
<label>Sleep Number</label>
|
||||||
<description>The Sleep Number setting of the chamber</description>
|
<description>The Sleep Number setting of the chamber</description>
|
||||||
<state readOnly="true"/>
|
<state readOnly="false" min="5" max="100" step="5" pattern="%d"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
<channel-type id="pressureType">
|
<channel-type id="pressureType">
|
||||||
<item-type>Number</item-type>
|
<item-type>Number</item-type>
|
||||||
|
@ -126,5 +137,71 @@
|
||||||
<description>A detailed message describing an alert condition with the chamber</description>
|
<description>A detailed message describing an alert condition with the chamber</description>
|
||||||
<state readOnly="true"/>
|
<state readOnly="true"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
<channel-type id="firstNameType">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>First Name</label>
|
||||||
|
<description>The first name of the sleeper</description>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="sleepGoalMinutesType">
|
||||||
|
<item-type>Number:Time</item-type>
|
||||||
|
<label>Sleep Goal</label>
|
||||||
|
<description>The goal for the amount of sleep per night (in minutes)</description>
|
||||||
|
<state readOnly="true" pattern="%d %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="privacyMode">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Privacy Mode</label>
|
||||||
|
<description>Enable/disable privacy mode</description>
|
||||||
|
<state readOnly="false"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="todaySleepIQType">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Today's Sleep IQ</label>
|
||||||
|
<description>The Sleep Quotient for today</description>
|
||||||
|
<state readOnly="true" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="todayAverageHeartRateType">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Today's Avg Heart Rate</label>
|
||||||
|
<description>The average heart rate for today</description>
|
||||||
|
<state readOnly="true" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="todayAverageRespirationRateType">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Today's Avg Respiration Rate</label>
|
||||||
|
<description>The average respiration rate for today</description>
|
||||||
|
<state readOnly="true" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="todayMessageType">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Today's Message</label>
|
||||||
|
<description>The description of today's sleep quality</description>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="todaySleepDurationSecondsType">
|
||||||
|
<item-type>Number:Time</item-type>
|
||||||
|
<label>Today's Sleep Duration</label>
|
||||||
|
<description>The total duration of sleep for today in seconds</description>
|
||||||
|
<state readOnly="true" pattern="%d %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="monthlySleepIQType">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Monthly Sleep IQ</label>
|
||||||
|
<description>The overall Sleep Quotient for the past month</description>
|
||||||
|
<state readOnly="true" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="monthlyAverageHeartRateType">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Monthly Avg Heart Rate</label>
|
||||||
|
<description>The average heart rate for the past month</description>
|
||||||
|
<state readOnly="true" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="monthlyAverageRespirationRateType">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Monthly Avg Respiration Rate</label>
|
||||||
|
<description>The average respiration rate for the past month</description>
|
||||||
|
<state readOnly="true" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
</thing:thing-descriptions>
|
</thing:thing-descriptions>
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.api.model;
|
||||||
|
|
||||||
|
@ -19,20 +16,23 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedSideStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.TimeSince;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BedSideStatusTest} tests deserialization of a bed side status object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class BedSideStatusTest extends AbstractTest {
|
public class BedSideStatusTest extends AbstractTest {
|
||||||
private static Gson gson;
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSerializeAllFields() throws Exception {
|
public void testSerializeAllFields() throws Exception {
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.api.model;
|
||||||
|
|
||||||
|
@ -19,20 +16,23 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedSideStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BedStatusText} tests deserialization of a bed status object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class BedStatusTest extends AbstractTest {
|
public class BedStatusTest extends AbstractTest {
|
||||||
private static Gson gson;
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSerializeAllFields() throws Exception {
|
public void testSerializeAllFields() throws Exception {
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.api.model;
|
||||||
|
|
||||||
|
@ -21,20 +18,22 @@ import java.io.FileReader;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Bed;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BedTest} tests deserialization of a bed object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class BedTest extends AbstractTest {
|
public class BedTest extends AbstractTest {
|
||||||
private static Gson gson;
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSerializeAllFields() throws Exception {
|
public void testSerializeAllFields() throws Exception {
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.api.model;
|
||||||
|
|
||||||
|
@ -21,20 +18,23 @@ import java.io.FileReader;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Bed;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedsResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link BedsResponseTest} tests deserialization of a beds response object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class BedsResponseTest extends AbstractTest {
|
public class BedsResponseTest extends AbstractTest {
|
||||||
private static Gson gson;
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSerializeAllFields() throws Exception {
|
public void testSerializeAllFields() throws Exception {
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.api.model;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.BedStatus;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.FamilyStatusResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link FamilyStatusText} tests deserialization of a family status object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class FamilyStatusTest extends AbstractTest {
|
||||||
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSerializeAllFields() throws Exception {
|
||||||
|
FamilyStatusResponse familyStatus = new FamilyStatusResponse()
|
||||||
|
.withBeds(Arrays.asList(new BedStatus().withStatus(1L)));
|
||||||
|
assertEquals(readJson("family-status.json"), gson.toJson(familyStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeserializeAllFields() throws Exception {
|
||||||
|
try (FileReader reader = new FileReader(getTestDataFile("family-status.json"))) {
|
||||||
|
FamilyStatusResponse familyStatus = gson.fromJson(reader, FamilyStatusResponse.class);
|
||||||
|
|
||||||
|
List<BedStatus> beds = familyStatus.getBeds();
|
||||||
|
assertNotNull(beds);
|
||||||
|
assertEquals(1, beds.size());
|
||||||
|
assertEquals(Long.valueOf(1L), beds.get(0).getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sleepiq.api.model;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.io.FileReader;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.PauseModeResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PauseModeTest} tests deserialization of a pause mode object.
|
||||||
|
*
|
||||||
|
* @author Mark Hilbush - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class PauseModeTest extends AbstractTest {
|
||||||
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSerializeAllFields() throws Exception {
|
||||||
|
PauseModeResponse pauseMode = new PauseModeResponse().withAccountId("-8888888888888888888")
|
||||||
|
.withBedId("-9999999999999999999").withPauseMode("off");
|
||||||
|
assertEquals(readJson("pause-mode.json"), gson.toJson(pauseMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeserializeAllFields() throws Exception {
|
||||||
|
try (FileReader reader = new FileReader(getTestDataFile("pause-mode.json"))) {
|
||||||
|
PauseModeResponse pauseMode = gson.fromJson(reader, PauseModeResponse.class);
|
||||||
|
assertEquals("-8888888888888888888", pauseMode.getAccountId());
|
||||||
|
assertEquals("-9999999999999999999", pauseMode.getBedId());
|
||||||
|
assertEquals("off", pauseMode.getPauseMode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.api.model;
|
||||||
|
|
||||||
|
@ -19,20 +16,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Sleeper;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.enums.Side;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleeperTest} tests deserialization of a sleeper object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SleeperTest extends AbstractTest {
|
public class SleeperTest extends AbstractTest {
|
||||||
private static Gson gson;
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSerializeAllFields() throws Exception {
|
public void testSerializeAllFields() throws Exception {
|
||||||
|
@ -40,7 +40,7 @@ public class SleeperTest extends AbstractTest {
|
||||||
.withAvatar("").withBedId("-9999999999999999999").withBirthMonth(6).withBirthYear("1970")
|
.withAvatar("").withBedId("-9999999999999999999").withBirthMonth(6).withBirthYear("1970")
|
||||||
.withChild(false).withDuration("").withEmail("alice@domain.com").withEmailValidated(true)
|
.withChild(false).withDuration("").withEmail("alice@domain.com").withEmailValidated(true)
|
||||||
.withFirstName("Alice").withHeight(64).withLastLogin("2017-02-17 20:19:36 CST").withLicenseVersion(6L)
|
.withFirstName("Alice").withHeight(64).withLastLogin("2017-02-17 20:19:36 CST").withLicenseVersion(6L)
|
||||||
.withMale(false).withSide(1).withSleeperId("-1111111111111111111").withSleepGoal(450)
|
.withMale(false).withSide(Side.RIGHT).withSleeperId("-1111111111111111111").withSleepGoal(450)
|
||||||
.withTimezone("US/Pacific").withUsername("alice@domain.com").withWeight(110).withZipCode("90210");
|
.withTimezone("US/Pacific").withUsername("alice@domain.com").withWeight(110).withZipCode("90210");
|
||||||
assertEquals(readJson("sleeper.json"), gson.toJson(sleeper));
|
assertEquals(readJson("sleeper.json"), gson.toJson(sleeper));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class SleeperTest extends AbstractTest {
|
||||||
assertEquals("2017-02-17 20:19:36 CST", sleeper.getLastLogin());
|
assertEquals("2017-02-17 20:19:36 CST", sleeper.getLastLogin());
|
||||||
assertEquals(Long.valueOf(6L), sleeper.getLicenseVersion());
|
assertEquals(Long.valueOf(6L), sleeper.getLicenseVersion());
|
||||||
assertEquals(false, sleeper.isMale());
|
assertEquals(false, sleeper.isMale());
|
||||||
assertEquals(Integer.valueOf(1), sleeper.getSide());
|
assertEquals(Side.RIGHT, sleeper.getSide());
|
||||||
assertEquals("-1111111111111111111", sleeper.getSleeperId());
|
assertEquals("-1111111111111111111", sleeper.getSleeperId());
|
||||||
assertEquals(Integer.valueOf(450), sleeper.getSleepGoal());
|
assertEquals(Integer.valueOf(450), sleeper.getSleepGoal());
|
||||||
assertEquals("US/Pacific", sleeper.getTimezone());
|
assertEquals("US/Pacific", sleeper.getTimezone());
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.api.model;
|
||||||
|
|
||||||
|
@ -21,20 +18,23 @@ import java.io.FileReader;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
|
||||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.Sleeper;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.SleepersResponse;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.impl.GsonGenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SleepersResponseTest} tests deserialization of a sleepers response object.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SleepersResponseTest extends AbstractTest {
|
public class SleepersResponseTest extends AbstractTest {
|
||||||
private static Gson gson;
|
private static Gson gson = GsonGenerator.create(true);
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setUpBeforeClass() {
|
|
||||||
gson = GsonGenerator.create(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSerializeAllFields() throws Exception {
|
public void testSerializeAllFields() throws Exception {
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.model;
|
package org.openhab.binding.sleepiq.api.model;
|
||||||
|
|
||||||
|
@ -19,8 +16,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.openhab.binding.sleepiq.internal.api.dto.TimeSince;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link TimeSinceText} tests TimeSince.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class TimeSinceTest {
|
public class TimeSinceTest {
|
||||||
@Test
|
@Test
|
||||||
public void testWithDuration() {
|
public void testWithDuration() {
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2017 Gregory Moyer
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
* you may not use this file except in compliance with the License.
|
* information.
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* 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
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.sleepiq.api.test;
|
package org.openhab.binding.sleepiq.api.test;
|
||||||
|
|
||||||
|
@ -24,6 +21,14 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link AbstractTest} tests deserialization of a sleepiq API objects.
|
||||||
|
*
|
||||||
|
* @author Gregory Moyer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public abstract class AbstractTest {
|
public abstract class AbstractTest {
|
||||||
private static final String RESOURCES_PATH = "src/test/resources/";
|
private static final String RESOURCES_PATH = "src/test/resources/";
|
||||||
|
|
||||||
|
@ -31,6 +36,7 @@ public abstract class AbstractTest {
|
||||||
return getTestDataPath(name).toFile();
|
return getTestDataPath(name).toFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("null")
|
||||||
protected Path getTestDataPath(String name) {
|
protected Path getTestDataPath(String name) {
|
||||||
String packageName = this.getClass().getPackage().getName();
|
String packageName = this.getClass().getPackage().getName();
|
||||||
|
|
Loading…
Reference in New Issue