core/homeassistant/components/sensor/efergy.py

153 lines
5.4 KiB
Python

"""
Support for Efergy sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.efergy/
"""
import logging
import voluptuous as vol
from requests import RequestException, get
import homeassistant.helpers.config_validation as cv
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
_RESOURCE = 'https://engage.efergy.com/mobile_proxy/'
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'
CONF_AMOUNT = 'amount'
CONF_BUDGET = 'budget'
CONF_COST = 'cost'
CONF_CURRENT_VALUES = 'current_values'
DEFAULT_PERIOD = 'year'
DEFAULT_UTC_OFFSET = '0'
SENSOR_TYPES = {
CONF_INSTANT: ['Energy Usage', 'W'],
CONF_AMOUNT: ['Energy Consumed', 'kWh'],
CONF_BUDGET: ['Energy Budget', None],
CONF_COST: ['Energy Cost', None],
CONF_CURRENT_VALUES: ['Per-Device Usage', 'W']
}
TYPES_SCHEMA = vol.In(SENSOR_TYPES)
SENSORS_SCHEMA = vol.Schema({
vol.Required(CONF_SENSOR_TYPE): TYPES_SCHEMA,
vol.Optional(CONF_CURRENCY, default=''): cv.string,
vol.Optional(CONF_PERIOD, default=DEFAULT_PERIOD): cv.string,
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_APPTOKEN): cv.string,
vol.Optional(CONF_UTC_OFFSET, default=DEFAULT_UTC_OFFSET): cv.string,
vol.Required(CONF_MONITORED_VARIABLES): [SENSORS_SCHEMA]
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Efergy sensor."""
app_token = config.get(CONF_APPTOKEN)
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, True)
class EfergySensor(Entity):
"""Implementation of an Efergy sensor."""
def __init__(self, sensor_type, app_token, utc_offset, period,
currency, sid=None):
"""Initialize the sensor."""
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
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):
"""Return the name of the sensor."""
return 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
def update(self):
"""Get the Efergy monitor data from the web service."""
try:
if self.type == 'instant_readings':
url_string = _RESOURCE + 'getInstant?token=' + self.app_token
response = get(url_string, timeout=10)
self._state = response.json()['reading']
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']
elif self.type == 'budget':
url_string = _RESOURCE + 'getBudget?token=' + self.app_token
response = get(url_string, timeout=10)
self._state = response.json()['status']
elif self.type == 'cost':
url_string = _RESOURCE + 'getCost?token=' + self.app_token \
+ '&offset=' + self.utc_offset + '&period=' \
+ 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
else:
self._state = 'Unknown'
except (RequestException, ValueError, KeyError):
_LOGGER.warning("Could not update status for %s", self.name)