2015-07-09 16:05:19 +00:00
|
|
|
"""
|
2016-03-08 15:46:34 +00:00
|
|
|
Support for Efergy sensors.
|
2015-07-09 16:05:19 +00:00
|
|
|
|
2015-10-20 19:24:11 +00:00
|
|
|
For more details about this platform, please refer to the documentation at
|
2015-11-09 12:12:18 +00:00
|
|
|
https://home-assistant.io/components/sensor.efergy/
|
2015-07-09 16:05:19 +00:00
|
|
|
"""
|
|
|
|
import logging
|
2016-08-23 03:51:17 +00:00
|
|
|
import voluptuous as vol
|
2016-02-19 05:27:50 +00:00
|
|
|
|
|
|
|
from requests import RequestException, get
|
2015-07-09 16:05:19 +00:00
|
|
|
|
2016-08-23 03:51:17 +00:00
|
|
|
import homeassistant.helpers.config_validation as cv
|
|
|
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
2015-07-09 16:05:19 +00:00
|
|
|
from homeassistant.helpers.entity import Entity
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
_RESOURCE = 'https://engage.efergy.com/mobile_proxy/'
|
2016-08-23 03:51:17 +00:00
|
|
|
|
|
|
|
CONF_APPTOKEN = 'app_token'
|
|
|
|
CONF_UTC_OFFSET = 'utc_offset'
|
|
|
|
CONF_MONITORED_VARIABLES = 'monitored_variables'
|
|
|
|
CONF_SENSOR_TYPE = 'type'
|
|
|
|
|
|
|
|
CONF_CURRENCY = 'currency'
|
|
|
|
CONF_PERIOD = 'period'
|
|
|
|
|
|
|
|
CONF_INSTANT = 'instant_readings'
|
2016-12-02 06:00:17 +00:00
|
|
|
CONF_AMOUNT = 'amount'
|
2016-08-23 03:51:17 +00:00
|
|
|
CONF_BUDGET = 'budget'
|
|
|
|
CONF_COST = 'cost'
|
2017-03-17 06:22:10 +00:00
|
|
|
CONF_CURRENT_VALUES = 'current_values'
|
2016-08-23 03:51:17 +00:00
|
|
|
|
2017-05-02 16:18:47 +00:00
|
|
|
DEFAULT_PERIOD = 'year'
|
2017-12-14 04:03:41 +00:00
|
|
|
DEFAULT_UTC_OFFSET = '0'
|
2017-05-02 16:18:47 +00:00
|
|
|
|
2015-07-09 16:05:19 +00:00
|
|
|
SENSOR_TYPES = {
|
2017-08-01 03:41:45 +00:00
|
|
|
CONF_INSTANT: ['Energy Usage', 'W'],
|
2016-12-02 06:00:17 +00:00
|
|
|
CONF_AMOUNT: ['Energy Consumed', 'kWh'],
|
2016-08-23 03:51:17 +00:00
|
|
|
CONF_BUDGET: ['Energy Budget', None],
|
|
|
|
CONF_COST: ['Energy Cost', None],
|
2017-08-01 03:41:45 +00:00
|
|
|
CONF_CURRENT_VALUES: ['Per-Device Usage', 'W']
|
2015-07-09 16:05:19 +00:00
|
|
|
}
|
|
|
|
|
2016-12-02 06:00:17 +00:00
|
|
|
TYPES_SCHEMA = vol.In(SENSOR_TYPES)
|
2016-08-23 03:51:17 +00:00
|
|
|
|
|
|
|
SENSORS_SCHEMA = vol.Schema({
|
|
|
|
vol.Required(CONF_SENSOR_TYPE): TYPES_SCHEMA,
|
|
|
|
vol.Optional(CONF_CURRENCY, default=''): cv.string,
|
2017-05-02 16:18:47 +00:00
|
|
|
vol.Optional(CONF_PERIOD, default=DEFAULT_PERIOD): cv.string,
|
2016-08-23 03:51:17 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|
|
|
vol.Required(CONF_APPTOKEN): cv.string,
|
2017-12-14 04:03:41 +00:00
|
|
|
vol.Optional(CONF_UTC_OFFSET, default=DEFAULT_UTC_OFFSET): cv.string,
|
2016-08-23 03:51:17 +00:00
|
|
|
vol.Required(CONF_MONITORED_VARIABLES): [SENSORS_SCHEMA]
|
|
|
|
})
|
|
|
|
|
2015-07-09 16:05:19 +00:00
|
|
|
|
|
|
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
2017-05-02 16:18:47 +00:00
|
|
|
"""Set up the Efergy sensor."""
|
2016-08-23 03:51:17 +00:00
|
|
|
app_token = config.get(CONF_APPTOKEN)
|
|
|
|
utc_offset = str(config.get(CONF_UTC_OFFSET))
|
2015-07-09 16:05:19 +00:00
|
|
|
dev = []
|
2016-08-23 03:51:17 +00:00
|
|
|
for variable in config[CONF_MONITORED_VARIABLES]:
|
2017-03-17 06:22:10 +00:00
|
|
|
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))
|
2016-08-23 03:51:17 +00:00
|
|
|
dev.append(EfergySensor(
|
|
|
|
variable[CONF_SENSOR_TYPE], app_token, utc_offset,
|
|
|
|
variable[CONF_PERIOD], variable[CONF_CURRENCY]))
|
2015-07-09 16:05:19 +00:00
|
|
|
|
2017-03-17 06:22:10 +00:00
|
|
|
add_devices(dev, True)
|
2015-07-09 16:05:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
class EfergySensor(Entity):
|
2016-03-08 15:46:34 +00:00
|
|
|
"""Implementation of an Efergy sensor."""
|
2015-07-09 16:05:19 +00:00
|
|
|
|
2017-03-17 06:22:10 +00:00
|
|
|
def __init__(self, sensor_type, app_token, utc_offset, period,
|
|
|
|
currency, sid=None):
|
2016-03-08 15:46:34 +00:00
|
|
|
"""Initialize the sensor."""
|
2017-03-17 06:22:10 +00:00
|
|
|
self.sid = sid
|
|
|
|
if sid:
|
|
|
|
self._name = 'efergy_' + sid
|
|
|
|
else:
|
|
|
|
self._name = SENSOR_TYPES[sensor_type][0]
|
2015-07-09 16:05:19 +00:00
|
|
|
self.type = sensor_type
|
|
|
|
self.app_token = app_token
|
|
|
|
self.utc_offset = utc_offset
|
|
|
|
self._state = None
|
|
|
|
self.period = period
|
|
|
|
self.currency = currency
|
|
|
|
if self.type == 'cost':
|
|
|
|
self._unit_of_measurement = self.currency + '/' + self.period
|
|
|
|
else:
|
|
|
|
self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self):
|
2016-03-08 15:46:34 +00:00
|
|
|
"""Return the name of the sensor."""
|
2015-07-09 16:05:19 +00:00
|
|
|
return self._name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def state(self):
|
2016-03-08 15:46:34 +00:00
|
|
|
"""Return the state of the sensor."""
|
2015-07-09 16:05:19 +00:00
|
|
|
return self._state
|
|
|
|
|
|
|
|
@property
|
|
|
|
def unit_of_measurement(self):
|
2016-03-08 15:46:34 +00:00
|
|
|
"""Return the unit of measurement of this entity, if any."""
|
2015-07-09 16:05:19 +00:00
|
|
|
return self._unit_of_measurement
|
|
|
|
|
|
|
|
def update(self):
|
2016-03-08 15:46:34 +00:00
|
|
|
"""Get the Efergy monitor data from the web service."""
|
2015-10-28 10:57:10 +00:00
|
|
|
try:
|
|
|
|
if self.type == 'instant_readings':
|
|
|
|
url_string = _RESOURCE + 'getInstant?token=' + self.app_token
|
2016-12-02 06:00:17 +00:00
|
|
|
response = get(url_string, timeout=10)
|
2017-08-01 03:41:45 +00:00
|
|
|
self._state = response.json()['reading']
|
2016-12-02 06:00:17 +00:00
|
|
|
elif self.type == 'amount':
|
|
|
|
url_string = _RESOURCE + 'getEnergy?token=' + self.app_token \
|
|
|
|
+ '&offset=' + self.utc_offset + '&period=' \
|
|
|
|
+ self.period
|
|
|
|
response = get(url_string, timeout=10)
|
|
|
|
self._state = response.json()['sum']
|
2015-10-28 10:57:10 +00:00
|
|
|
elif self.type == 'budget':
|
|
|
|
url_string = _RESOURCE + 'getBudget?token=' + self.app_token
|
2016-12-02 06:00:17 +00:00
|
|
|
response = get(url_string, timeout=10)
|
2015-10-28 10:57:10 +00:00
|
|
|
self._state = response.json()['status']
|
|
|
|
elif self.type == 'cost':
|
|
|
|
url_string = _RESOURCE + 'getCost?token=' + self.app_token \
|
|
|
|
+ '&offset=' + self.utc_offset + '&period=' \
|
|
|
|
+ self.period
|
2016-12-02 06:00:17 +00:00
|
|
|
response = get(url_string, timeout=10)
|
2015-10-28 10:57:10 +00:00
|
|
|
self._state = response.json()['sum']
|
2017-03-17 06:22:10 +00:00
|
|
|
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()))
|
2017-08-01 03:41:45 +00:00
|
|
|
self._state = measurement
|
2015-10-28 10:57:10 +00:00
|
|
|
else:
|
|
|
|
self._state = 'Unknown'
|
2016-02-16 12:05:00 +00:00
|
|
|
except (RequestException, ValueError, KeyError):
|
2017-05-02 16:18:47 +00:00
|
|
|
_LOGGER.warning("Could not update status for %s", self.name)
|