Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8303fd9
WIP
mdz Feb 23, 2021
b5e84be
test passing
mdz Feb 24, 2021
96f8498
add secondary filtration service
mdz Feb 24, 2021
affb2b2
add services.yaml
mdz Feb 24, 2021
8c2a7fe
fix safeguard
mdz Feb 24, 2021
eb58497
ensure upcase
mdz Feb 24, 2021
212825f
gen requirements
mdz Feb 24, 2021
7d34403
fix validators
mdz Feb 24, 2021
5e9fac6
Update homeassistant/components/smarttub/sensor.py
mdz Feb 24, 2021
7cbc04a
Update homeassistant/components/smarttub/sensor.py
mdz Feb 24, 2021
dd59e3a
Update homeassistant/components/smarttub/sensor.py
mdz Feb 24, 2021
b0a1db6
Update homeassistant/components/smarttub/sensor.py
mdz Feb 24, 2021
5046f9a
update services.yaml to new format
mdz Feb 24, 2021
46bc01b
use make_entity_service_schema
mdz Feb 24, 2021
b795e84
simplify schema definition
mdz Feb 24, 2021
2fd9f9e
WIP
mdz Feb 28, 2021
4f7a76c
remove stray import
mdz Feb 28, 2021
3d8ea27
Merge remote-tracking branch 'upstream/dev' into smarttub-filtration-…
mdz Feb 28, 2021
6d67d9a
remove unused copypasta
mdz Feb 28, 2021
976fbc7
filter entities by supported feature
mdz Feb 28, 2021
3b79d85
mode is required
mdz Feb 28, 2021
02cb31f
remove supported_features, doesn't work
mdz Feb 28, 2021
0540618
Merge remote-tracking branch 'upstream/dev' into smarttub-filtration-…
mdz Mar 1, 2021
c0af0ea
Merge remote-tracking branch 'upstream/dev' into smarttub-filtration-…
mdz Mar 3, 2021
d3885ba
Merge remote-tracking branch 'upstream/dev' into smarttub-filtration-…
mdz Mar 7, 2021
70585f3
Merge remote-tracking branch 'upstream/dev' into smarttub-filtration-…
mdz Mar 8, 2021
d2da1f2
remove required
mdz Mar 17, 2021
8d97119
Merge remote-tracking branch 'upstream/dev' into smarttub-filtration-…
mdz Apr 16, 2021
3c4df54
Merge remote-tracking branch 'upstream/dev' into smarttub-filtration-…
mdz Apr 23, 2021
a75e836
add properties for clarity
mdz Apr 23, 2021
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
2 changes: 1 addition & 1 deletion homeassistant/components/smarttub/entity.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""SmartTub integration."""
"""Base classes for SmartTub entities."""
import logging

import smarttub
Expand Down
52 changes: 52 additions & 0 deletions homeassistant/components/smarttub/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
from enum import Enum
import logging

import smarttub
import voluptuous as vol

from homeassistant.helpers import config_validation as cv, entity_platform

from .const import DOMAIN, SMARTTUB_CONTROLLER
from .entity import SmartTubSensorBase

Expand All @@ -14,6 +19,25 @@
# the hour of the day at which to start the cycle (0-23)
ATTR_START_HOUR = "start_hour"

SET_PRIMARY_FILTRATION_SCHEMA = vol.All(
cv.has_at_least_one_key(ATTR_DURATION, ATTR_START_HOUR),
cv.make_entity_service_schema(
{
vol.Optional(ATTR_DURATION): vol.All(int, vol.Range(min=1, max=24)),
vol.Optional(ATTR_START_HOUR): vol.All(int, vol.Range(min=0, max=23)),
Comment thread
mdz marked this conversation as resolved.
},
),
)

SET_SECONDARY_FILTRATION_SCHEMA = {
vol.Required(ATTR_MODE): vol.In(
{
mode.name.lower()
for mode in smarttub.SpaSecondaryFiltrationCycle.SecondaryFiltrationMode
}
),
}


async def async_setup_entry(hass, entry, async_add_entities):
"""Set up sensor entities for the sensors in the tub."""
Expand Down Expand Up @@ -43,6 +67,20 @@ async def async_setup_entry(hass, entry, async_add_entities):

async_add_entities(entities)

platform = entity_platform.current_platform.get()

platform.async_register_entity_service(
"set_primary_filtration",
SET_PRIMARY_FILTRATION_SCHEMA,
"async_set_primary_filtration",
)

platform.async_register_entity_service(
"set_secondary_filtration",
SET_SECONDARY_FILTRATION_SCHEMA,
"async_set_secondary_filtration",
)


class SmartTubSensor(SmartTubSensorBase):
"""Generic class for SmartTub status sensors."""
Expand Down Expand Up @@ -80,6 +118,13 @@ def device_state_attributes(self):
ATTR_START_HOUR: state.start_hour,
}

async def async_set_primary_filtration(self, **kwargs):
"""Update primary filtration settings."""
await self._state.set(
duration=kwargs.get(ATTR_DURATION),
start_hour=kwargs.get(ATTR_START_HOUR),
)


class SmartTubSecondaryFiltrationCycle(SmartTubSensor):
"""The secondary filtration cycle."""
Expand All @@ -103,3 +148,10 @@ def device_state_attributes(self):
ATTR_CYCLE_LAST_UPDATED: state.last_updated.isoformat(),
ATTR_MODE: state.mode.name.lower(),
}

async def async_set_secondary_filtration(self, **kwargs):
"""Update primary filtration settings."""
mode = smarttub.SpaSecondaryFiltrationCycle.SecondaryFiltrationMode[
kwargs[ATTR_MODE].upper()
]
await self._state.set_mode(mode)
49 changes: 49 additions & 0 deletions homeassistant/components/smarttub/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
set_primary_filtration:
Comment thread
mdz marked this conversation as resolved.
Outdated
name: Update primary filtration settings
description: Updates the primary filtration settings
target:
entity:
integration: smarttub
domain: sensor
fields:
duration:
name: Duration
description: The desired duration of the primary filtration cycle
required: true
default: 8
selector:
number:
min: 1
max: 24
unit_of_measurement: "hours"
mode: slider
example: 8
start_hour:
description: The hour of the day at which to begin the primary filtration cycle
required: true
default: 0
example: 2
selector:
number:
min: 0
max: 23
unit_of_measurement: "hour"

set_secondary_filtration:
name: Update secondary filtration settings
description: Updates the secondary filtration settings
target:
entity:
integration: smarttub
domain: sensor
fields:
mode:
description: The secondary filtration mode.
selector:
select:
options:
- "frequent"
- "infrequent"
- "away"
required: true
example: "frequent"
32 changes: 24 additions & 8 deletions tests/components/smarttub/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,11 @@ async def setup_component(hass):
assert await async_setup_component(hass, DOMAIN, {}) is True


@pytest.fixture(name="spa")
def mock_spa():
"""Mock a smarttub.Spa."""
@pytest.fixture(name="spa_state")
def mock_spa_state():
"""Create a smarttub.SpaState with mocks."""

mock_spa = create_autospec(smarttub.Spa, instance=True)
mock_spa.id = "mockspa1"
mock_spa.brand = "mockbrand1"
mock_spa.model = "mockmodel1"
mock_spa.get_status.return_value = smarttub.SpaState(
state = smarttub.SpaState(
mock_spa,
**{
"setTemperature": 39,
Expand Down Expand Up @@ -71,6 +67,26 @@ def mock_spa():
"cleanupCycle": "INACTIVE",
},
)
state.primary_filtration.set = create_autospec(
smarttub.SpaPrimaryFiltrationCycle, instance=True
).set
state.secondary_filtration.set_mode = create_autospec(
smarttub.SpaSecondaryFiltrationCycle, instance=True
).set_mode
return state


@pytest.fixture(name="spa")
def mock_spa(spa_state):
"""Mock a smarttub.Spa."""

mock_spa = create_autospec(smarttub.Spa, instance=True)
mock_spa.id = "mockspa1"
mock_spa.brand = "mockbrand1"
mock_spa.model = "mockmodel1"

mock_spa.get_status.return_value = spa_state

mock_circulation_pump = create_autospec(smarttub.SpaPump, instance=True)
mock_circulation_pump.id = "CP"
mock_circulation_pump.spa = mock_spa
Expand Down
24 changes: 24 additions & 0 deletions tests/components/smarttub/test_sensor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Test the SmartTub sensor platform."""

import pytest
import smarttub


@pytest.mark.parametrize(
Expand Down Expand Up @@ -35,6 +36,16 @@ async def test_primary_filtration(spa, setup_entry, hass):
assert state.attributes["mode"] == "normal"
assert state.attributes["start_hour"] == 2

await hass.services.async_call(
"smarttub",
"set_primary_filtration",
{"entity_id": entity_id, "duration": 8, "start_hour": 1},
blocking=True,
)
spa.get_status.return_value.primary_filtration.set.assert_called_with(
duration=8, start_hour=1
)


async def test_secondary_filtration(spa, setup_entry, hass):
"""Test the secondary filtration cycle sensor."""
Expand All @@ -45,3 +56,16 @@ async def test_secondary_filtration(spa, setup_entry, hass):
assert state.state == "inactive"
assert state.attributes["cycle_last_updated"] is not None
assert state.attributes["mode"] == "away"

await hass.services.async_call(
"smarttub",
"set_secondary_filtration",
{
"entity_id": entity_id,
"mode": "frequent",
},
blocking=True,
)
spa.get_status.return_value.secondary_filtration.set_mode.assert_called_with(
mode=smarttub.SpaSecondaryFiltrationCycle.SecondaryFiltrationMode.FREQUENT
)