diff --git a/CODEOWNERS b/CODEOWNERS index 375842e33cd..6e178069816 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -134,6 +134,7 @@ homeassistant/components/ecobee/* @marthoc homeassistant/components/econet/* @vangorra @w1ll1am23 homeassistant/components/ecovacs/* @OverloadUT homeassistant/components/edl21/* @mtdcr +homeassistant/components/efergy/* @tkdrob homeassistant/components/egardia/* @jeroenterheerdt homeassistant/components/eight_sleep/* @mezz64 homeassistant/components/elgato/* @frenck diff --git a/homeassistant/components/efergy/manifest.json b/homeassistant/components/efergy/manifest.json index fe9ea7e6047..3b84d243d46 100644 --- a/homeassistant/components/efergy/manifest.json +++ b/homeassistant/components/efergy/manifest.json @@ -2,6 +2,7 @@ "domain": "efergy", "name": "Efergy", "documentation": "https://www.home-assistant.io/integrations/efergy", - "codeowners": [], + "requirements": ["pyefergy==0.0.3"], + "codeowners": ["@tkdrob"], "iot_class": "cloud_polling" } diff --git a/homeassistant/components/efergy/sensor.py b/homeassistant/components/efergy/sensor.py index e7116a360e7..338609cf342 100644 --- a/homeassistant/components/efergy/sensor.py +++ b/homeassistant/components/efergy/sensor.py @@ -1,10 +1,7 @@ """Support for Efergy sensors.""" from __future__ import annotations -import logging -from typing import Any - -import requests +from pyefergy import Efergy import voluptuous as vol from homeassistant.components.sensor import ( @@ -23,13 +20,11 @@ from homeassistant.const import ( POWER_WATT, ) from homeassistant.core import HomeAssistant +from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType -_LOGGER = logging.getLogger(__name__) -_RESOURCE = "https://engage.efergy.com/mobile_proxy/" - CONF_APPTOKEN = "app_token" CONF_UTC_OFFSET = "utc_offset" @@ -93,37 +88,36 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( ) -def setup_platform( +async def async_setup_platform( hass: HomeAssistant, config: ConfigType, add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType = None, ) -> None: """Set up the Efergy sensor.""" - app_token = config.get(CONF_APPTOKEN) - utc_offset = str(config.get(CONF_UTC_OFFSET)) + api = Efergy( + config[CONF_APPTOKEN], + async_get_clientsession(hass), + utc_offset=config[CONF_UTC_OFFSET], + ) dev = [] + sensors = await api.get_sids() for variable in config[CONF_MONITORED_VARIABLES]: if variable[CONF_TYPE] == CONF_CURRENT_VALUES: - url_string = f"{_RESOURCE}getCurrentValuesSummary?token={app_token}" - response = requests.get(url_string, timeout=10) - for sensor in response.json(): - sid = sensor["sid"] + for sensor in sensors: dev.append( EfergySensor( - app_token, - utc_offset, + api, variable[CONF_PERIOD], variable[CONF_CURRENCY], SENSOR_TYPES[variable[CONF_TYPE]], - sid=sid, + sid=sensor["sid"], ) ) dev.append( EfergySensor( - app_token, - utc_offset, + api, variable[CONF_PERIOD], variable[CONF_CURRENCY], SENSOR_TYPES[variable[CONF_TYPE]], @@ -138,8 +132,7 @@ class EfergySensor(SensorEntity): def __init__( self, - app_token: Any, - utc_offset: str, + api: Efergy, period: str, currency: str, description: SensorEntityDescription, @@ -148,41 +141,15 @@ class EfergySensor(SensorEntity): """Initialize the sensor.""" self.entity_description = description self.sid = sid + self.api = api + self.period = period if sid: self._attr_name = f"efergy_{sid}" - self.app_token = app_token - self.utc_offset = utc_offset - self.period = period if description.key == CONF_COST: self._attr_native_unit_of_measurement = f"{currency}/{period}" - def update(self) -> None: + async def async_update(self) -> None: """Get the Efergy monitor data from the web service.""" - try: - if self.entity_description.key == CONF_INSTANT: - url_string = f"{_RESOURCE}getInstant?token={self.app_token}" - response = requests.get(url_string, timeout=10) - self._attr_native_value = response.json()["reading"] - elif self.entity_description.key == CONF_AMOUNT: - url_string = f"{_RESOURCE}getEnergy?token={self.app_token}&offset={self.utc_offset}&period={self.period}" - response = requests.get(url_string, timeout=10) - self._attr_native_value = response.json()["sum"] - elif self.entity_description.key == CONF_BUDGET: - url_string = f"{_RESOURCE}getBudget?token={self.app_token}" - response = requests.get(url_string, timeout=10) - self._attr_native_value = response.json()["status"] - elif self.entity_description.key == CONF_COST: - url_string = f"{_RESOURCE}getCost?token={self.app_token}&offset={self.utc_offset}&period={self.period}" - response = requests.get(url_string, timeout=10) - self._attr_native_value = response.json()["sum"] - elif self.entity_description.key == CONF_CURRENT_VALUES: - url_string = ( - f"{_RESOURCE}getCurrentValuesSummary?token={self.app_token}" - ) - response = requests.get(url_string, timeout=10) - for sensor in response.json(): - if self.sid == sensor["sid"]: - measurement = next(iter(sensor["data"][0].values())) - self._attr_native_value = measurement - except (requests.RequestException, ValueError, KeyError): - _LOGGER.warning("Could not update status for %s", self.name) + self._attr_native_value = await self.api.async_get_reading( + self.entity_description.key, period=self.period, sid=self.sid + ) diff --git a/requirements_all.txt b/requirements_all.txt index d9ba931e894..2a064e990f8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1450,6 +1450,9 @@ pyeconet==0.1.14 # homeassistant.components.edimax pyedimax==0.2.1 +# homeassistant.components.efergy +pyefergy==0.0.3 + # homeassistant.components.eight_sleep pyeight==0.1.9 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 2352fed82e0..4ccbc5c1d66 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -838,6 +838,9 @@ pydispatcher==2.0.5 # homeassistant.components.econet pyeconet==0.1.14 +# homeassistant.components.efergy +pyefergy==0.0.3 + # homeassistant.components.everlights pyeverlights==0.1.0 diff --git a/tests/components/efergy/test_sensor.py b/tests/components/efergy/test_sensor.py index a56e28cb3ef..97478155483 100644 --- a/tests/components/efergy/test_sensor.py +++ b/tests/components/efergy/test_sensor.py @@ -1,8 +1,10 @@ """The tests for Efergy sensor platform.""" +from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component from tests.common import load_fixture +from tests.test_util.aiohttp import AiohttpClientMocker token = "9p6QGJ7dpZfO3fqPTBk1fyEmjV1cGoLT" multi_sensor_token = "9r6QGF7dpZfO3fqPTBl1fyRmjV1cGoLT" @@ -28,38 +30,40 @@ MULTI_SENSOR_CONFIG = { } -def mock_responses(mock): +def mock_responses(aioclient_mock: AiohttpClientMocker): """Mock responses for Efergy.""" base_url = "https://engage.efergy.com/mobile_proxy/" - mock.get( + aioclient_mock.get( f"{base_url}getInstant?token={token}", - text=load_fixture("efergy_instant.json"), + text=load_fixture("efergy/efergy_instant.json"), ) - mock.get( + aioclient_mock.get( f"{base_url}getEnergy?token={token}&offset=300&period=day", - text=load_fixture("efergy_energy.json"), + text=load_fixture("efergy/efergy_energy.json"), ) - mock.get( + aioclient_mock.get( f"{base_url}getBudget?token={token}", - text=load_fixture("efergy_budget.json"), + text=load_fixture("efergy/efergy_budget.json"), ) - mock.get( + aioclient_mock.get( f"{base_url}getCost?token={token}&offset=300&period=day", - text=load_fixture("efergy_cost.json"), + text=load_fixture("efergy/efergy_cost.json"), ) - mock.get( + aioclient_mock.get( f"{base_url}getCurrentValuesSummary?token={token}", - text=load_fixture("efergy_current_values_single.json"), + text=load_fixture("efergy/efergy_current_values_single.json"), ) - mock.get( + aioclient_mock.get( f"{base_url}getCurrentValuesSummary?token={multi_sensor_token}", - text=load_fixture("efergy_current_values_multi.json"), + text=load_fixture("efergy/efergy_current_values_multi.json"), ) -async def test_single_sensor_readings(hass, requests_mock): +async def test_single_sensor_readings( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +): """Test for successfully setting up the Efergy platform.""" - mock_responses(requests_mock) + mock_responses(aioclient_mock) assert await async_setup_component(hass, "sensor", {"sensor": ONE_SENSOR_CONFIG}) await hass.async_block_till_done() @@ -70,9 +74,11 @@ async def test_single_sensor_readings(hass, requests_mock): assert hass.states.get("sensor.efergy_728386").state == "1628" -async def test_multi_sensor_readings(hass, requests_mock): +async def test_multi_sensor_readings( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +): """Test for multiple sensors in one household.""" - mock_responses(requests_mock) + mock_responses(aioclient_mock) assert await async_setup_component(hass, "sensor", {"sensor": MULTI_SENSOR_CONFIG}) await hass.async_block_till_done() diff --git a/tests/fixtures/efergy_budget.json b/tests/fixtures/efergy/efergy_budget.json similarity index 100% rename from tests/fixtures/efergy_budget.json rename to tests/fixtures/efergy/efergy_budget.json diff --git a/tests/fixtures/efergy_cost.json b/tests/fixtures/efergy/efergy_cost.json similarity index 100% rename from tests/fixtures/efergy_cost.json rename to tests/fixtures/efergy/efergy_cost.json diff --git a/tests/fixtures/efergy_current_values_multi.json b/tests/fixtures/efergy/efergy_current_values_multi.json similarity index 100% rename from tests/fixtures/efergy_current_values_multi.json rename to tests/fixtures/efergy/efergy_current_values_multi.json diff --git a/tests/fixtures/efergy_current_values_single.json b/tests/fixtures/efergy/efergy_current_values_single.json similarity index 100% rename from tests/fixtures/efergy_current_values_single.json rename to tests/fixtures/efergy/efergy_current_values_single.json diff --git a/tests/fixtures/efergy_energy.json b/tests/fixtures/efergy/efergy_energy.json similarity index 100% rename from tests/fixtures/efergy_energy.json rename to tests/fixtures/efergy/efergy_energy.json diff --git a/tests/fixtures/efergy_instant.json b/tests/fixtures/efergy/efergy_instant.json similarity index 100% rename from tests/fixtures/efergy_instant.json rename to tests/fixtures/efergy/efergy_instant.json