-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added smappee component #11491
added smappee component #11491
Changes from 13 commits
e2f5fd2
96de31b
313f18d
286523b
a854a08
7784cf3
ca915d6
1c2bbf8
67ae8f0
bd4991e
1c3edbe
dd47a67
691583a
2536f17
ada9f24
f298223
5fd0625
9ff4b31
693dd4a
01066c2
3e91f32
0097f02
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
""" | ||
Support for monitoring a Smappee energy sensor. | ||
|
||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/sensor.smappee/ | ||
""" | ||
import logging | ||
from datetime import datetime, timedelta | ||
|
||
from homeassistant.components.smappee import DATA_SMAPPEE | ||
from homeassistant.helpers.entity import Entity | ||
from homeassistant.util import Throttle | ||
|
||
DEPENDENCIES = ['smappee'] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
SENSOR_PREFIX = 'Smappee' | ||
SENSOR_TYPES = { | ||
'solar': ['Solar', 'mdi:white-balance-sunny', 'local', 'W'], | ||
'alwaysOn': ['Always On', 'mdi:gauge', 'remote', 'W'], | ||
'active_power': ['Active Power', 'mdi:power-plug', 'local', 'W'], | ||
'current': ['Current', 'mdi:gauge', 'local', 'Amps'], | ||
'voltage': ['Voltage', 'mdi:gauge', 'local', 'V'], | ||
'active_cosfi': ['Power Factor', 'mdi:gauge', 'local', '%'], | ||
'solar_today': ['Solar Today', 'mdi:white-balance-sunny', 'remote', 'kW'], | ||
'power_today': ['Power Today', 'mdi:power-plug', 'remote', 'kW'] | ||
} | ||
|
||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) | ||
|
||
|
||
def setup_platform(hass, config, add_devices, discovery_info=None): | ||
"""Set up the Smappee sensor.""" | ||
smappee = hass.data[DATA_SMAPPEE] | ||
|
||
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)) | ||
|
||
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)) | ||
add_devices(dev) | ||
|
||
|
||
class SmappeeSensor(Entity): | ||
"""Implementation of a Smappee sensor.""" | ||
|
||
def __init__(self, smappee, location_id, sensor): | ||
"""Initialize the sensor.""" | ||
self._smappee = smappee | ||
self._location_id = location_id | ||
self._sensor = sensor | ||
self.data = None | ||
self._state = None | ||
self._timestamp = None | ||
self.update() | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the sensor.""" | ||
if self._location_id: | ||
location_name = self._smappee.locations[self._location_id] | ||
else: | ||
location_name = 'Local' | ||
|
||
return "{} {} {}".format(SENSOR_PREFIX, | ||
location_name, | ||
SENSOR_TYPES[self._sensor][0]) | ||
|
||
@property | ||
def icon(self): | ||
"""Icon to use in the frontend.""" | ||
return SENSOR_TYPES[self._sensor][1] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you cache this in the constructor so you don't have to do the same lookup on each update |
||
|
||
@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 SENSOR_TYPES[self._sensor][3] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same |
||
|
||
@property | ||
def device_state_attributes(self): | ||
"""Return the state attributes of the device.""" | ||
attr = {} | ||
if self._location_id: | ||
attr['Location Id'] = self._location_id | ||
attr['Location Name'] = self._smappee.locations[self._location_id] | ||
attr['Last Update'] = self._timestamp | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't include this. States already have a last update attribute |
||
return attr | ||
|
||
@Throttle(MIN_TIME_BETWEEN_UPDATES) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of this, just define SCAN_INTERVAL and this method will never be called more than once during that interval. |
||
def update(self): | ||
"""Get the latest data from Smappee and update the state.""" | ||
if self._sensor == 'alwaysOn': | ||
data = self._smappee.get_consumption( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is doing a call to the API per sensor per update (every 30 seconds!). Any way you can fetch all data at once? |
||
self._location_id, aggregation=1, delta=30) | ||
_LOGGER.debug("%s %s", self._sensor, data) | ||
if data: | ||
consumption = data.get('consumptions')[-1] | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
self._state = consumption.get(self._sensor) | ||
elif self._sensor == 'solar_today': | ||
data = self._smappee.get_consumption( | ||
self._location_id, aggregation=3, delta=1440) | ||
_LOGGER.debug("%s %s", self._sensor, data) | ||
if data: | ||
consumption = data.get('consumptions')[-1] | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
self._state = round(consumption.get('solar') / 1000, 2) | ||
elif self._sensor == 'power_today': | ||
data = self._smappee.get_consumption( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no error handling being done here. This method can return False. |
||
self._location_id, aggregation=3, delta=1440) | ||
_LOGGER.debug("%s %s", self._sensor, data) | ||
if data: | ||
consumption = data.get('consumptions')[-1] | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
self._state = round(consumption.get('consumption') / 1000, 2) | ||
elif self._sensor == 'active_cosfi': | ||
cosfi = self._smappee.active_cosfi() | ||
_LOGGER.debug("%s %s", self._sensor, cosfi) | ||
if cosfi: | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
self._state = round(cosfi, 2) | ||
elif self._sensor == 'current': | ||
current = self._smappee.active_current() | ||
_LOGGER.debug("%s %s", self._sensor, current) | ||
if current: | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
self._state = round(current, 2) | ||
elif self._sensor == 'voltage': | ||
voltage = self._smappee.active_voltage() | ||
_LOGGER.debug("%s %s", self._sensor, voltage) | ||
if voltage: | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
self._state = round(voltage, 3) | ||
elif self._sensor is 'active_power': | ||
data = self._smappee.load_instantaneous() | ||
_LOGGER.debug("%s %s", self._sensor, data) | ||
if data: | ||
value1 = [float(i['value']) for i in data | ||
if i['key'].endswith('phase0ActivePower')] | ||
value2 = [float(i['value']) for i in data | ||
if i['key'].endswith('phase1ActivePower')] | ||
value3 = [float(i['value']) for i in data | ||
if i['key'].endswith('phase2ActivePower')] | ||
active_power = sum(value1 + value2 + value3) / 1000 | ||
self._state = round(active_power, 2) | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
elif self._sensor is 'solar': | ||
data = self._smappee.load_instantaneous() | ||
_LOGGER.debug("%s %s", self._sensor, data) | ||
if data: | ||
value1 = [float(i['value']) for i in data | ||
if i['key'].endswith('phase3ActivePower')] | ||
value2 = [float(i['value']) for i in data | ||
if i['key'].endswith('phase4ActivePower')] | ||
value3 = [float(i['value']) for i in data | ||
if i['key'].endswith('phase5ActivePower')] | ||
power = sum(value1 + value2 + value3) / 1000 | ||
self._state = round(power, 2) | ||
self._timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
else: | ||
return None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this. Does nothing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't call
update
in constructor. Instead addTrue
as second param toadd_devices