From 2e9e8a16bd001358c2f865c998fdad3a68f2edfa Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 10 Oct 2019 20:51:04 +0200 Subject: [PATCH] Remove hydroquebec integration (ADR-0004) (#27407) --- .../components/hydroquebec/__init__.py | 1 - .../components/hydroquebec/manifest.json | 10 - .../components/hydroquebec/sensor.py | 227 ------------------ requirements_all.txt | 3 - requirements_test_all.txt | 3 - tests/components/hydroquebec/__init__.py | 1 - tests/components/hydroquebec/test_sensor.py | 102 -------- 7 files changed, 347 deletions(-) delete mode 100644 homeassistant/components/hydroquebec/__init__.py delete mode 100644 homeassistant/components/hydroquebec/manifest.json delete mode 100644 homeassistant/components/hydroquebec/sensor.py delete mode 100644 tests/components/hydroquebec/__init__.py delete mode 100644 tests/components/hydroquebec/test_sensor.py diff --git a/homeassistant/components/hydroquebec/__init__.py b/homeassistant/components/hydroquebec/__init__.py deleted file mode 100644 index 08a12f7955e..00000000000 --- a/homeassistant/components/hydroquebec/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""The hydroquebec component.""" diff --git a/homeassistant/components/hydroquebec/manifest.json b/homeassistant/components/hydroquebec/manifest.json deleted file mode 100644 index dbe8af0b41b..00000000000 --- a/homeassistant/components/hydroquebec/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "domain": "hydroquebec", - "name": "Hydroquebec", - "documentation": "https://www.home-assistant.io/integrations/hydroquebec", - "requirements": [ - "pyhydroquebec==2.2.2" - ], - "dependencies": [], - "codeowners": [] -} diff --git a/homeassistant/components/hydroquebec/sensor.py b/homeassistant/components/hydroquebec/sensor.py deleted file mode 100644 index c3ad79c1c98..00000000000 --- a/homeassistant/components/hydroquebec/sensor.py +++ /dev/null @@ -1,227 +0,0 @@ -""" -Support for HydroQuebec. - -Get data from 'My Consumption Profile' page: -https://www.hydroquebec.com/portail/en/group/clientele/portrait-de-consommation - -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/sensor.hydroquebec/ -""" -import logging -from datetime import timedelta - -import voluptuous as vol - -from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import ( - CONF_USERNAME, - CONF_PASSWORD, - ENERGY_KILO_WATT_HOUR, - CONF_NAME, - CONF_MONITORED_VARIABLES, - TEMP_CELSIUS, -) -from homeassistant.helpers.entity import Entity -from homeassistant.util import Throttle -import homeassistant.helpers.config_validation as cv - -_LOGGER = logging.getLogger(__name__) - -KILOWATT_HOUR = ENERGY_KILO_WATT_HOUR -PRICE = "CAD" -DAYS = "days" -CONF_CONTRACT = "contract" - -DEFAULT_NAME = "HydroQuebec" - -REQUESTS_TIMEOUT = 15 -MIN_TIME_BETWEEN_UPDATES = timedelta(hours=1) -SCAN_INTERVAL = timedelta(hours=1) - -SENSOR_TYPES = { - "balance": ["Balance", PRICE, "mdi:square-inc-cash"], - "period_total_bill": ["Period total bill", PRICE, "mdi:square-inc-cash"], - "period_length": ["Period length", DAYS, "mdi:calendar-today"], - "period_total_days": ["Period total days", DAYS, "mdi:calendar-today"], - "period_mean_daily_bill": ["Period mean daily bill", PRICE, "mdi:square-inc-cash"], - "period_mean_daily_consumption": [ - "Period mean daily consumption", - KILOWATT_HOUR, - "mdi:flash", - ], - "period_total_consumption": [ - "Period total consumption", - KILOWATT_HOUR, - "mdi:flash", - ], - "period_lower_price_consumption": [ - "Period lower price consumption", - KILOWATT_HOUR, - "mdi:flash", - ], - "period_higher_price_consumption": [ - "Period higher price consumption", - KILOWATT_HOUR, - "mdi:flash", - ], - "yesterday_total_consumption": [ - "Yesterday total consumption", - KILOWATT_HOUR, - "mdi:flash", - ], - "yesterday_lower_price_consumption": [ - "Yesterday lower price consumption", - KILOWATT_HOUR, - "mdi:flash", - ], - "yesterday_higher_price_consumption": [ - "Yesterday higher price consumption", - KILOWATT_HOUR, - "mdi:flash", - ], - "yesterday_average_temperature": [ - "Yesterday average temperature", - TEMP_CELSIUS, - "mdi:thermometer", - ], - "period_average_temperature": [ - "Period average temperature", - TEMP_CELSIUS, - "mdi:thermometer", - ], -} - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - { - vol.Required(CONF_MONITORED_VARIABLES): vol.All( - cv.ensure_list, [vol.In(SENSOR_TYPES)] - ), - vol.Required(CONF_USERNAME): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Required(CONF_CONTRACT): cv.string, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - } -) - -HOST = "https://www.hydroquebec.com" -HOME_URL = f"{HOST}/portail/web/clientele/authentification" -PROFILE_URL = "{}/portail/fr/group/clientele/" "portrait-de-consommation".format(HOST) -MONTHLY_MAP = ( - ("period_total_bill", "montantFacturePeriode"), - ("period_length", "nbJourLecturePeriode"), - ("period_total_days", "nbJourPrevuPeriode"), - ("period_mean_daily_bill", "moyenneDollarsJourPeriode"), - ("period_mean_daily_consumption", "moyenneKwhJourPeriode"), - ("period_total_consumption", "consoTotalPeriode"), - ("period_lower_price_consumption", "consoRegPeriode"), - ("period_higher_price_consumption", "consoHautPeriode"), -) -DAILY_MAP = ( - ("yesterday_total_consumption", "consoTotalQuot"), - ("yesterday_lower_price_consumption", "consoRegQuot"), - ("yesterday_higher_price_consumption", "consoHautQuot"), -) - - -async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): - """Set up the HydroQuebec sensor.""" - # Create a data fetcher to support all of the configured sensors. Then make - # the first call to init the data. - - username = config.get(CONF_USERNAME) - password = config.get(CONF_PASSWORD) - contract = config.get(CONF_CONTRACT) - - httpsession = hass.helpers.aiohttp_client.async_get_clientsession() - hydroquebec_data = HydroquebecData(username, password, httpsession, contract) - contracts = await hydroquebec_data.get_contract_list() - if not contracts: - return - _LOGGER.info("Contract list: %s", ", ".join(contracts)) - - name = config.get(CONF_NAME) - - sensors = [] - for variable in config[CONF_MONITORED_VARIABLES]: - sensors.append(HydroQuebecSensor(hydroquebec_data, variable, name)) - - async_add_entities(sensors, True) - - -class HydroQuebecSensor(Entity): - """Implementation of a HydroQuebec sensor.""" - - def __init__(self, hydroquebec_data, sensor_type, name): - """Initialize the sensor.""" - self.client_name = name - self.type = sensor_type - self._name = SENSOR_TYPES[sensor_type][0] - self._unit_of_measurement = SENSOR_TYPES[sensor_type][1] - self._icon = SENSOR_TYPES[sensor_type][2] - self.hydroquebec_data = hydroquebec_data - self._state = None - - @property - def name(self): - """Return the name of the sensor.""" - return f"{self.client_name} {self._name}" - - @property - def state(self): - """Return the state of the sensor.""" - return self._state - - @property - def unit_of_measurement(self): - """Return the unit of measurement of this entity, if any.""" - return self._unit_of_measurement - - @property - def icon(self): - """Icon to use in the frontend, if any.""" - return self._icon - - async def async_update(self): - """Get the latest data from Hydroquebec and update the state.""" - await self.hydroquebec_data.async_update() - if self.hydroquebec_data.data.get(self.type) is not None: - self._state = round(self.hydroquebec_data.data[self.type], 2) - - -class HydroquebecData: - """Get data from HydroQuebec.""" - - def __init__(self, username, password, httpsession, contract=None): - """Initialize the data object.""" - from pyhydroquebec import HydroQuebecClient - - self.client = HydroQuebecClient( - username, password, REQUESTS_TIMEOUT, httpsession - ) - self._contract = contract - self.data = {} - - async def get_contract_list(self): - """Return the contract list.""" - # Fetch data - ret = await self._fetch_data() - if ret: - return self.client.get_contracts() - return [] - - @Throttle(MIN_TIME_BETWEEN_UPDATES) - async def _fetch_data(self): - """Fetch latest data from HydroQuebec.""" - from pyhydroquebec.client import PyHydroQuebecError - - try: - await self.client.fetch_data() - except PyHydroQuebecError as exp: - _LOGGER.error("Error on receive last Hydroquebec data: %s", exp) - return False - return True - - async def async_update(self): - """Return the latest collected data from HydroQuebec.""" - await self._fetch_data() - self.data = self.client.get_data(self._contract)[self._contract] diff --git a/requirements_all.txt b/requirements_all.txt index 7e9d78afb46..8a215b6350b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1231,9 +1231,6 @@ pyhomematic==0.1.60 # homeassistant.components.homeworks pyhomeworks==0.0.6 -# homeassistant.components.hydroquebec -pyhydroquebec==2.2.2 - # homeassistant.components.ialarm pyialarm==0.3 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0e40702b9d9..1bc01f6e73e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -419,9 +419,6 @@ pyheos==0.6.0 # homeassistant.components.homematic pyhomematic==0.1.60 -# homeassistant.components.hydroquebec -pyhydroquebec==2.2.2 - # homeassistant.components.ipma pyipma==1.2.1 diff --git a/tests/components/hydroquebec/__init__.py b/tests/components/hydroquebec/__init__.py deleted file mode 100644 index 1342395d265..00000000000 --- a/tests/components/hydroquebec/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for the hydroquebec component.""" diff --git a/tests/components/hydroquebec/test_sensor.py b/tests/components/hydroquebec/test_sensor.py deleted file mode 100644 index 9b2dd5ab5b5..00000000000 --- a/tests/components/hydroquebec/test_sensor.py +++ /dev/null @@ -1,102 +0,0 @@ -"""The test for the hydroquebec sensor platform.""" -import asyncio -import logging -import sys -from unittest.mock import MagicMock - -from homeassistant.bootstrap import async_setup_component -from homeassistant.components.hydroquebec import sensor as hydroquebec -from tests.common import assert_setup_component - - -CONTRACT = "123456789" - - -class HydroQuebecClientMock: - """Fake Hydroquebec client.""" - - def __init__(self, username, password, contract=None, httpsession=None): - """Fake Hydroquebec client init.""" - pass - - def get_data(self, contract): - """Return fake hydroquebec data.""" - return {CONTRACT: {"balance": 160.12}} - - def get_contracts(self): - """Return fake hydroquebec contracts.""" - return [CONTRACT] - - @asyncio.coroutine - def fetch_data(self): - """Return fake fetching data.""" - pass - - -class HydroQuebecClientMockError(HydroQuebecClientMock): - """Fake Hydroquebec client error.""" - - def get_contracts(self): - """Return fake hydroquebec contracts.""" - return [] - - @asyncio.coroutine - def fetch_data(self): - """Return fake fetching data.""" - raise PyHydroQuebecErrorMock("Fake Error") - - -class PyHydroQuebecErrorMock(BaseException): - """Fake PyHydroquebec Error.""" - - -class PyHydroQuebecClientFakeModule: - """Fake pyfido.client module.""" - - PyHydroQuebecError = PyHydroQuebecErrorMock - - -class PyHydroQuebecFakeModule: - """Fake pyfido module.""" - - HydroQuebecClient = HydroQuebecClientMockError - - -@asyncio.coroutine -def test_hydroquebec_sensor(loop, hass): - """Test the Hydroquebec number sensor.""" - sys.modules["pyhydroquebec"] = MagicMock() - sys.modules["pyhydroquebec.client"] = MagicMock() - sys.modules["pyhydroquebec.client.PyHydroQuebecError"] = PyHydroQuebecErrorMock - import pyhydroquebec.client - - pyhydroquebec.HydroQuebecClient = HydroQuebecClientMock - pyhydroquebec.client.PyHydroQuebecError = PyHydroQuebecErrorMock - config = { - "sensor": { - "platform": "hydroquebec", - "name": "hydro", - "contract": CONTRACT, - "username": "myusername", - "password": "password", - "monitored_variables": ["balance"], - } - } - with assert_setup_component(1): - yield from async_setup_component(hass, "sensor", config) - state = hass.states.get("sensor.hydro_balance") - assert state.state == "160.12" - assert state.attributes.get("unit_of_measurement") == "CAD" - - -@asyncio.coroutine -def test_error(hass, caplog): - """Test the Hydroquebec sensor errors.""" - caplog.set_level(logging.ERROR) - sys.modules["pyhydroquebec"] = PyHydroQuebecFakeModule() - sys.modules["pyhydroquebec.client"] = PyHydroQuebecClientFakeModule() - - config = {} - fake_async_add_entities = MagicMock() - yield from hydroquebec.async_setup_platform(hass, config, fake_async_add_entities) - assert fake_async_add_entities.called is False