added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.neato/.classpath
Normal file
32
bundles/org.openhab.binding.neato/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.neato/.project
Normal file
23
bundles/org.openhab.binding.neato/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.neato</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.binding.neato/NOTICE
Normal file
13
bundles/org.openhab.binding.neato/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
110
bundles/org.openhab.binding.neato/README.md
Normal file
110
bundles/org.openhab.binding.neato/README.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Neato Binding
|
||||
|
||||
This binding is used to connect your openHAB 2 system with Neato web (where you log in and find Your Neato's). The binding supports discovery via configuring your login and password to a bridge. From the binding, you will get status of your vacuum cleaners and also a command channel where you can control them. Since the binding uses a polling mechanism, there may be some latency depending on your setting regarding refresh time.
|
||||
|
||||
For log in transaction, the binding uses Neato Beehive API and for status and control, the binding uses Nucleao API.
|
||||
|
||||
## Supported Things
|
||||
|
||||
Supported thing types
|
||||
|
||||
* neatoaccount (bridge)
|
||||
* vacuumcleaner
|
||||
|
||||
A bridge is required to connect to your Neato Cloud account.
|
||||
|
||||
All "Connected" type vacuum cleaners should be supported by this binding since they are supported by the Neato API. As of todays date, it is only verified with Neato Connected and Neato D7 vacuum cleaners.
|
||||
|
||||
## Discovery
|
||||
|
||||
Discovery is used _after_ a bridge has been created and configured with your login information.
|
||||
|
||||
1. Add the binding
|
||||
2. Add a new thing of type NeatoAccount and configure with username and password
|
||||
3. Go to Inbox and start discovery of Vacuums using Neato Binding
|
||||
4. Vacuums should appear in your inbox!
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
In order to manually create a thing file and not use the discovery routine you will need to know the vacuums serial number as well as the secret used in web service calls. This is a bit difficult to get. The easiest way of getting this information is to use the third party python library that is available at https://github.com/stianaske/pybotvac.
|
||||
|
||||
Neato Account Config
|
||||
|
||||
| Config | Description |
|
||||
|----------|------------------------------------ |
|
||||
| email | Email address tied to Neato Account |
|
||||
| password | Password tied to Neato Account |
|
||||
|
||||
Vacuum Cleaner Config
|
||||
|
||||
| Config | Description |
|
||||
|----------|-----------------------------------------|
|
||||
| serial | Serial Number of your Neato Robot |
|
||||
| secret | Secret for accessing Neato web services (see note above) |
|
||||
| refresh | Refresh time interval in seconds for updates from the Neato Web Service. Defaults to 60 sec |
|
||||
|
||||
## Channels
|
||||
|
||||
| Channel | Type | Label | Description | Read Only |
|
||||
|---------------------|--------|----------------------------|-------------------------------------------------------------------------------------------|-----------|
|
||||
| battery-level| Number | Battery Level | Battery Level of the vacuum cleaner. | True |
|
||||
| state | String | Current State | Current state of the vacuum cleaner. | True |
|
||||
| available-services | String | Current available services | List of services that are currently available for the vacuum cleaner | True |
|
||||
| action | String | Current Action | Current action of the vacuum cleaner. | True |
|
||||
| dock-has-been-seen | Switch | Dock has been seen | True or False value if the dock has been seen | True |
|
||||
| is-docked | Switch | Is docked | Is the vacuum cleaner in the docking station? | True |
|
||||
| is-scheduled | Switch | Is scheduled enabled | True or False value if the vacuum cleaner is scheduled for cleaning. | True |
|
||||
| is-charging | Switch | Is Charging | Is the vacuum cleaner currently charging? | True |
|
||||
| available-commands | String | Available Commands | List of available commands. | True |
|
||||
| error | String | Error | Current error message in system. | True |
|
||||
| command | String | Send Command | Send Commands to Vacuum Cleaner. (clean with map, clean, pause, resume, stop, dock) | False |
|
||||
| cleaning-category | String | Cleaning Category | Current or Last category of the cleaning. Manual, Normal House Cleaning or Spot Cleaning. | True |
|
||||
| cleaning-mode | String | Cleaning Mode | Current or Last cleaning mode. Eco or Turbo. | True |
|
||||
| cleaning-modifier | String | Cleaning Modifier | Modifier of current or last cleaning. Normal or Double. | True |
|
||||
| cleaning-spotwidth | Number | Spot Width | Current or Last cleaning, width of spot. 100-400cm. | True |
|
||||
| cleaning-spotheight | Number | Spot Height | Current or Last cleaning, height of spot. 100-400cm. | True |
|
||||
|
||||
## Full Example
|
||||
|
||||
Below you will find examples of the necessary files:
|
||||
|
||||
**neato.items**
|
||||
|
||||
```
|
||||
Group GNeato
|
||||
Number FannDammBattery "Battery level [%.0f %%]" <battery> (GNeato) { channel = "neato:vacuumcleaner:fanndamm:battery-level" }
|
||||
String FannDammState "Status [MAP(neato-sv.map):%s]" (GNeato) { channel = "neato:vacuumcleaner:fanndamm:state" }
|
||||
String FannDammError "Error [%s]" (GNeato) { channel = "neato:vacuumcleaner:fanndamm:error" }
|
||||
String FannDammAction "Action [MAP(neato-sv.map):%s]" (GNeato) { channel = "neato:vacuumcleaner:fanndamm:action" }
|
||||
Switch FannDammDockHasBeenSeen "Seen dock [%s]" <present> (GNeato) { channel = "neato:vacuumcleaner:fanndamm:dock-has-been-seen" }
|
||||
Switch FannDammIsDocked "In dock [MAP(neato-sv.map):%s]" <present> (GNeato) { channel = "neato:vacuumcleaner:fanndamm:is-docked" }
|
||||
Switch FannDammIsScheduled "Scheduled [%s]" (GNeato) { channel = "neato:vacuumcleaner:fanndamm:is-scheduled" }
|
||||
Switch FannDammIsCharging "Is Charging [%s]" <heating> (GNeato) { channel = "neato:vacuumcleaner:fanndamm:is-charging" }
|
||||
String FannDammCategory "Cleaning Category [MAP(neato-sv.map):%s]" (GNeato) { channel = "neato:vacuumcleaner:fanndamm:cleaning-category" }
|
||||
String FannDammMode "Cleaning Mode [MAP(neato-sv.map):%s]" (GNeato) { channel = "neato:vacuumcleaner:fanndamm:cleaning-mode" }
|
||||
String FannDammModifier "Cleaning Modifier [MAP(neato-sv.map):%s]" (GNeato) { channel = "neato:vacuumcleaner:fanndamm:cleaning-modifier" }
|
||||
Number FannDammSpotWidth "SpotWidth [%.0f]" <niveau> (GNeato) { channel = "neato:vacuumcleaner:fanndamm:cleaning-spotwidth" }
|
||||
Number FannDammSpotHeight "SpotHeight [%.0f]" <niveau> (GNeato) { channel = "neato:vacuumcleaner:fanndamm:cleaning-spotheight" }
|
||||
String FannDammCommand "Send Command" { channel = "neato:vacuumcleaner:fanndamm:command" }
|
||||
```
|
||||
|
||||
**sitemap**
|
||||
|
||||
```
|
||||
Frame label="Neato BotVac Connected" {
|
||||
Switch item=FannDammCommand mappings=[cleanWithMap="cleanWithMap", clean="Clean",stop="Stop",pause="Pause",resume="Resume", dock="Send to dock"]
|
||||
Text item=FannDammBattery label="Battery level"
|
||||
Text item=FannDammState
|
||||
Text item=FannDammError label="Error Message" icon="siren"
|
||||
Text item=FannDammAction label="Activity"
|
||||
Text item=FannDammIsDocked label="In dock"
|
||||
Group label="Mer information" item=GNeato
|
||||
}
|
||||
```
|
||||
|
||||
**neato.things**
|
||||
|
||||
```
|
||||
neato:vacuumcleaner:fanndamm [ serial="vacuumcleaner-serial", secret="secret-string"]
|
||||
```
|
||||
|
||||
17
bundles/org.openhab.binding.neato/pom.xml
Normal file
17
bundles/org.openhab.binding.neato/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.neato</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Neato Binding</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.neato-${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-neato" description="Neato Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.neato/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.neato.internal;
|
||||
|
||||
/**
|
||||
* The {@link CouldNotFindRobotException} is the internal excepton class for the case when robot could not be found.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class CouldNotFindRobotException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CouldNotFindRobotException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 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.neato.internal;
|
||||
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link NeatoBinding} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class NeatoBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "neato";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID BRIDGE_TYPE_NEATOACCOUNT = new ThingTypeUID(BINDING_ID, "neatoaccount");
|
||||
public static final ThingTypeUID THING_TYPE_VACUUMCLEANER = new ThingTypeUID(BINDING_ID, "vacuumcleaner");
|
||||
|
||||
// List of all Channel ids
|
||||
public static final String CHANNEL_BATTERY = "battery-level";
|
||||
public static final String CHANNEL_STATE = "state";
|
||||
public static final String CHANNEL_ERROR = "error";
|
||||
public static final String CHANNEL_ACTION = "action";
|
||||
public static final String CHANNEL_DOCKHASBEENSEEN = "dock-has-been-seen";
|
||||
public static final String CHANNEL_ISDOCKED = "is-docked";
|
||||
public static final String CHANNEL_ISSCHEDULED = "is-scheduled";
|
||||
public static final String CHANNEL_ISCHARGING = "is-charging";
|
||||
public static final String COMMAND = "command";
|
||||
public static final String CHANNEL_NAME = "name";
|
||||
public static final String CHANNEL_CLEANINGCATEGORY = "cleaning-category";
|
||||
public static final String CHANNEL_CLEANINGMODE = "cleaning-mode";
|
||||
public static final String CHANNEL_CLEANINGMODIFIER = "cleaning-modifier";
|
||||
public static final String CHANNEL_CLEANINGSPOTWIDTH = "cleaning-spotwidth";
|
||||
public static final String CHANNEL_CLEANINGSPOTHEIGHT = "cleaning-spotheight";
|
||||
|
||||
public static final String CONFIG_SECRET = "secret";
|
||||
public static final String CONFIG_SERIAL = "serial";
|
||||
public static final String CONFIG_REFRESHTIME = "refresh";
|
||||
|
||||
public static final String PROPERTY_NAME = "robot-name";
|
||||
}
|
||||
@@ -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.neato.internal;
|
||||
|
||||
/**
|
||||
* Exception to encapsulate any issues communicating with Neato APIs
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*/
|
||||
public class NeatoCommunicationException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public NeatoCommunicationException(Throwable cause) {
|
||||
super("Error attempting to communicate with Neato", cause);
|
||||
}
|
||||
|
||||
public NeatoCommunicationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 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.neato.internal;
|
||||
|
||||
import static org.openhab.binding.neato.internal.NeatoBindingConstants.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.openhab.binding.neato.internal.discovery.NeatoAccountDiscoveryService;
|
||||
import org.openhab.binding.neato.internal.handler.NeatoAccountHandler;
|
||||
import org.openhab.binding.neato.internal.handler.NeatoHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link NeatoHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
* @author Jeff Lauterbach - Adding Bridge thing type
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.neato")
|
||||
public class NeatoHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPE_UIDS = Collections
|
||||
.unmodifiableSet(Stream.of(BRIDGE_TYPE_NEATOACCOUNT, THING_TYPE_VACUUMCLEANER).collect(Collectors.toSet()));
|
||||
|
||||
public static final Set<ThingTypeUID> DISCOVERABLE_THING_TYPE_UIDS = Collections
|
||||
.singleton(THING_TYPE_VACUUMCLEANER);
|
||||
|
||||
private Map<ThingUID, ServiceRegistration<DiscoveryService>> discoveryServiceRegistrations = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_VACUUMCLEANER)) {
|
||||
return new NeatoHandler(thing);
|
||||
} else if (thingTypeUID.equals(BRIDGE_TYPE_NEATOACCOUNT)) {
|
||||
NeatoAccountHandler handler = new NeatoAccountHandler((Bridge) thing);
|
||||
registerAccountDiscoveryService(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeHandler(@NonNull ThingHandler thingHandler) {
|
||||
ServiceRegistration<DiscoveryService> serviceRegistration = discoveryServiceRegistrations
|
||||
.get(thingHandler.getThing().getUID());
|
||||
|
||||
if (serviceRegistration != null) {
|
||||
serviceRegistration.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
private void registerAccountDiscoveryService(NeatoAccountHandler handler) {
|
||||
NeatoAccountDiscoveryService discoveryService = new NeatoAccountDiscoveryService(handler);
|
||||
|
||||
ServiceRegistration<DiscoveryService> serviceRegistration = this.bundleContext
|
||||
.registerService(DiscoveryService.class, discoveryService, null);
|
||||
|
||||
discoveryServiceRegistrations.put(handler.getThing().getUID(), serviceRegistration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neato.internal;
|
||||
|
||||
import static org.openhab.binding.neato.internal.classes.Category.HOUSE;
|
||||
import static org.openhab.binding.neato.internal.classes.Category.MAP;
|
||||
import static org.openhab.binding.neato.internal.classes.Mode.TURBO;
|
||||
import static org.openhab.binding.neato.internal.classes.NavigationMode.DEEP;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.openhab.binding.neato.internal.classes.*;
|
||||
import org.openhab.binding.neato.internal.config.NeatoRobotConfig;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* The {@link NeatoRobot} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
* @author Jeff Lauterbach - Code Cleanup and Refactor
|
||||
*/
|
||||
|
||||
public class NeatoRobot {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(NeatoRobot.class);
|
||||
|
||||
private String serialNumber;
|
||||
private String secret;
|
||||
|
||||
private NeatoState state;
|
||||
private NeatoRobotInfo info;
|
||||
private NeatoGeneralInfo generalInfo;
|
||||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
public NeatoRobot(NeatoRobotConfig config) {
|
||||
this.serialNumber = config.getSerial();
|
||||
this.secret = config.getSecret();
|
||||
}
|
||||
|
||||
public NeatoState getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public NeatoRobotInfo getInfo() {
|
||||
return this.info;
|
||||
}
|
||||
|
||||
public NeatoGeneralInfo getGeneralInfo() {
|
||||
return this.generalInfo;
|
||||
}
|
||||
|
||||
private String callNeatoWS(String body) throws NeatoCommunicationException {
|
||||
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
||||
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
// Time in GMT
|
||||
String dateString = dateFormatGmt.format(new Date());
|
||||
|
||||
Mac sha256Hmac;
|
||||
try {
|
||||
sha256Hmac = Mac.getInstance("HmacSHA256");
|
||||
String stringToSign = this.serialNumber.toLowerCase() + "\n" + dateString + "\n" + body;
|
||||
|
||||
SecretKeySpec secretKey = new SecretKeySpec(this.secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
|
||||
sha256Hmac.init(secretKey);
|
||||
|
||||
byte[] signature = sha256Hmac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
|
||||
String hexString = HexUtils.bytesToHex(signature);
|
||||
|
||||
// Properties headers = new Properties
|
||||
Properties headers = new Properties();
|
||||
headers.setProperty("Date", dateString);
|
||||
headers.setProperty("Authorization", "NEATOAPP " + hexString);
|
||||
headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
|
||||
|
||||
logger.debug("Calling Neato WS with body: {}", body);
|
||||
|
||||
InputStream stream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return HttpUtil.executeUrl("POST",
|
||||
"https://nucleo.neatocloud.com:4443/vendors/neato/robots/" + this.serialNumber + "/messages",
|
||||
headers, stream, "text/html; charset=ISO-8859-1", 20000);
|
||||
|
||||
} catch (IOException | NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
throw new NeatoCommunicationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendCommand(String command) throws NeatoCommunicationException {
|
||||
CommandRequest request = new CommandRequest();
|
||||
logger.debug("State neato : {}", this.state);
|
||||
|
||||
if ("clean".equalsIgnoreCase(command)) {
|
||||
String houseCleaningStr = this.state.getAvailableServices().getHouseCleaning();
|
||||
logger.debug("Mode cleaning : {}", houseCleaningStr);
|
||||
logger.debug("State neato : {}", this.state);
|
||||
|
||||
request.setCmd("startCleaning");
|
||||
request.addParam("category", HOUSE.getCategory());
|
||||
|
||||
if ("basic-1".equalsIgnoreCase(houseCleaningStr)) {
|
||||
request.addParam("mode", this.state.getCleaning().getModeValue());
|
||||
request.addParam("modifier", 1);
|
||||
} else if ("minimal-2".equalsIgnoreCase(houseCleaningStr)) {
|
||||
request.addParam("navigationMode", this.state.getCleaning().getNavigationModeValue());
|
||||
} else {
|
||||
if (!"basic-3".equalsIgnoreCase(houseCleaningStr) && !"basic-4".equalsIgnoreCase(houseCleaningStr)) {
|
||||
logger.debug(
|
||||
"Unknown service for houseCleaning: {}. Will attempt to start cleaning using basic-4 message",
|
||||
houseCleaningStr);
|
||||
}
|
||||
|
||||
request.addParam("mode", this.state.getCleaning().getModeValue());
|
||||
request.addParam("category", HOUSE.getCategory());
|
||||
|
||||
Integer navigationMode = this.state.getCleaning().getNavigationModeValue();
|
||||
if (Integer.valueOf(TURBO.getMode()).equals(this.state.getCleaning().getModeValue())) {
|
||||
// From the Neato API Docs...
|
||||
// Note that navigationMode can only be set to 3 if mode is 2,
|
||||
// otherwise an error will be returned.
|
||||
navigationMode = DEEP.getNavigationMode();
|
||||
}
|
||||
request.addParam("navigationMode", navigationMode);
|
||||
}
|
||||
} else if ("cleanWithMap".equalsIgnoreCase(command)) {
|
||||
request.setCmd("startCleaning");
|
||||
request.addParam("category", MAP.getCategory());
|
||||
request.addParam("mode", TURBO.getMode());
|
||||
request.addParam("navigationMode", DEEP.getNavigationMode());
|
||||
} else if ("pause".equalsIgnoreCase(command)) {
|
||||
request.setCmd("pauseCleaning");
|
||||
} else if ("stop".equalsIgnoreCase(command)) {
|
||||
request.setCmd("stopCleaning");
|
||||
} else if ("resume".equalsIgnoreCase(command)) {
|
||||
request.setCmd("resumeCleaning");
|
||||
} else if ("dock".equalsIgnoreCase(command)) {
|
||||
request.setCmd("sendToBase");
|
||||
} else if ("dismissAlert".equalsIgnoreCase(command)) {
|
||||
request.setCmd("dismissCurrentAlert");
|
||||
} else {
|
||||
logger.debug("Unexpected command received: {}", command);
|
||||
return;
|
||||
}
|
||||
|
||||
String result = this.callNeatoWS(gson.toJson(request));
|
||||
logger.debug("Result from sendCommand: {}", result);
|
||||
}
|
||||
|
||||
public Boolean sendGetRobotInfo() throws NeatoCommunicationException {
|
||||
logger.debug("Will get INFO for Robot {}", this.serialNumber);
|
||||
|
||||
CommandRequest request = new CommandRequest();
|
||||
request.setCmd("getRobotInfo");
|
||||
|
||||
String result = this.callNeatoWS(gson.toJson(request));
|
||||
logger.debug("Result from getRobotInfo: {}", result);
|
||||
|
||||
this.info = gson.fromJson(result, NeatoRobotInfo.class);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void sendGetState() throws NeatoCommunicationException, CouldNotFindRobotException {
|
||||
logger.debug("Will get STATE for Robot {}", this.serialNumber);
|
||||
|
||||
CommandRequest request = new CommandRequest();
|
||||
request.setCmd("getRobotState");
|
||||
|
||||
String result = this.callNeatoWS(gson.toJson(request));
|
||||
logger.debug("Result from getRobotState: {}", result);
|
||||
|
||||
ErrorMessage eMessage = gson.fromJson(result, ErrorMessage.class);
|
||||
if (eMessage.getMessage() != null) {
|
||||
logger.error("Error when getting Robot State. Error message: {}", eMessage.getMessage());
|
||||
throw new CouldNotFindRobotException(eMessage.getMessage());
|
||||
}
|
||||
|
||||
this.state = gson.fromJson(result, NeatoState.class);
|
||||
|
||||
logger.debug("Successfully got and parsed new state for {}", this.serialNumber);
|
||||
}
|
||||
|
||||
public void sendGetGeneralInfo() throws NeatoCommunicationException {
|
||||
if ("basic-1".equals(state.getAvailableServices().getGeneralInfo())
|
||||
|| "advanced-1".equals(state.getAvailableServices().getGeneralInfo())) {
|
||||
logger.debug("Will get GENERAL INFO for Robot {}", this.serialNumber);
|
||||
|
||||
CommandRequest request = new CommandRequest();
|
||||
request.setCmd("getGeneralInfo");
|
||||
|
||||
String result = this.callNeatoWS(gson.toJson(request));
|
||||
logger.debug("Result from getGeneralInfo: {}", result);
|
||||
|
||||
this.generalInfo = gson.fromJson(result, NeatoGeneralInfo.class);
|
||||
} else {
|
||||
logger.debug("Your vacuum cleaner does not support General Info messages");
|
||||
this.generalInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CommandRequest {
|
||||
private String reqId = "1";
|
||||
private String cmd;
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
public String getReqId() {
|
||||
return reqId;
|
||||
}
|
||||
|
||||
public void setReqId(String reqId) {
|
||||
this.reqId = reqId;
|
||||
}
|
||||
|
||||
public String getCmd() {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
public void setCmd(String cmd) {
|
||||
this.cmd = cmd;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void addParam(String param, String value) {
|
||||
this.params.put(param, value);
|
||||
}
|
||||
|
||||
public void addParam(String param, int value) {
|
||||
this.params.put(param, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link AvailableCommands} is responsible for listing all available commands.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class AvailableCommands {
|
||||
|
||||
private Boolean start;
|
||||
private Boolean stop;
|
||||
private Boolean pause;
|
||||
private Boolean resume;
|
||||
private Boolean goToBase;
|
||||
|
||||
public Boolean getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(Boolean start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public Boolean getStop() {
|
||||
return stop;
|
||||
}
|
||||
|
||||
public void setStop(Boolean stop) {
|
||||
this.stop = stop;
|
||||
}
|
||||
|
||||
public Boolean getPause() {
|
||||
return pause;
|
||||
}
|
||||
|
||||
public void setPause(Boolean pause) {
|
||||
this.pause = pause;
|
||||
}
|
||||
|
||||
public Boolean getResume() {
|
||||
return resume;
|
||||
}
|
||||
|
||||
public void setResume(Boolean resume) {
|
||||
this.resume = resume;
|
||||
}
|
||||
|
||||
public Boolean getGoToBase() {
|
||||
return goToBase;
|
||||
}
|
||||
|
||||
public void setGoToBase(Boolean goToBase) {
|
||||
this.goToBase = goToBase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link AvailableServices} is responsible for listing all available services.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class AvailableServices {
|
||||
|
||||
private String houseCleaning;
|
||||
private String spotCleaning;
|
||||
private String manualCleaning;
|
||||
private String easyConnect;
|
||||
private String schedule;
|
||||
private String generalInfo;
|
||||
|
||||
public String getGeneralInfo() {
|
||||
return generalInfo;
|
||||
}
|
||||
|
||||
public void setGeneralInfo(String generalInfo) {
|
||||
this.generalInfo = generalInfo;
|
||||
}
|
||||
|
||||
public String getHouseCleaning() {
|
||||
return houseCleaning;
|
||||
}
|
||||
|
||||
public void setHouseCleaning(String houseCleaning) {
|
||||
this.houseCleaning = houseCleaning;
|
||||
}
|
||||
|
||||
public String getSpotCleaning() {
|
||||
return spotCleaning;
|
||||
}
|
||||
|
||||
public void setSpotCleaning(String spotCleaning) {
|
||||
this.spotCleaning = spotCleaning;
|
||||
}
|
||||
|
||||
public String getManualCleaning() {
|
||||
return manualCleaning;
|
||||
}
|
||||
|
||||
public void setManualCleaning(String manualCleaning) {
|
||||
this.manualCleaning = manualCleaning;
|
||||
}
|
||||
|
||||
public String getEasyConnect() {
|
||||
return easyConnect;
|
||||
}
|
||||
|
||||
public void setEasyConnect(String easyConnect) {
|
||||
this.easyConnect = easyConnect;
|
||||
}
|
||||
|
||||
public String getSchedule() {
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public void setSchedule(String schedule) {
|
||||
this.schedule = schedule;
|
||||
}
|
||||
}
|
||||
@@ -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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link Battery} is the internal class for battery information.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class Battery {
|
||||
|
||||
private Integer level;
|
||||
private Integer timeToEmpty;
|
||||
private Integer timeToFullCharge;
|
||||
private Integer totalCharges;
|
||||
private String manufacturingDate;
|
||||
private Integer authorizationStatus;
|
||||
private String vendor;
|
||||
|
||||
public Integer getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(Integer level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public Integer getTimeToEmpty() {
|
||||
return timeToEmpty;
|
||||
}
|
||||
|
||||
public void setTimeToEmpty(Integer timeToEmpty) {
|
||||
this.timeToEmpty = timeToEmpty;
|
||||
}
|
||||
|
||||
public Integer getTimeToFullCharge() {
|
||||
return timeToFullCharge;
|
||||
}
|
||||
|
||||
public void setTimeToFullCharge(Integer timeToFullCharge) {
|
||||
this.timeToFullCharge = timeToFullCharge;
|
||||
}
|
||||
|
||||
public Integer getTotalCharges() {
|
||||
return totalCharges;
|
||||
}
|
||||
|
||||
public void setTotalCharges(Integer totalCharges) {
|
||||
this.totalCharges = totalCharges;
|
||||
}
|
||||
|
||||
public String getManufacturingDate() {
|
||||
return manufacturingDate;
|
||||
}
|
||||
|
||||
public void setManufacturingDate(String manufacturingDate) {
|
||||
this.manufacturingDate = manufacturingDate;
|
||||
}
|
||||
|
||||
public Integer getAuthorizationStatus() {
|
||||
return authorizationStatus;
|
||||
}
|
||||
|
||||
public void setAuthorizationStatus(Integer authorizationStatus) {
|
||||
this.authorizationStatus = authorizationStatus;
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return vendor;
|
||||
}
|
||||
|
||||
public void setVendor(String vendor) {
|
||||
this.vendor = vendor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link BeehiveAuthenticcation} is the internal class for handling authentication.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class BeehiveAuthentication {
|
||||
|
||||
@SerializedName("access_token")
|
||||
private String accessToken;
|
||||
@SerializedName("current_time")
|
||||
private String currentTime;
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public String getCurrentTime() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
public void setCurrentTime(String currentTime) {
|
||||
this.currentTime = currentTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The enum {@link Category} is the internal class to set category to the cleaning request
|
||||
*
|
||||
* @author Lapenta Giuseppe - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Category {
|
||||
MANUAL(1),
|
||||
HOUSE(2),
|
||||
SPOT(3),
|
||||
MAP(4);
|
||||
|
||||
private final int category;
|
||||
|
||||
Category(int category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public int getCategory() {
|
||||
return category;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link Cleaning} is the internal class for different Cleaning states and related information.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class Cleaning {
|
||||
|
||||
@SerializedName("category")
|
||||
private Integer categoryValue;
|
||||
@SerializedName("mode")
|
||||
private Integer modeValue;
|
||||
@SerializedName("modifier")
|
||||
private Integer modifierValue;
|
||||
@SerializedName("navigationMode")
|
||||
private Integer navigationModeValue;
|
||||
private Integer spotWidth;
|
||||
private Integer spotHeight;
|
||||
|
||||
public enum Category {
|
||||
MANUAL(1),
|
||||
HOUSE(2),
|
||||
SPOT(3),
|
||||
MAP(4),
|
||||
UNRECOGNIZED(-1);
|
||||
|
||||
private int value;
|
||||
|
||||
private Category(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static Category fromValue(int value) {
|
||||
for (Category c : values()) {
|
||||
if (c.value == value) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Mode {
|
||||
ECO(1),
|
||||
TURBO(2);
|
||||
|
||||
private int value;
|
||||
|
||||
private Mode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static Mode fromValue(int value) {
|
||||
for (Mode m : values()) {
|
||||
if (m.value == value) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return TURBO;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Modifier {
|
||||
NORMAL(1),
|
||||
DOUBLE(2);
|
||||
|
||||
private int value;
|
||||
|
||||
private Modifier(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static Modifier fromValue(int value) {
|
||||
for (Modifier m : values()) {
|
||||
if (m.value == value) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
public enum NavigationMode {
|
||||
NORMAL(1),
|
||||
EXTRA_CARE(2),
|
||||
DEEP(3);
|
||||
|
||||
private int value;
|
||||
|
||||
private NavigationMode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static NavigationMode fromValue(int value) {
|
||||
for (NavigationMode m : values()) {
|
||||
if (m.value == value) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getCategoryValue() {
|
||||
return categoryValue;
|
||||
}
|
||||
|
||||
public void setCategoryValue(Integer categoryValue) {
|
||||
this.categoryValue = categoryValue;
|
||||
}
|
||||
|
||||
public Category getCategory() {
|
||||
return Category.fromValue(categoryValue);
|
||||
}
|
||||
|
||||
public Integer getModeValue() {
|
||||
return modeValue;
|
||||
}
|
||||
|
||||
public void setModeValue(Integer modeValue) {
|
||||
this.modeValue = modeValue;
|
||||
}
|
||||
|
||||
public Mode getMode() {
|
||||
return Mode.fromValue(modeValue);
|
||||
}
|
||||
|
||||
public Integer getModifierValue() {
|
||||
return modifierValue;
|
||||
}
|
||||
|
||||
public void setModifierValue(Integer modifierValue) {
|
||||
this.modifierValue = modifierValue;
|
||||
}
|
||||
|
||||
public Modifier getModifier() {
|
||||
return Modifier.fromValue(modifierValue);
|
||||
}
|
||||
|
||||
public Integer getNavigationModeValue() {
|
||||
return navigationModeValue;
|
||||
}
|
||||
|
||||
public void setNavigationModeValue(Integer navigationMode) {
|
||||
this.navigationModeValue = navigationMode;
|
||||
}
|
||||
|
||||
public NavigationMode getNavigationMode() {
|
||||
return NavigationMode.fromValue(navigationModeValue);
|
||||
}
|
||||
|
||||
public Integer getSpotWidth() {
|
||||
return spotWidth;
|
||||
}
|
||||
|
||||
public void setSpotWidth(Integer spotWidth) {
|
||||
this.spotWidth = spotWidth;
|
||||
}
|
||||
|
||||
public Integer getSpotHeight() {
|
||||
return spotHeight;
|
||||
}
|
||||
|
||||
public void setSpotHeight(Integer spotHeight) {
|
||||
this.spotHeight = spotHeight;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link Details} is the internal class for detailed information about the vacuum cleaner.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class Details {
|
||||
|
||||
private Boolean isCharging;
|
||||
private Boolean isDocked;
|
||||
private Boolean isScheduleEnabled;
|
||||
private Boolean dockHasBeenSeen;
|
||||
private Integer charge;
|
||||
|
||||
public Boolean getIsCharging() {
|
||||
return isCharging;
|
||||
}
|
||||
|
||||
public void setIsCharging(Boolean isCharging) {
|
||||
this.isCharging = isCharging;
|
||||
}
|
||||
|
||||
public Boolean getIsDocked() {
|
||||
return isDocked;
|
||||
}
|
||||
|
||||
public void setIsDocked(Boolean isDocked) {
|
||||
this.isDocked = isDocked;
|
||||
}
|
||||
|
||||
public Boolean getIsScheduleEnabled() {
|
||||
return isScheduleEnabled;
|
||||
}
|
||||
|
||||
public void setIsScheduleEnabled(Boolean isScheduleEnabled) {
|
||||
this.isScheduleEnabled = isScheduleEnabled;
|
||||
}
|
||||
|
||||
public Boolean getDockHasBeenSeen() {
|
||||
return dockHasBeenSeen;
|
||||
}
|
||||
|
||||
public void setDockHasBeenSeen(Boolean dockHasBeenSeen) {
|
||||
this.dockHasBeenSeen = dockHasBeenSeen;
|
||||
}
|
||||
|
||||
public Integer getCharge() {
|
||||
return charge;
|
||||
}
|
||||
|
||||
public void setCharge(Integer charge) {
|
||||
this.charge = charge;
|
||||
}
|
||||
}
|
||||
@@ -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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link ErrorMessage} is the internal class for error messages.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class ErrorMessage {
|
||||
|
||||
private String message;
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link Meta} is the internal class for vacuum cleaner meta information.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class Meta {
|
||||
|
||||
private String modelName;
|
||||
private String firmware;
|
||||
|
||||
public String getModelName() {
|
||||
return modelName;
|
||||
}
|
||||
|
||||
public void setModelName(String modelName) {
|
||||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public String getFirmware() {
|
||||
return firmware;
|
||||
}
|
||||
|
||||
public void setFirmware(String firmware) {
|
||||
this.firmware = firmware;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The enum {@link Mode} is the internal class to set cleaning mode to the cleaning request
|
||||
*
|
||||
* @author Lapenta Giuseppe - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Mode {
|
||||
ECO(1),
|
||||
TURBO(2); // Note that navigationMode can only be set to 3 if mode is 2, otherwise an error will be returned.
|
||||
|
||||
private final int mode;
|
||||
|
||||
Mode(int mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public int getMode() {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The enum {@link NavigationMode} is the internal class to set navigation mode to the cleaning request
|
||||
*
|
||||
* @author Lapenta Giuseppe - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum NavigationMode {
|
||||
NORMAL(1),
|
||||
EXTRA_CARE(2),
|
||||
DEEP(3); // Note that navigationMode can only be set to 3 if mode is 2, otherwise an error will be returned.
|
||||
|
||||
private final int navigationMode;
|
||||
|
||||
NavigationMode(int navigationMode) {
|
||||
this.navigationMode = navigationMode;
|
||||
}
|
||||
|
||||
public int getNavigationMode() {
|
||||
return navigationMode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.neato.internal.classes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link NeatoAccountInformation} is the internal class for the neato web service account and information.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class NeatoAccountInformation {
|
||||
|
||||
private String email;
|
||||
private Object firstName;
|
||||
private Object lastName;
|
||||
private String locale;
|
||||
@SerializedName("country_code")
|
||||
private String countryCode;
|
||||
private Boolean developer;
|
||||
private Boolean newsletter;
|
||||
@SerializedName("created_at")
|
||||
private String createdAt;
|
||||
@SerializedName("verified_at")
|
||||
private String verifiedAt;
|
||||
private List<Robot> robots = null;
|
||||
@SerializedName("recent_firmwares")
|
||||
private RecentFirmwares recentFirmwares;
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Object getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(Object firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public Object getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(Object lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public String getCountryCode() {
|
||||
return countryCode;
|
||||
}
|
||||
|
||||
public void setCountryCode(String countryCode) {
|
||||
this.countryCode = countryCode;
|
||||
}
|
||||
|
||||
public Boolean getDeveloper() {
|
||||
return developer;
|
||||
}
|
||||
|
||||
public void setDeveloper(Boolean developer) {
|
||||
this.developer = developer;
|
||||
}
|
||||
|
||||
public Boolean getNewsletter() {
|
||||
return newsletter;
|
||||
}
|
||||
|
||||
public void setNewsletter(Boolean newsletter) {
|
||||
this.newsletter = newsletter;
|
||||
}
|
||||
|
||||
public String getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(String createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public String getVerifiedAt() {
|
||||
return verifiedAt;
|
||||
}
|
||||
|
||||
public void setVerifiedAt(String verifiedAt) {
|
||||
this.verifiedAt = verifiedAt;
|
||||
}
|
||||
|
||||
public List<Robot> getRobots() {
|
||||
return robots;
|
||||
}
|
||||
|
||||
public void setRobots(List<Robot> robots) {
|
||||
this.robots = robots;
|
||||
}
|
||||
|
||||
public RecentFirmwares getRecentFirmwares() {
|
||||
return recentFirmwares;
|
||||
}
|
||||
|
||||
public void setRecentFirmwares(RecentFirmwares recentFirmwares) {
|
||||
this.recentFirmwares = recentFirmwares;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link NeatoGeneralInfo} is the internal class for Neato general information.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class NeatoGeneralInfo {
|
||||
|
||||
private String productNumber;
|
||||
private String serial;
|
||||
private String model;
|
||||
private String language;
|
||||
private String firmware;
|
||||
private Battery battery;
|
||||
|
||||
public String getProductNumber() {
|
||||
return productNumber;
|
||||
}
|
||||
|
||||
public void setProductNumber(String productNumber) {
|
||||
this.productNumber = productNumber;
|
||||
}
|
||||
|
||||
public String getSerial() {
|
||||
return serial;
|
||||
}
|
||||
|
||||
public void setSerial(String serial) {
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public String getFirmware() {
|
||||
return firmware;
|
||||
}
|
||||
|
||||
public void setFirmware(String firmware) {
|
||||
this.firmware = firmware;
|
||||
}
|
||||
|
||||
public Battery getBattery() {
|
||||
return battery;
|
||||
}
|
||||
|
||||
public void setBattery(Battery battery) {
|
||||
this.battery = battery;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link NeatoRobotInfo} is the internal class for the Neato Robot information.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class NeatoRobotInfo {
|
||||
|
||||
private Integer version;
|
||||
private String reqId;
|
||||
private String result;
|
||||
private String error;
|
||||
private RobotInfoData data;
|
||||
|
||||
public Integer getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getReqId() {
|
||||
return reqId;
|
||||
}
|
||||
|
||||
public void setReqId(String reqId) {
|
||||
this.reqId = reqId;
|
||||
}
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(String result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public RobotInfoData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(RobotInfoData data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link NeatoState} is the internal class for state information from the vacuum cleaner.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class NeatoState {
|
||||
|
||||
private Integer version;
|
||||
private String reqId;
|
||||
private String result;
|
||||
private String error;
|
||||
private RobotInfoData data;
|
||||
private Integer state;
|
||||
private Integer action;
|
||||
private Cleaning cleaning;
|
||||
private Details details;
|
||||
private AvailableCommands availableCommands;
|
||||
private AvailableServices availableServices;
|
||||
private Meta meta;
|
||||
|
||||
public enum RobotState {
|
||||
INVALID(0),
|
||||
IDLE(1),
|
||||
BUSY(2),
|
||||
PAUSED(3),
|
||||
ERROR(4);
|
||||
|
||||
private int value;
|
||||
|
||||
RobotState(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static RobotState fromValue(int value) {
|
||||
for (RobotState s : RobotState.values()) {
|
||||
if (s.value == value) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
public enum RobotAction {
|
||||
INVALID(0),
|
||||
HOUSE_CLEANING(1),
|
||||
SPOT_CLEANING(2),
|
||||
MANUAL_CLEANING(3),
|
||||
DOCKING(4),
|
||||
USER_MENU_ACTIVE(5),
|
||||
SUSPENDED_CLEANING(6),
|
||||
UPDATING(7),
|
||||
COPYING_LOGS(8),
|
||||
RECOVERING_LOCATION(9),
|
||||
IEC_TEST(10),
|
||||
MAP_CLEANING(11),
|
||||
EXPLORING_MAP(12),
|
||||
AQUIRING_MAP_IDS(13),
|
||||
CREATING_MAP(14),
|
||||
SUSPENDED_EXPLORATION(15);
|
||||
|
||||
private int value;
|
||||
|
||||
RobotAction(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static RobotAction fromValue(int value) {
|
||||
for (RobotAction a : RobotAction.values()) {
|
||||
if (a.value == value) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getReqId() {
|
||||
return reqId;
|
||||
}
|
||||
|
||||
public void setReqId(String reqId) {
|
||||
this.reqId = reqId;
|
||||
}
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(String result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public RobotInfoData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(RobotInfoData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Integer getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public RobotState getRobotState() {
|
||||
return RobotState.fromValue(this.state);
|
||||
}
|
||||
|
||||
public void setState(Integer state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public Integer getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public RobotAction getRobotAction() {
|
||||
return RobotAction.fromValue(this.action);
|
||||
}
|
||||
|
||||
public void setAction(Integer action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public Cleaning getCleaning() {
|
||||
return cleaning;
|
||||
}
|
||||
|
||||
public void setCleaning(Cleaning cleaning) {
|
||||
this.cleaning = cleaning;
|
||||
}
|
||||
|
||||
public Details getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(Details details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public AvailableCommands getAvailableCommands() {
|
||||
return availableCommands;
|
||||
}
|
||||
|
||||
public void setAvailableCommands(AvailableCommands availableCommands) {
|
||||
this.availableCommands = availableCommands;
|
||||
}
|
||||
|
||||
public AvailableServices getAvailableServices() {
|
||||
return availableServices;
|
||||
}
|
||||
|
||||
public void setAvailableServices(AvailableServices availableServices) {
|
||||
this.availableServices = availableServices;
|
||||
}
|
||||
|
||||
public Meta getMeta() {
|
||||
return meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NeatoState{" + "version=" + version + ", reqId='" + reqId + '\'' + ", result='" + result + '\''
|
||||
+ ", error='" + error + '\'' + ", data=" + data + ", state=" + state + ", action=" + action
|
||||
+ ", cleaning=" + cleaning + ", details=" + details + ", availableCommands=" + availableCommands
|
||||
+ ", availableServices=" + availableServices + ", meta=" + meta + '}';
|
||||
}
|
||||
|
||||
public void setMeta(Meta meta) {
|
||||
this.meta = meta;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
/**
|
||||
* The {@link RecentFirmwares} is something that is included in the JSON-structure given from Neato WS calls..
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class RecentFirmwares {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link Robot} is the internal class for Neato Robot. Information is retrieved from the web service call.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class Robot {
|
||||
|
||||
private String serial;
|
||||
private Object prefix;
|
||||
private String name;
|
||||
private String model;
|
||||
@SerializedName("secret_key")
|
||||
private String secretKey;
|
||||
private List<Object> traits = null;
|
||||
@SerializedName("purchased_at")
|
||||
private Object purchasedAt;
|
||||
@SerializedName("linked_at")
|
||||
private String linkedAt;
|
||||
@SerializedName("proof_of_purchase_url")
|
||||
private Object proofOfPurchaseUrl;
|
||||
@SerializedName("proof_of_purchase_url_valid_for_seconds")
|
||||
private Integer proofOfPurchaseUrlValidForSeconds;
|
||||
@SerializedName("proof_of_purchase_generated_at")
|
||||
private Object proofOfPurchaseGeneratedAt;
|
||||
@SerializedName("mac_address")
|
||||
private String macAddress;
|
||||
@SerializedName("created_at")
|
||||
private String createdAt;
|
||||
|
||||
public String getSerial() {
|
||||
return serial;
|
||||
}
|
||||
|
||||
public void setSerial(String serial) {
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
public Object getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(Object prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getSecretKey() {
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
public void setSecretKey(String secretKey) {
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
public Object getPurchasedAt() {
|
||||
return purchasedAt;
|
||||
}
|
||||
|
||||
public void setPurchasedAt(Object purchasedAt) {
|
||||
this.purchasedAt = purchasedAt;
|
||||
}
|
||||
|
||||
public String getLinkedAt() {
|
||||
return linkedAt;
|
||||
}
|
||||
|
||||
public void setLinkedAt(String linkedAt) {
|
||||
this.linkedAt = linkedAt;
|
||||
}
|
||||
|
||||
public List<Object> getTraits() {
|
||||
return traits;
|
||||
}
|
||||
|
||||
public void setTraits(List<Object> traits) {
|
||||
this.traits = traits;
|
||||
}
|
||||
|
||||
public Object getProofOfPurchaseUrl() {
|
||||
return proofOfPurchaseUrl;
|
||||
}
|
||||
|
||||
public void setProofOfPurchaseUrl(Object proofOfPurchaseUrl) {
|
||||
this.proofOfPurchaseUrl = proofOfPurchaseUrl;
|
||||
}
|
||||
|
||||
public Integer getProofOfPurchaseUrlValidForSeconds() {
|
||||
return proofOfPurchaseUrlValidForSeconds;
|
||||
}
|
||||
|
||||
public void setProofOfPurchaseUrlValidForSeconds(Integer proofOfPurchaseUrlValidForSeconds) {
|
||||
this.proofOfPurchaseUrlValidForSeconds = proofOfPurchaseUrlValidForSeconds;
|
||||
}
|
||||
|
||||
public Object getProofOfPurchaseGeneratedAt() {
|
||||
return proofOfPurchaseGeneratedAt;
|
||||
}
|
||||
|
||||
public void setProofOfPurchaseGeneratedAt(Object proofOfPurchaseGeneratedAt) {
|
||||
this.proofOfPurchaseGeneratedAt = proofOfPurchaseGeneratedAt;
|
||||
}
|
||||
|
||||
public String getMacAddress() {
|
||||
return macAddress;
|
||||
}
|
||||
|
||||
public void setMacAddress(String macAddress) {
|
||||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
public String getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(String createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,793 @@
|
||||
/**
|
||||
* 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.neato.internal.classes;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link RobotInfoData} is the internal class for storing Information Data for the vacuum cleaneer.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
*/
|
||||
public class RobotInfoData {
|
||||
|
||||
private String modelName;
|
||||
@SerializedName("CPUMACID")
|
||||
private String cpuMacId;
|
||||
@SerializedName("MainBrdMfgDate")
|
||||
private String mainBrdMfgDate;
|
||||
@SerializedName("RobotMfgDate")
|
||||
private String robotMfgDate;
|
||||
@SerializedName("BoardRev")
|
||||
private Integer boardRev;
|
||||
@SerializedName("ChassisRev")
|
||||
private Integer chassisRev;
|
||||
@SerializedName("BatteryType")
|
||||
private Integer batteryType;
|
||||
@SerializedName("WheelPodType")
|
||||
private Integer wheelPodType;
|
||||
@SerializedName("DropSensorType")
|
||||
private Integer dropSensorType;
|
||||
@SerializedName("MagSensorType")
|
||||
private Integer magSensorType;
|
||||
@SerializedName("WallSensorType")
|
||||
private Integer wallSensorType;
|
||||
@SerializedName("LDSMotorType")
|
||||
private Integer ldsMotorType;
|
||||
@SerializedName("Locale")
|
||||
private Integer locale;
|
||||
@SerializedName("USMode")
|
||||
private Integer usMode;
|
||||
@SerializedName(value = "InternalModelName", alternate = "ModelName")
|
||||
private String internalModelName;
|
||||
@SerializedName("NeatoServer")
|
||||
private String neatoServer;
|
||||
@SerializedName("CartID")
|
||||
private Integer cartId;
|
||||
@SerializedName("brushSpeed")
|
||||
private Integer brushSpeed;
|
||||
@SerializedName("brushSpeedEco")
|
||||
private Integer brushSpeedEco;
|
||||
@SerializedName("vacuumSpeed")
|
||||
private Integer vacuumSpeed;
|
||||
@SerializedName("vacuumPwrPercent")
|
||||
private Integer vacuumPwrPercent;
|
||||
@SerializedName("vacuumPwrPercentEco")
|
||||
private Integer vacuumPwrPercentEco;
|
||||
@SerializedName("runTime")
|
||||
private Integer runTime;
|
||||
@SerializedName("BrushPresent")
|
||||
private Integer brushPresent;
|
||||
@SerializedName("VacuumPresent")
|
||||
private Integer vacuumPresent;
|
||||
@SerializedName("PadPresent")
|
||||
private Integer padPresent;
|
||||
@SerializedName("PlatenPresent")
|
||||
private Integer platenPresent;
|
||||
@SerializedName("BrushDirection")
|
||||
private Integer brushDirection;
|
||||
@SerializedName("VacuumDirection")
|
||||
private Integer vacuumDirection;
|
||||
@SerializedName("PadDirection")
|
||||
private Integer padDirection;
|
||||
@SerializedName("CumulativeCartridgeTimeInSecs")
|
||||
private Integer cumulativeCartridgeTimeInSecs;
|
||||
@SerializedName("nCleaningsStartedWhereDustBinWasFull")
|
||||
private Integer nCleaningsStartedWhereDustBinWasFull;
|
||||
@SerializedName("BlowerType")
|
||||
private Integer blowerType;
|
||||
@SerializedName("BrushMotorType")
|
||||
private Integer brushMotorType;
|
||||
@SerializedName("SideBrushType")
|
||||
private Integer sideBrushType;
|
||||
@SerializedName("SideBrushPower")
|
||||
private Integer sideBrushPower;
|
||||
@SerializedName("nAutoCycleCleaningsStarted")
|
||||
private Integer nAutoCycleCleaningsStarted;
|
||||
@SerializedName("hardware_version_major")
|
||||
private Integer hardwareVersionMajor;
|
||||
@SerializedName("hardware_version_minor")
|
||||
private Integer hardwareVersionMinor;
|
||||
@SerializedName("software_version_major")
|
||||
private Integer softwareVersionMajor;
|
||||
@SerializedName("software_version_minor")
|
||||
private Integer softwareVersionMinor;
|
||||
@SerializedName("max_voltage")
|
||||
private Integer maxVoltage;
|
||||
@SerializedName("max_current")
|
||||
private Integer maxCurrent;
|
||||
@SerializedName("voltage_multiplier")
|
||||
private Integer voltageMultiplier;
|
||||
@SerializedName("current_multiplier")
|
||||
private Integer currentMultiplier;
|
||||
@SerializedName("capacity_mode")
|
||||
private Integer capacityMode;
|
||||
@SerializedName("design_capacity")
|
||||
private Integer designCapacity;
|
||||
@SerializedName("design_voltage")
|
||||
private Integer designVoltage;
|
||||
@SerializedName("mfg_day")
|
||||
private Integer mfgDay;
|
||||
@SerializedName("mfg_month")
|
||||
private Integer mfgMonth;
|
||||
@SerializedName("mfg_year")
|
||||
private Integer mfgYear;
|
||||
@SerializedName("serial_number")
|
||||
private Integer serialNumber;
|
||||
@SerializedName("sw_ver")
|
||||
private Integer swVer;
|
||||
@SerializedName("data_ver")
|
||||
private Integer dataVer;
|
||||
@SerializedName("mfg_access")
|
||||
private Integer mfgAccess;
|
||||
@SerializedName("mfg_name")
|
||||
private String mfgName;
|
||||
@SerializedName("device_name")
|
||||
private String deviceName;
|
||||
@SerializedName("chemistry_name")
|
||||
private String chemistryName;
|
||||
@SerializedName("Major")
|
||||
private Integer major;
|
||||
@SerializedName("Minor")
|
||||
private Integer minor;
|
||||
@SerializedName("Build")
|
||||
private Integer build;
|
||||
@SerializedName("ldsVer")
|
||||
private String ldsVer;
|
||||
@SerializedName("ldsSerial")
|
||||
private String ldsSerial;
|
||||
@SerializedName("ldsCPU")
|
||||
private String ldsCpu;
|
||||
@SerializedName("ldsBuildNum")
|
||||
private String ldsBuildNum;
|
||||
@SerializedName("bootLoaderVersion")
|
||||
private Integer bootLoaderVersion;
|
||||
@SerializedName("uiBoardSWVer")
|
||||
private Integer uiBoardSWVer;
|
||||
@SerializedName("uiBoardHWVer")
|
||||
private Integer uiBoardHWVer;
|
||||
@SerializedName("qaState")
|
||||
private Integer qaState;
|
||||
@SerializedName("manufacturer")
|
||||
private Integer manufacturer;
|
||||
@SerializedName("driverVersion")
|
||||
private Integer driverVersion;
|
||||
@SerializedName("driverID")
|
||||
private Integer driverId;
|
||||
@SerializedName("ultrasonicSW")
|
||||
private Integer ultrasonicSW;
|
||||
@SerializedName("ultrasonicHW")
|
||||
private Integer ultrasonicHW;
|
||||
@SerializedName("blowerHW")
|
||||
private Integer blowerHW;
|
||||
@SerializedName("blowerSWMajor")
|
||||
private Integer blowerSWMajor;
|
||||
@SerializedName("blowerSWMinor")
|
||||
private Integer blowerSWMinor;
|
||||
|
||||
public String getModelName() {
|
||||
return modelName;
|
||||
}
|
||||
|
||||
public void setModelName(String modelName) {
|
||||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public String getCpuMacId() {
|
||||
return cpuMacId;
|
||||
}
|
||||
|
||||
public void setCpuMacId(String cpuMacId) {
|
||||
this.cpuMacId = cpuMacId;
|
||||
}
|
||||
|
||||
public String getMainBrdMfgDate() {
|
||||
return mainBrdMfgDate;
|
||||
}
|
||||
|
||||
public void setMainBrdMfgDate(String mainBrdMfgDate) {
|
||||
this.mainBrdMfgDate = mainBrdMfgDate;
|
||||
}
|
||||
|
||||
public String getRobotMfgDate() {
|
||||
return robotMfgDate;
|
||||
}
|
||||
|
||||
public void setRobotMfgDate(String robotMfgDate) {
|
||||
this.robotMfgDate = robotMfgDate;
|
||||
}
|
||||
|
||||
public Integer getBoardRev() {
|
||||
return boardRev;
|
||||
}
|
||||
|
||||
public void setBoardRev(Integer boardRev) {
|
||||
this.boardRev = boardRev;
|
||||
}
|
||||
|
||||
public Integer getChassisRev() {
|
||||
return chassisRev;
|
||||
}
|
||||
|
||||
public void setChassisRev(Integer chassisRev) {
|
||||
this.chassisRev = chassisRev;
|
||||
}
|
||||
|
||||
public Integer getBatteryType() {
|
||||
return batteryType;
|
||||
}
|
||||
|
||||
public void setBatteryType(Integer batteryType) {
|
||||
this.batteryType = batteryType;
|
||||
}
|
||||
|
||||
public Integer getWheelPodType() {
|
||||
return wheelPodType;
|
||||
}
|
||||
|
||||
public void setWheelPodType(Integer wheelPodType) {
|
||||
this.wheelPodType = wheelPodType;
|
||||
}
|
||||
|
||||
public Integer getDropSensorType() {
|
||||
return dropSensorType;
|
||||
}
|
||||
|
||||
public void setDropSensorType(Integer dropSensorType) {
|
||||
this.dropSensorType = dropSensorType;
|
||||
}
|
||||
|
||||
public Integer getMagSensorType() {
|
||||
return magSensorType;
|
||||
}
|
||||
|
||||
public void setMagSensorType(Integer magSensorType) {
|
||||
this.magSensorType = magSensorType;
|
||||
}
|
||||
|
||||
public Integer getWallSensorType() {
|
||||
return wallSensorType;
|
||||
}
|
||||
|
||||
public void setWallSensorType(Integer wallSensorType) {
|
||||
this.wallSensorType = wallSensorType;
|
||||
}
|
||||
|
||||
public Integer getLDSMotorType() {
|
||||
return ldsMotorType;
|
||||
}
|
||||
|
||||
public void setLDSMotorType(Integer lDSMotorType) {
|
||||
this.ldsMotorType = lDSMotorType;
|
||||
}
|
||||
|
||||
public Integer getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(Integer locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public Integer getUSMode() {
|
||||
return usMode;
|
||||
}
|
||||
|
||||
public void setUSMode(Integer uSMode) {
|
||||
this.usMode = uSMode;
|
||||
}
|
||||
|
||||
public String getInternalModelName() {
|
||||
return internalModelName;
|
||||
}
|
||||
|
||||
public void setInternalModelName(String internalModelName) {
|
||||
this.internalModelName = internalModelName;
|
||||
}
|
||||
|
||||
public String getNeatoServer() {
|
||||
return neatoServer;
|
||||
}
|
||||
|
||||
public void setNeatoServer(String neatoServer) {
|
||||
this.neatoServer = neatoServer;
|
||||
}
|
||||
|
||||
public Integer getCartID() {
|
||||
return cartId;
|
||||
}
|
||||
|
||||
public void setCartID(Integer cartID) {
|
||||
this.cartId = cartID;
|
||||
}
|
||||
|
||||
public Integer getBrushSpeed() {
|
||||
return brushSpeed;
|
||||
}
|
||||
|
||||
public void setBrushSpeed(Integer brushSpeed) {
|
||||
this.brushSpeed = brushSpeed;
|
||||
}
|
||||
|
||||
public Integer getBrushSpeedEco() {
|
||||
return brushSpeedEco;
|
||||
}
|
||||
|
||||
public void setBrushSpeedEco(Integer brushSpeedEco) {
|
||||
this.brushSpeedEco = brushSpeedEco;
|
||||
}
|
||||
|
||||
public Integer getVacuumSpeed() {
|
||||
return vacuumSpeed;
|
||||
}
|
||||
|
||||
public void setVacuumSpeed(Integer vacuumSpeed) {
|
||||
this.vacuumSpeed = vacuumSpeed;
|
||||
}
|
||||
|
||||
public Integer getVacuumPwrPercent() {
|
||||
return vacuumPwrPercent;
|
||||
}
|
||||
|
||||
public void setVacuumPwrPercent(Integer vacuumPwrPercent) {
|
||||
this.vacuumPwrPercent = vacuumPwrPercent;
|
||||
}
|
||||
|
||||
public Integer getVacuumPwrPercentEco() {
|
||||
return vacuumPwrPercentEco;
|
||||
}
|
||||
|
||||
public void setVacuumPwrPercentEco(Integer vacuumPwrPercentEco) {
|
||||
this.vacuumPwrPercentEco = vacuumPwrPercentEco;
|
||||
}
|
||||
|
||||
public Integer getRunTime() {
|
||||
return runTime;
|
||||
}
|
||||
|
||||
public void setRunTime(Integer runTime) {
|
||||
this.runTime = runTime;
|
||||
}
|
||||
|
||||
public Integer getBrushPresent() {
|
||||
return brushPresent;
|
||||
}
|
||||
|
||||
public void setBrushPresent(Integer brushPresent) {
|
||||
this.brushPresent = brushPresent;
|
||||
}
|
||||
|
||||
public Integer getVacuumPresent() {
|
||||
return vacuumPresent;
|
||||
}
|
||||
|
||||
public void setVacuumPresent(Integer vacuumPresent) {
|
||||
this.vacuumPresent = vacuumPresent;
|
||||
}
|
||||
|
||||
public Integer getPadPresent() {
|
||||
return padPresent;
|
||||
}
|
||||
|
||||
public void setPadPresent(Integer padPresent) {
|
||||
this.padPresent = padPresent;
|
||||
}
|
||||
|
||||
public Integer getPlatenPresent() {
|
||||
return platenPresent;
|
||||
}
|
||||
|
||||
public void setPlatenPresent(Integer platenPresent) {
|
||||
this.platenPresent = platenPresent;
|
||||
}
|
||||
|
||||
public Integer getBrushDirection() {
|
||||
return brushDirection;
|
||||
}
|
||||
|
||||
public void setBrushDirection(Integer brushDirection) {
|
||||
this.brushDirection = brushDirection;
|
||||
}
|
||||
|
||||
public Integer getVacuumDirection() {
|
||||
return vacuumDirection;
|
||||
}
|
||||
|
||||
public void setVacuumDirection(Integer vacuumDirection) {
|
||||
this.vacuumDirection = vacuumDirection;
|
||||
}
|
||||
|
||||
public Integer getPadDirection() {
|
||||
return padDirection;
|
||||
}
|
||||
|
||||
public void setPadDirection(Integer padDirection) {
|
||||
this.padDirection = padDirection;
|
||||
}
|
||||
|
||||
public Integer getCumulativeCartridgeTimeInSecs() {
|
||||
return cumulativeCartridgeTimeInSecs;
|
||||
}
|
||||
|
||||
public void setCumulativeCartridgeTimeInSecs(Integer cumulativeCartridgeTimeInSecs) {
|
||||
this.cumulativeCartridgeTimeInSecs = cumulativeCartridgeTimeInSecs;
|
||||
}
|
||||
|
||||
public Integer getNCleaningsStartedWhereDustBinWasFull() {
|
||||
return nCleaningsStartedWhereDustBinWasFull;
|
||||
}
|
||||
|
||||
public void setNCleaningsStartedWhereDustBinWasFull(Integer nCleaningsStartedWhereDustBinWasFull) {
|
||||
this.nCleaningsStartedWhereDustBinWasFull = nCleaningsStartedWhereDustBinWasFull;
|
||||
}
|
||||
|
||||
public Integer getBlowerType() {
|
||||
return blowerType;
|
||||
}
|
||||
|
||||
public void setBlowerType(Integer blowerType) {
|
||||
this.blowerType = blowerType;
|
||||
}
|
||||
|
||||
public Integer getBrushMotorType() {
|
||||
return brushMotorType;
|
||||
}
|
||||
|
||||
public void setBrushMotorType(Integer brushMotorType) {
|
||||
this.brushMotorType = brushMotorType;
|
||||
}
|
||||
|
||||
public Integer getSideBrushType() {
|
||||
return sideBrushType;
|
||||
}
|
||||
|
||||
public void setSideBrushType(Integer sideBrushType) {
|
||||
this.sideBrushType = sideBrushType;
|
||||
}
|
||||
|
||||
public Integer getSideBrushPower() {
|
||||
return sideBrushPower;
|
||||
}
|
||||
|
||||
public void setSideBrushPower(Integer sideBrushPower) {
|
||||
this.sideBrushPower = sideBrushPower;
|
||||
}
|
||||
|
||||
public Integer getNAutoCycleCleaningsStarted() {
|
||||
return nAutoCycleCleaningsStarted;
|
||||
}
|
||||
|
||||
public void setNAutoCycleCleaningsStarted(Integer nAutoCycleCleaningsStarted) {
|
||||
this.nAutoCycleCleaningsStarted = nAutoCycleCleaningsStarted;
|
||||
}
|
||||
|
||||
public Integer getHardwareVersionMajor() {
|
||||
return hardwareVersionMajor;
|
||||
}
|
||||
|
||||
public void setHardwareVersionMajor(Integer hardwareVersionMajor) {
|
||||
this.hardwareVersionMajor = hardwareVersionMajor;
|
||||
}
|
||||
|
||||
public Integer getHardwareVersionMinor() {
|
||||
return hardwareVersionMinor;
|
||||
}
|
||||
|
||||
public void setHardwareVersionMinor(Integer hardwareVersionMinor) {
|
||||
this.hardwareVersionMinor = hardwareVersionMinor;
|
||||
}
|
||||
|
||||
public Integer getSoftwareVersionMajor() {
|
||||
return softwareVersionMajor;
|
||||
}
|
||||
|
||||
public void setSoftwareVersionMajor(Integer softwareVersionMajor) {
|
||||
this.softwareVersionMajor = softwareVersionMajor;
|
||||
}
|
||||
|
||||
public Integer getSoftwareVersionMinor() {
|
||||
return softwareVersionMinor;
|
||||
}
|
||||
|
||||
public void setSoftwareVersionMinor(Integer softwareVersionMinor) {
|
||||
this.softwareVersionMinor = softwareVersionMinor;
|
||||
}
|
||||
|
||||
public Integer getMaxVoltage() {
|
||||
return maxVoltage;
|
||||
}
|
||||
|
||||
public void setMaxVoltage(Integer maxVoltage) {
|
||||
this.maxVoltage = maxVoltage;
|
||||
}
|
||||
|
||||
public Integer getMaxCurrent() {
|
||||
return maxCurrent;
|
||||
}
|
||||
|
||||
public void setMaxCurrent(Integer maxCurrent) {
|
||||
this.maxCurrent = maxCurrent;
|
||||
}
|
||||
|
||||
public Integer getVoltageMultiplier() {
|
||||
return voltageMultiplier;
|
||||
}
|
||||
|
||||
public void setVoltageMultiplier(Integer voltageMultiplier) {
|
||||
this.voltageMultiplier = voltageMultiplier;
|
||||
}
|
||||
|
||||
public Integer getCurrentMultiplier() {
|
||||
return currentMultiplier;
|
||||
}
|
||||
|
||||
public void setCurrentMultiplier(Integer currentMultiplier) {
|
||||
this.currentMultiplier = currentMultiplier;
|
||||
}
|
||||
|
||||
public Integer getCapacityMode() {
|
||||
return capacityMode;
|
||||
}
|
||||
|
||||
public void setCapacityMode(Integer capacityMode) {
|
||||
this.capacityMode = capacityMode;
|
||||
}
|
||||
|
||||
public Integer getDesignCapacity() {
|
||||
return designCapacity;
|
||||
}
|
||||
|
||||
public void setDesignCapacity(Integer designCapacity) {
|
||||
this.designCapacity = designCapacity;
|
||||
}
|
||||
|
||||
public Integer getDesignVoltage() {
|
||||
return designVoltage;
|
||||
}
|
||||
|
||||
public void setDesignVoltage(Integer designVoltage) {
|
||||
this.designVoltage = designVoltage;
|
||||
}
|
||||
|
||||
public Integer getMfgDay() {
|
||||
return mfgDay;
|
||||
}
|
||||
|
||||
public void setMfgDay(Integer mfgDay) {
|
||||
this.mfgDay = mfgDay;
|
||||
}
|
||||
|
||||
public Integer getMfgMonth() {
|
||||
return mfgMonth;
|
||||
}
|
||||
|
||||
public void setMfgMonth(Integer mfgMonth) {
|
||||
this.mfgMonth = mfgMonth;
|
||||
}
|
||||
|
||||
public Integer getMfgYear() {
|
||||
return mfgYear;
|
||||
}
|
||||
|
||||
public void setMfgYear(Integer mfgYear) {
|
||||
this.mfgYear = mfgYear;
|
||||
}
|
||||
|
||||
public Integer getSerialNumber() {
|
||||
return serialNumber;
|
||||
}
|
||||
|
||||
public void setSerialNumber(Integer serialNumber) {
|
||||
this.serialNumber = serialNumber;
|
||||
}
|
||||
|
||||
public Integer getSwVer() {
|
||||
return swVer;
|
||||
}
|
||||
|
||||
public void setSwVer(Integer swVer) {
|
||||
this.swVer = swVer;
|
||||
}
|
||||
|
||||
public Integer getDataVer() {
|
||||
return dataVer;
|
||||
}
|
||||
|
||||
public void setDataVer(Integer dataVer) {
|
||||
this.dataVer = dataVer;
|
||||
}
|
||||
|
||||
public Integer getMfgAccess() {
|
||||
return mfgAccess;
|
||||
}
|
||||
|
||||
public void setMfgAccess(Integer mfgAccess) {
|
||||
this.mfgAccess = mfgAccess;
|
||||
}
|
||||
|
||||
public String getMfgName() {
|
||||
return mfgName;
|
||||
}
|
||||
|
||||
public void setMfgName(String mfgName) {
|
||||
this.mfgName = mfgName;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public void setDeviceName(String deviceName) {
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
public String getChemistryName() {
|
||||
return chemistryName;
|
||||
}
|
||||
|
||||
public void setChemistryName(String chemistryName) {
|
||||
this.chemistryName = chemistryName;
|
||||
}
|
||||
|
||||
public Integer getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public void setMajor(Integer major) {
|
||||
this.major = major;
|
||||
}
|
||||
|
||||
public Integer getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public void setMinor(Integer minor) {
|
||||
this.minor = minor;
|
||||
}
|
||||
|
||||
public Integer getBuild() {
|
||||
return build;
|
||||
}
|
||||
|
||||
public void setBuild(Integer build) {
|
||||
this.build = build;
|
||||
}
|
||||
|
||||
public String getLdsVer() {
|
||||
return ldsVer;
|
||||
}
|
||||
|
||||
public void setLdsVer(String ldsVer) {
|
||||
this.ldsVer = ldsVer;
|
||||
}
|
||||
|
||||
public String getLdsSerial() {
|
||||
return ldsSerial;
|
||||
}
|
||||
|
||||
public void setLdsSerial(String ldsSerial) {
|
||||
this.ldsSerial = ldsSerial;
|
||||
}
|
||||
|
||||
public String getLdsCPU() {
|
||||
return ldsCpu;
|
||||
}
|
||||
|
||||
public void setLdsCPU(String ldsCPU) {
|
||||
this.ldsCpu = ldsCPU;
|
||||
}
|
||||
|
||||
public String getLdsBuildNum() {
|
||||
return ldsBuildNum;
|
||||
}
|
||||
|
||||
public void setLdsBuildNum(String ldsBuildNum) {
|
||||
this.ldsBuildNum = ldsBuildNum;
|
||||
}
|
||||
|
||||
public Integer getBootLoaderVersion() {
|
||||
return bootLoaderVersion;
|
||||
}
|
||||
|
||||
public void setBootLoaderVersion(Integer bootLoaderVersion) {
|
||||
this.bootLoaderVersion = bootLoaderVersion;
|
||||
}
|
||||
|
||||
public Integer getUiBoardSWVer() {
|
||||
return uiBoardSWVer;
|
||||
}
|
||||
|
||||
public void setUiBoardSWVer(Integer uiBoardSWVer) {
|
||||
this.uiBoardSWVer = uiBoardSWVer;
|
||||
}
|
||||
|
||||
public Integer getUiBoardHWVer() {
|
||||
return uiBoardHWVer;
|
||||
}
|
||||
|
||||
public void setUiBoardHWVer(Integer uiBoardHWVer) {
|
||||
this.uiBoardHWVer = uiBoardHWVer;
|
||||
}
|
||||
|
||||
public Integer getQaState() {
|
||||
return qaState;
|
||||
}
|
||||
|
||||
public void setQaState(Integer qaState) {
|
||||
this.qaState = qaState;
|
||||
}
|
||||
|
||||
public Integer getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
public void setManufacturer(Integer manufacturer) {
|
||||
this.manufacturer = manufacturer;
|
||||
}
|
||||
|
||||
public Integer getDriverVersion() {
|
||||
return driverVersion;
|
||||
}
|
||||
|
||||
public void setDriverVersion(Integer driverVersion) {
|
||||
this.driverVersion = driverVersion;
|
||||
}
|
||||
|
||||
public Integer getDriverID() {
|
||||
return driverId;
|
||||
}
|
||||
|
||||
public void setDriverID(Integer driverID) {
|
||||
this.driverId = driverID;
|
||||
}
|
||||
|
||||
public Integer getUltrasonicSW() {
|
||||
return ultrasonicSW;
|
||||
}
|
||||
|
||||
public void setUltrasonicSW(Integer ultrasonicSW) {
|
||||
this.ultrasonicSW = ultrasonicSW;
|
||||
}
|
||||
|
||||
public Integer getUltrasonicHW() {
|
||||
return ultrasonicHW;
|
||||
}
|
||||
|
||||
public void setUltrasonicHW(Integer ultrasonicHW) {
|
||||
this.ultrasonicHW = ultrasonicHW;
|
||||
}
|
||||
|
||||
public Integer getBlowerHW() {
|
||||
return blowerHW;
|
||||
}
|
||||
|
||||
public void setBlowerHW(Integer blowerHW) {
|
||||
this.blowerHW = blowerHW;
|
||||
}
|
||||
|
||||
public Integer getBlowerSWMajor() {
|
||||
return blowerSWMajor;
|
||||
}
|
||||
|
||||
public void setBlowerSWMajor(Integer blowerSWMajor) {
|
||||
this.blowerSWMajor = blowerSWMajor;
|
||||
}
|
||||
|
||||
public Integer getBlowerSWMinor() {
|
||||
return blowerSWMinor;
|
||||
}
|
||||
|
||||
public void setBlowerSWMinor(Integer blowerSWMinor) {
|
||||
this.blowerSWMinor = blowerSWMinor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.neato.internal.config;
|
||||
|
||||
/**
|
||||
* Parameters used for bridge configuration.
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*/
|
||||
public class NeatoAccountConfig {
|
||||
|
||||
private String email;
|
||||
private String password;
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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.neato.internal.config;
|
||||
|
||||
/**
|
||||
* Config class for a Neato Robot
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
public class NeatoRobotConfig {
|
||||
|
||||
private int refresh;
|
||||
private String secret;
|
||||
private String serial;
|
||||
|
||||
public int getRefresh() {
|
||||
return refresh;
|
||||
}
|
||||
|
||||
public void setRefresh(int refresh) {
|
||||
this.refresh = refresh;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getSerial() {
|
||||
return serial;
|
||||
}
|
||||
|
||||
public void setSerial(String serial) {
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NeatoRobotConfig [refresh=" + refresh + ", secret=" + secret + ", serial=" + serial + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 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.neato.internal.discovery;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openhab.binding.neato.internal.NeatoBindingConstants;
|
||||
import org.openhab.binding.neato.internal.NeatoHandlerFactory;
|
||||
import org.openhab.binding.neato.internal.classes.Robot;
|
||||
import org.openhab.binding.neato.internal.handler.NeatoAccountHandler;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link NeatoAccountDiscoveryService} is responsible for starting the discovery procedure
|
||||
* that connects to Neato Web and imports all registered vacuum cleaners.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
* @author Jeff Lauterbach - Start discovery service from bridge
|
||||
*/
|
||||
public class NeatoAccountDiscoveryService extends AbstractDiscoveryService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(NeatoAccountDiscoveryService.class);
|
||||
|
||||
private static final int TIMEOUT = 15;
|
||||
|
||||
private NeatoAccountHandler handler;
|
||||
private ThingUID bridgeUID;
|
||||
|
||||
private ScheduledFuture<?> scanTask;
|
||||
|
||||
public NeatoAccountDiscoveryService(NeatoAccountHandler handler) {
|
||||
super(NeatoHandlerFactory.DISCOVERABLE_THING_TYPE_UIDS, TIMEOUT);
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
private void findRobots() {
|
||||
List<Robot> robots = handler.getRobotsFromNeato();
|
||||
|
||||
for (Robot robot : robots) {
|
||||
addThing(robot);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
findRobots();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScan() {
|
||||
if (this.scanTask != null) {
|
||||
scanTask.cancel(true);
|
||||
}
|
||||
this.scanTask = scheduler.schedule(() -> findRobots(), 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopScan() {
|
||||
super.stopScan();
|
||||
|
||||
if (this.scanTask != null) {
|
||||
this.scanTask.cancel(true);
|
||||
this.scanTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void addThing(Robot robot) {
|
||||
logger.debug("addThing(): Adding new Neato unit {} to the smarthome inbox", robot.getName());
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
ThingUID thingUID = new ThingUID(NeatoBindingConstants.THING_TYPE_VACUUMCLEANER, bridgeUID, robot.getSerial());
|
||||
properties.put(NeatoBindingConstants.CONFIG_SECRET, robot.getSecretKey());
|
||||
properties.put(NeatoBindingConstants.CONFIG_SERIAL, robot.getSerial());
|
||||
properties.put(Thing.PROPERTY_MODEL_ID, robot.getModel());
|
||||
properties.put(NeatoBindingConstants.PROPERTY_NAME, robot.getName());
|
||||
|
||||
thingDiscovered(
|
||||
DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID).withProperties(properties).build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* 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.neato.internal.handler;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.openhab.binding.neato.internal.classes.BeehiveAuthentication;
|
||||
import org.openhab.binding.neato.internal.classes.NeatoAccountInformation;
|
||||
import org.openhab.binding.neato.internal.classes.Robot;
|
||||
import org.openhab.binding.neato.internal.config.NeatoAccountConfig;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* Bridge handler to manage Neato Cloud Account
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
public class NeatoAccountHandler extends BaseBridgeHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(NeatoAccountHandler.class);
|
||||
|
||||
public NeatoAccountHandler(Bridge bridge) {
|
||||
super(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
}
|
||||
|
||||
private List<Robot> sendGetRobots(String accessToken) {
|
||||
Properties headers = new Properties();
|
||||
headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
|
||||
|
||||
headers.setProperty("Authorization", "Token token=" + accessToken);
|
||||
|
||||
try {
|
||||
String resultString = HttpUtil.executeUrl("GET", "https://beehive.neatocloud.com/dashboard", headers, null,
|
||||
"application/json", 20000);
|
||||
|
||||
Gson gson = new Gson();
|
||||
NeatoAccountInformation accountInformation = gson.fromJson(resultString, NeatoAccountInformation.class);
|
||||
|
||||
logger.debug("Result from WS call to get Robots: {}", resultString);
|
||||
|
||||
return accountInformation.getRobots();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error attempting to find robots registered to account", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Error attempting to find robots registered to account");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public @NonNull List<Robot> getRobotsFromNeato() {
|
||||
logger.debug("Attempting to find robots tied to account");
|
||||
NeatoAccountConfig accountConfig = getConfigAs(NeatoAccountConfig.class);
|
||||
String accessToken = authenticate(accountConfig.getEmail(), accountConfig.getPassword());
|
||||
|
||||
if (accessToken != null) {
|
||||
return sendGetRobots(accessToken);
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private String authenticate(String username, String password) {
|
||||
Gson gson = new Gson();
|
||||
|
||||
AuthRequest req = new AuthRequest(username, password, "ios",
|
||||
new BigInteger(130, new SecureRandom()).toString(64));
|
||||
|
||||
String authenticationResponse = "";
|
||||
try {
|
||||
authenticationResponse = sendAuthRequestToNeato(gson.toJson(req));
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error when sending Authentication request to Neato.", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Error when sending Authentication request to Neato.");
|
||||
}
|
||||
|
||||
BeehiveAuthentication authenticationObject = gson.fromJson(authenticationResponse, BeehiveAuthentication.class);
|
||||
return authenticationObject.getAccessToken();
|
||||
}
|
||||
|
||||
private String sendAuthRequestToNeato(String data) throws IOException {
|
||||
Properties headers = new Properties();
|
||||
headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
|
||||
|
||||
InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
|
||||
String resultString = HttpUtil.executeUrl("POST", "https://beehive.neatocloud.com/sessions", headers, stream,
|
||||
"application/json", 20000);
|
||||
|
||||
logger.debug("Authentication Response: {}", resultString);
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
private static class AuthRequest {
|
||||
private String email;
|
||||
private String password;
|
||||
private String os;
|
||||
private String token;
|
||||
|
||||
public AuthRequest(String email, String password, String os, String token) {
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.os = os;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getOs() {
|
||||
return os;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* 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.neato.internal.handler;
|
||||
|
||||
import static org.openhab.binding.neato.internal.NeatoBindingConstants.*;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.openhab.binding.neato.internal.CouldNotFindRobotException;
|
||||
import org.openhab.binding.neato.internal.NeatoBindingConstants;
|
||||
import org.openhab.binding.neato.internal.NeatoCommunicationException;
|
||||
import org.openhab.binding.neato.internal.NeatoRobot;
|
||||
import org.openhab.binding.neato.internal.classes.Cleaning;
|
||||
import org.openhab.binding.neato.internal.classes.Details;
|
||||
import org.openhab.binding.neato.internal.classes.NeatoState;
|
||||
import org.openhab.binding.neato.internal.config.NeatoRobotConfig;
|
||||
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.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link NeatoHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Patrik Wimnell - Initial contribution
|
||||
* @author Jeff Lauterbach - Code Cleanup and Refactor
|
||||
*/
|
||||
public class NeatoHandler extends BaseThingHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(NeatoHandler.class);
|
||||
|
||||
private NeatoRobot mrRobot;
|
||||
|
||||
private int refreshTime;
|
||||
private ScheduledFuture<?> refreshTask;
|
||||
|
||||
public NeatoHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(@NonNull ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
refreshStateAndUpdate();
|
||||
} else if (channelUID.getId().equals(NeatoBindingConstants.COMMAND)) {
|
||||
sendCommandToRobot(command);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendCommandToRobot(Command command) {
|
||||
logger.debug("Ok - will handle command for CHANNEL_COMMAND");
|
||||
|
||||
try {
|
||||
mrRobot.sendCommand(command.toString());
|
||||
} catch (NeatoCommunicationException e) {
|
||||
logger.debug("Error while processing command from openHAB.", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
this.refreshStateAndUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Running dispose()");
|
||||
if (this.refreshTask != null) {
|
||||
this.refreshTask.cancel(true);
|
||||
this.refreshTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
logger.debug("Will boot up Neato Vacuum Cleaner binding!");
|
||||
|
||||
NeatoRobotConfig config = getThing().getConfiguration().as(NeatoRobotConfig.class);
|
||||
|
||||
logger.debug("Neato Robot Config: {}", config);
|
||||
|
||||
refreshTime = config.getRefresh();
|
||||
if (refreshTime < 30) {
|
||||
logger.warn(
|
||||
"Refresh time [{}] is not valid. Refresh time must be at least 30 seconds. Setting to minimum of 30 sec",
|
||||
refreshTime);
|
||||
config.setRefresh(30);
|
||||
}
|
||||
|
||||
mrRobot = new NeatoRobot(config);
|
||||
startAutomaticRefresh();
|
||||
}
|
||||
|
||||
public void refreshStateAndUpdate() {
|
||||
if (mrRobot != null) {
|
||||
try {
|
||||
mrRobot.sendGetState();
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
|
||||
mrRobot.sendGetGeneralInfo();
|
||||
|
||||
publishChannels();
|
||||
} catch (NeatoCommunicationException | CouldNotFindRobotException e) {
|
||||
logger.debug("Error when refreshing state.", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startAutomaticRefresh() {
|
||||
Runnable refresher = () -> refreshStateAndUpdate();
|
||||
|
||||
this.refreshTask = scheduler.scheduleWithFixedDelay(refresher, 0, refreshTime, TimeUnit.SECONDS);
|
||||
logger.debug("Start automatic refresh at {} seconds", refreshTime);
|
||||
}
|
||||
|
||||
private void publishChannels() {
|
||||
logger.debug("Updating Channels");
|
||||
|
||||
NeatoState neatoState = mrRobot.getState();
|
||||
if (neatoState == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateProperty(Thing.PROPERTY_FIRMWARE_VERSION, neatoState.getMeta().getFirmware());
|
||||
updateProperty(Thing.PROPERTY_MODEL_ID, neatoState.getMeta().getModelName());
|
||||
|
||||
updateState(CHANNEL_STATE, new StringType(neatoState.getRobotState().name()));
|
||||
updateState(CHANNEL_ERROR, new StringType((String) ObjectUtils.defaultIfNull(neatoState.getError(), "")));
|
||||
updateState(CHANNEL_ACTION, new StringType(neatoState.getRobotAction().name()));
|
||||
|
||||
Details details = neatoState.getDetails();
|
||||
if (details != null) {
|
||||
updateState(CHANNEL_BATTERY, new DecimalType(details.getCharge()));
|
||||
updateState(CHANNEL_DOCKHASBEENSEEN, details.getDockHasBeenSeen() ? OnOffType.ON : OnOffType.OFF);
|
||||
updateState(CHANNEL_ISCHARGING, details.getIsCharging() ? OnOffType.ON : OnOffType.OFF);
|
||||
updateState(CHANNEL_ISSCHEDULED, details.getIsScheduleEnabled() ? OnOffType.ON : OnOffType.OFF);
|
||||
updateState(CHANNEL_ISDOCKED, details.getIsDocked() ? OnOffType.ON : OnOffType.OFF);
|
||||
}
|
||||
|
||||
Cleaning cleaning = neatoState.getCleaning();
|
||||
if (cleaning != null) {
|
||||
updateState(CHANNEL_CLEANINGCATEGORY, new StringType(cleaning.getCategory().name()));
|
||||
updateState(CHANNEL_CLEANINGMODE, new StringType(cleaning.getMode().name()));
|
||||
updateState(CHANNEL_CLEANINGMODIFIER, new StringType(cleaning.getModifier().name()));
|
||||
updateState(CHANNEL_CLEANINGSPOTWIDTH, new DecimalType(cleaning.getSpotWidth()));
|
||||
updateState(CHANNEL_CLEANINGSPOTHEIGHT, new DecimalType(cleaning.getSpotHeight()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="neato" 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>Neato Binding</name>
|
||||
<description>This is the binding for Neato.</description>
|
||||
<author>Patrik Wimnell</author>
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,216 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="neato"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="neatoaccount">
|
||||
<label>Neato Account</label>
|
||||
<description>Access to Neato Account. Used to discover robots tied to account.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="email" type="text">
|
||||
<label>E-mail Address</label>
|
||||
<description>E-mail address for your Neato Cloud account.</description>
|
||||
<required>true</required>
|
||||
<context>email</context>
|
||||
</parameter>
|
||||
<parameter name="password" type="text">
|
||||
<label>Password</label>
|
||||
<description>Password for your Neato Cloud account.</description>
|
||||
<required>true</required>
|
||||
<context>password</context>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
|
||||
<thing-type id="vacuumcleaner">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="neatoaccount"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Neato Vacuum Cleaner</label>
|
||||
<description>Provides communication with Neato Vacuum cleaner.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="battery-level" typeId="system.battery-level"/>
|
||||
<channel id="state" typeId="state"/>
|
||||
<channel id="action" typeId="action"/>
|
||||
<channel id="dock-has-been-seen" typeId="dock-has-been-seen"/>
|
||||
<channel id="is-docked" typeId="is-docked"/>
|
||||
<channel id="is-scheduled" typeId="is-scheduled"/>
|
||||
<channel id="is-charging" typeId="is-charging"/>
|
||||
<channel id="error" typeId="error"/>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="cleaning-category" typeId="cleaning-category"/>
|
||||
<channel id="cleaning-mode" typeId="cleaning-mode"/>
|
||||
<channel id="cleaning-modifier" typeId="cleaning-modifier"/>
|
||||
<channel id="cleaning-spotwidth" typeId="cleaning-spotwidth"/>
|
||||
<channel id="cleaning-spotheight" typeId="cleaning-spotheight"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="serial" type="text" required="true">
|
||||
<label>Neato Vacuum Serial</label>
|
||||
<description>Serial number of the vacuum cleaner</description>
|
||||
</parameter>
|
||||
|
||||
<parameter name="secret" type="text" required="true">
|
||||
<label>Neato Vacuum Secret</label>
|
||||
<description>Secret for accessing Neato web services.</description>
|
||||
</parameter>
|
||||
|
||||
<parameter name="refresh" type="integer">
|
||||
<label>Refresh Time Interval</label>
|
||||
<description>Refresh time interval in seconds for updates from the Neato Web Service.</description>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="state">
|
||||
<item-type>String</item-type>
|
||||
<label>Current State</label>
|
||||
<description>Current state of the vacuum cleaner.</description>
|
||||
<state readOnly="true" pattern="%s">
|
||||
<options>
|
||||
<option value="INVALID">Invalid</option>
|
||||
<option value="IDLE">Idle</option>
|
||||
<option value="BUSY">Busy</option>
|
||||
<option value="PAUSED">Paused</option>
|
||||
<option value="ERROR">Error</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="action">
|
||||
<item-type>String</item-type>
|
||||
<label>Current Action</label>
|
||||
<description>Current action of the vacuum cleaner.</description>
|
||||
<state readOnly="true" pattern="%s">
|
||||
<options>
|
||||
<option value="INVALID">Invalid</option>
|
||||
<option value="HOUSE_CLEANING">House Cleaning</option>
|
||||
<option value="SPOT_CLEANING">Spot Cleaning</option>
|
||||
<option value="MANUAL_CLEANING">Manual Cleaning</option>
|
||||
<option value="DOCKING">Docking</option>
|
||||
<option value="USER_MENU_ACTIVE">User Menu Active</option>
|
||||
<option value="SUSPENDED_CLEANING">Suspended Cleaning</option>
|
||||
<option value="UPDATING">Updating</option>
|
||||
<option value="COPYING_LOGS">Copying Logs</option>
|
||||
<option value="RECOVERING_LOCATION">Recovering Location</option>
|
||||
<option value="IEC_TEST">Iec Test</option>
|
||||
<option value="MAP_CLEANING">Map Cleaning</option>
|
||||
<option value="EXPLORING_MAP">Exploring map (creating a persistent map)</option>
|
||||
<option value="AQUIRING_MAP_IDS">Acquiring Persistent Map IDs</option>
|
||||
<option value="CREATING_MAP">Creating & Uploading Map</option>
|
||||
<option value="SUSPENDED_EXPLORATION">Suspended Exploration</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="dock-has-been-seen">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Dock Has Been Seen</label>
|
||||
<description>True or False value if the dock has been seen</description>
|
||||
<state readOnly="true" pattern="%s"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="is-docked">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Is Docked</label>
|
||||
<description>Is the vacuum cleaner in the docking station?</description>
|
||||
<state readOnly="true" pattern="%s"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="is-scheduled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Is Scheduled Enabled</label>
|
||||
<description>True or False value if the vacuum cleaner is scheduled for cleaning.</description>
|
||||
<state readOnly="true" pattern="%s"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="is-charging">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Is Charging</label>
|
||||
<description>Is the vacuum cleaner currently charging?</description>
|
||||
<state readOnly="true" pattern="%s"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="error">
|
||||
<item-type>String</item-type>
|
||||
<label>Error</label>
|
||||
<description>Last error message in system.</description>
|
||||
<state readOnly="true" pattern="%s"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="command">
|
||||
<item-type>String</item-type>
|
||||
<label>Send Command</label>
|
||||
<description>Send Commands to Vacuum Cleaner. (clean with map, clean, pause, resume, stop, dock)</description>
|
||||
<state readOnly="false" pattern="%s">
|
||||
<options>
|
||||
<option value="clean">Clean</option>
|
||||
<option value="cleanWithMap">Clean with Map</option>
|
||||
<option value="pause">Pause</option>
|
||||
<option value="resume">Resume</option>
|
||||
<option value="stop">Stop</option>
|
||||
<option value="dock">Go to Dock</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="cleaning-category">
|
||||
<item-type>String</item-type>
|
||||
<label>Cleaning Category</label>
|
||||
<description>Current or last category of the cleaning.</description>
|
||||
<state readOnly="true" pattern="%s">
|
||||
<options>
|
||||
<option value="MANUAL">Manual Cleaning</option>
|
||||
<option value="SPOT">Spot Cleaning</option>
|
||||
<option value="HOUSE">House Cleaning</option>
|
||||
<option value="MAP">Map Cleaning</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="cleaning-mode">
|
||||
<item-type>String</item-type>
|
||||
<label>Cleaning Mode</label>
|
||||
<description>Current or last cleaning mode.</description>
|
||||
<state readOnly="true" pattern="%s">
|
||||
<options>
|
||||
<option value="ECO">Eco</option>
|
||||
<option value="TURBO">Turbo</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="cleaning-modifier">
|
||||
<item-type>String</item-type>
|
||||
<label>Cleaning Modifier</label>
|
||||
<description>Modifier of current or last cleaning.</description>
|
||||
<state readOnly="true" pattern="%s">
|
||||
<options>
|
||||
<option value="NORMAL">Normal</option>
|
||||
<option value="DOUBLE">Double</option>
|
||||
<option value="DEEP">Deep</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="cleaning-spotwidth">
|
||||
<item-type>Number</item-type>
|
||||
<label>Spot Width</label>
|
||||
<description>Current or Last cleaning, width of spot. 100-400cm.</description>
|
||||
<state readOnly="true" pattern="%d"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="cleaning-spotheight">
|
||||
<item-type>Number</item-type>
|
||||
<label>Spot Height</label>
|
||||
<description>Current or Last cleaning, height of spot. 100-400cm.</description>
|
||||
<state readOnly="true" pattern="%d"/>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user