Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c130226a1 | |||
| 590772ec2c | |||
| 4f92ce5eba | |||
| ba0a2f9ed8 | |||
| d1bb42c769 | |||
| 4ac0dc84d1 |
@@ -1,3 +1,8 @@
|
|||||||
|
# Builtin HASS integration has options to not verify self-signed certificate now, this integration no longer needed.
|
||||||
|
|
||||||
|
## Latest version is 1.7.0 that includes updates that SHOULD at least let the component work with newer HASS versions. This version includes async updates so the comoponent won't crap out on setup if it's unable to reach the vacuum. I am unable to tset these changes since I don't have HASS currently setup and I don't have my old Ecovacs vacuum anymore (handed down to younger sis).
|
||||||
|
# If 1.7.0 doesn't work, use version 1.6.0. I just made the bare minimum changes to the component that again SHOULD work, but I'm unable to test it. HASS ditched the VacuumEntity import for the vacuum component at some point and change it to StateVacuumEntity. That's all that's included in this update. Thanks @guillaume042 for making it easy for me by pointing me straight to a an issue with another component using VacuumEntity (though theirs was just leftover code that wasn't actually being used).
|
||||||
|
|
||||||
# Home Assistant Ecovacs Custom Component with Bumper Support
|
# Home Assistant Ecovacs Custom Component with Bumper Support
|
||||||
Based off the regular home assistant ecovacs components and bmartin's fork of sucks, https://github.com/bmartin5692/sucks. Replaces built in ecovacs component, with some upgrades and fixes. Allows SSL verification to be set to false to work with a self-hosted bumper server, https://github.com/bmartin5692/bumper, a replacement for Ecovacs servers to truly get local control.
|
Based off the regular home assistant ecovacs components and bmartin's fork of sucks, https://github.com/bmartin5692/sucks. Replaces built in ecovacs component, with some upgrades and fixes. Allows SSL verification to be set to false to work with a self-hosted bumper server, https://github.com/bmartin5692/bumper, a replacement for Ecovacs servers to truly get local control.
|
||||||
|
|
||||||
|
|||||||
@@ -44,55 +44,60 @@ ECOVACS_API_DEVICEID = "".join(
|
|||||||
random.choice(string.ascii_uppercase + string.digits) for _ in range(8)
|
random.choice(string.ascii_uppercase + string.digits) for _ in range(8)
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
"""Set up the Ecovacs component."""
|
"""Set up the Ecovacs component."""
|
||||||
LOGGER.debug("Creating new Ecovacs component")
|
LOGGER.debug("Creating new Ecovacs component")
|
||||||
hass.data[ECOVACS_DEVICES] = []
|
def get_devices() -> list[VacBot]:
|
||||||
|
ecovacs_api = EcoVacsAPI(
|
||||||
|
ECOVACS_API_DEVICEID,
|
||||||
|
config[DOMAIN].get(CONF_USERNAME),
|
||||||
|
EcoVacsAPI.md5(config[DOMAIN].get(CONF_PASSWORD)),
|
||||||
|
config[DOMAIN].get(CONF_COUNTRY),
|
||||||
|
config[DOMAIN].get(CONF_CONTINENT),
|
||||||
|
)
|
||||||
|
ecovacs_devices = ecovacs_api.devices()
|
||||||
|
_LOGGER.debug("Ecobot devices: %s", ecovacs_devices)
|
||||||
|
|
||||||
SERVER_ADDRESS = None
|
SERVER_ADDRESS = None
|
||||||
|
|
||||||
ecovacs_api = EcoVacsAPI(
|
devices: list[VacBot] = []
|
||||||
ECOVACS_API_DEVICEID,
|
for device in ecovacs_devices:
|
||||||
config[DOMAIN].get(CONF_USERNAME),
|
_LOGGER.info(
|
||||||
EcoVacsAPI.md5(config[DOMAIN].get(CONF_PASSWORD)),
|
"Discovered Ecovacs device on account: %s with nickname %s",
|
||||||
config[DOMAIN].get(CONF_COUNTRY),
|
device.get("did"),
|
||||||
config[DOMAIN].get(CONF_CONTINENT),
|
device.get("nick"),
|
||||||
config[DOMAIN].get(CONF_VERIFY_SSL), # add to class call
|
)
|
||||||
)
|
vacbot = VacBot(
|
||||||
|
ecovacs_api.uid,
|
||||||
|
ecovacs_api.REALM,
|
||||||
|
ecovacs_api.resource,
|
||||||
|
ecovacs_api.user_access_token,
|
||||||
|
device,
|
||||||
|
config[DOMAIN].get(CONF_CONTINENT).lower(),
|
||||||
|
config[DOMAIN].get(CONF_VERIFY_SSL), # add to class call
|
||||||
|
monitor=True,
|
||||||
|
)
|
||||||
|
|
||||||
devices = ecovacs_api.devices()
|
devices.append(vacbot)
|
||||||
LOGGER.debug("Ecobot devices: %s", devices)
|
return devices
|
||||||
|
|
||||||
for device in devices:
|
hass.data[ECOVACS_DEVICES] = await hass.async_add_executor_job(get_devices)
|
||||||
LOGGER.info(
|
|
||||||
"Discovered Ecovacs device on account: %s with nickname %s",
|
|
||||||
device.get("did"),
|
|
||||||
device.get("nick"),
|
|
||||||
)
|
|
||||||
vacbot = VacBot(
|
|
||||||
ecovacs_api.uid,
|
|
||||||
ecovacs_api.REALM,
|
|
||||||
ecovacs_api.resource,
|
|
||||||
ecovacs_api.user_access_token,
|
|
||||||
device,
|
|
||||||
config[DOMAIN].get(CONF_CONTINENT).lower(),
|
|
||||||
SERVER_ADDRESS, # include server address in class, if it's null should be no effect
|
|
||||||
config[DOMAIN].get(CONF_VERIFY_SSL), # add to class call
|
|
||||||
monitor=True
|
|
||||||
)
|
|
||||||
hass.data[ECOVACS_DEVICES].append(vacbot)
|
|
||||||
|
|
||||||
def stop(event: object) -> None:
|
async def async_stop(event: object) -> None:
|
||||||
"""Shut down open connections to Ecovacs XMPP server."""
|
"""Shut down open connections to Ecovacs XMPP server."""
|
||||||
for device in hass.data[ECOVACS_DEVICES]:
|
devices: list[VacBot] = hass.data[ECOVACS_DEVICES]
|
||||||
|
for device in devices:
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
"Shutting down connection to Ecovacs device %s",
|
"Shutting down connection to Ecovacs device %s",
|
||||||
device.vacuum.get("did"),
|
device.vacuum.get("did"),
|
||||||
)
|
)
|
||||||
device.disconnect()
|
await hass.async_add_executor_job(device.disconnect)
|
||||||
|
|
||||||
# Listen for HA stop to disconnect.
|
# Listen for HA stop to disconnect.
|
||||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop)
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_stop)
|
||||||
if hass.data[ECOVACS_DEVICES]:
|
if hass.data[ECOVACS_DEVICES]:
|
||||||
LOGGER.debug("Starting vacuum components")
|
LOGGER.debug("Starting vacuum components")
|
||||||
discovery.load_platform(hass, Platform.VACUUM, DOMAIN, {}, config)
|
hass.async_create_task(
|
||||||
|
discovery.async_load_platform(hass, Platform.VACUUM, DOMAIN, {}, config)
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
@@ -7,7 +7,7 @@ from typing import Any
|
|||||||
#sucks
|
#sucks
|
||||||
from . import sucks
|
from . import sucks
|
||||||
|
|
||||||
from homeassistant.components.vacuum import VacuumEntity, VacuumEntityFeature
|
from homeassistant.components.vacuum import StateVacuumEntity, VacuumEntityFeature
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.icon import icon_for_battery_level
|
from homeassistant.helpers.icon import icon_for_battery_level
|
||||||
@@ -21,21 +21,23 @@ ATTR_ERROR = "error"
|
|||||||
ATTR_COMPONENT_PREFIX = "component_"
|
ATTR_COMPONENT_PREFIX = "component_"
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Ecovacs vacuums."""
|
"""Set up the Ecovacs vacuums."""
|
||||||
vacuums = []
|
vacuums = []
|
||||||
for device in hass.data[ECOVACS_DEVICES]:
|
devices: list[sucks.VacBot] = hass.data[ECOVACS_DEVICES]
|
||||||
|
for device in devices:
|
||||||
|
await hass.async_add_executor_job(device.connect_and_wait_until_ready)
|
||||||
vacuums.append(EcovacsVacuum(device))
|
vacuums.append(EcovacsVacuum(device))
|
||||||
_LOGGER.debug("Adding Ecovacs Vacuums to Home Assistant: %s", vacuums)
|
_LOGGER.debug("Adding Ecovacs Vacuums to Home Assistant: %s", vacuums)
|
||||||
add_entities(vacuums, True)
|
async_add_entities(vacuums)
|
||||||
|
|
||||||
|
|
||||||
class EcovacsVacuum(VacuumEntity):
|
class EcovacsVacuum(StateVacuumEntity):
|
||||||
"""Ecovacs Vacuums such as Deebot."""
|
"""Ecovacs Vacuums such as Deebot."""
|
||||||
|
|
||||||
_attr_fan_speed_list = [sucks.FAN_SPEED_NORMAL, sucks.FAN_SPEED_HIGH]
|
_attr_fan_speed_list = [sucks.FAN_SPEED_NORMAL, sucks.FAN_SPEED_HIGH]
|
||||||
@@ -56,7 +58,7 @@ class EcovacsVacuum(VacuumEntity):
|
|||||||
def __init__(self, device: sucks.VacBot) -> None:
|
def __init__(self, device: sucks.VacBot) -> None:
|
||||||
"""Initialize the Ecovacs Vacuum."""
|
"""Initialize the Ecovacs Vacuum."""
|
||||||
self.device = device
|
self.device = device
|
||||||
self.device.connect_and_wait_until_ready()
|
|
||||||
if self.device.vacuum.get("nick") is not None:
|
if self.device.vacuum.get("nick") is not None:
|
||||||
self._attr_name = str(self.device.vacuum["nick"])
|
self._attr_name = str(self.device.vacuum["nick"])
|
||||||
else:
|
else:
|
||||||
@@ -64,7 +66,6 @@ class EcovacsVacuum(VacuumEntity):
|
|||||||
self._attr_name = str(format(self.device.vacuum["did"]))
|
self._attr_name = str(format(self.device.vacuum["did"]))
|
||||||
|
|
||||||
self._error = None
|
self._error = None
|
||||||
_LOGGER.debug("Vacuum initialized: %s", self.name)
|
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Set up the event listeners now that hass is ready."""
|
"""Set up the event listeners now that hass is ready."""
|
||||||
|
|||||||
Reference in New Issue
Block a user