Skip to content

Commit

Permalink
Add new features
Browse files Browse the repository at this point in the history
  • Loading branch information
alemuro committed Sep 17, 2022
1 parent 10c29e5 commit f69904f
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 19 deletions.
13 changes: 13 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"

[packages]
boto3 = "*"
python-dotenv = "*"

[dev-packages]

[requires]
python_version = "3.8"
79 changes: 79 additions & 0 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,41 @@ This integration has been tested with the following vacuum cleaners:
## Supported functionalities

So far the following features have been implemented:
* `TURN_ON`
* `RETURN_HOME` (`TURN_OFF` does the same)
* `TURN_ON` - Enables the button to start the vacuum.
* `RETURN_HOME` (`TURN_OFF` does the same) - Enables the button to return the vacuum to home.
* `BATTERY` - Shows the status of the battery.
* `FAN_SPEED` - Allows changing the speed of the fan when the vacuum is cleaning.
* `SEND_COMMAND` - Allows sending custom commands, like setting water drop or starting a plan (in future releases).

A lot of ideas are in the backlog :) Do you have some idea? [Raise an issue!](https://github.com/alemuro/ha-cecotec-conga/issues/new?assignees=&labels=&template=feature_request.md&title=)

### Set water drop level

This is allowed through the `vacuum.send_command` service. Use the command `set_water_level` and provide the param `water_level` with some of these values: `Off`, `Low`, `Medium` or `High`. Only works when the vacuum is already cleaning. Allowed levels are shown as an attribute of the vacuum entity.

```
service: vacuum.send_command
target:
entity_id: vacuum.conga
data:
command: set_water_level
params:
water_level: Medium
```

## Developers

### Local testing

If you already have a Conga, I encourage you to test it by executing the `test.py`.

1. Install dependencies throuhg `pipenv`. Execute `pipenv install`.
2. Open virtualenv: `pipenv shell`.
3. Create a `.env` file with the variables `CONGA_USERNAME`, `CONGA_PASSWORD` and `CONGA_SN` (serial number). The serial number is retrieved by the script.
4. Execute `python test.py`.

There is a Makefile target to start a Docker container with this integration installed as a `custom_component`. Execute `make test-local`.

## Legal notice
This is a personal project and isn't in any way affiliated with, sponsored or endorsed by [CECOTEC](https://www.cecotec.es/).

Expand Down
95 changes: 91 additions & 4 deletions custom_components/cecotec_conga/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import logging
import random
import requests
import string
import json
import boto3
import datetime
Expand All @@ -13,8 +15,8 @@


async def async_setup_entry(hass, entry):
"""Set up Cecotec Conga vacuums based on a config entry."""

"""Set up Cecotec Conga sensors based on a config entry."""
_LOGGER.info("Setting up Cecotec Conga integration")
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, "vacuum")
)
Expand Down Expand Up @@ -42,12 +44,43 @@ def list_vacuums(self):
_LOGGER.warn(self._devices)
return self._devices

def list_plans(self, sn):
self._refresh_api_token()
response = requests.post(
f'{CECOTEC_API_BASE_URL}/api/user/file_list',
json={
"sn": sn,
"file_type": 2,
"sort": -1,
"page_size": 10,
"last_page_key": None
},
auth=self._api_token
)
response.raise_for_status()
try:
pages = response.json()["data"]["page_items"]
plans = []
plan_names = []
for page in pages:
if "planName" in page["task_cmd"]["cmd"]:
plans.append(page["task_cmd"]["cmd"])
plan_names.append(page["task_cmd"]["cmd"]["planName"])

self._plans = plans
self._plan_names = plan_names
except:
self._plans = []
self._plan_names = []

return self._plan_names

def status(self, sn):
self._refresh_iot_client()
r = self._iot_client.get_thing_shadow(thingName=sn)
return json.load(r['payload'])

def start(self, sn):
def start(self, sn, fan_speed):
payload = {
"state": {
"desired": {
Expand All @@ -56,7 +89,7 @@ def start(self, sn):
"body": {
"mode": "Auto",
"deepClean": 0,
"fanLevel": 1,
"fanLevel": fan_speed,
"water": 1,
"autoBoost": 0,
"params": "[]"
Expand All @@ -68,6 +101,53 @@ def start(self, sn):

self._send_payload(sn, payload)

def set_fan_speed(self, sn, level):
payload = {
"state": {
"desired": {
"workNoisy": level
}
}
}
_LOGGER.debug(payload)
self._refresh_iot_client()
self._iot_client.update_thing_shadow(
thingName=sn,
payload=bytes(json.dumps(payload), "ascii")
)

def set_water_level(self, sn, level):
payload = {
"state": {
"desired": {
"water": level
}
}
}
_LOGGER.debug(payload)
self._refresh_iot_client()
self._iot_client.update_thing_shadow(
thingName=sn,
payload=bytes(json.dumps(payload), "ascii")
)

def start_plan(self, sn, plan_name):
allowed_chars = string.ascii_lowercase + \
string.ascii_uppercase + string.digits
result_str = ''.join(random.choice(allowed_chars) for i in range(10))
plan = self._get_plan_details(plan_name)
payload = {
"state": {
"desired": {
"StartTimedCleanTask": {
"id": result_str,
"params": json.dumps(plan)
}
}
}
}
self._send_payload(sn, payload)

def home(self, sn):
payload = {
"state": {
Expand All @@ -79,7 +159,14 @@ def home(self, sn):

self._send_payload(sn, payload)

def _get_plan_details(self, plan_name):
for plan in self._plans:
if plan['planName'] == plan_name:
return plan
return ""

def _send_payload(self, sn, payload):
_LOGGER.debug(payload)
self._refresh_iot_client()
self._iot_client.update_thing_shadow(
thingName=sn,
Expand Down
4 changes: 2 additions & 2 deletions custom_components/cecotec_conga/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Config flow for TMB."""
"""Config flow for Cecotec Conga."""
import logging

from requests.models import HTTPError
Expand All @@ -19,7 +19,7 @@


class CecotecCongaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""TMB config flow."""
"""Cecotec Conga config flow."""

VERSION = 1

Expand Down
8 changes: 8 additions & 0 deletions custom_components/cecotec_conga/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,11 @@
CONF_USERNAME = "username"
CONF_PASSWORD = "password"
CONF_DEVICES = "devices"
FAN_SPEED_0 = "Off"
FAN_SPEED_1 = "Eco"
FAN_SPEED_2 = "Normal"
FAN_SPEED_3 = "Turbo"
WATER_LEVEL_0 = "Off"
WATER_LEVEL_1 = "Low"
WATER_LEVEL_2 = "Medium"
WATER_LEVEL_3 = "High"
Loading

0 comments on commit f69904f

Please sign in to comment.