mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00:00
Add timers to xiaomi_miio vacuum (#35417)
* Add timers to xiaomi_miio vacuum * Add timezone * Add cron and next_schedule * Use next_schedule from backend library * Use as_utc from utils
This commit is contained in:
parent
8e44d797a3
commit
44708ed8bb
@ -3,7 +3,7 @@
|
|||||||
"name": "Xiaomi Miio",
|
"name": "Xiaomi Miio",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/xiaomi_miio",
|
"documentation": "https://www.home-assistant.io/integrations/xiaomi_miio",
|
||||||
"requirements": ["construct==2.9.45", "python-miio==0.5.0.1"],
|
"requirements": ["construct==2.9.45", "python-miio==0.5.1"],
|
||||||
"codeowners": ["@rytilahti", "@syssi"],
|
"codeowners": ["@rytilahti", "@syssi"],
|
||||||
"zeroconf": ["_miio._udp.local."]
|
"zeroconf": ["_miio._udp.local."]
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ from homeassistant.components.vacuum import (
|
|||||||
)
|
)
|
||||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_TOKEN, STATE_OFF, STATE_ON
|
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_TOKEN, STATE_OFF, STATE_ON
|
||||||
from homeassistant.helpers import config_validation as cv, entity_platform
|
from homeassistant.helpers import config_validation as cv, entity_platform
|
||||||
|
from homeassistant.util.dt import as_utc
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
SERVICE_CLEAN_ZONE,
|
SERVICE_CLEAN_ZONE,
|
||||||
@ -72,6 +73,7 @@ ATTR_RC_VELOCITY = "velocity"
|
|||||||
ATTR_STATUS = "status"
|
ATTR_STATUS = "status"
|
||||||
ATTR_ZONE_ARRAY = "zone"
|
ATTR_ZONE_ARRAY = "zone"
|
||||||
ATTR_ZONE_REPEATER = "repeats"
|
ATTR_ZONE_REPEATER = "repeats"
|
||||||
|
ATTR_TIMERS = "timers"
|
||||||
|
|
||||||
SUPPORT_XIAOMI = (
|
SUPPORT_XIAOMI = (
|
||||||
SUPPORT_STATE
|
SUPPORT_STATE
|
||||||
@ -216,6 +218,8 @@ class MiroboVacuum(StateVacuumEntity):
|
|||||||
self._fan_speeds = None
|
self._fan_speeds = None
|
||||||
self._fan_speeds_reverse = None
|
self._fan_speeds_reverse = None
|
||||||
|
|
||||||
|
self._timers = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Return the name of the device."""
|
"""Return the name of the device."""
|
||||||
@ -262,6 +266,18 @@ class MiroboVacuum(StateVacuumEntity):
|
|||||||
"""Get the list of available fan speed steps of the vacuum cleaner."""
|
"""Get the list of available fan speed steps of the vacuum cleaner."""
|
||||||
return list(self._fan_speeds) if self._fan_speeds else []
|
return list(self._fan_speeds) if self._fan_speeds else []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def timers(self):
|
||||||
|
"""Get the list of added timers of the vacuum cleaner."""
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"enabled": timer.enabled,
|
||||||
|
"cron": timer.cron,
|
||||||
|
"next_schedule": as_utc(timer.next_schedule),
|
||||||
|
}
|
||||||
|
for timer in self._timers
|
||||||
|
]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the specific state attributes of this vacuum cleaner."""
|
"""Return the specific state attributes of this vacuum cleaner."""
|
||||||
@ -307,6 +323,9 @@ class MiroboVacuum(StateVacuumEntity):
|
|||||||
|
|
||||||
if self.vacuum_state.got_error:
|
if self.vacuum_state.got_error:
|
||||||
attrs[ATTR_ERROR] = self.vacuum_state.error
|
attrs[ATTR_ERROR] = self.vacuum_state.error
|
||||||
|
|
||||||
|
if self.timers:
|
||||||
|
attrs[ATTR_TIMERS] = self.timers
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -442,6 +461,8 @@ class MiroboVacuum(StateVacuumEntity):
|
|||||||
self.last_clean = self._vacuum.last_clean_details()
|
self.last_clean = self._vacuum.last_clean_details()
|
||||||
self.dnd_state = self._vacuum.dnd_status()
|
self.dnd_state = self._vacuum.dnd_status()
|
||||||
|
|
||||||
|
self._timers = self._vacuum.timer()
|
||||||
|
|
||||||
self._available = True
|
self._available = True
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
_LOGGER.error("Got OSError while fetching the state: %s", exc)
|
_LOGGER.error("Got OSError while fetching the state: %s", exc)
|
||||||
|
@ -1702,7 +1702,7 @@ python-juicenet==1.0.1
|
|||||||
# python-lirc==1.2.3
|
# python-lirc==1.2.3
|
||||||
|
|
||||||
# homeassistant.components.xiaomi_miio
|
# homeassistant.components.xiaomi_miio
|
||||||
python-miio==0.5.0.1
|
python-miio==0.5.1
|
||||||
|
|
||||||
# homeassistant.components.mpd
|
# homeassistant.components.mpd
|
||||||
python-mpd2==1.0.0
|
python-mpd2==1.0.0
|
||||||
|
@ -717,7 +717,7 @@ python-izone==1.1.2
|
|||||||
python-juicenet==1.0.1
|
python-juicenet==1.0.1
|
||||||
|
|
||||||
# homeassistant.components.xiaomi_miio
|
# homeassistant.components.xiaomi_miio
|
||||||
python-miio==0.5.0.1
|
python-miio==0.5.1
|
||||||
|
|
||||||
# homeassistant.components.nest
|
# homeassistant.components.nest
|
||||||
python-nest==4.1.0
|
python-nest==4.1.0
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
"""The tests for the Xiaomi vacuum platform."""
|
"""The tests for the Xiaomi vacuum platform."""
|
||||||
from datetime import time, timedelta
|
from datetime import datetime, time, timedelta
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from pytz import utc
|
||||||
|
|
||||||
from homeassistant.components.vacuum import (
|
from homeassistant.components.vacuum import (
|
||||||
ATTR_BATTERY_ICON,
|
ATTR_BATTERY_ICON,
|
||||||
@ -33,6 +34,7 @@ from homeassistant.components.xiaomi_miio.vacuum import (
|
|||||||
ATTR_FILTER_LEFT,
|
ATTR_FILTER_LEFT,
|
||||||
ATTR_MAIN_BRUSH_LEFT,
|
ATTR_MAIN_BRUSH_LEFT,
|
||||||
ATTR_SIDE_BRUSH_LEFT,
|
ATTR_SIDE_BRUSH_LEFT,
|
||||||
|
ATTR_TIMERS,
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_TOKEN,
|
CONF_TOKEN,
|
||||||
@ -60,6 +62,7 @@ STATUS_CALLS = [
|
|||||||
mock.call.consumable_status(),
|
mock.call.consumable_status(),
|
||||||
mock.call.clean_history(),
|
mock.call.clean_history(),
|
||||||
mock.call.dnd_status(),
|
mock.call.dnd_status(),
|
||||||
|
mock.call.timer(),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -94,6 +97,18 @@ def mirobo_is_got_error_fixture():
|
|||||||
mock_vacuum.dnd_status().start = time(hour=22, minute=0)
|
mock_vacuum.dnd_status().start = time(hour=22, minute=0)
|
||||||
mock_vacuum.dnd_status().end = time(hour=6, minute=0)
|
mock_vacuum.dnd_status().end = time(hour=6, minute=0)
|
||||||
|
|
||||||
|
mock_timer_1 = mock.MagicMock()
|
||||||
|
mock_timer_1.enabled = True
|
||||||
|
mock_timer_1.cron = "5 5 1 8 1"
|
||||||
|
mock_timer_1.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||||
|
|
||||||
|
mock_timer_2 = mock.MagicMock()
|
||||||
|
mock_timer_2.enabled = False
|
||||||
|
mock_timer_2.cron = "5 5 1 8 2"
|
||||||
|
mock_timer_2.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||||
|
|
||||||
|
mock_vacuum.timer.return_value = [mock_timer_1, mock_timer_2]
|
||||||
|
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"homeassistant.components.xiaomi_miio.vacuum.Vacuum"
|
"homeassistant.components.xiaomi_miio.vacuum.Vacuum"
|
||||||
) as mock_vaccum_cls:
|
) as mock_vaccum_cls:
|
||||||
@ -160,6 +175,18 @@ def mirobo_is_on_fixture():
|
|||||||
mock_vacuum.status().state_code = 5
|
mock_vacuum.status().state_code = 5
|
||||||
mock_vacuum.dnd_status().enabled = False
|
mock_vacuum.dnd_status().enabled = False
|
||||||
|
|
||||||
|
mock_timer_1 = mock.MagicMock()
|
||||||
|
mock_timer_1.enabled = True
|
||||||
|
mock_timer_1.cron = "5 5 1 8 1"
|
||||||
|
mock_timer_1.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||||
|
|
||||||
|
mock_timer_2 = mock.MagicMock()
|
||||||
|
mock_timer_2.enabled = False
|
||||||
|
mock_timer_2.cron = "5 5 1 8 2"
|
||||||
|
mock_timer_2.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||||
|
|
||||||
|
mock_vacuum.timer.return_value = [mock_timer_1, mock_timer_2]
|
||||||
|
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"homeassistant.components.xiaomi_miio.vacuum.Vacuum"
|
"homeassistant.components.xiaomi_miio.vacuum.Vacuum"
|
||||||
) as mock_vaccum_cls:
|
) as mock_vaccum_cls:
|
||||||
@ -241,6 +268,18 @@ async def test_xiaomi_vacuum_services(hass, caplog, mock_mirobo_is_got_error):
|
|||||||
assert state.attributes.get(ATTR_CLEANING_COUNT) == 35
|
assert state.attributes.get(ATTR_CLEANING_COUNT) == 35
|
||||||
assert state.attributes.get(ATTR_CLEANED_TOTAL_AREA) == 123
|
assert state.attributes.get(ATTR_CLEANED_TOTAL_AREA) == 123
|
||||||
assert state.attributes.get(ATTR_CLEANING_TOTAL_TIME) == 695
|
assert state.attributes.get(ATTR_CLEANING_TOTAL_TIME) == 695
|
||||||
|
assert state.attributes.get(ATTR_TIMERS) == [
|
||||||
|
{
|
||||||
|
"enabled": True,
|
||||||
|
"cron": "5 5 1 8 1",
|
||||||
|
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled": False,
|
||||||
|
"cron": "5 5 1 8 2",
|
||||||
|
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
# Call services
|
# Call services
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
@ -341,6 +380,18 @@ async def test_xiaomi_specific_services(hass, caplog, mock_mirobo_is_on):
|
|||||||
assert state.attributes.get(ATTR_CLEANING_COUNT) == 41
|
assert state.attributes.get(ATTR_CLEANING_COUNT) == 41
|
||||||
assert state.attributes.get(ATTR_CLEANED_TOTAL_AREA) == 323
|
assert state.attributes.get(ATTR_CLEANED_TOTAL_AREA) == 323
|
||||||
assert state.attributes.get(ATTR_CLEANING_TOTAL_TIME) == 675
|
assert state.attributes.get(ATTR_CLEANING_TOTAL_TIME) == 675
|
||||||
|
assert state.attributes.get(ATTR_TIMERS) == [
|
||||||
|
{
|
||||||
|
"enabled": True,
|
||||||
|
"cron": "5 5 1 8 1",
|
||||||
|
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled": False,
|
||||||
|
"cron": "5 5 1 8 2",
|
||||||
|
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
# Xiaomi vacuum specific services:
|
# Xiaomi vacuum specific services:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user