From b5149dfba652340bffc519a8a9f604f8e6444309 Mon Sep 17 00:00:00 2001 From: miniconfig Date: Fri, 17 Mar 2017 02:22:10 -0400 Subject: [PATCH] Added support for multiple efergy sensors in the same household. (#6630) * Added support for multiple efergy sensors in the same household. Also added inital tests for the efergy platform. * Fixed current_values units. Changed name to include efergy_ prefix. --- .coveragerc | 1 - homeassistant/components/sensor/efergy.py | 30 ++++- tests/components/sensor/test_efergy.py | 108 ++++++++++++++++++ tests/fixtures/efergy_budget.json | 1 + tests/fixtures/efergy_cost.json | 1 + .../fixtures/efergy_current_values_multi.json | 35 ++++++ .../efergy_current_values_single.json | 13 +++ tests/fixtures/efergy_energy.json | 1 + tests/fixtures/efergy_instant.json | 5 + 9 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 tests/components/sensor/test_efergy.py create mode 100644 tests/fixtures/efergy_budget.json create mode 100644 tests/fixtures/efergy_cost.json create mode 100644 tests/fixtures/efergy_current_values_multi.json create mode 100644 tests/fixtures/efergy_current_values_single.json create mode 100644 tests/fixtures/efergy_energy.json create mode 100644 tests/fixtures/efergy_instant.json diff --git a/.coveragerc b/.coveragerc index 752bebe6123..be48f4750ea 100644 --- a/.coveragerc +++ b/.coveragerc @@ -329,7 +329,6 @@ omit = homeassistant/components/sensor/dovado.py homeassistant/components/sensor/dte_energy_bridge.py homeassistant/components/sensor/ebox.py - homeassistant/components/sensor/efergy.py homeassistant/components/sensor/eliqonline.py homeassistant/components/sensor/emoncms.py homeassistant/components/sensor/fastdotcom.py diff --git a/homeassistant/components/sensor/efergy.py b/homeassistant/components/sensor/efergy.py index f930bc9c23b..8731158cb6a 100644 --- a/homeassistant/components/sensor/efergy.py +++ b/homeassistant/components/sensor/efergy.py @@ -28,12 +28,14 @@ CONF_INSTANT = 'instant_readings' CONF_AMOUNT = 'amount' CONF_BUDGET = 'budget' CONF_COST = 'cost' +CONF_CURRENT_VALUES = 'current_values' SENSOR_TYPES = { CONF_INSTANT: ['Energy Usage', 'kW'], CONF_AMOUNT: ['Energy Consumed', 'kWh'], CONF_BUDGET: ['Energy Budget', None], CONF_COST: ['Energy Cost', None], + CONF_CURRENT_VALUES: ['Per-Device Usage', 'kW'] } TYPES_SCHEMA = vol.In(SENSOR_TYPES) @@ -57,19 +59,33 @@ def setup_platform(hass, config, add_devices, discovery_info=None): utc_offset = str(config.get(CONF_UTC_OFFSET)) dev = [] for variable in config[CONF_MONITORED_VARIABLES]: + if variable[CONF_SENSOR_TYPE] == CONF_CURRENT_VALUES: + url_string = _RESOURCE + 'getCurrentValuesSummary?token=' \ + + app_token + response = get(url_string, timeout=10) + for sensor in response.json(): + sid = sensor['sid'] + dev.append(EfergySensor(variable[CONF_SENSOR_TYPE], app_token, + utc_offset, variable[CONF_PERIOD], + variable[CONF_CURRENCY], sid)) dev.append(EfergySensor( variable[CONF_SENSOR_TYPE], app_token, utc_offset, variable[CONF_PERIOD], variable[CONF_CURRENCY])) - add_devices(dev) + add_devices(dev, True) class EfergySensor(Entity): """Implementation of an Efergy sensor.""" - def __init__(self, sensor_type, app_token, utc_offset, period, currency): + def __init__(self, sensor_type, app_token, utc_offset, period, + currency, sid=None): """Initialize the sensor.""" - self._name = SENSOR_TYPES[sensor_type][0] + self.sid = sid + if sid: + self._name = 'efergy_' + sid + else: + self._name = SENSOR_TYPES[sensor_type][0] self.type = sensor_type self.app_token = app_token self.utc_offset = utc_offset @@ -119,6 +135,14 @@ class EfergySensor(Entity): + self.period response = get(url_string, timeout=10) self._state = response.json()['sum'] + elif self.type == 'current_values': + url_string = _RESOURCE + 'getCurrentValuesSummary?token=' \ + + self.app_token + response = get(url_string, timeout=10) + for sensor in response.json(): + if self.sid == sensor['sid']: + measurement = next(iter(sensor['data'][0].values())) + self._state = measurement / 1000 else: self._state = 'Unknown' except (RequestException, ValueError, KeyError): diff --git a/tests/components/sensor/test_efergy.py b/tests/components/sensor/test_efergy.py new file mode 100644 index 00000000000..3ecedcd12f3 --- /dev/null +++ b/tests/components/sensor/test_efergy.py @@ -0,0 +1,108 @@ +"""The tests for Efergy sensor platform.""" +import unittest + +import requests_mock + +from homeassistant.setup import setup_component + +from tests.common import load_fixture, get_test_home_assistant + +token = '9p6QGJ7dpZfO3fqPTBk1fyEmjV1cGoLT' +multi_sensor_token = '9r6QGF7dpZfO3fqPTBl1fyRmjV1cGoLT' + +ONE_SENSOR_CONFIG = { + 'platform': 'efergy', + 'app_token': token, + 'utc_offset': '300', + 'monitored_variables': [{'type': 'amount', 'period': 'day'}, + {'type': 'instant_readings'}, + {'type': 'budget'}, + {'type': 'cost', 'period': 'day', 'currency': '$'}, + {'type': 'current_values'} + ] +} + +MULTI_SENSOR_CONFIG = { + 'platform': 'efergy', + 'app_token': multi_sensor_token, + 'utc_offset': '300', + 'monitored_variables': [ + {'type': 'current_values'} + ] +} + + +def mock_responses(mock): + """Mock responses for Efergy.""" + base_url = 'https://engage.efergy.com/mobile_proxy/' + mock.get( + base_url + 'getInstant?token=' + token, + text=load_fixture('efergy_instant.json')) + mock.get( + base_url + 'getEnergy?token=' + token + '&offset=300&period=day', + text=load_fixture('efergy_energy.json')) + mock.get( + base_url + 'getBudget?token=' + token, + text=load_fixture('efergy_budget.json')) + mock.get( + base_url + 'getCost?token=' + token + '&offset=300&period=day', + text=load_fixture('efergy_cost.json')) + mock.get( + base_url + 'getCurrentValuesSummary?token=' + token, + text=load_fixture('efergy_current_values_single.json')) + mock.get( + base_url + 'getCurrentValuesSummary?token=' + multi_sensor_token, + text=load_fixture('efergy_current_values_multi.json')) + + +class TestEfergySensor(unittest.TestCase): + """Tests the Efergy Sensor platform.""" + + DEVICES = [] + + @requests_mock.Mocker() + def add_devices(self, devices, mock): + """Mock add devices.""" + mock_responses(mock) + for device in devices: + device.update() + self.DEVICES.append(device) + + def setUp(self): + """Initialize values for this testcase class.""" + self.hass = get_test_home_assistant() + self.config = ONE_SENSOR_CONFIG + + def tearDown(self): # pylint: disable=invalid-name + """Stop everything that was started.""" + self.hass.stop() + + @requests_mock.Mocker() + def test_single_sensor_readings(self, mock): + """Test for successfully setting up the Efergy platform.""" + mock_responses(mock) + assert setup_component(self.hass, 'sensor', { + 'sensor': ONE_SENSOR_CONFIG}) + self.assertEqual('38.21', + self.hass.states.get('sensor.energy_consumed').state) + self.assertEqual('1.58', + self.hass.states.get('sensor.energy_usage').state) + self.assertEqual('ok', + self.hass.states.get('sensor.energy_budget').state) + self.assertEqual('5.27', + self.hass.states.get('sensor.energy_cost').state) + self.assertEqual('1.628', + self.hass.states.get('sensor.efergy_728386').state) + + @requests_mock.Mocker() + def test_multi_sensor_readings(self, mock): + """Test for multiple sensors in one household.""" + mock_responses(mock) + assert setup_component(self.hass, 'sensor', { + 'sensor': MULTI_SENSOR_CONFIG}) + self.assertEqual('0.218', + self.hass.states.get('sensor.efergy_728386').state) + self.assertEqual('1.808', + self.hass.states.get('sensor.efergy_0').state) + self.assertEqual('0.312', + self.hass.states.get('sensor.efergy_728387').state) diff --git a/tests/fixtures/efergy_budget.json b/tests/fixtures/efergy_budget.json new file mode 100644 index 00000000000..2b0a64fbae5 --- /dev/null +++ b/tests/fixtures/efergy_budget.json @@ -0,0 +1 @@ +{"status":"ok", "monthly_budget":250.0000} \ No newline at end of file diff --git a/tests/fixtures/efergy_cost.json b/tests/fixtures/efergy_cost.json new file mode 100644 index 00000000000..8b2ccfff18a --- /dev/null +++ b/tests/fixtures/efergy_cost.json @@ -0,0 +1 @@ +{"sum":"5.27","duration":70320,"units":"GBP"} \ No newline at end of file diff --git a/tests/fixtures/efergy_current_values_multi.json b/tests/fixtures/efergy_current_values_multi.json new file mode 100644 index 00000000000..95ee28a6102 --- /dev/null +++ b/tests/fixtures/efergy_current_values_multi.json @@ -0,0 +1,35 @@ +[ + { + "cid": "PWER", + "data": [ + { + "1485853183000": 218 + } + ], + "sid": "728386", + "units": "kWm", + "age": 3 + }, + { + "cid": "PWER", + "data": [ + { + "1485695742000": 1808 + } + ], + "sid": "0", + "units": "kWm", + "age": 157444 + }, + { + "cid": "PWER_GAC", + "data": [ + { + "1485853181000": 312 + } + ], + "sid": "728387", + "units": null, + "age": 5 + } +] \ No newline at end of file diff --git a/tests/fixtures/efergy_current_values_single.json b/tests/fixtures/efergy_current_values_single.json new file mode 100644 index 00000000000..df9e5b9ecb4 --- /dev/null +++ b/tests/fixtures/efergy_current_values_single.json @@ -0,0 +1,13 @@ +[ + { + "cid": "PWER", + "data": [ + { + "1486247500000": 1628 + } + ], + "sid": "728386", + "units": "kWm", + "age": 5 + } +] \ No newline at end of file diff --git a/tests/fixtures/efergy_energy.json b/tests/fixtures/efergy_energy.json new file mode 100644 index 00000000000..4033ad074a6 --- /dev/null +++ b/tests/fixtures/efergy_energy.json @@ -0,0 +1 @@ +{"sum":"38.21","duration":70320,"units":"kWh"} \ No newline at end of file diff --git a/tests/fixtures/efergy_instant.json b/tests/fixtures/efergy_instant.json new file mode 100644 index 00000000000..e66bc4312c9 --- /dev/null +++ b/tests/fixtures/efergy_instant.json @@ -0,0 +1,5 @@ +{ + "age": 1, + "last_reading_time": 1486247836000, + "reading": 1580 +} \ No newline at end of file