added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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.net.URI;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* This class represents configuration parameters for using {@link SleepIQ}.
|
||||
*
|
||||
* @author Gregory Moyer
|
||||
*/
|
||||
public class Configuration
|
||||
{
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
private URI baseUri = URI.create("https://api.sleepiq.sleepnumber.com/rest");
|
||||
|
||||
private boolean logging = false;
|
||||
|
||||
/**
|
||||
* Get the username on the account.
|
||||
*
|
||||
* @return the username
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username on the account. This should be the username used to
|
||||
* register with SleepIQ.
|
||||
*
|
||||
* @param username
|
||||
* the value to set
|
||||
*/
|
||||
public void setUsername(String username)
|
||||
{
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username on the account. This should be the username used to
|
||||
* register with SleepIQ.
|
||||
*
|
||||
* @param username
|
||||
* the value to set
|
||||
* @return this configuration instance
|
||||
*/
|
||||
public Configuration withUsername(String username)
|
||||
{
|
||||
setUsername(username);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password on the account.
|
||||
*
|
||||
* @return the password
|
||||
*/
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password on the account. This should be the password used to
|
||||
* register with SleepIQ.
|
||||
*
|
||||
* @param password
|
||||
* the value to set
|
||||
*/
|
||||
public void setPassword(String password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password on the account. This should be the password used to
|
||||
* register with SleepIQ.
|
||||
*
|
||||
* @param password
|
||||
* the value to set
|
||||
* @return this configuration instance
|
||||
*/
|
||||
public Configuration withPassword(String password)
|
||||
{
|
||||
setPassword(password);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base URI of the SleepIQ cloud service.
|
||||
*
|
||||
* @return the base URI
|
||||
*/
|
||||
public URI getBaseUri()
|
||||
{
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base URI of the SleepIQ cloud service. It is unlikely that this
|
||||
* will need to be changed from its default value.
|
||||
*
|
||||
* @param baseUri
|
||||
* the value to set
|
||||
*/
|
||||
public void setBaseUri(URI baseUri)
|
||||
{
|
||||
this.baseUri = baseUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base URI of the SleepIQ cloud service. It is unlikely that this
|
||||
* will need to be changed from its default value.
|
||||
*
|
||||
* @param baseUri
|
||||
* the value to set
|
||||
* @return this configuration instance
|
||||
*/
|
||||
public Configuration withBaseUri(URI baseUri)
|
||||
{
|
||||
setBaseUri(baseUri);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the logging flag.
|
||||
*
|
||||
* @return the logging flag
|
||||
*/
|
||||
public boolean isLogging()
|
||||
{
|
||||
return logging;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the logging flag. When this is set to <code>true</code>, all requests
|
||||
* and responses will be logged at the {@link Level#INFO} level. <b>This
|
||||
* includes usernames and passwords!</b>
|
||||
*
|
||||
* @param logging
|
||||
* the value to set
|
||||
*/
|
||||
public void setLogging(boolean logging)
|
||||
{
|
||||
this.logging = logging;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the logging flag. When this is set to <code>true</code>, all requests
|
||||
* and responses will be logged at the {@link Level#INFO} level. <b>This
|
||||
* includes usernames and passwords!</b>
|
||||
*
|
||||
* @param logging
|
||||
* the value to set
|
||||
* @return this configuration instance
|
||||
*/
|
||||
public Configuration withLogging(boolean logging)
|
||||
{
|
||||
setLogging(logging);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
101
bundles/org.openhab.binding.sleepiq/src/3rdparty/java/org/openhab/binding/sleepiq/api/SleepIQ.java
vendored
Normal file
101
bundles/org.openhab.binding.sleepiq/src/3rdparty/java/org/openhab/binding/sleepiq/api/SleepIQ.java
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 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)
|
||||
{
|
||||
return new SleepIQImpl(config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public SleepIQImpl(Configuration config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@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()
|
||||
{
|
||||
ClientBuilder builder = ClientBuilder.newBuilder();
|
||||
|
||||
// setup Gson (de)serialization
|
||||
GsonProvider<Object> gsonProvider = new GsonProvider<>(getGson());
|
||||
builder.register(gsonProvider);
|
||||
|
||||
// turn on logging if requested
|
||||
if (config.isLogging())
|
||||
{
|
||||
builder.register(new LoggingFilter(Logger.getLogger(SleepIQImpl.class.getName()),
|
||||
true));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface Request
|
||||
{
|
||||
public Response execute(Map<String, Object> data) throws LoginException;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* Type adapter for jsr310 {@link LocalTime} class.
|
||||
*
|
||||
* @author Christophe Bornet
|
||||
*/
|
||||
public class LocalTimeTypeAdapter extends TemporalTypeAdapter<LocalTime> {
|
||||
|
||||
public LocalTimeTypeAdapter() {
|
||||
super(LocalTime::parse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* Type adapter for jsr310 {@link OffsetDateTime} class.
|
||||
*
|
||||
* @author Christophe Bornet
|
||||
*/
|
||||
public class OffsetDateTimeTypeAdapter extends DateTimeTypeAdapter<OffsetDateTime> {
|
||||
|
||||
public OffsetDateTimeTypeAdapter() {
|
||||
super(OffsetDateTime::parse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* Type adapter for jsr310 {@link OffsetTime} class.
|
||||
*
|
||||
* @author Christophe Bornet
|
||||
*/
|
||||
public class OffsetTimeTypeAdapter extends TemporalTypeAdapter<OffsetTime> {
|
||||
|
||||
public OffsetTimeTypeAdapter() {
|
||||
super(OffsetTime::parse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Abstract type adapter for jsr310 date-time types.
|
||||
*
|
||||
* @author Christophe Bornet
|
||||
*/
|
||||
abstract class TemporalTypeAdapter<T> extends TypeAdapter<T> {
|
||||
|
||||
Function<String, T> parseFunction;
|
||||
|
||||
TemporalTypeAdapter(Function<String, T> parseFunction) {
|
||||
Objects.requireNonNull(parseFunction);
|
||||
this.parseFunction = parseFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
} else {
|
||||
out.value(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
String temporalString = preProcess(in.nextString());
|
||||
return parseFunction.apply(temporalString);
|
||||
}
|
||||
|
||||
public String preProcess(String in) {
|
||||
return in;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* Type adapter for jsr310 {@link ZonedDateTime} class.
|
||||
*
|
||||
* @author Christophe Bornet
|
||||
*/
|
||||
public class ZonedDateTimeTypeAdapter extends DateTimeTypeAdapter<ZonedDateTime> {
|
||||
|
||||
public ZonedDateTimeTypeAdapter() {
|
||||
super(ZonedDateTime::parse);
|
||||
}
|
||||
}
|
||||
472
bundles/org.openhab.binding.sleepiq/src/3rdparty/java/org/openhab/binding/sleepiq/api/model/Bed.java
vendored
Normal file
472
bundles/org.openhab.binding.sleepiq/src/3rdparty/java/org/openhab/binding/sleepiq/api/model/Bed.java
vendored
Normal file
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
* 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.time.ZonedDateTime;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Bed
|
||||
{
|
||||
private ZonedDateTime registrationDate;
|
||||
private String sleeperRightId;
|
||||
private String base;
|
||||
private Long returnRequestStatus;
|
||||
private String size;
|
||||
private String name;
|
||||
private String serial;
|
||||
@SerializedName("isKidsBed")
|
||||
private Boolean kidsBed;
|
||||
private Boolean dualSleep;
|
||||
private String bedId;
|
||||
private Long status;
|
||||
private String sleeperLeftId;
|
||||
private String version;
|
||||
private String accountId;
|
||||
private String timezone;
|
||||
private String model;
|
||||
private ZonedDateTime purchaseDate;
|
||||
private String macAddress;
|
||||
private String sku;
|
||||
@SerializedName("zipcode")
|
||||
private String zipCode;
|
||||
private String reference;
|
||||
|
||||
public ZonedDateTime getRegistrationDate()
|
||||
{
|
||||
return registrationDate;
|
||||
}
|
||||
|
||||
public void setRegistrationDate(ZonedDateTime registrationDate)
|
||||
{
|
||||
this.registrationDate = registrationDate;
|
||||
}
|
||||
|
||||
public Bed withRegistrationDate(ZonedDateTime registrationDate)
|
||||
{
|
||||
setRegistrationDate(registrationDate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSleeperRightId()
|
||||
{
|
||||
return sleeperRightId;
|
||||
}
|
||||
|
||||
public void setSleeperRightId(String sleeperRightId)
|
||||
{
|
||||
this.sleeperRightId = sleeperRightId;
|
||||
}
|
||||
|
||||
public Bed withSleeperRightId(String sleeperRightId)
|
||||
{
|
||||
setSleeperRightId(sleeperRightId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getBase()
|
||||
{
|
||||
return base;
|
||||
}
|
||||
|
||||
public void setBase(String base)
|
||||
{
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public Bed withBase(String base)
|
||||
{
|
||||
setBase(base);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getReturnRequestStatus()
|
||||
{
|
||||
return returnRequestStatus;
|
||||
}
|
||||
|
||||
public void setReturnRequestStatus(Long returnRequestStatus)
|
||||
{
|
||||
this.returnRequestStatus = returnRequestStatus;
|
||||
}
|
||||
|
||||
public Bed withReturnRequestStatus(Long returnRequestStatus)
|
||||
{
|
||||
setReturnRequestStatus(returnRequestStatus);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(String size)
|
||||
{
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Bed withSize(String size)
|
||||
{
|
||||
setSize(size);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Bed withName(String name)
|
||||
{
|
||||
setName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSerial()
|
||||
{
|
||||
return serial;
|
||||
}
|
||||
|
||||
public void setSerial(String serial)
|
||||
{
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
public Bed withSerial(String serial)
|
||||
{
|
||||
setSerial(serial);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean isKidsBed()
|
||||
{
|
||||
return kidsBed;
|
||||
}
|
||||
|
||||
public void setKidsBed(Boolean kidsBed)
|
||||
{
|
||||
this.kidsBed = kidsBed;
|
||||
}
|
||||
|
||||
public Bed withKidsBed(Boolean kidsBed)
|
||||
{
|
||||
setKidsBed(kidsBed);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean isDualSleep()
|
||||
{
|
||||
return dualSleep;
|
||||
}
|
||||
|
||||
public void setDualSleep(Boolean dualSleep)
|
||||
{
|
||||
this.dualSleep = dualSleep;
|
||||
}
|
||||
|
||||
public Bed withDualSleep(Boolean dualSleep)
|
||||
{
|
||||
setDualSleep(dualSleep);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getBedId()
|
||||
{
|
||||
return bedId;
|
||||
}
|
||||
|
||||
public void setBedId(String bedId)
|
||||
{
|
||||
this.bedId = bedId;
|
||||
}
|
||||
|
||||
public Bed withBedId(String bedId)
|
||||
{
|
||||
setBedId(bedId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Long status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Bed withStatus(Long status)
|
||||
{
|
||||
setStatus(status);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSleeperLeftId()
|
||||
{
|
||||
return sleeperLeftId;
|
||||
}
|
||||
|
||||
public void setSleeperLeftId(String sleeperLeftId)
|
||||
{
|
||||
this.sleeperLeftId = sleeperLeftId;
|
||||
}
|
||||
|
||||
public Bed withSleeperLeftId(String sleeperLeftId)
|
||||
{
|
||||
setSleeperLeftId(sleeperLeftId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version)
|
||||
{
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public Bed withVersion(String version)
|
||||
{
|
||||
setVersion(version);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAccountId()
|
||||
{
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(String accountId)
|
||||
{
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public Bed withAccountId(String accountId)
|
||||
{
|
||||
setAccountId(accountId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTimezone()
|
||||
{
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone)
|
||||
{
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
public Bed withTimezone(String timezone)
|
||||
{
|
||||
setTimezone(timezone);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getModel()
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model)
|
||||
{
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public Bed withModel(String model)
|
||||
{
|
||||
setModel(model);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ZonedDateTime getPurchaseDate()
|
||||
{
|
||||
return purchaseDate;
|
||||
}
|
||||
|
||||
public void setPurchaseDate(ZonedDateTime purchaseDate)
|
||||
{
|
||||
this.purchaseDate = purchaseDate;
|
||||
}
|
||||
|
||||
public Bed withPurchaseDate(ZonedDateTime purchaseDate)
|
||||
{
|
||||
setPurchaseDate(purchaseDate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMacAddress()
|
||||
{
|
||||
return macAddress;
|
||||
}
|
||||
|
||||
public void setMacAddress(String macAddress)
|
||||
{
|
||||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
public Bed withMacAddress(String macAddress)
|
||||
{
|
||||
setMacAddress(macAddress);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSku()
|
||||
{
|
||||
return sku;
|
||||
}
|
||||
|
||||
public void setSku(String sku)
|
||||
{
|
||||
this.sku = sku;
|
||||
}
|
||||
|
||||
public Bed withSku(String sku)
|
||||
{
|
||||
setSku(sku);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getZipCode()
|
||||
{
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(String zipCode)
|
||||
{
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
|
||||
public Bed withZipCode(String zipCode)
|
||||
{
|
||||
setZipCode(zipCode);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getReference()
|
||||
{
|
||||
return reference;
|
||||
}
|
||||
|
||||
public void setReference(String reference)
|
||||
{
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
public Bed withReference(String reference)
|
||||
{
|
||||
setReference(reference);
|
||||
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 Bed))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Bed other = (Bed)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("Bed [registrationDate=");
|
||||
builder.append(registrationDate);
|
||||
builder.append(", sleeperRightId=");
|
||||
builder.append(sleeperRightId);
|
||||
builder.append(", base=");
|
||||
builder.append(base);
|
||||
builder.append(", returnRequestStatus=");
|
||||
builder.append(returnRequestStatus);
|
||||
builder.append(", size=");
|
||||
builder.append(size);
|
||||
builder.append(", name=");
|
||||
builder.append(name);
|
||||
builder.append(", serial=");
|
||||
builder.append(serial);
|
||||
builder.append(", kidsBed=");
|
||||
builder.append(kidsBed);
|
||||
builder.append(", dualSleep=");
|
||||
builder.append(dualSleep);
|
||||
builder.append(", bedId=");
|
||||
builder.append(bedId);
|
||||
builder.append(", status=");
|
||||
builder.append(status);
|
||||
builder.append(", sleeperLeftId=");
|
||||
builder.append(sleeperLeftId);
|
||||
builder.append(", version=");
|
||||
builder.append(version);
|
||||
builder.append(", accountId=");
|
||||
builder.append(accountId);
|
||||
builder.append(", timezone=");
|
||||
builder.append(timezone);
|
||||
builder.append(", model=");
|
||||
builder.append(model);
|
||||
builder.append(", purchaseDate=");
|
||||
builder.append(purchaseDate);
|
||||
builder.append(", macAddress=");
|
||||
builder.append(macAddress);
|
||||
builder.append(", sku=");
|
||||
builder.append(sku);
|
||||
builder.append(", zipCode=");
|
||||
builder.append(zipCode);
|
||||
builder.append(", reference=");
|
||||
builder.append(reference);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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 BedSideStatus
|
||||
{
|
||||
@SerializedName("isInBed")
|
||||
private Boolean inBed;
|
||||
private String alertDetailedMessage;
|
||||
private Integer sleepNumber;
|
||||
private Long alertId;
|
||||
private TimeSince lastLink;
|
||||
private Integer pressure; // appears to be in kPa
|
||||
|
||||
public Boolean isInBed()
|
||||
{
|
||||
return inBed;
|
||||
}
|
||||
|
||||
public void setInBed(Boolean inBed)
|
||||
{
|
||||
this.inBed = inBed;
|
||||
}
|
||||
|
||||
public BedSideStatus withInBed(Boolean inBed)
|
||||
{
|
||||
setInBed(inBed);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAlertDetailedMessage()
|
||||
{
|
||||
return alertDetailedMessage;
|
||||
}
|
||||
|
||||
public void setAlertDetailedMessage(String alertDetailedMessage)
|
||||
{
|
||||
this.alertDetailedMessage = alertDetailedMessage;
|
||||
}
|
||||
|
||||
public BedSideStatus withAlertDetailedMessage(String alertDetailedMessage)
|
||||
{
|
||||
setAlertDetailedMessage(alertDetailedMessage);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getSleepNumber()
|
||||
{
|
||||
return sleepNumber;
|
||||
}
|
||||
|
||||
public void setSleepNumber(Integer sleepNumber)
|
||||
{
|
||||
this.sleepNumber = sleepNumber;
|
||||
}
|
||||
|
||||
public BedSideStatus withSleepNumber(Integer sleepNumber)
|
||||
{
|
||||
setSleepNumber(sleepNumber);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getAlertId()
|
||||
{
|
||||
return alertId;
|
||||
}
|
||||
|
||||
public void setAlertId(Long alertId)
|
||||
{
|
||||
this.alertId = alertId;
|
||||
}
|
||||
|
||||
public BedSideStatus withAlertId(Long alertId)
|
||||
{
|
||||
setAlertId(alertId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TimeSince getLastLink()
|
||||
{
|
||||
return lastLink;
|
||||
}
|
||||
|
||||
public void setLastLink(TimeSince lastLink)
|
||||
{
|
||||
this.lastLink = lastLink;
|
||||
}
|
||||
|
||||
public BedSideStatus withLastLink(TimeSince lastLink)
|
||||
{
|
||||
setLastLink(lastLink);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getPressure()
|
||||
{
|
||||
return pressure;
|
||||
}
|
||||
|
||||
public void setPressure(Integer pressure)
|
||||
{
|
||||
this.pressure = pressure;
|
||||
}
|
||||
|
||||
public BedSideStatus withPressure(Integer pressure)
|
||||
{
|
||||
setPressure(pressure);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ((alertDetailedMessage == null) ? 0 : alertDetailedMessage.hashCode());
|
||||
result = prime * result + ((alertId == null) ? 0 : alertId.hashCode());
|
||||
result = prime * result + ((inBed == null) ? 0 : inBed.hashCode());
|
||||
result = prime * result + ((lastLink == null) ? 0 : lastLink.hashCode());
|
||||
result = prime * result + ((pressure == null) ? 0 : pressure.hashCode());
|
||||
result = prime * result + ((sleepNumber == null) ? 0 : sleepNumber.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof BedSideStatus))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BedSideStatus other = (BedSideStatus)obj;
|
||||
if (alertDetailedMessage == null)
|
||||
{
|
||||
if (other.alertDetailedMessage != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!alertDetailedMessage.equals(other.alertDetailedMessage))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (alertId == null)
|
||||
{
|
||||
if (other.alertId != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!alertId.equals(other.alertId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (inBed == null)
|
||||
{
|
||||
if (other.inBed != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!inBed.equals(other.inBed))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (lastLink == null)
|
||||
{
|
||||
if (other.lastLink != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!lastLink.equals(other.lastLink))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (pressure == null)
|
||||
{
|
||||
if (other.pressure != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!pressure.equals(other.pressure))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (sleepNumber == null)
|
||||
{
|
||||
if (other.sleepNumber != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!sleepNumber.equals(other.sleepNumber))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("BedSideStatus [inBed=");
|
||||
builder.append(inBed);
|
||||
builder.append(", alertDetailedMessage=");
|
||||
builder.append(alertDetailedMessage);
|
||||
builder.append(", sleepNumber=");
|
||||
builder.append(sleepNumber);
|
||||
builder.append(", alertId=");
|
||||
builder.append(alertId);
|
||||
builder.append(", lastLink=");
|
||||
builder.append(lastLink);
|
||||
builder.append(", pressure=");
|
||||
builder.append(pressure);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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 LoginInfo
|
||||
{
|
||||
private String userId;
|
||||
private String key;
|
||||
private Long registrationState;
|
||||
private Long edpLoginStatus;
|
||||
private String edpLoginMessage;
|
||||
|
||||
public String getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public LoginInfo withUserId(String userId)
|
||||
{
|
||||
setUserId(userId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public LoginInfo withKey(String key)
|
||||
{
|
||||
setKey(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getRegistrationState()
|
||||
{
|
||||
return registrationState;
|
||||
}
|
||||
|
||||
public void setRegistrationState(Long registrationState)
|
||||
{
|
||||
this.registrationState = registrationState;
|
||||
}
|
||||
|
||||
public LoginInfo withRegistrationState(Long registrationState)
|
||||
{
|
||||
setRegistrationState(registrationState);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getEdpLoginStatus()
|
||||
{
|
||||
return edpLoginStatus;
|
||||
}
|
||||
|
||||
public void setEdpLoginStatus(Long edpLoginStatus)
|
||||
{
|
||||
this.edpLoginStatus = edpLoginStatus;
|
||||
}
|
||||
|
||||
public LoginInfo withEdpLoginStatus(Long edpLoginStatus)
|
||||
{
|
||||
setEdpLoginStatus(edpLoginStatus);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getEdpLoginMessage()
|
||||
{
|
||||
return edpLoginMessage;
|
||||
}
|
||||
|
||||
public void setEdpLoginMessage(String edpLoginMessage)
|
||||
{
|
||||
this.edpLoginMessage = edpLoginMessage;
|
||||
}
|
||||
|
||||
public LoginInfo withEdpLoginMessage(String edpLoginMessage)
|
||||
{
|
||||
setEdpLoginMessage(edpLoginMessage);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
||||
result = prime * result + (int)(registrationState ^ (registrationState >>> 32));
|
||||
result = prime * result + ((userId == null) ? 0 : userId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof LoginInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
LoginInfo other = (LoginInfo)obj;
|
||||
if (key == null)
|
||||
{
|
||||
if (other.key != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!key.equals(other.key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!registrationState.equals(other.registrationState))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (userId == null)
|
||||
{
|
||||
if (other.userId != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!userId.equals(other.userId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("LoginInfo [userId=");
|
||||
builder.append(userId);
|
||||
builder.append(", key=");
|
||||
builder.append(key);
|
||||
builder.append(", registrationState=");
|
||||
builder.append(registrationState);
|
||||
builder.append(", edpLoginStatus=");
|
||||
builder.append(edpLoginStatus);
|
||||
builder.append(", edpLoginMessage=");
|
||||
builder.append(edpLoginMessage);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* 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 Sleeper
|
||||
{
|
||||
private String firstName;
|
||||
private Boolean active;
|
||||
private Boolean emailValidated;
|
||||
@SerializedName("isChild")
|
||||
private Boolean child;
|
||||
private String bedId;
|
||||
private String birthYear;
|
||||
private String zipCode;
|
||||
private String timezone;
|
||||
@SerializedName("isMale")
|
||||
private Boolean male;
|
||||
private Integer weight; // lbs
|
||||
private String duration;
|
||||
private String sleeperId;
|
||||
private Integer height; // inches
|
||||
private Long licenseVersion;
|
||||
private String username;
|
||||
private Integer birthMonth; // 0-based; 12 means not entered?
|
||||
private Integer sleepGoal;
|
||||
@SerializedName("isAccountOwner")
|
||||
private Boolean accountOwner;
|
||||
private String accountId;
|
||||
private String email;
|
||||
private String avatar;
|
||||
private String lastLogin; // should be ZonedDateTime but provider passes string "null" when missing
|
||||
private Integer side; // 0=left; 1=right
|
||||
|
||||
public String getFirstName()
|
||||
{
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName)
|
||||
{
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public Sleeper withFirstName(String firstName)
|
||||
{
|
||||
setFirstName(firstName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean isActive()
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(Boolean active)
|
||||
{
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public Sleeper withActive(Boolean active)
|
||||
{
|
||||
setActive(active);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean isEmailValidated()
|
||||
{
|
||||
return emailValidated;
|
||||
}
|
||||
|
||||
public void setEmailValidated(Boolean emailValidated)
|
||||
{
|
||||
this.emailValidated = emailValidated;
|
||||
}
|
||||
|
||||
public Sleeper withEmailValidated(Boolean emailValidated)
|
||||
{
|
||||
setEmailValidated(emailValidated);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean isChild()
|
||||
{
|
||||
return child;
|
||||
}
|
||||
|
||||
public void setChild(Boolean child)
|
||||
{
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
public Sleeper withChild(Boolean child)
|
||||
{
|
||||
setChild(child);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getBedId()
|
||||
{
|
||||
return bedId;
|
||||
}
|
||||
|
||||
public void setBedId(String bedId)
|
||||
{
|
||||
this.bedId = bedId;
|
||||
}
|
||||
|
||||
public Sleeper withBedId(String bedId)
|
||||
{
|
||||
setBedId(bedId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getBirthYear()
|
||||
{
|
||||
return birthYear;
|
||||
}
|
||||
|
||||
public void setBirthYear(String birthYear)
|
||||
{
|
||||
this.birthYear = birthYear;
|
||||
}
|
||||
|
||||
public Sleeper withBirthYear(String birthYear)
|
||||
{
|
||||
setBirthYear(birthYear);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getZipCode()
|
||||
{
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(String zipCode)
|
||||
{
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
|
||||
public Sleeper withZipCode(String zipCode)
|
||||
{
|
||||
setZipCode(zipCode);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTimezone()
|
||||
{
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone)
|
||||
{
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
public Sleeper withTimezone(String timezone)
|
||||
{
|
||||
setTimezone(timezone);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean isMale()
|
||||
{
|
||||
return male;
|
||||
}
|
||||
|
||||
public void setMale(Boolean male)
|
||||
{
|
||||
this.male = male;
|
||||
}
|
||||
|
||||
public Sleeper withMale(Boolean male)
|
||||
{
|
||||
setMale(male);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getWeight()
|
||||
{
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Integer weight)
|
||||
{
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public Sleeper withWeight(Integer weight)
|
||||
{
|
||||
setWeight(weight);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDuration()
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(String duration)
|
||||
{
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public Sleeper withDuration(String duration)
|
||||
{
|
||||
setDuration(duration);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSleeperId()
|
||||
{
|
||||
return sleeperId;
|
||||
}
|
||||
|
||||
public void setSleeperId(String sleeperId)
|
||||
{
|
||||
this.sleeperId = sleeperId;
|
||||
}
|
||||
|
||||
public Sleeper withSleeperId(String sleeperId)
|
||||
{
|
||||
setSleeperId(sleeperId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Integer height)
|
||||
{
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public Sleeper withHeight(Integer height)
|
||||
{
|
||||
setHeight(height);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getLicenseVersion()
|
||||
{
|
||||
return licenseVersion;
|
||||
}
|
||||
|
||||
public void setLicenseVersion(Long licenseVersion)
|
||||
{
|
||||
this.licenseVersion = licenseVersion;
|
||||
}
|
||||
|
||||
public Sleeper withLicenseVersion(Long licenseVersion)
|
||||
{
|
||||
setLicenseVersion(licenseVersion);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username)
|
||||
{
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public Sleeper withUsername(String username)
|
||||
{
|
||||
setUsername(username);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getBirthMonth()
|
||||
{
|
||||
return birthMonth;
|
||||
}
|
||||
|
||||
public void setBirthMonth(Integer birthMonth)
|
||||
{
|
||||
this.birthMonth = birthMonth;
|
||||
}
|
||||
|
||||
public Sleeper withBirthMonth(Integer birthMonth)
|
||||
{
|
||||
setBirthMonth(birthMonth);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getSleepGoal()
|
||||
{
|
||||
return sleepGoal;
|
||||
}
|
||||
|
||||
public void setSleepGoal(Integer sleepGoal)
|
||||
{
|
||||
this.sleepGoal = sleepGoal;
|
||||
}
|
||||
|
||||
public Sleeper withSleepGoal(Integer sleepGoal)
|
||||
{
|
||||
setSleepGoal(sleepGoal);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean isAccountOwner()
|
||||
{
|
||||
return accountOwner;
|
||||
}
|
||||
|
||||
public void setAccountOwner(Boolean accountOwner)
|
||||
{
|
||||
this.accountOwner = accountOwner;
|
||||
}
|
||||
|
||||
public Sleeper withAccountOwner(Boolean accountOwner)
|
||||
{
|
||||
setAccountOwner(accountOwner);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAccountId()
|
||||
{
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(String accountId)
|
||||
{
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public Sleeper withAccountId(String accountId)
|
||||
{
|
||||
setAccountId(accountId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email)
|
||||
{
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Sleeper withEmail(String email)
|
||||
{
|
||||
setEmail(email);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAvatar()
|
||||
{
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void setAvatar(String avatar)
|
||||
{
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public Sleeper withAvatar(String avatar)
|
||||
{
|
||||
setAvatar(avatar);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLastLogin()
|
||||
{
|
||||
return lastLogin;
|
||||
}
|
||||
|
||||
public void setLastLogin(String lastLogin)
|
||||
{
|
||||
this.lastLogin = lastLogin;
|
||||
}
|
||||
|
||||
public Sleeper withLastLogin(String lastLogin)
|
||||
{
|
||||
setLastLogin(lastLogin);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getSide()
|
||||
{
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(Integer side)
|
||||
{
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public Sleeper withSide(Integer side)
|
||||
{
|
||||
setSide(side);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((sleeperId == null) ? 0 : sleeperId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof Sleeper))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Sleeper other = (Sleeper)obj;
|
||||
if (sleeperId == null)
|
||||
{
|
||||
if (other.sleeperId != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!sleeperId.equals(other.sleeperId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Sleeper [firstName=");
|
||||
builder.append(firstName);
|
||||
builder.append(", active=");
|
||||
builder.append(active);
|
||||
builder.append(", emailValidated=");
|
||||
builder.append(emailValidated);
|
||||
builder.append(", child=");
|
||||
builder.append(child);
|
||||
builder.append(", bedId=");
|
||||
builder.append(bedId);
|
||||
builder.append(", birthYear=");
|
||||
builder.append(birthYear);
|
||||
builder.append(", zipCode=");
|
||||
builder.append(zipCode);
|
||||
builder.append(", timezone=");
|
||||
builder.append(timezone);
|
||||
builder.append(", male=");
|
||||
builder.append(male);
|
||||
builder.append(", weight=");
|
||||
builder.append(weight);
|
||||
builder.append(", duration=");
|
||||
builder.append(duration);
|
||||
builder.append(", sleeperId=");
|
||||
builder.append(sleeperId);
|
||||
builder.append(", height=");
|
||||
builder.append(height);
|
||||
builder.append(", licenseVersion=");
|
||||
builder.append(licenseVersion);
|
||||
builder.append(", username=");
|
||||
builder.append(username);
|
||||
builder.append(", birthMonth=");
|
||||
builder.append(birthMonth);
|
||||
builder.append(", sleepGoal=");
|
||||
builder.append(sleepGoal);
|
||||
builder.append(", accountOwner=");
|
||||
builder.append(accountOwner);
|
||||
builder.append(", accountId=");
|
||||
builder.append(accountId);
|
||||
builder.append(", email=");
|
||||
builder.append(email);
|
||||
builder.append(", avatar=");
|
||||
builder.append(avatar);
|
||||
builder.append(", lastLogin=");
|
||||
builder.append(lastLogin);
|
||||
builder.append(", side=");
|
||||
builder.append(side);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.time.Duration;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TimeSince
|
||||
{
|
||||
private static final Pattern PATTERN = Pattern.compile("(([0-9]+) d )?([0-9]{2}):([0-9]{2}):([0-9]{2})",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private Duration duration;
|
||||
|
||||
public Duration getDuration()
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(Duration duration)
|
||||
{
|
||||
this.duration = duration == null ? null : duration.abs();
|
||||
}
|
||||
|
||||
public TimeSince withDuration(long days, long hours, long minutes, long seconds)
|
||||
{
|
||||
return withDuration(Duration.ofSeconds(TimeUnit.DAYS.toSeconds(days)
|
||||
+ TimeUnit.HOURS.toSeconds(hours)
|
||||
+ TimeUnit.MINUTES.toSeconds(minutes)
|
||||
+ seconds));
|
||||
}
|
||||
|
||||
public TimeSince withDuration(Duration duration)
|
||||
{
|
||||
setDuration(duration);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((duration == null) ? 0 : duration.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof TimeSince))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TimeSince other = (TimeSince)obj;
|
||||
if (duration == null)
|
||||
{
|
||||
if (other.duration != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!duration.equals(other.duration))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
long totalDays = duration.toDays();
|
||||
long totalHours = duration.toHours();
|
||||
long totalMinutes = duration.toMinutes();
|
||||
long totalSeconds = duration.getSeconds();
|
||||
|
||||
long hours = totalHours - TimeUnit.DAYS.toHours(totalDays);
|
||||
long minutes = totalMinutes - TimeUnit.HOURS.toMinutes(totalHours);
|
||||
long seconds = totalSeconds - TimeUnit.MINUTES.toSeconds(totalMinutes);
|
||||
|
||||
if (totalDays > 0)
|
||||
{
|
||||
return String.format("%d d %02d:%02d:%02d", totalDays, hours, minutes, seconds);
|
||||
}
|
||||
|
||||
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
public static TimeSince parse(CharSequence text)
|
||||
{
|
||||
Objects.requireNonNull(text, "text");
|
||||
|
||||
Matcher matcher = PATTERN.matcher(text);
|
||||
if (!matcher.matches())
|
||||
{
|
||||
throw new DateTimeParseException("Text cannot be parsed", text, 0);
|
||||
}
|
||||
|
||||
String dayMatch = matcher.group(2);
|
||||
String hourMatch = matcher.group(3);
|
||||
String minuteMatch = matcher.group(4);
|
||||
String secondMatch = matcher.group(5);
|
||||
|
||||
StringBuilder sb = new StringBuilder("P");
|
||||
if (dayMatch != null)
|
||||
{
|
||||
sb.append(dayMatch).append('D');
|
||||
}
|
||||
sb.append('T')
|
||||
.append(hourMatch)
|
||||
.append('H')
|
||||
.append(minuteMatch)
|
||||
.append('M')
|
||||
.append(secondMatch)
|
||||
.append('S');
|
||||
|
||||
return new TimeSince().withDuration(Duration.parse(sb.toString()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.io.FileReader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.BedSideStatus;
|
||||
import org.openhab.binding.sleepiq.api.model.TimeSince;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BedSideStatusTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass()
|
||||
{
|
||||
gson = GsonGenerator.create(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAllFields() throws Exception
|
||||
{
|
||||
BedSideStatus bedSideStatus = new BedSideStatus().withAlertDetailedMessage("No Alert")
|
||||
.withAlertId(0L)
|
||||
.withInBed(false)
|
||||
.withLastLink(new TimeSince().withDuration(3,
|
||||
5,
|
||||
4,
|
||||
38))
|
||||
.withPressure(573)
|
||||
.withSleepNumber(55);
|
||||
assertEquals(readJson("bed-side-status.json"), gson.toJson(bedSideStatus));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeAllFields() throws Exception
|
||||
{
|
||||
try (FileReader reader = new FileReader(getTestDataFile("bed-side-status.json")))
|
||||
{
|
||||
BedSideStatus bedSideStatus = gson.fromJson(reader, BedSideStatus.class);
|
||||
assertEquals("No Alert", bedSideStatus.getAlertDetailedMessage());
|
||||
assertEquals(Long.valueOf(0L), bedSideStatus.getAlertId());
|
||||
assertFalse(bedSideStatus.isInBed());
|
||||
assertEquals(new TimeSince().withDuration(3, 5, 4, 38), bedSideStatus.getLastLink());
|
||||
assertEquals(Integer.valueOf(573), bedSideStatus.getPressure());
|
||||
assertEquals(Integer.valueOf(55), bedSideStatus.getSleepNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.FileReader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.BedSideStatus;
|
||||
import org.openhab.binding.sleepiq.api.model.BedStatus;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BedStatusTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass()
|
||||
{
|
||||
gson = GsonGenerator.create(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAllFields() throws Exception
|
||||
{
|
||||
BedStatus bedStatus = new BedStatus().withBedId("-9999999999999999999")
|
||||
.withLeftSide(new BedSideStatus().withInBed(true))
|
||||
.withRightSide(new BedSideStatus().withInBed(false))
|
||||
.withStatus(1L);
|
||||
assertEquals(readJson("bed-status.json"), gson.toJson(bedStatus));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeAllFields() throws Exception
|
||||
{
|
||||
try (FileReader reader = new FileReader(getTestDataFile("bed-status.json")))
|
||||
{
|
||||
BedStatus bedStatus = gson.fromJson(reader, BedStatus.class);
|
||||
assertEquals("-9999999999999999999", bedStatus.getBedId());
|
||||
assertEquals(Long.valueOf(1L), bedStatus.getStatus());
|
||||
|
||||
BedSideStatus leftSide = bedStatus.getLeftSide();
|
||||
assertNotNull(leftSide);
|
||||
assertTrue(leftSide.isInBed());
|
||||
|
||||
BedSideStatus rightSide = bedStatus.getRightSide();
|
||||
assertNotNull(rightSide);
|
||||
assertFalse(rightSide.isInBed());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BedTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass()
|
||||
{
|
||||
gson = GsonGenerator.create(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAllFields() throws Exception
|
||||
{
|
||||
Bed bed = new Bed().withAccountId("-8888888888888888888")
|
||||
.withBase("MODULAR")
|
||||
.withBedId("-9999999999999999999")
|
||||
.withDualSleep(true)
|
||||
.withKidsBed(false)
|
||||
.withMacAddress("AABBCCDDEEFF")
|
||||
.withModel("P5")
|
||||
.withName("Bed")
|
||||
.withPurchaseDate(ZonedDateTime.of(2017,
|
||||
2,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
ZoneId.of("Z").normalized()))
|
||||
.withReference("55555555555-5")
|
||||
.withRegistrationDate(ZonedDateTime.of(2017,
|
||||
2,
|
||||
17,
|
||||
2,
|
||||
14,
|
||||
10,
|
||||
0,
|
||||
ZoneId.of("Z").normalized()))
|
||||
.withReturnRequestStatus(0L)
|
||||
.withSerial("")
|
||||
.withSize("QUEEN")
|
||||
.withSku("QP5")
|
||||
.withSleeperLeftId("-2222222222222222222")
|
||||
.withSleeperRightId("-1111111111111111111")
|
||||
.withStatus(1L)
|
||||
.withTimezone("US/Pacific")
|
||||
.withVersion("")
|
||||
.withZipCode("90210");
|
||||
assertEquals(readJson("bed.json"), gson.toJson(bed));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeAllFields() throws Exception
|
||||
{
|
||||
try (FileReader reader = new FileReader(getTestDataFile("bed.json")))
|
||||
{
|
||||
Bed bed = gson.fromJson(reader, Bed.class);
|
||||
assertEquals("-8888888888888888888", bed.getAccountId());
|
||||
assertEquals("MODULAR", bed.getBase());
|
||||
assertEquals("-9999999999999999999", bed.getBedId());
|
||||
assertEquals(true, bed.isDualSleep());
|
||||
assertEquals(false, bed.isKidsBed());
|
||||
assertEquals("AABBCCDDEEFF", bed.getMacAddress());
|
||||
assertEquals("P5", bed.getModel());
|
||||
assertEquals("Bed", bed.getName());
|
||||
assertEquals(ZonedDateTime.of(2017, 2, 2, 0, 0, 1, 0, ZoneId.of("Z").normalized()),
|
||||
bed.getPurchaseDate());
|
||||
assertEquals("55555555555-5", bed.getReference());
|
||||
assertEquals(ZonedDateTime.of(2017, 2, 17, 2, 14, 10, 0, ZoneId.of("Z").normalized()),
|
||||
bed.getRegistrationDate());
|
||||
assertEquals(Long.valueOf(0L), bed.getReturnRequestStatus());
|
||||
assertEquals("", bed.getSerial());
|
||||
assertEquals("QUEEN", bed.getSize());
|
||||
assertEquals("QP5", bed.getSku());
|
||||
assertEquals("-2222222222222222222", bed.getSleeperLeftId());
|
||||
assertEquals("-1111111111111111111", bed.getSleeperRightId());
|
||||
assertEquals(Long.valueOf(1L), bed.getStatus());
|
||||
assertEquals("US/Pacific", bed.getTimezone());
|
||||
assertEquals("", bed.getVersion());
|
||||
assertEquals("90210", bed.getZipCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
||||
import org.openhab.binding.sleepiq.api.model.BedsResponse;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BedsResponseTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass()
|
||||
{
|
||||
gson = GsonGenerator.create(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAllFields() throws Exception
|
||||
{
|
||||
BedsResponse bedsResponse = new BedsResponse().withBeds(Arrays.asList(new Bed().withName("Bed1"),
|
||||
new Bed().withName("Bed2")));
|
||||
assertEquals(readJson("beds-response.json"), gson.toJson(bedsResponse));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeAllFields() throws Exception
|
||||
{
|
||||
try (FileReader reader = new FileReader(getTestDataFile("beds-response.json")))
|
||||
{
|
||||
BedsResponse bedsResponse = gson.fromJson(reader, BedsResponse.class);
|
||||
|
||||
List<Bed> beds = bedsResponse.getBeds();
|
||||
assertNotNull(beds);
|
||||
assertEquals(2, beds.size());
|
||||
assertEquals("Bed1", beds.get(0).getName());
|
||||
assertEquals("Bed2", beds.get(1).getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.BedStatus;
|
||||
import org.openhab.binding.sleepiq.api.model.FamilyStatus;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class FamilyStatusTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
|
||||
import java.io.FileReader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.PauseMode;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class PauseModeTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
|
||||
import java.io.FileReader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.Sleeper;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class SleeperTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass()
|
||||
{
|
||||
gson = GsonGenerator.create(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAllFields() throws Exception
|
||||
{
|
||||
Sleeper sleeper = new Sleeper().withAccountId("-5555555555555555555")
|
||||
.withAccountOwner(true)
|
||||
.withActive(true)
|
||||
.withAvatar("")
|
||||
.withBedId("-9999999999999999999")
|
||||
.withBirthMonth(6)
|
||||
.withBirthYear("1970")
|
||||
.withChild(false)
|
||||
.withDuration("")
|
||||
.withEmail("alice@domain.com")
|
||||
.withEmailValidated(true)
|
||||
.withFirstName("Alice")
|
||||
.withHeight(64)
|
||||
.withLastLogin("2017-02-17 20:19:36 CST")
|
||||
.withLicenseVersion(6L)
|
||||
.withMale(false)
|
||||
.withSide(1)
|
||||
.withSleeperId("-1111111111111111111")
|
||||
.withSleepGoal(450)
|
||||
.withTimezone("US/Pacific")
|
||||
.withUsername("alice@domain.com")
|
||||
.withWeight(110)
|
||||
.withZipCode("90210");
|
||||
assertEquals(readJson("sleeper.json"), gson.toJson(sleeper));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeLastLoginNull() throws Exception
|
||||
{
|
||||
Sleeper sleeper = new Sleeper().withLastLogin("null");
|
||||
assertEquals(readJson("sleeper-lastlogin-null.json"), gson.toJson(sleeper));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeAllFields() throws Exception
|
||||
{
|
||||
try (FileReader reader = new FileReader(getTestDataFile("sleeper.json")))
|
||||
{
|
||||
Sleeper sleeper = gson.fromJson(reader, Sleeper.class);
|
||||
assertEquals("-5555555555555555555", sleeper.getAccountId());
|
||||
assertEquals(true, sleeper.isAccountOwner());
|
||||
assertEquals(true, sleeper.isActive());
|
||||
assertEquals("", sleeper.getAvatar());
|
||||
assertEquals("-9999999999999999999", sleeper.getBedId());
|
||||
assertEquals(Integer.valueOf(6), sleeper.getBirthMonth());
|
||||
assertEquals("1970", sleeper.getBirthYear());
|
||||
assertEquals(false, sleeper.isChild());
|
||||
assertEquals("", sleeper.getDuration());
|
||||
assertEquals("alice@domain.com", sleeper.getEmail());
|
||||
assertEquals(true, sleeper.isEmailValidated());
|
||||
assertEquals("Alice", sleeper.getFirstName());
|
||||
assertEquals(Integer.valueOf(64), sleeper.getHeight());
|
||||
assertEquals("2017-02-17 20:19:36 CST", sleeper.getLastLogin());
|
||||
assertEquals(Long.valueOf(6L), sleeper.getLicenseVersion());
|
||||
assertEquals(false, sleeper.isMale());
|
||||
assertEquals(Integer.valueOf(1), sleeper.getSide());
|
||||
assertEquals("-1111111111111111111", sleeper.getSleeperId());
|
||||
assertEquals(Integer.valueOf(450), sleeper.getSleepGoal());
|
||||
assertEquals("US/Pacific", sleeper.getTimezone());
|
||||
assertEquals("alice@domain.com", sleeper.getUsername());
|
||||
assertEquals(Integer.valueOf(110), sleeper.getWeight());
|
||||
assertEquals("90210", sleeper.getZipCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeLastLoginNull() throws Exception
|
||||
{
|
||||
try (FileReader reader = new FileReader(getTestDataFile("sleeper-lastlogin-null.json")))
|
||||
{
|
||||
Sleeper sleeper = gson.fromJson(reader, Sleeper.class);
|
||||
assertEquals("null", sleeper.getLastLogin());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.impl.GsonGenerator;
|
||||
import org.openhab.binding.sleepiq.api.model.Sleeper;
|
||||
import org.openhab.binding.sleepiq.api.model.SleepersResponse;
|
||||
import org.openhab.binding.sleepiq.api.test.AbstractTest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class SleepersResponseTest extends AbstractTest
|
||||
{
|
||||
private static Gson gson;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass()
|
||||
{
|
||||
gson = GsonGenerator.create(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAllFields() throws Exception
|
||||
{
|
||||
SleepersResponse sleepersResponse = new SleepersResponse().withSleepers(Arrays.asList(new Sleeper().withFirstName("Alice"),
|
||||
new Sleeper().withFirstName("Bob")));
|
||||
assertEquals(readJson("sleepers-response.json"), gson.toJson(sleepersResponse));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeAllFields() throws Exception
|
||||
{
|
||||
try (FileReader reader = new FileReader(getTestDataFile("sleepers-response.json")))
|
||||
{
|
||||
SleepersResponse sleepersResponse = gson.fromJson(reader, SleepersResponse.class);
|
||||
|
||||
List<Sleeper> sleepers = sleepersResponse.getSleepers();
|
||||
assertNotNull(sleepers);
|
||||
assertEquals(2, sleepers.size());
|
||||
assertEquals("Alice", sleepers.get(0).getFirstName());
|
||||
assertEquals("Bob", sleepers.get(1).getFirstName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.Assert.assertEquals;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.sleepiq.api.model.TimeSince;
|
||||
|
||||
public class TimeSinceTest
|
||||
{
|
||||
@Test
|
||||
public void testWithDuration()
|
||||
{
|
||||
assertEquals(new TimeSince().withDuration(0, 0, 0, 0).getDuration(),
|
||||
new TimeSince().withDuration(Duration.parse("PT00H00M00S")).getDuration());
|
||||
assertEquals(new TimeSince().withDuration(0, 2, 3, 4).getDuration(),
|
||||
new TimeSince().withDuration(Duration.parse("PT02H03M04S")).getDuration());
|
||||
assertEquals(new TimeSince().withDuration(0, 12, 34, 56).getDuration(),
|
||||
new TimeSince().withDuration(Duration.parse("PT12H34M56S")).getDuration());
|
||||
assertEquals(new TimeSince().withDuration(1, 2, 3, 4).getDuration(),
|
||||
new TimeSince().withDuration(Duration.parse("P1DT02H03M04S")).getDuration());
|
||||
assertEquals(new TimeSince().withDuration(12, 23, 34, 45).getDuration(),
|
||||
new TimeSince().withDuration(Duration.parse("P12DT23H34M45S")).getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString()
|
||||
{
|
||||
assertEquals("00:00:00",
|
||||
new TimeSince().withDuration(Duration.parse("PT00H00M00S")).toString());
|
||||
assertEquals("02:03:04",
|
||||
new TimeSince().withDuration(Duration.parse("PT02H03M04S")).toString());
|
||||
assertEquals("12:34:56",
|
||||
new TimeSince().withDuration(Duration.parse("PT12H34M56S")).toString());
|
||||
assertEquals("1 d 02:03:04",
|
||||
new TimeSince().withDuration(Duration.parse("P1DT02H03M04S")).toString());
|
||||
assertEquals("12 d 23:34:45",
|
||||
new TimeSince().withDuration(Duration.parse("P12DT23H34M45S")).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParse()
|
||||
{
|
||||
assertEquals(Duration.parse("PT00H00M00S"), TimeSince.parse("00:00:00").getDuration());
|
||||
assertEquals(Duration.parse("PT2H3M4S"), TimeSince.parse("02:03:04").getDuration());
|
||||
assertEquals(Duration.parse("PT12H34M56S"), TimeSince.parse("12:34:56").getDuration());
|
||||
assertEquals(Duration.parse("P1DT2H3M4S"), TimeSince.parse("1 d 02:03:04").getDuration());
|
||||
assertEquals(Duration.parse("P12DT23H34M45S"),
|
||||
TimeSince.parse("12 d 23:34:45").getDuration());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractTest {
|
||||
private static final String RESOURCES_PATH = "src/test/resources/";
|
||||
|
||||
protected File getTestDataFile(String name) {
|
||||
return getTestDataPath(name).toFile();
|
||||
}
|
||||
|
||||
protected Path getTestDataPath(String name) {
|
||||
String packageName = this.getClass().getPackage().getName();
|
||||
|
||||
List<String> paths = new ArrayList<>();
|
||||
paths.addAll(Arrays.asList(packageName.split("\\.")));
|
||||
paths.add(name);
|
||||
|
||||
return Paths.get(RESOURCES_PATH, paths.toArray(new String[paths.size()]));
|
||||
}
|
||||
|
||||
protected String readJson(String jsonFileName) throws IOException {
|
||||
return String.join("\n", Files.readAllLines(getTestDataPath(jsonFileName)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.sleepiq-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-sleepiq" description="SleepIQ Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.sleepiq/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link SleepIQBinding} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SleepIQBindingConstants {
|
||||
public static final String BINDING_ID = "sleepiq";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
|
||||
// bridge
|
||||
public static final ThingTypeUID THING_TYPE_CLOUD = new ThingTypeUID(BINDING_ID, "cloud");
|
||||
|
||||
// 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");
|
||||
|
||||
// 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_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_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_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_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_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_RIGHT_ALERT_DETAILED_MESSAGE = "right#alertDetailedMessage";
|
||||
|
||||
// List of non-standard Properties
|
||||
public static final String PROPERTY_BASE = "base";
|
||||
public static final String PROPERTY_KIDS_BED = "kidsBed";
|
||||
public static final String PROPERTY_MAC_ADDRESS = "macAddress";
|
||||
public static final String PROPERTY_NAME = "name";
|
||||
public static final String PROPERTY_PURCHASE_DATE = "purchaseDate";
|
||||
public static final String PROPERTY_SIZE = "size";
|
||||
public static final String PROPERTY_SKU = "sku";
|
||||
|
||||
private SleepIQBindingConstants() {
|
||||
// utility class
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal;
|
||||
|
||||
/**
|
||||
* The {@link SleepIQConfigStatusMessage} defines the keys to be used for configuration status messages.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*
|
||||
*/
|
||||
public interface SleepIQConfigStatusMessage {
|
||||
public static final String USERNAME_MISSING = "missing-username-configuration";
|
||||
public static final String PASSWORD_MISSING = "missing-password-configuration";
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.openhab.binding.sleepiq.internal.discovery.SleepIQBedDiscoveryService;
|
||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQCloudHandler;
|
||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQDualBedHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SleepIQHandlerFactory} is responsible for creating thing handlers.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.sleepiq")
|
||||
public class SleepIQHandlerFactory extends BaseThingHandlerFactory {
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections
|
||||
.unmodifiableSet(Stream.concat(SleepIQCloudHandler.SUPPORTED_THING_TYPE_UIDS.stream(),
|
||||
SleepIQDualBedHandler.SUPPORTED_THING_TYPE_UIDS.stream()).collect(Collectors.toSet()));
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SleepIQHandlerFactory.class);
|
||||
|
||||
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceReg = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(final ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThingHandler createHandler(final Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (SleepIQCloudHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
|
||||
logger.debug("Creating SleepIQ cloud thing handler");
|
||||
SleepIQCloudHandler cloudHandler = new SleepIQCloudHandler((Bridge) thing);
|
||||
registerBedDiscoveryService(cloudHandler);
|
||||
return cloudHandler;
|
||||
} else if (SleepIQDualBedHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
|
||||
logger.debug("Creating SleepIQ dual bed thing handler");
|
||||
return new SleepIQDualBedHandler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeHandler(final ThingHandler thingHandler) {
|
||||
logger.debug("Removing SleepIQ thing handler");
|
||||
|
||||
if (thingHandler instanceof SleepIQCloudHandler) {
|
||||
unregisterBedDiscoveryService((SleepIQCloudHandler) thingHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given cloud handler to participate in discovery of new beds.
|
||||
*
|
||||
* @param cloudHandler the cloud handler to register (must not be <code>null</code>)
|
||||
*/
|
||||
private synchronized void registerBedDiscoveryService(final SleepIQCloudHandler cloudHandler) {
|
||||
logger.debug("Registering bed discovery service");
|
||||
SleepIQBedDiscoveryService discoveryService = new SleepIQBedDiscoveryService(cloudHandler);
|
||||
discoveryServiceReg.put(cloudHandler.getThing().getUID(),
|
||||
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the given cloud handler from participating in discovery of new beds.
|
||||
*
|
||||
* @param cloudHandler the cloud handler to unregister (must not be <code>null</code>)
|
||||
*/
|
||||
private synchronized void unregisterBedDiscoveryService(final SleepIQCloudHandler cloudHandler) {
|
||||
ThingUID thingUID = cloudHandler.getThing().getUID();
|
||||
ServiceRegistration<?> serviceReg = discoveryServiceReg.remove(thingUID);
|
||||
if (serviceReg != null) {
|
||||
logger.debug("Unregistering bed discovery service");
|
||||
serviceReg.unregister();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal.config;
|
||||
|
||||
/**
|
||||
* Configuration class for a SleepIQ bed.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
public class SleepIQBedConfiguration {
|
||||
public static final String BED_ID = "bedId";
|
||||
|
||||
public String bedId;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal.config;
|
||||
|
||||
/**
|
||||
* Configuration class for the SleepIQ cloud.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
public class SleepIQCloudConfiguration {
|
||||
public static final String USERNAME = "username";
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String POLLING_INTERVAL = "pollingInterval";
|
||||
|
||||
public String username;
|
||||
public String password;
|
||||
public int pollingInterval;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal.discovery;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
||||
import org.openhab.binding.sleepiq.internal.SleepIQBindingConstants;
|
||||
import org.openhab.binding.sleepiq.internal.config.SleepIQBedConfiguration;
|
||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQCloudHandler;
|
||||
import org.openhab.binding.sleepiq.internal.handler.SleepIQDualBedHandler;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SleepIQBedDiscoveryService} is responsible for processing the
|
||||
* results of devices found through the SleepIQ cloud service.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
public class SleepIQBedDiscoveryService extends AbstractDiscoveryService {
|
||||
private static final int TIMEOUT = 60;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SleepIQBedDiscoveryService.class);
|
||||
|
||||
private final SleepIQCloudHandler cloudHandler;
|
||||
|
||||
/**
|
||||
* Discovers beds in the SleepIQ cloud service account.
|
||||
*
|
||||
* @param cloudHandler the cloud service handler (bridge)
|
||||
*/
|
||||
public SleepIQBedDiscoveryService(final SleepIQCloudHandler cloudHandler) {
|
||||
super(SleepIQDualBedHandler.SUPPORTED_THING_TYPE_UIDS, TIMEOUT, true);
|
||||
this.cloudHandler = cloudHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
logger.debug("Starting background discovery for new beds");
|
||||
startScan();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScan() {
|
||||
logger.debug("Starting scan for new beds");
|
||||
|
||||
for (Bed bed : cloudHandler.getBeds()) {
|
||||
// only dual chamber beds are supported currently
|
||||
if (!bed.isDualSleep()) {
|
||||
logger.info("Found a bed that is not dual chamber - currently unsupported");
|
||||
continue;
|
||||
}
|
||||
|
||||
ThingUID bridgeUID = cloudHandler.getThing().getUID();
|
||||
ThingUID thingUID = new ThingUID(SleepIQBindingConstants.THING_TYPE_DUAL_BED, bridgeUID,
|
||||
bed.getMacAddress());
|
||||
|
||||
// thing already exists
|
||||
if (cloudHandler.getThing().getThing(thingUID) != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.debug("New bed found with MAC address {}", bed.getMacAddress());
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
Map<String, Object> properties = (Map) cloudHandler.updateProperties(bed, new HashMap<>());
|
||||
properties.put(SleepIQBedConfiguration.BED_ID, bed.getBedId());
|
||||
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
|
||||
.withBridge(bridgeUID).withLabel(bed.getName() + " - " + bed.getModel()).build();
|
||||
thingDiscovered(discoveryResult);
|
||||
}
|
||||
|
||||
stopScan();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal.handler;
|
||||
|
||||
import org.openhab.binding.sleepiq.api.SleepIQ;
|
||||
import org.openhab.binding.sleepiq.api.model.BedStatus;
|
||||
|
||||
/**
|
||||
* The {@link BedStatusListener} is notified when a chamber is updated.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
public interface BedStatusListener {
|
||||
/**
|
||||
* This method will be called whenever a new bed status is received by the cloud handler.
|
||||
*
|
||||
* @param cloud the cloud service that can be used to gather additional information
|
||||
* @param status the status returned from the cloud service
|
||||
*/
|
||||
public void onBedStateChanged(SleepIQ cloud, BedStatus status);
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal.handler;
|
||||
|
||||
import static org.openhab.binding.sleepiq.internal.SleepIQBindingConstants.THING_TYPE_CLOUD;
|
||||
import static org.openhab.binding.sleepiq.internal.config.SleepIQCloudConfiguration.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
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.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.SleepIQConfigStatusMessage;
|
||||
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.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.ConfigStatusBridgeHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SleepIQCloudHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections.singleton(THING_TYPE_CLOUD);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SleepIQCloudHandler.class);
|
||||
|
||||
private final List<BedStatusListener> bedStatusListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private ExpiringCache<FamilyStatus> statusCache;
|
||||
|
||||
private ScheduledFuture<?> pollingJob;
|
||||
|
||||
private SleepIQ cloud;
|
||||
|
||||
public SleepIQCloudHandler(final Bridge bridge) {
|
||||
super(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
try {
|
||||
logger.debug("Configuring bed status cache");
|
||||
statusCache = new ExpiringCache<>(TimeUnit.SECONDS.toMillis(getPollingInterval() / 2),
|
||||
() -> cloud.getFamilyStatus());
|
||||
|
||||
createCloudConnection();
|
||||
|
||||
logger.debug("Setting SleepIQ cloud online");
|
||||
updateListenerManagement();
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} catch (UnauthorizedException e) {
|
||||
logger.debug("SleepIQ cloud authentication failed", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Invalid SleepIQ credentials");
|
||||
} catch (LoginException e) {
|
||||
logger.debug("SleepIQ cloud login failed", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"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.
|
||||
*
|
||||
* @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);
|
||||
|
||||
logger.debug("Authenticating at the SleepIQ cloud service");
|
||||
cloud.login();
|
||||
|
||||
logger.info("Successfully authenticated at the SleepIQ cloud service");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void dispose() {
|
||||
logger.debug("Disposing SleepIQ cloud handler");
|
||||
|
||||
if (pollingJob != null && !pollingJob.isCancelled()) {
|
||||
pollingJob.cancel(true);
|
||||
pollingJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start or stop a background polling job to look for bed status updates based on whether or not there are any
|
||||
* 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
|
||||
*/
|
||||
private int getPollingInterval() {
|
||||
return getConfigAs(SleepIQCloudConfiguration.class).pollingInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the latest status on all beds and update all registered listeners.
|
||||
*/
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given listener to receive bed status updates.
|
||||
*
|
||||
* @param listener the listener to register
|
||||
*/
|
||||
public void registerBedStatusListener(final BedStatusListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
bedStatusListeners.add(listener);
|
||||
refreshBedStatus();
|
||||
updateListenerManagement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the given listener from further bed status updates.
|
||||
*
|
||||
* @param listener the listener to unregister
|
||||
* @return <code>true</code> if listener was previously registered and is now unregistered; <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
public boolean unregisterBedStatusListener(final BedStatusListener listener) {
|
||||
boolean result = bedStatusListeners.remove(listener);
|
||||
if (result) {
|
||||
updateListenerManagement();
|
||||
}
|
||||
|
||||
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 (StringUtils.isEmpty(username)) {
|
||||
configStatusMessages.add(ConfigStatusMessage.Builder.error(USERNAME)
|
||||
.withMessageKeySuffix(SleepIQConfigStatusMessage.USERNAME_MISSING).withArguments(USERNAME).build());
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(password)) {
|
||||
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.
|
||||
*
|
||||
* @return the list of beds (never <code>null</code>)
|
||||
*/
|
||||
public List<Bed> getBeds() {
|
||||
return cloud.getBeds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Bed} corresponding to the given identifier.
|
||||
*
|
||||
* @param bedId the bed identifier
|
||||
* @return the identified {@link Bed} or <code>null</code> if no such bed exists
|
||||
*/
|
||||
public Bed getBed(final String bedId) {
|
||||
for (Bed bed : getBeds()) {
|
||||
if (bedId.equals(bed.getBedId())) {
|
||||
return bed;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the given properties with attributes of the given bed. If no properties are given, a new map will be
|
||||
* created.
|
||||
*
|
||||
* @param bed the source of data
|
||||
* @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
|
||||
*/
|
||||
public Map<String, String> updateProperties(final Bed bed, Map<String, String> properties) {
|
||||
if (bed != null) {
|
||||
properties.put(Thing.PROPERTY_MODEL_ID, bed.getModel());
|
||||
properties.put(SleepIQBindingConstants.PROPERTY_BASE, bed.getBase());
|
||||
if (bed.isKidsBed() != null) {
|
||||
properties.put(SleepIQBindingConstants.PROPERTY_KIDS_BED, bed.isKidsBed().toString());
|
||||
}
|
||||
properties.put(SleepIQBindingConstants.PROPERTY_MAC_ADDRESS, bed.getMacAddress());
|
||||
properties.put(SleepIQBindingConstants.PROPERTY_NAME, bed.getName());
|
||||
if (bed.getPurchaseDate() != null) {
|
||||
properties.put(SleepIQBindingConstants.PROPERTY_PURCHASE_DATE, bed.getPurchaseDate().toString());
|
||||
}
|
||||
properties.put(SleepIQBindingConstants.PROPERTY_SIZE, bed.getSize());
|
||||
properties.put(SleepIQBindingConstants.PROPERTY_SKU, bed.getSku());
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.sleepiq.internal.handler;
|
||||
|
||||
import static org.openhab.binding.sleepiq.internal.SleepIQBindingConstants.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.openhab.binding.sleepiq.api.SleepIQ;
|
||||
import org.openhab.binding.sleepiq.api.model.Bed;
|
||||
import org.openhab.binding.sleepiq.api.model.BedSideStatus;
|
||||
import org.openhab.binding.sleepiq.api.model.BedStatus;
|
||||
import org.openhab.binding.sleepiq.internal.config.SleepIQBedConfiguration;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
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.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SleepIQDualBedHandler} is responsible for handling channel state updates from the cloud service.
|
||||
*
|
||||
* @author Gregory Moyer - Initial contribution
|
||||
*/
|
||||
public class SleepIQDualBedHandler extends BaseThingHandler implements BedStatusListener {
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections.singleton(THING_TYPE_DUAL_BED);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SleepIQDualBedHandler.class);
|
||||
|
||||
private volatile String bedId;
|
||||
|
||||
public SleepIQDualBedHandler(final Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Verifying SleepIQ cloud/bridge configuration");
|
||||
|
||||
Bridge bridge = getBridge();
|
||||
if (bridge == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"No cloud service bridge has been configured");
|
||||
return;
|
||||
}
|
||||
|
||||
ThingHandler handler = bridge.getHandler();
|
||||
if (!(handler instanceof SleepIQCloudHandler)) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Incorrect bridge thing found");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug("Reading SleepIQ bed binding configuration");
|
||||
bedId = getConfigAs(SleepIQBedConfiguration.class).bedId;
|
||||
|
||||
logger.debug("Registering SleepIQ bed status listener");
|
||||
SleepIQCloudHandler cloudHandler = (SleepIQCloudHandler) handler;
|
||||
cloudHandler.registerBedStatusListener(this);
|
||||
|
||||
if (ThingStatus.ONLINE != bridge.getStatus()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
} else {
|
||||
updateProperties();
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
super.bridgeStatusChanged(bridgeStatusInfo);
|
||||
|
||||
if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
|
||||
updateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProperties() {
|
||||
logger.debug("Updating SleepIQ bed properties for bed {}", bedId);
|
||||
|
||||
SleepIQCloudHandler cloudHandler = (SleepIQCloudHandler) getBridge().getHandler();
|
||||
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()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Disposing bed handler for bed {}", 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;
|
||||
}
|
||||
|
||||
logger.debug("Updating left side status for bed {}", bedId);
|
||||
BedSideStatus left = status.getLeftSide();
|
||||
updateState(CHANNEL_LEFT_IN_BED, left.isInBed() ? OnOffType.ON : OnOffType.OFF);
|
||||
updateState(CHANNEL_LEFT_SLEEP_NUMBER, new DecimalType(left.getSleepNumber()));
|
||||
updateState(CHANNEL_LEFT_PRESSURE, new DecimalType(left.getPressure()));
|
||||
updateState(CHANNEL_LEFT_LAST_LINK, new StringType(left.getLastLink().toString()));
|
||||
updateState(CHANNEL_LEFT_ALERT_ID, new DecimalType(left.getAlertId()));
|
||||
updateState(CHANNEL_LEFT_ALERT_DETAILED_MESSAGE, new StringType(left.getAlertDetailedMessage()));
|
||||
|
||||
logger.debug("Updating right side status for bed {}", bedId);
|
||||
BedSideStatus right = status.getRightSide();
|
||||
updateState(CHANNEL_RIGHT_IN_BED, right.isInBed() ? OnOffType.ON : OnOffType.OFF);
|
||||
updateState(CHANNEL_RIGHT_SLEEP_NUMBER, new DecimalType(right.getSleepNumber()));
|
||||
updateState(CHANNEL_RIGHT_PRESSURE, new DecimalType(right.getPressure()));
|
||||
updateState(CHANNEL_RIGHT_LAST_LINK, new StringType(right.getLastLink().toString()));
|
||||
updateState(CHANNEL_RIGHT_ALERT_ID, new DecimalType(right.getAlertId()));
|
||||
updateState(CHANNEL_RIGHT_ALERT_DETAILED_MESSAGE, new StringType(right.getAlertDetailedMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(final ChannelUID channelUID, final Command command) {
|
||||
// all channels are read-only
|
||||
|
||||
if (command == RefreshType.REFRESH) {
|
||||
SleepIQCloudHandler cloudHandler = (SleepIQCloudHandler) getBridge().getHandler();
|
||||
cloudHandler.refreshBedStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="sleepiq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>SleepIQ Binding</name>
|
||||
<description>This is the binding for the Sleep Number SleepIQ system.</description>
|
||||
<author>Gregory Moyer</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,3 @@
|
||||
# configuration messages
|
||||
config-status.error.missing-username-configuration=No username for the SleepIQ cloud has been provided.
|
||||
config-status.error.missing-password-configuration=No password for the SleepIQ cloud has been provided.
|
||||
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="sleepiq"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<!-- SleepIQ Cloud Service -->
|
||||
<bridge-type id="cloud">
|
||||
<label>SleepIQ Cloud</label>
|
||||
<description>The SleepIQ cloud service provides connections to all beds in an account.</description>
|
||||
|
||||
<properties>
|
||||
<property name="vendor">Select Comfort</property>
|
||||
</properties>
|
||||
|
||||
<config-description>
|
||||
<parameter name="username" type="text">
|
||||
<label>Username</label>
|
||||
<description>Username of a registered SleepIQ account owner</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
<parameter name="password" type="text">
|
||||
<context>password</context>
|
||||
<label>Password</label>
|
||||
<description>Password of a registered SleepIQ account owner</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="pollingInterval" type="integer" min="30" step="30">
|
||||
<label>Polling Interval</label>
|
||||
<description>Seconds between fetching values from the cloud service</description>
|
||||
<required>true</required>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
<!-- Bed thing with a single chamber -->
|
||||
<!-- Single chamber bed support is disabled until test devices are available
|
||||
<thing-type id="singleBed">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="cloud" />
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Single Chamber Bed</label>
|
||||
<description>A Sleep Number bed with SleepIQ and a single air chamber</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="bed" typeId="chamberGroupType"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="bedId" type="text">
|
||||
<label>Bed ID</label>
|
||||
<description>The bed identifier identifies a specific bed</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
-->
|
||||
|
||||
<!-- Bed thing with two separate chambers -->
|
||||
<thing-type id="dualBed">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="cloud"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Dual Chamber Bed</label>
|
||||
<description>A Sleep Number bed with SleepIQ and two individual air chambers</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="left" typeId="chamberGroupType"/>
|
||||
<channel-group id="right" typeId="chamberGroupType"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="bedId" type="text">
|
||||
<label>Bed ID</label>
|
||||
<description>The bed identifier identifies a specific bed</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<!-- The attributes of a chamber -->
|
||||
<channel-group-type id="chamberGroupType">
|
||||
<label>Chamber</label>
|
||||
<channels>
|
||||
<channel id="inBed" typeId="inBedType"/>
|
||||
<channel id="sleepNumber" typeId="sleepNumberType"/>
|
||||
<channel id="pressure" typeId="pressureType"/>
|
||||
<channel id="lastLink" typeId="lastLinkType"/>
|
||||
<channel id="alertId" typeId="alertIdType"/>
|
||||
<channel id="alertDetailedMessage" typeId="alertDetailedMessageType"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-type id="inBedType">
|
||||
<item-type>Switch</item-type>
|
||||
<label>In Bed</label>
|
||||
<description>The presence of a person or object on the chamber</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="sleepNumberType">
|
||||
<item-type>Number</item-type>
|
||||
<label>Sleep Number</label>
|
||||
<description>The Sleep Number setting of the chamber</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="pressureType">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pressure</label>
|
||||
<description>The current pressure inside the chamber</description>
|
||||
<state pattern="%d kPa" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="lastLinkType">
|
||||
<item-type>String</item-type>
|
||||
<label>Last Link</label>
|
||||
<description>The amount of time that has passed since a connection was made from the chamber to the cloud service (D d
|
||||
HH:MM:SS)</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="alertIdType">
|
||||
<item-type>Number</item-type>
|
||||
<label>Alert ID</label>
|
||||
<description>Identifier for an alert condition with the chamber</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="alertDetailedMessageType">
|
||||
<item-type>String</item-type>
|
||||
<label>Alert Detailed Message</label>
|
||||
<description>A detailed message describing an alert condition with the chamber</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"isInBed": false,
|
||||
"alertDetailedMessage": "No Alert",
|
||||
"sleepNumber": 55,
|
||||
"alertId": 0,
|
||||
"lastLink": "3 d 05:04:38",
|
||||
"pressure": 573
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"status": 1,
|
||||
"bedId": "-9999999999999999999",
|
||||
"leftSide": {
|
||||
"isInBed": true
|
||||
},
|
||||
"rightSide": {
|
||||
"isInBed": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"registrationDate": "2017-02-17T02:14:10Z",
|
||||
"sleeperRightId": "-1111111111111111111",
|
||||
"base": "MODULAR",
|
||||
"returnRequestStatus": 0,
|
||||
"size": "QUEEN",
|
||||
"name": "Bed",
|
||||
"serial": "",
|
||||
"isKidsBed": false,
|
||||
"dualSleep": true,
|
||||
"bedId": "-9999999999999999999",
|
||||
"status": 1,
|
||||
"sleeperLeftId": "-2222222222222222222",
|
||||
"version": "",
|
||||
"accountId": "-8888888888888888888",
|
||||
"timezone": "US/Pacific",
|
||||
"model": "P5",
|
||||
"purchaseDate": "2017-02-02T00:00:01Z",
|
||||
"macAddress": "AABBCCDDEEFF",
|
||||
"sku": "QP5",
|
||||
"zipcode": "90210",
|
||||
"reference": "55555555555-5"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"beds": [
|
||||
{
|
||||
"name": "Bed1"
|
||||
},
|
||||
{
|
||||
"name": "Bed2"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"beds": [
|
||||
{
|
||||
"status": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"accountId": "-8888888888888888888",
|
||||
"bedId": "-9999999999999999999",
|
||||
"pauseMode": "off"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"lastLogin": "null"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"firstName": "Alice",
|
||||
"active": true,
|
||||
"emailValidated": true,
|
||||
"isChild": false,
|
||||
"bedId": "-9999999999999999999",
|
||||
"birthYear": "1970",
|
||||
"zipCode": "90210",
|
||||
"timezone": "US/Pacific",
|
||||
"isMale": false,
|
||||
"weight": 110,
|
||||
"duration": "",
|
||||
"sleeperId": "-1111111111111111111",
|
||||
"height": 64,
|
||||
"licenseVersion": 6,
|
||||
"username": "alice@domain.com",
|
||||
"birthMonth": 6,
|
||||
"sleepGoal": 450,
|
||||
"isAccountOwner": true,
|
||||
"accountId": "-5555555555555555555",
|
||||
"email": "alice@domain.com",
|
||||
"avatar": "",
|
||||
"lastLogin": "2017-02-17 20:19:36 CST",
|
||||
"side": 1
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"sleepers": [
|
||||
{
|
||||
"firstName": "Alice"
|
||||
},
|
||||
{
|
||||
"firstName": "Bob"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user