added support for smappee water sensors (#12831)

* added support for smappee water sensors

* fixed lint error and wrong location_id

* fixed lint error

* Use string formatting
pull/13729/head
Henrik Nicolaisen 2018-04-06 23:14:31 +02:00 committed by Fabian Affolter
parent 262ea14e5a
commit fdf93d1829
2 changed files with 72 additions and 25 deletions

View File

@ -31,7 +31,19 @@ SENSOR_TYPES = {
'solar_today':
['Solar Today', 'mdi:white-balance-sunny', 'remote', 'kWh', 'solar'],
'power_today':
['Power Today', 'mdi:power-plug', 'remote', 'kWh', 'consumption']
['Power Today', 'mdi:power-plug', 'remote', 'kWh', 'consumption'],
'water_sensor_1':
['Water Sensor 1', 'mdi:water', 'water', 'm3', 'value1'],
'water_sensor_2':
['Water Sensor 2', 'mdi:water', 'water', 'm3', 'value2'],
'water_sensor_temperature':
['Water Sensor Temperature', 'mdi:temperature-celsius',
'water', '°', 'temperature'],
'water_sensor_humidity':
['Water Sensor Humidity', 'mdi:water-percent', 'water',
'%', 'humidity'],
'water_sensor_battery':
['Water Sensor Battery', 'mdi:battery', 'water', '%', 'battery'],
}
SCAN_INTERVAL = timedelta(seconds=30)
@ -43,36 +55,50 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
dev = []
if smappee.is_remote_active:
for sensor in SENSOR_TYPES:
if 'remote' in SENSOR_TYPES[sensor]:
for location_id in smappee.locations.keys():
dev.append(SmappeeSensor(smappee, location_id, sensor))
for location_id in smappee.locations.keys():
for sensor in SENSOR_TYPES:
if 'remote' in SENSOR_TYPES[sensor]:
dev.append(SmappeeSensor(smappee, location_id,
sensor,
SENSOR_TYPES[sensor]))
elif 'water' in SENSOR_TYPES[sensor]:
for items in smappee.info[location_id].get('sensors'):
dev.append(SmappeeSensor(
smappee,
location_id,
'{}:{}'.format(sensor, items.get('id')),
SENSOR_TYPES[sensor]))
if smappee.is_local_active:
for sensor in SENSOR_TYPES:
if 'local' in SENSOR_TYPES[sensor]:
if smappee.is_remote_active:
for location_id in smappee.locations.keys():
dev.append(SmappeeSensor(smappee, location_id, sensor))
else:
dev.append(SmappeeSensor(smappee, None, sensor))
for location_id in smappee.locations.keys():
for sensor in SENSOR_TYPES:
if 'local' in SENSOR_TYPES[sensor]:
if smappee.is_remote_active:
dev.append(SmappeeSensor(smappee, location_id, sensor,
SENSOR_TYPES[sensor]))
else:
dev.append(SmappeeSensor(smappee, None, sensor,
SENSOR_TYPES[sensor]))
add_devices(dev, True)
class SmappeeSensor(Entity):
"""Implementation of a Smappee sensor."""
def __init__(self, smappee, location_id, sensor):
"""Initialize the sensor."""
def __init__(self, smappee, location_id, sensor, attributes):
"""Initialize the Smappee sensor."""
self._smappee = smappee
self._location_id = location_id
self._attributes = attributes
self._sensor = sensor
self.data = None
self._state = None
self._name = SENSOR_TYPES[self._sensor][0]
self._icon = SENSOR_TYPES[self._sensor][1]
self._unit_of_measurement = SENSOR_TYPES[self._sensor][3]
self._smappe_name = SENSOR_TYPES[self._sensor][4]
self._name = self._attributes[0]
self._icon = self._attributes[1]
self._type = self._attributes[2]
self._unit_of_measurement = self._attributes[3]
self._smappe_name = self._attributes[4]
@property
def name(self):
@ -82,9 +108,7 @@ class SmappeeSensor(Entity):
else:
location_name = 'Local'
return "{} {} {}".format(SENSOR_PREFIX,
location_name,
self._name)
return "{} {} {}".format(SENSOR_PREFIX, location_name, self._name)
@property
def icon(self):
@ -160,3 +184,13 @@ class SmappeeSensor(Entity):
if i['key'].endswith('phase5ActivePower')]
power = sum(value1 + value2 + value3) / 1000
self._state = round(power, 2)
elif self._type == 'water':
sensor_name, sensor_id = self._sensor.split(":")
data = self._smappee.sensor_consumption[self._location_id]\
.get(int(sensor_id))
if data:
consumption = data.get('records')[-1]
_LOGGER.debug("%s (%s) %s",
sensor_name, sensor_id, consumption)
value = consumption.get(self._smappe_name)
self._state = value

View File

@ -110,6 +110,7 @@ class Smappee(object):
self.locations = {}
self.info = {}
self.consumption = {}
self.sensor_consumption = {}
self.instantaneous = {}
if self._remote_active or self._local_active:
@ -124,11 +125,22 @@ class Smappee(object):
for location in service_locations:
location_id = location.get('serviceLocationId')
if location_id is not None:
self.sensor_consumption[location_id] = {}
self.locations[location_id] = location.get('name')
self.info[location_id] = self._smappy \
.get_service_location_info(location_id)
_LOGGER.debug("Remote info %s %s",
self.locations, self.info)
self.locations, self.info[location_id])
for sensors in self.info[location_id].get('sensors'):
sensor_id = sensors.get('id')
self.sensor_consumption[location_id]\
.update({sensor_id: self.get_sensor_consumption(
location_id, sensor_id,
aggregation=3, delta=1440)})
_LOGGER.debug("Remote sensors %s %s",
self.locations,
self.sensor_consumption[location_id])
self.consumption[location_id] = self.get_consumption(
location_id, aggregation=3, delta=1440)
@ -190,7 +202,8 @@ class Smappee(object):
"Error getting comsumption from Smappee cloud. (%s)",
error)
def get_sensor_consumption(self, location_id, sensor_id):
def get_sensor_consumption(self, location_id, sensor_id,
aggregation, delta):
"""Update data from Smappee."""
# Start & End accept epoch (in milliseconds),
# datetime and pandas timestamps
@ -203,13 +216,13 @@ class Smappee(object):
if not self.is_remote_active:
return
start = datetime.utcnow() - timedelta(minutes=30)
end = datetime.utcnow()
start = end - timedelta(minutes=delta)
try:
return self._smappy.get_sensor_consumption(location_id,
sensor_id,
start,
end, 1)
end, aggregation)
except RequestException as error:
_LOGGER.error(
"Error getting comsumption from Smappee cloud. (%s)",