Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ecovacs] Initial contribution #12231

Merged
merged 72 commits into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
b23d814
[ecovacs] Initial contribution
maniac103 Jan 3, 2022
7bd8004
[ecovacs] Set API bridge offline if no country is configured
maniac103 Feb 11, 2022
60f5f08
[ecovacs] Improve last cleaning map download
maniac103 Feb 12, 2022
ade68b9
[ecovacs] Improve MQTT subscription code
maniac103 Feb 13, 2022
6638b28
[ecovacs] Fix/improve exception handling
maniac103 Feb 20, 2022
1fe4276
[ecovacs] Refactor state channel handling.
maniac103 Feb 22, 2022
b181d33
[ecovacs] Fix deadlock on MQTT disconnection
maniac103 Feb 24, 2022
1cf3b5c
[ecovacs] Fix API server selection for users in UK and China
maniac103 Feb 26, 2022
2f1b9ad
[ecovacs] Fix a few warnings
maniac103 Feb 26, 2022
c89b55a
[ecovacs] Fix login for UK, take 2
maniac103 Feb 28, 2022
6e7704a
[ecovacs] Minor cleanup
maniac103 Mar 1, 2022
c7e3051
[ecovacs] Correctly handle missing lists in API responses.
maniac103 Mar 4, 2022
d00fc03
[ecovacs] Handle expired auth token
maniac103 Mar 4, 2022
e18a77d
[ecovacs] Make scheduled runnable management more robust.
maniac103 Mar 9, 2022
db9fa3d
[ecovacs] Use a 10 second timeout for HTTP requests
maniac103 Mar 9, 2022
91a24f9
[ecovacs] Fix device reconnection logic
maniac103 Mar 9, 2022
78ac787
[ecovacs] Fix Deebot 610 device definition
maniac103 Mar 9, 2022
7ec2ead
[ecovacs] Clean/deduplicate API implementation
maniac103 Mar 9, 2022
430e454
[ecovacs] Remove unused method from EcovacsDevice interface.
maniac103 Mar 9, 2022
46f964e
[ecovacs] Improve device metadata
maniac103 May 13, 2022
030670e
[ecovacs] Filter out last clean mode and map for XML devices
maniac103 May 20, 2022
3fc6a00
[ecovacs] Fix copy'n'paste mistake in readme
maniac103 May 23, 2022
c8084d3
[ecovacs] Add rule action for sound playback
maniac103 May 24, 2022
0789a5d
[ecovacs] Correctly detect 'custom area' mode for XML devices
maniac103 Jun 1, 2022
d0c0edf
[ecovacs] Add support for custom area cleaning command
maniac103 Jun 1, 2022
1849656
[ecovacs] Map current cleaning spot definition into a channel
maniac103 Jun 14, 2022
b85d999
[ecovacs] Fix event updates when multiple cleaners are used
maniac103 Jun 22, 2022
d089522
[ecovacs] Update OH version
maniac103 Jul 11, 2022
1e53a7f
[ecovacs] Change spotArea and customArea command definitions
maniac103 Sep 2, 2022
bd11e04
[ecovacs] Add T10 models to supported device list.
maniac103 Sep 16, 2022
7f250b9
[ecovacs] Fix device reconnection on access token expiry
maniac103 Sep 21, 2022
ae7ac8b
[ecovacs] Only set device to ONLINE if full init sequence succeeded
maniac103 Nov 6, 2022
1c8d28c
[ecovacs] Fix formatting mistake in README
maniac103 Nov 6, 2022
2dafb3d
[ecovacs] Add some new channels
maniac103 Jan 6, 2023
3970eba
[ecovacs] Update to OH4 snapshot
maniac103 Jan 9, 2023
798f579
[ecovacs] Update license headers to 2023
maniac103 Jan 9, 2023
c7835d2
[Ecovacs] Fix message format for unknown error codes
maniac103 Jan 9, 2023
7c68304
[ecovacs] Update confirmed devices in README
maniac103 Jan 13, 2023
b83575c
[ecovacs] Fix device feature list for newer models with station
maniac103 Jan 14, 2023
2e6fb45
[ecovacs] Fix initialization failure for Deebot X1 Omni
maniac103 Jan 14, 2023
ec035fd
[ecovacs] Convert binding.xml to addon.xml
maniac103 Jan 16, 2023
af19bbd
[ecovacs] Fix verified model list in README
maniac103 Jan 16, 2023
3c96f4a
[ecovacs] Add cleaning pad washing state to state channel
maniac103 Jan 16, 2023
ee8f1a5
[ecovacs] Ignore onFwBuryPoint-bd_sysinfo MQTT message
maniac103 Jan 18, 2023
b9d3299
[ecovacs] Detect authentication problems in device command responses
maniac103 Feb 1, 2023
8d11b01
[ecovacs] Add channel for unit maintenance remaining time
maniac103 Feb 4, 2023
ba6be18
Apply review suggestions for readme
maniac103 Mar 8, 2023
f96ff4a
Implement some review comments
maniac103 Mar 8, 2023
ebaee53
Move client keys to EcovacsBindingConstants
maniac103 Mar 8, 2023
1e0932e
Implement more review comments
maniac103 Mar 8, 2023
23ff757
Implement more review comments
maniac103 Mar 8, 2023
87ddff5
Fix warnings
maniac103 Mar 8, 2023
cd719f7
Address more review comments
maniac103 Mar 9, 2023
0bdff77
Address more review comments
maniac103 Mar 9, 2023
5fc23e9
Add description for RSSI channel
maniac103 Mar 9, 2023
30d9487
Apply spotless
maniac103 Mar 9, 2023
49e549c
Fix NPE when loading supported device list.
maniac103 Mar 9, 2023
2a40f11
[ecovacs] Refactor API handler login handling
maniac103 Mar 9, 2023
116586f
[ecovacs] Work around SASL library bundle not being installed
maniac103 Mar 13, 2023
3c068b1
[ecovacs] Add missing models to supported device list
maniac103 Mar 14, 2023
4e90a4d
[ecovacs] Use serial number as representation property
maniac103 Mar 20, 2023
f650fa7
Implement review comments
maniac103 Mar 20, 2023
8a7432b
[ecovacs] Regenerate i18n properties
maniac103 Mar 20, 2023
a9e1af4
FIx lint issue in readme
maniac103 Mar 20, 2023
433d19a
Remove outdated translation strings.
maniac103 Mar 20, 2023
fca85dc
[ecovacs] Derive EcovacsApiException from Exception
maniac103 Mar 20, 2023
6438c07
[ecovacs] Simplify serial number handling.
maniac103 Mar 20, 2023
cef9667
[ecovacs] Initialize device serial number in initialize()
maniac103 Mar 20, 2023
976efdb
[ecovacs] Update README
maniac103 Mar 20, 2023
ba11c97
[ecovacs] Fixup readme format
maniac103 Mar 20, 2023
63ae901
[ecovacs] Fix manual scan and add some more logging
maniac103 Mar 21, 2023
55486b6
[ecovacs] Fix some code style issues
maniac103 Mar 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
/bundles/org.openhab.binding.echonetlite/ @mikeb01
/bundles/org.openhab.binding.ecobee/ @mhilbush
/bundles/org.openhab.binding.ecotouch/ @sibbi77
/bundles/org.openhab.binding.ecovacs/ @maniac103
/bundles/org.openhab.binding.ecowatt/ @lolodomo
/bundles/org.openhab.binding.ekey/ @hmerk
/bundles/org.openhab.binding.electroluxair/ @jannegpriv
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,11 @@
<artifactId>org.openhab.binding.ecotouch</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.ecovacs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.ecowatt</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.ecovacs/NOTICE
Original file line number Diff line number Diff line change
@@ -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
175 changes: 175 additions & 0 deletions bundles/org.openhab.binding.ecovacs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Ecovacs Binding

This binding provides integration for vacuum cleaning / mopping robots made by Ecovacs (<https://www.ecovacs.com/>).
It discovers devices and communicates to them by using Ecovacs' cloud services.

## Supported Things

- Ecovacs cloud API (`ecovacsapi`)
- Vacuum cleaner (`vacuum`)

At this point, the following devices are fully supported and verified to be working:

- Deebot OZMO 900/905
- Deebot OZMO 920
- Deebot OZMO 930
- Deebot OZMO 950
- Deebot OZMO Slim 10/11
- Deebot N8 series

The following devices will likely work because they are using similar protocols as the above ones:

- Deebot 600/601/605
- Deebot 900/901
- Deebot OZMO 610
- Deebot 710/711/711s
- Deebot OZMO T5
- Deebot (OZMO) T8 series
- Deebot T9 series
- Deebot Slim 2
- Deebot N3 MAX
- Deebot N7
- Deebot U2 series
- Deebot X1 Omni

## Discovery

At first, you need to manually create the bridge thing for the cloud API.
Once that is done, the supported devices will be automatically discovered and added to the inbox.

## Thing Configuration

For the cloud API thing, the following parameters must be configured:

| Config | Description |
|-----------|-------------------------------------------------------------------------------------------------------------------------------|
| email | The email address you used when registering the Ecovacs cloud account |
| password | The cloud account password |
| continent | The continent you are residing on, or 'World' if none matches. This is used to select the correct cloud server to connect to. |
maniac103 marked this conversation as resolved.
Show resolved Hide resolved

For the vacuum things, there is no required configuration (when using discovery). The following parameters exist:

| Config | Description |
|--------------|-------------------------------------------------------------------------------------------------------------------------------|
| serialNumber | Required: The device's serial number as printed on the barcode below the dust bin. Filled automatically when using discovery. |
| refresh | Refresh interval for polled data (see below), in minutes. By default set to 5 minutes. |

## Channels

The list below lists all channels supported by the binding.
In case a particular channel is not supported by a given device (see remarks), it is automatically removed from the given thing.

| Channel | Type | Description | Read Only | Updated By | Remarks |
|-----------------------------------------|----------------------|-----------------------------------------------------------|-----------|------------|----------|
| actions#command | String | Command to execute | No | Event | [1] |
| status#state | String | Current operational state | Yes | Event | [2] |
| status#current-cleaning-mode | String | Mode used in current cleaning run | Yes | Event | [3], [4] |
| status#current-cleaning-time | Number:Time | Time spent in current cleaning run | Yes | Event | [4] |
| status#current-cleaned-area | Number:Area | Area cleaned in current cleaning run | Yes | Event | [4] |
| status#current-cleaning-spot-definition | String | The spot to clean in current cleaning run | Yes | Event | [4], [5] |
| status#water-system-present | Switch | Whether the device is currently ready for mopping | Yes | Event | [6] |
| status#wifi-rssi | Number:Power | The current Wi-Fi signal strength of the device | Yes | Polling | [7] |
| consumables#main-brush-lifetime | Number:Dimensionless | The remaining life time of the main brush in percent | Yes | Polling | [8] |
| consumables#side-brush-lifetime | Number:Dimensionless | The remaining life time of the side brush in percent | Yes | Polling | |
| consumables#dust-filter-lifetime | Number:Dimensionless | The remaining life time of the dust bin filter in percent | Yes | Polling | |
| consumables#other-component-lifetime | Number:Dimensionless | The remaining time until device maintenance in percent | Yes | Polling | [9] |
| last-clean#last-clean-start | DateTime | The start time of the last completed cleaning run | Yes | Polling | |
| last-clean#last-clean-duration | Number:Time | The duration of the last completed cleaning run | Yes | Polling | |
| last-clean#last-clean-area | Number:Area | The area cleaned in the last completed cleaning run | Yes | Polling | |
| last-clean#last-clean-mode | String | The mode used for the last completed cleaning run | Yes | Polling | [3] |
| last-clean#last-clean-map | Image | The map image of the last completed cleaning run | Yes | Polling | |
| total-stats#total-cleaning-time | Number:Time | The total time spent cleaning during the device life time | Yes | Polling | |
| total-stats#total-cleaned-area | Number:Area | The total area cleaned during the device life time | Yes | Polling | |
| total-stats#total-clean-runs | Number | The total number of clean runs in the device life time | Yes | Polling | |
| settings#auto-empty | Switch | Whether dust bin auto empty to station is enabled | No | Polling | [10] |
| settings#cleaning-passes | Number | Number of cleaning passes to be used (1 or 2) | No | Polling | [9] |
| settings#continuous-cleaning | Switch | Whether unfinished cleaning resumes after charging | No | Polling | |
| settings#suction-power | String | The power level used during cleaning | No | Polling | [11] |
| settings#true-detect-3d | Switch | Whether True Detect 3D is enabled | No | Polling | [12] |
| settings#voice-volume | Dimmer | The voice volume level in percent | No | Polling | [13] |
| settings#water-amount | String | The amount of water to be used when mopping | No | Polling | [14] |

Remarks:

- [1] See [section below](#command-channel-actions)
- [2] Possible states: 'cleaning', 'pause', 'stop', 'drying', 'washing', 'returning' and 'charging' (where 'drying' and 'washing' are only available on newer models with auto empty station)
- [3] Possible states: 'auto', 'edge', 'spot', 'spotArea', 'customArea', 'singleRoom' (some of which depend on device capabilities)
- [4] Current cleaning status is only valid if the device is currently cleaning
- [5] Only valid for 'spot', 'spotArea' and 'customArea' cleaning modes; value can be used for 'spotArea' and 'customArea' commands (see below)
- [6] Only present if device has a mopping system
- [7] Only present on newer generation devices (Deebot OZMO 950 and newer)
- [8] Only present if device has a main brush
- [9] Only present on newer generation devices (Deebot N8/T8 or newer)
- [10] Only present if device has a dustbin auto empty station; supports both on/off command (to turn on/off the setting) and the string 'trigger' (to trigger immediate auto empty)
- [11] Only present if device can control power level. Possible values vary by device: 'normal' and 'high' are always supported, 'silent' and 'higher' are supported for some models
- [12] Only present if device supports True Detect 3D
- [13] Only present if device has voice reporting
- [14] Only present if device has a mopping system. Possible values include 'low', 'medium', 'high' and 'veryhigh'

## Command Channel Actions

The following actions are supported by the `command` channel:

| Name | Action | Remarks |
|--------------|-------------------------------------------|------------------------------------------------------|
| `clean` | Start cleaning in automatic mode. | |
| `spotArea` | Start cleaning specific rooms. | <ul><li>Only if supported by device, which can be recognized by `spotArea` being present in the list of possible states of the `current-cleaning-mode` channel.</li><li>Format: `spotArea:<room IDs>`, where `room IDs` is a semicolon separated list of room letters as shown in Ecovacs' app, so a valid command could e.g. be `spotArea:A;D;E`.</li><li>If you want to run 2 clean passes, amend `:x2` to the command, e.g. `spotArea:A;C;B:x2`.</li></ul> |
| `customArea` | Start cleaning specific areas. | <ul><li>Only if supported by device, which can be recognized by `customArea` being present in the list of possible states of the `current-cleaning-mode` channel.</li><li>Format: `customArea:<x1>;<y1>;<x2>;<y2>, where the parameters are coordinates (in mm) relative to the map.</li><li>The coordinates can be obtained from the `current-cleaning-spot-definition` channel when starting a custom area run from the app.</li><li>If you want to run 2 clean passes, amend `:x2` to the command, e.g. `customArea:100;100;1000;1000:x2`.</li></ul> |
| `pause` | Pause cleaning if it's currently active. | If the device is idle, the command is ignored. |
| `resume` | Resume cleaning if it's currently paused. | If the device is not paused, the command is ignored. |
| `stop` | Stop cleaning immediately. | |
| `charge` | Send device to charging station. | |

## Rule actions

This binding includes a rule action, which allows playback of specific sounds on the device in case the device has a speaker.
There is a separate instance for each device, which can be retrieved like this:

```java
val vacuumActions = getActions("ecovacs","ecovacs:vacuum:1234567890")
```

where the first parameter always has to be `ecovacs` and the second is the full Thing UID of the device that should be used.
Once this action instance is retrieved, you can invoke the `playSound(String type)` method on it:

```java
vacuumActions.playSound("beep")
```

Supported sound types include:

- `beep`
- `iAmHere`
- `startup`
- `suspended`
- `batteryLow`

For special use cases, there is also a `playSoundWithId(int soundId)` method, where you can pass the numeric ID of the sound to play.
The exact meaning of the number depends on the specific device; you'll need to experiment with different numbers to see how the number-to-sound mapping looks like.
For reference, a list for the Deebot 900 can be found [here](https://github.com/bmartin5692/sucks/blob/D901/protocol.md#user-content-sounds).

## File Based Configuration

If you want to create the API bridge in a .things file, the entry has to look as follows:

```java
Bridge ecovacs:ecovacsapi:ecovacsapi [ email="[email protected]", password="yourpassword", continent="ww" ]
```

The possible values for `continent` include the following values:

- `ww` for World
- `eu` for Europe
- `na` for North America
- `as` for Asia

The devices are detected automatically.
If you also want to enter those manually, the syntax is as follows:

```java
Bridge ecovacs:ecovacsapi:ecovacsapi [ email="[email protected]", password="yourpassword", continent="ww" ]
{
Thing vacuum myDeebot "Deebot Vacuum" [ serialNumber="serial as printed on label below dust bin" ]
}
```

51 changes: 51 additions & 0 deletions bundles/org.openhab.binding.ecovacs/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://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>4.0.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.ecovacs</artifactId>

<name>openHAB Add-ons :: Bundles :: Ecovacs Binding</name>
<properties>
<smack.version>4.3.3</smack.version>
</properties>

<dependencies>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-tcp</artifactId>
<version>${smack.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-im</artifactId>
<version>${smack.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-extensions</artifactId>
<version>${smack.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-java7</artifactId>
<version>${smack.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-resolver-javax</artifactId>
<version>${smack.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.ecovacs-${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-ecovacs" description="Ecovacs Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<feature dependency="true">openhab.tp-hivemqclient</feature>
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-tcp/4.3.3</bundle>
<bundle dependency="true">mvn:org.jxmpp/jxmpp-core/0.6.3</bundle>
<bundle dependency="true">mvn:org.jxmpp/jxmpp-jid/0.6.3</bundle>
<bundle dependency="true">mvn:org.jxmpp/jxmpp-util-cache/0.6.3</bundle>
<bundle dependency="true">mvn:org.minidns/minidns-core/0.3.3</bundle>
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-core/4.3.3</bundle>
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-im/4.3.3</bundle>
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-extensions/4.3.3</bundle>
<bundle dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xpp3/1.1.4c_7</bundle>
<bundle start-level="80">mvn:org.igniterealtime.smack/smack-resolver-javax/4.3.3</bundle>
<bundle start-level="80">mvn:org.igniterealtime.smack/smack-java7/4.3.3</bundle>
<bundle start-level="80">mvn:org.igniterealtime.smack/smack-sasl-javax/4.3.3</bundle>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.ecovacs/${project.version}</bundle>
</feature>
</features>
Loading