Add switch support to Freedompro (#52727)
* Update Freedompro * add test state updates from the API * fix test switch * fix testpull/52726/head
parent
b49fb1f657
commit
d09035db2a
|
@ -14,7 +14,7 @@ from .const import DOMAIN
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORMS = ["light"]
|
||||
PLATFORMS = ["light", "switch"]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
"""Support for Freedompro switch."""
|
||||
import json
|
||||
|
||||
from pyfreedompro import put_state
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.const import CONF_API_KEY
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry, async_add_entities):
|
||||
"""Set up Freedompro switch."""
|
||||
api_key = entry.data[CONF_API_KEY]
|
||||
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
async_add_entities(
|
||||
Device(hass, api_key, device, coordinator)
|
||||
for device in coordinator.data
|
||||
if device["type"] == "switch" or device["type"] == "outlet"
|
||||
)
|
||||
|
||||
|
||||
class Device(CoordinatorEntity, SwitchEntity):
|
||||
"""Representation of an Freedompro switch."""
|
||||
|
||||
def __init__(self, hass, api_key, device, coordinator):
|
||||
"""Initialize the Freedompro switch."""
|
||||
super().__init__(coordinator)
|
||||
self._hass = hass
|
||||
self._session = aiohttp_client.async_get_clientsession(self._hass)
|
||||
self._api_key = api_key
|
||||
self._attr_name = device["name"]
|
||||
self._attr_unique_id = device["uid"]
|
||||
self._type = device["type"]
|
||||
self._characteristics = device["characteristics"]
|
||||
self._attr_device_info = {
|
||||
"name": self._attr_name,
|
||||
"identifiers": {
|
||||
(DOMAIN, self._attr_unique_id),
|
||||
},
|
||||
"model": self._type,
|
||||
"manufacturer": "Freedompro",
|
||||
}
|
||||
self._attr_is_on = False
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
device = next(
|
||||
(
|
||||
device
|
||||
for device in self.coordinator.data
|
||||
if device["uid"] == self._attr_unique_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
if device is not None and "state" in device:
|
||||
state = device["state"]
|
||||
if "on" in state:
|
||||
self._attr_is_on = state["on"]
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""When entity is added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
self._handle_coordinator_update()
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Async function to set on to switch."""
|
||||
payload = {"on": True}
|
||||
payload = json.dumps(payload)
|
||||
await put_state(
|
||||
self._session,
|
||||
self._api_key,
|
||||
self._attr_unique_id,
|
||||
payload,
|
||||
)
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Async function to set off to switch."""
|
||||
payload = {"on": False}
|
||||
payload = json.dumps(payload)
|
||||
await put_state(
|
||||
self._session,
|
||||
self._api_key,
|
||||
self._attr_unique_id,
|
||||
payload,
|
||||
)
|
||||
await self.coordinator.async_request_refresh()
|
|
@ -39,7 +39,7 @@ DEVICES = [
|
|||
},
|
||||
{
|
||||
"uid": "3WRRJR6RCZQZSND8VP0YTO3YXCSOFPKBMW8T51TU-LQ*1JKU1MVWHQL-Z9SCUS85VFXMRGNDCDNDDUVVDKBU31W",
|
||||
"name": "irrigation",
|
||||
"name": "Irrigation switch",
|
||||
"type": "switch",
|
||||
"characteristics": ["on"],
|
||||
},
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
"""Tests for the Freedompro switch."""
|
||||
from datetime import timedelta
|
||||
from unittest.mock import ANY, patch
|
||||
|
||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SERVICE_TURN_ON
|
||||
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, STATE_OFF, STATE_ON
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
from tests.components.freedompro.const import DEVICES_STATE
|
||||
|
||||
uid = "3WRRJR6RCZQZSND8VP0YTO3YXCSOFPKBMW8T51TU-LQ*1JKU1MVWHQL-Z9SCUS85VFXMRGNDCDNDDUVVDKBU31W"
|
||||
|
||||
|
||||
async def test_switch_get_state(hass, init_integration):
|
||||
"""Test states of the switch."""
|
||||
init_integration
|
||||
registry = er.async_get(hass)
|
||||
|
||||
entity_id = "switch.irrigation_switch"
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == STATE_OFF
|
||||
assert state.attributes.get("friendly_name") == "Irrigation switch"
|
||||
|
||||
entry = registry.async_get(entity_id)
|
||||
assert entry
|
||||
assert entry.unique_id == uid
|
||||
|
||||
get_states_response = list(DEVICES_STATE)
|
||||
for state_response in get_states_response:
|
||||
if state_response["uid"] == uid:
|
||||
state_response["state"]["on"] = True
|
||||
with patch(
|
||||
"homeassistant.components.freedompro.get_states",
|
||||
return_value=get_states_response,
|
||||
):
|
||||
async_fire_time_changed(hass, utcnow() + timedelta(hours=2))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.attributes.get("friendly_name") == "Irrigation switch"
|
||||
|
||||
entry = registry.async_get(entity_id)
|
||||
assert entry
|
||||
assert entry.unique_id == uid
|
||||
|
||||
assert state.state == STATE_ON
|
||||
|
||||
|
||||
async def test_switch_set_off(hass, init_integration):
|
||||
"""Test set off of the switch."""
|
||||
init_integration
|
||||
registry = er.async_get(hass)
|
||||
|
||||
entity_id = "switch.irrigation_switch"
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes.get("friendly_name") == "Irrigation switch"
|
||||
|
||||
entry = registry.async_get(entity_id)
|
||||
assert entry
|
||||
assert entry.unique_id == uid
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.freedompro.switch.put_state"
|
||||
) as mock_put_state:
|
||||
assert await hass.services.async_call(
|
||||
SWITCH_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: [entity_id]},
|
||||
blocking=True,
|
||||
)
|
||||
mock_put_state.assert_called_once_with(ANY, ANY, ANY, '{"on": false}')
|
||||
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
|
||||
|
||||
async def test_switch_set_on(hass, init_integration):
|
||||
"""Test set on of the switch."""
|
||||
init_integration
|
||||
registry = er.async_get(hass)
|
||||
|
||||
entity_id = "switch.irrigation_switch"
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes.get("friendly_name") == "Irrigation switch"
|
||||
|
||||
entry = registry.async_get(entity_id)
|
||||
assert entry
|
||||
assert entry.unique_id == uid
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.freedompro.switch.put_state"
|
||||
) as mock_put_state:
|
||||
assert await hass.services.async_call(
|
||||
SWITCH_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: [entity_id]},
|
||||
blocking=True,
|
||||
)
|
||||
mock_put_state.assert_called_once_with(ANY, ANY, ANY, '{"on": true}')
|
||||
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
Loading…
Reference in New Issue