Skip to content
This repository has been archived by the owner on Apr 3, 2024. It is now read-only.

Commit

Permalink
React on settings change done from other clients (ex. App) (#201)
Browse files Browse the repository at this point in the history
* update lib to 3.0.0b3 - use new commands

* fix manifest

* use refactored commands

* fire event for custom commands

* upgrade lib to 3.0.0b4

* updated readme examples

* update library to 3.0.0
  • Loading branch information
edenhaus authored Oct 5, 2021
1 parent 98134cb commit 797e9c1
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 92 deletions.
3 changes: 3 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ version-resolver:
template: |
[![Downloads for this release](https://img.shields.io/github/downloads/And3rsL/Deebotozmo/$RESOLVED_VERSION/total.svg)](https://github.com/And3rsL/Deebotozmo/releases/$RESOLVED_VERSION)
$CHANGES
**Like my work and want to support me?**
<a href="https://www.buymeacoffee.com/edenhaus" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-black.png" width="150px" height="35px" alt="Buy Me A Coffee" style="height: 35px !important;width: 150px !important;" ></a>
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
pip install -r requirements.txt
- name: Run pre-commit checks
run: |
pre-commit run --hook-stage manual --all-files --show-diff-on-failure
SKIP=no-commit-to-branch pre-commit run --hook-stage manual --all-files --show-diff-on-failure
- name: Pylint review
run: |
pylint custom_components
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ venv
.venv
.coverage
.idea
.mypy_cache
.pytest_cache
136 changes: 104 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg?style=for-the-badge)](https://github.com/custom-components/hacs)
<br><a href="https://www.buymeacoffee.com/4nd3rs" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-black.png" width="150px" height="35px" alt="Buy Me A Coffee" style="height: 35px !important;width: 150px !important;" ></a>
<br><a href="https://www.buymeacoffee.com/edenhaus" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-black.png" width="150px" height="35px" alt="Buy Me A Coffee" style="height: 35px !important;width: 150px !important;" ></a>

# Home Assistant Custom Component for Ecovacs vacuum cleaner

Expand Down Expand Up @@ -88,12 +88,7 @@ This integration expose a number of sensors
- sensor.ROBOTNAME_stats_type (Clean Type - Auto|Manual|Custom)
- sensor.ROBOTNAME_water_level (Current set water level, you can get fan speed by vacuum attributes)
- binary_sensor.ROBOTNAME_mop_attached (On/off is mop is attached)

### Live Map:

If is true live_map it will try to generate a live map camera feed

- camera.ROBOTNAME_liveMap
- camera.ROBOTNAME_liveMap The live map

## UI examples

Expand All @@ -115,55 +110,132 @@ Get room numbers dynamically, very helpful if your robot is multi-floor or if yo

## Example commands:

```yaml
# Clean all
service: vacuum.start
target:
entity_id: vacuum.YOUR_ROBOT_NAME
```
Relocate Robot (the little GPS icon in the APP)
```yaml
# Relocate Robot
entity_id: vacuum.YOUR_ROBOT_NAME
command: relocate
service: vacuum.send_command
target:
entity_id: vacuum.YOUR_ROBOT_NAME
data:
command: relocate
```
You can clean certain area by specify it in rooms params, you can find room number under vacuum attributes
```yaml
# Clean Area
entity_id: vacuum.YOUR_ROBOT_NAME
command: spot_area
params:
rooms: 10,14
cleanings: 1
service: vacuum.send_command
target:
entity_id: vacuum.YOUR_ROBOT_NAME
data:
command: spot_area
params:
rooms: 10,14
cleanings: 1
```
```yaml
# Customize Clean
# You can get coordinates with fiddler and the official APP [Advance User]
entity_id: vacuum.YOUR_ROBOT_NAME
command: custom_area
params:
coordinates: -1339,-1511,296,-2587
service: vacuum.send_command
target:
entity_id: vacuum.YOUR_ROBOT_NAME
data:
command: custom_area
params:
coordinates: -1339,-1511,296,-2587
```
Use the app to send the vacuum to a custom area and afterwards search your logs for `Last custom area values (x1,y1,x2,y2):` entries to get the coordinates.

```yaml
# Set Water Level
# Possible amount values: low|medium|high|ultrahigh
entity_id: vacuum.YOUR_ROBOT_NAME
command: set_water
params:
amount: ultrahigh
service: vacuum.send_command
target:
entity_id: vacuum.YOUR_ROBOT_NAME
data:
command: set_water
params:
amount: ultrahigh
```

### Custom commands

It's also possible to send commands, which are not officially supported by this integration yet.
For that use also the `vacuum.send_command` service and you will get the response as `deebot_custom_command` event.

Example with the command `getAdvancedMode`

```yaml
service: vacuum.send_command
target:
entity_id: vacuum.YOUR_ROBOT_NAME
data:
command: getAdvancedMode
```

When calling the above example you will get the event `deebot_custom_command` similar to:

```json
{
"event_type": "deebot_custom_command",
"data": {
"name": "getAdvancedMode",
"response": {
"header": {
"pri": 1,
"tzm": 480,
"ts": "1295442034442",
"ver": "0.0.1",
"fwVer": "1.8.2",
"hwVer": "0.1.1"
},
"body": {
"code": 0,
"msg": "ok",
"data": {
"enable": 1
}
}
}
},
"origin": "LOCAL",
"time_fired": "2021-10-05T21:45:40.294958+00:00",
"context": {
"id": "[REMOVED]",
"parent_id": null,
"user_id": null
}
}
```

The interesting part is normally inside `response->body->data`. In the example above it means I have enabled the advanced mode.

## Services

This integration adds the service `deebot.refresh`, which allows to manually refresh some parts of the vacuum.
In addition to the vacuum entity you must specify part you want to refresh.
An example call looks like:

```yaml
# Clean
#Possible values: auto
entity_id: vacuum.YOUR_ROBOT_NAME
command: auto_clean
params:
type: auto
service: deebot.refresh
data:
part: Status
target:
entity_id: vacuum.YOUR_ROBOT_NAME
```

### Issues
## Issues

If you have an issue with this component, please file a GitHub Issue and include your Home Assistant logs in the report. To get full debug output from both the Ecovacs integration and the underlying deebotozmo library, place this in your configuration.yaml file:
If you have an issue with this component, please file a GitHub Issue and include y`ur Home Assistant logs in the report. To get full debug output from both the Ecovacs integration and the underlying deebotozmo library, place this in your configuration.yaml file:

```yaml
logger:
Expand All @@ -176,6 +248,6 @@ logger:
YAML
Warning: doing this will cause your authentication token to visible in your log files. Be sure to remove any tokens and other authentication details from your log before posting them in an issue.

### Misc
## Misc

An SVG of the Deebot 950 can be found under [images](docs/images/deebot950.svg)
14 changes: 8 additions & 6 deletions custom_components/deebot/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@
DEEBOT_DEVICES = f"{DOMAIN}_devices"

VACUUMSTATE_TO_STATE = {
VacuumState.STATE_IDLE: STATE_IDLE,
VacuumState.STATE_CLEANING: STATE_CLEANING,
VacuumState.STATE_RETURNING: STATE_RETURNING,
VacuumState.STATE_DOCKED: STATE_DOCKED,
VacuumState.STATE_ERROR: STATE_ERROR,
VacuumState.STATE_PAUSED: STATE_PAUSED,
VacuumState.IDLE: STATE_IDLE,
VacuumState.CLEANING: STATE_CLEANING,
VacuumState.RETURNING: STATE_RETURNING,
VacuumState.DOCKED: STATE_DOCKED,
VacuumState.ERROR: STATE_ERROR,
VacuumState.PAUSED: STATE_PAUSED,
}

LAST_ERROR = "last_error"
Expand All @@ -69,3 +69,5 @@
EVENT_LIFE_SPAN = "Life spans"
EVENT_ROOMS = "Rooms"
EVENT_MAP = "Map"

EVENT_CUSTOM_COMMAND = "deebot_custom_command"
17 changes: 10 additions & 7 deletions custom_components/deebot/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
import random
import string
from typing import Any, List, Mapping, Optional
from typing import Any, List, Mapping

import aiohttp
from aiohttp import ClientError
Expand Down Expand Up @@ -48,7 +48,10 @@ def __init__(self, hass: HomeAssistant, config: Mapping[str, Any]):
random.choice(string.ascii_uppercase + string.digits) for _ in range(12)
)

self._mqtt: Optional[EcovacsMqtt] = None
self._mqtt: EcovacsMqtt = EcovacsMqtt(
continent=self._continent, country=self._country
)

self._ecovacs_api = EcovacsAPI(
self._session,
device_id,
Expand All @@ -62,12 +65,13 @@ def __init__(self, hass: HomeAssistant, config: Mapping[str, Any]):
async def async_setup(self) -> None:
"""Init hub."""
try:
if self._mqtt:
self.disconnect()

await self._ecovacs_api.login()
auth = await self._ecovacs_api.get_request_auth()

self._mqtt = EcovacsMqtt(
auth, continent=self._continent, country=self._country
)
await self._mqtt.initialize(auth)

devices = await self._ecovacs_api.get_devices()

Expand Down Expand Up @@ -97,8 +101,7 @@ async def async_setup(self) -> None:

def disconnect(self) -> None:
"""Disconnect hub."""
if self._mqtt:
self._mqtt.disconnect()
self._mqtt.disconnect()

@property
def name(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion custom_components/deebot/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"config_flow": true,
"documentation": "https://github.com/And3rsL/Deebot-for-Home-Assistant",
"issue_tracker": "https://github.com/And3rsL/Deebot-for-Home-Assistant/issues",
"requirements": ["deebotozmo==3.0.0b1"],
"requirements": ["deebotozmo==3.0.0"],
"codeowners": ["@And3rsL", "@edenhaus"],
"iot_class": "cloud_polling"
}
22 changes: 10 additions & 12 deletions custom_components/deebot/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
import logging
from typing import Any, Dict, Optional

from deebotozmo.constants import (
COMPONENT_FILTER,
COMPONENT_MAIN_BRUSH,
COMPONENT_SIDE_BRUSH,
)
from deebotozmo.commands.life_span import LifeSpan
from deebotozmo.event_emitter import EventListener
from deebotozmo.events import (
CleanLogEvent,
ErrorEvent,
LifeSpanEvent,
StatsEvent,
StatusEvent,
WaterInfoEvent,
Expand Down Expand Up @@ -45,9 +42,9 @@ async def async_setup_entry(
new_devices.append(DeebotLastErrorSensor(vacbot))

# Components
new_devices.append(DeebotComponentSensor(vacbot, COMPONENT_MAIN_BRUSH))
new_devices.append(DeebotComponentSensor(vacbot, COMPONENT_SIDE_BRUSH))
new_devices.append(DeebotComponentSensor(vacbot, COMPONENT_FILTER))
new_devices.append(DeebotComponentSensor(vacbot, LifeSpan.BRUSH))
new_devices.append(DeebotComponentSensor(vacbot, LifeSpan.SIDE_BRUSH))
new_devices.append(DeebotComponentSensor(vacbot, LifeSpan.FILTER))

# Stats
new_devices.append(DeebotStatsSensor(vacbot, "area"))
Expand Down Expand Up @@ -148,19 +145,20 @@ class DeebotComponentSensor(DeebotBaseSensor):

_attr_native_unit_of_measurement = "%"

def __init__(self, vacuum_bot: VacuumBot, device_id: str):
def __init__(self, vacuum_bot: VacuumBot, component: LifeSpan):
"""Initialize the Sensor."""
device_id = component.value
super().__init__(vacuum_bot, device_id)
self._attr_icon = (
"mdi:air-filter" if device_id == COMPONENT_FILTER else "mdi:broom"
"mdi:air-filter" if component == LifeSpan.FILTER else "mdi:broom"
)
self._id = device_id
self._id: str = device_id

async def async_added_to_hass(self) -> None:
"""Set up the event listeners now that hass is ready."""
await super().async_added_to_hass()

async def on_event(event: Dict[str, float]) -> None:
async def on_event(event: LifeSpanEvent) -> None:
value = event.get(self._id, None)
if value:
self._attr_native_value = value
Expand Down
Loading

0 comments on commit 797e9c1

Please sign in to comment.