added smappee component (#11491)
* added smappee component * Fixed pylint errors and a few use cases when starting up with invalid credentials Added coverage omit * Added support to run only locally Added a few more sensors Added more error handling Better parsing and debug message * fixed smappee switch after local/remote support was added * Smappee - update switches for local support (#3) * Merged with local version * Updated smappy library with the patched one Fixed lint, added merge missing param Fixed missing run for requirements_all.txt Fixed lint * Fixed on/off based on library. Reverted change used for testing stacktrace * Fixed switches to work with both remote and local active Fixed lint Fixed switches Fixed lint * nothing to update per switch as the states are not saved by smappee system * added better error handling for communication errors with smappee * fixed lint errors * fixed comment * fixed lint error * fixed lint error * update smappee module with reviewer comments - update smappy module - cache cloud api requests - added actuator info - updated return states
This commit is contained in:
parent
60148f3e83
commit
72fa170265
5 changed files with 597 additions and 0 deletions
|
@ -208,6 +208,9 @@ omit =
|
|||
homeassistant/components/skybell.py
|
||||
homeassistant/components/*/skybell.py
|
||||
|
||||
homeassistant/components/smappee.py
|
||||
homeassistant/components/*/smappee.py
|
||||
|
||||
homeassistant/components/tado.py
|
||||
homeassistant/components/*/tado.py
|
||||
|
||||
|
|
162
homeassistant/components/sensor/smappee.py
Normal file
162
homeassistant/components/sensor/smappee.py
Normal file
|
@ -0,0 +1,162 @@
|
|||
"""
|
||||
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 timedelta
|
||||
|
||||
from homeassistant.components.smappee import DATA_SMAPPEE
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
DEPENDENCIES = ['smappee']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SENSOR_PREFIX = 'Smappee'
|
||||
SENSOR_TYPES = {
|
||||
'solar':
|
||||
['Solar', 'mdi:white-balance-sunny', 'local', 'W', 'solar'],
|
||||
'active_power':
|
||||
['Active Power', 'mdi:power-plug', 'local', 'W', 'active_power'],
|
||||
'current':
|
||||
['Current', 'mdi:gauge', 'local', 'Amps', 'current'],
|
||||
'voltage':
|
||||
['Voltage', 'mdi:gauge', 'local', 'V', 'voltage'],
|
||||
'active_cosfi':
|
||||
['Power Factor', 'mdi:gauge', 'local', '%', 'active_cosfi'],
|
||||
'alwayson_today':
|
||||
['Always On Today', 'mdi:gauge', 'remote', 'kW', 'alwaysOn'],
|
||||
'solar_today':
|
||||
['Solar Today', 'mdi:white-balance-sunny', 'remote', 'kW', 'solar'],
|
||||
'power_today':
|
||||
['Power Today', 'mdi:power-plug', 'remote', 'kW', 'consumption']
|
||||
}
|
||||
|
||||
SCAN_INTERVAL = 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, True)
|
||||
|
||||
|
||||
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._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]
|
||||
|
||||
@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,
|
||||
self._name)
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon to use in the frontend."""
|
||||
return self._icon
|
||||
|
||||
@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
|
||||
|
||||
@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]
|
||||
return attr
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data from Smappee and update the state."""
|
||||
self._smappee.update()
|
||||
|
||||
if self._sensor in ['alwayson_today', 'solar_today', 'power_today']:
|
||||
data = self._smappee.consumption[self._location_id]
|
||||
if data:
|
||||
consumption = data.get('consumptions')[-1]
|
||||
_LOGGER.debug("%s %s", self._sensor, consumption)
|
||||
value = consumption.get(self._smappe_name)
|
||||
self._state = round(value / 1000, 2)
|
||||
elif self._sensor == 'active_cosfi':
|
||||
cosfi = self._smappee.active_cosfi()
|
||||
_LOGGER.debug("%s %s", self._sensor, cosfi)
|
||||
if cosfi:
|
||||
self._state = round(cosfi, 2)
|
||||
elif self._sensor == 'current':
|
||||
current = self._smappee.active_current()
|
||||
_LOGGER.debug("%s %s", self._sensor, current)
|
||||
if current:
|
||||
self._state = round(current, 2)
|
||||
elif self._sensor == 'voltage':
|
||||
voltage = self._smappee.active_voltage()
|
||||
_LOGGER.debug("%s %s", self._sensor, voltage)
|
||||
if voltage:
|
||||
self._state = round(voltage, 3)
|
||||
elif self._sensor == 'active_power':
|
||||
data = self._smappee.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)
|
||||
elif self._sensor == 'solar':
|
||||
data = self._smappee.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)
|
337
homeassistant/components/smappee.py
Normal file
337
homeassistant/components/smappee.py
Normal file
|
@ -0,0 +1,337 @@
|
|||
"""
|
||||
Support for Smappee energy monitor.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/smappee/
|
||||
"""
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
import re
|
||||
import voluptuous as vol
|
||||
from requests.exceptions import RequestException
|
||||
from homeassistant.const import (
|
||||
CONF_USERNAME, CONF_PASSWORD, CONF_HOST
|
||||
)
|
||||
from homeassistant.util import Throttle
|
||||
from homeassistant.helpers.discovery import load_platform
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
REQUIREMENTS = ['smappy==0.2.15']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NAME = 'Smappee'
|
||||
DEFAULT_HOST_PASSWORD = 'admin'
|
||||
|
||||
CONF_CLIENT_ID = 'client_id'
|
||||
CONF_CLIENT_SECRET = 'client_secret'
|
||||
CONF_HOST_PASSWORD = 'host_password'
|
||||
|
||||
DOMAIN = 'smappee'
|
||||
DATA_SMAPPEE = 'SMAPPEE'
|
||||
|
||||
_SENSOR_REGEX = re.compile(
|
||||
r'(?P<key>([A-Za-z]+))\=' +
|
||||
r'(?P<value>([0-9\.]+))')
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
vol.Inclusive(CONF_CLIENT_ID, 'Server credentials'): cv.string,
|
||||
vol.Inclusive(CONF_CLIENT_SECRET, 'Server credentials'): cv.string,
|
||||
vol.Inclusive(CONF_USERNAME, 'Server credentials'): cv.string,
|
||||
vol.Inclusive(CONF_PASSWORD, 'Server credentials'): cv.string,
|
||||
vol.Optional(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_HOST_PASSWORD, default=DEFAULT_HOST_PASSWORD):
|
||||
cv.string
|
||||
}),
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up the Smapee component."""
|
||||
client_id = config.get(DOMAIN).get(CONF_CLIENT_ID)
|
||||
client_secret = config.get(DOMAIN).get(CONF_CLIENT_SECRET)
|
||||
username = config.get(DOMAIN).get(CONF_USERNAME)
|
||||
password = config.get(DOMAIN).get(CONF_PASSWORD)
|
||||
host = config.get(DOMAIN).get(CONF_HOST)
|
||||
host_password = config.get(DOMAIN).get(CONF_HOST_PASSWORD)
|
||||
|
||||
smappee = Smappee(client_id, client_secret, username,
|
||||
password, host, host_password)
|
||||
|
||||
if not smappee.is_local_active and not smappee.is_remote_active:
|
||||
_LOGGER.error("Neither Smappee server or local component enabled.")
|
||||
return False
|
||||
|
||||
hass.data[DATA_SMAPPEE] = smappee
|
||||
load_platform(hass, 'switch', DOMAIN)
|
||||
load_platform(hass, 'sensor', DOMAIN)
|
||||
return True
|
||||
|
||||
|
||||
class Smappee(object):
|
||||
"""Stores data retrieved from Smappee sensor."""
|
||||
|
||||
def __init__(self, client_id, client_secret, username,
|
||||
password, host, host_password):
|
||||
"""Initialize the data."""
|
||||
import smappy
|
||||
|
||||
self._remote_active = False
|
||||
self._local_active = False
|
||||
if client_id is not None:
|
||||
try:
|
||||
self._smappy = smappy.Smappee(client_id, client_secret)
|
||||
self._smappy.authenticate(username, password)
|
||||
self._remote_active = True
|
||||
except RequestException as error:
|
||||
self._smappy = None
|
||||
_LOGGER.exception(
|
||||
"Smappee server authentication failed (%s)",
|
||||
error)
|
||||
else:
|
||||
_LOGGER.warning("Smappee server component init skipped.")
|
||||
|
||||
if host is not None:
|
||||
try:
|
||||
self._localsmappy = smappy.LocalSmappee(host)
|
||||
self._localsmappy.logon(host_password)
|
||||
self._local_active = True
|
||||
except RequestException as error:
|
||||
self._localsmappy = None
|
||||
_LOGGER.exception(
|
||||
"Local Smappee device authentication failed (%s)",
|
||||
error)
|
||||
else:
|
||||
_LOGGER.warning("Smappee local component init skipped.")
|
||||
|
||||
self.locations = {}
|
||||
self.info = {}
|
||||
self.consumption = {}
|
||||
self.instantaneous = {}
|
||||
|
||||
if self._remote_active or self._local_active:
|
||||
self.update()
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
"""Update data from Smappee API."""
|
||||
if self.is_remote_active:
|
||||
service_locations = self._smappy.get_service_locations() \
|
||||
.get('serviceLocations')
|
||||
for location in service_locations:
|
||||
location_id = location.get('serviceLocationId')
|
||||
if location_id is not None:
|
||||
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.consumption[location_id] = self.get_consumption(
|
||||
location_id, aggregation=3, delta=1440)
|
||||
_LOGGER.debug("Remote consumption %s %s",
|
||||
self.locations,
|
||||
self.consumption[location_id])
|
||||
|
||||
if self.is_local_active:
|
||||
self.local_devices = self.get_switches()
|
||||
_LOGGER.debug("Local switches %s", self.local_devices)
|
||||
|
||||
self.instantaneous = self.load_instantaneous()
|
||||
_LOGGER.debug("Local values %s", self.instantaneous)
|
||||
|
||||
@property
|
||||
def is_remote_active(self):
|
||||
"""Return true if Smappe server is configured and working."""
|
||||
return self._remote_active
|
||||
|
||||
@property
|
||||
def is_local_active(self):
|
||||
"""Return true if Smappe local device is configured and working."""
|
||||
return self._local_active
|
||||
|
||||
def get_switches(self):
|
||||
"""Get switches from local Smappee."""
|
||||
if not self.is_local_active:
|
||||
return
|
||||
|
||||
try:
|
||||
return self._localsmappy.load_command_control_config()
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error getting switches from local Smappee. (%s)",
|
||||
error)
|
||||
|
||||
def get_consumption(self, location_id, aggregation, delta):
|
||||
"""Update data from Smappee."""
|
||||
# Start & End accept epoch (in milliseconds),
|
||||
# datetime and pandas timestamps
|
||||
# Aggregation:
|
||||
# 1 = 5 min values (only available for the last 14 days),
|
||||
# 2 = hourly values,
|
||||
# 3 = daily values,
|
||||
# 4 = monthly values,
|
||||
# 5 = quarterly values
|
||||
if not self.is_remote_active:
|
||||
return
|
||||
|
||||
end = datetime.utcnow()
|
||||
start = end - timedelta(minutes=delta)
|
||||
try:
|
||||
return self._smappy.get_consumption(location_id,
|
||||
start,
|
||||
end,
|
||||
aggregation)
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error getting comsumption from Smappee cloud. (%s)",
|
||||
error)
|
||||
|
||||
def get_sensor_consumption(self, location_id, sensor_id):
|
||||
"""Update data from Smappee."""
|
||||
# Start & End accept epoch (in milliseconds),
|
||||
# datetime and pandas timestamps
|
||||
# Aggregation:
|
||||
# 1 = 5 min values (only available for the last 14 days),
|
||||
# 2 = hourly values,
|
||||
# 3 = daily values,
|
||||
# 4 = monthly values,
|
||||
# 5 = quarterly values
|
||||
if not self.is_remote_active:
|
||||
return
|
||||
|
||||
start = datetime.utcnow() - timedelta(minutes=30)
|
||||
end = datetime.utcnow()
|
||||
try:
|
||||
return self._smappy.get_sensor_consumption(location_id,
|
||||
sensor_id,
|
||||
start,
|
||||
end, 1)
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error getting comsumption from Smappee cloud. (%s)",
|
||||
error)
|
||||
|
||||
def actuator_on(self, location_id, actuator_id,
|
||||
is_remote_switch, duration=None):
|
||||
"""Turn on actuator."""
|
||||
# Duration = 300,900,1800,3600
|
||||
# or any other value for an undetermined period of time.
|
||||
#
|
||||
# The comport plugs have a tendency to ignore the on/off signal.
|
||||
# And because you can't read the status of a plug, it's more
|
||||
# reliable to execute the command twice.
|
||||
try:
|
||||
if is_remote_switch:
|
||||
self._smappy.actuator_on(location_id, actuator_id, duration)
|
||||
self._smappy.actuator_on(location_id, actuator_id, duration)
|
||||
else:
|
||||
self._localsmappy.on_command_control(actuator_id)
|
||||
self._localsmappy.on_command_control(actuator_id)
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error turning actuator on. (%s)",
|
||||
error)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def actuator_off(self, location_id, actuator_id,
|
||||
is_remote_switch, duration=None):
|
||||
"""Turn off actuator."""
|
||||
# Duration = 300,900,1800,3600
|
||||
# or any other value for an undetermined period of time.
|
||||
#
|
||||
# The comport plugs have a tendency to ignore the on/off signal.
|
||||
# And because you can't read the status of a plug, it's more
|
||||
# reliable to execute the command twice.
|
||||
try:
|
||||
if is_remote_switch:
|
||||
self._smappy.actuator_off(location_id, actuator_id, duration)
|
||||
self._smappy.actuator_off(location_id, actuator_id, duration)
|
||||
else:
|
||||
self._localsmappy.off_command_control(actuator_id)
|
||||
self._localsmappy.off_command_control(actuator_id)
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error turning actuator on. (%s)",
|
||||
error)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def active_power(self):
|
||||
"""Get sum of all instantanious active power values from local hub."""
|
||||
if not self.is_local_active:
|
||||
return
|
||||
|
||||
try:
|
||||
return self._localsmappy.active_power()
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error getting data from Local Smappee unit. (%s)",
|
||||
error)
|
||||
|
||||
def active_cosfi(self):
|
||||
"""Get the average of all instantaneous cosfi values."""
|
||||
if not self.is_local_active:
|
||||
return
|
||||
|
||||
try:
|
||||
return self._localsmappy.active_cosfi()
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error getting data from Local Smappee unit. (%s)",
|
||||
error)
|
||||
|
||||
def instantaneous_values(self):
|
||||
"""ReportInstantaneousValues."""
|
||||
if not self.is_local_active:
|
||||
return
|
||||
|
||||
report_instantaneous_values = \
|
||||
self._localsmappy.report_instantaneous_values()
|
||||
|
||||
report_result = \
|
||||
report_instantaneous_values['report'].split('<BR>')
|
||||
properties = {}
|
||||
for lines in report_result:
|
||||
lines_result = lines.split(',')
|
||||
for prop in lines_result:
|
||||
match = _SENSOR_REGEX.search(prop)
|
||||
if match:
|
||||
properties[match.group('key')] = \
|
||||
match.group('value')
|
||||
_LOGGER.debug(properties)
|
||||
return properties
|
||||
|
||||
def active_current(self):
|
||||
"""Get current active Amps."""
|
||||
if not self.is_local_active:
|
||||
return
|
||||
|
||||
properties = self.instantaneous_values()
|
||||
return float(properties['current'])
|
||||
|
||||
def active_voltage(self):
|
||||
"""Get current active Voltage."""
|
||||
if not self.is_local_active:
|
||||
return
|
||||
|
||||
properties = self.instantaneous_values()
|
||||
return float(properties['voltage'])
|
||||
|
||||
def load_instantaneous(self):
|
||||
"""LoadInstantaneous."""
|
||||
if not self.is_local_active:
|
||||
return
|
||||
|
||||
try:
|
||||
return self._localsmappy.load_instantaneous()
|
||||
except RequestException as error:
|
||||
_LOGGER.error(
|
||||
"Error getting data from Local Smappee unit. (%s)",
|
||||
error)
|
92
homeassistant/components/switch/smappee.py
Normal file
92
homeassistant/components/switch/smappee.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
"""
|
||||
Support for interacting with Smappee Comport Plugs.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/switch.smappee/
|
||||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.smappee import DATA_SMAPPEE
|
||||
from homeassistant.components.switch import (SwitchDevice)
|
||||
|
||||
DEPENDENCIES = ['smappee']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ICON = 'mdi:power-plug'
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the Smappee Comfort Plugs."""
|
||||
smappee = hass.data[DATA_SMAPPEE]
|
||||
|
||||
dev = []
|
||||
if smappee.is_remote_active:
|
||||
for location_id in smappee.locations.keys():
|
||||
for items in smappee.info[location_id].get('actuators'):
|
||||
if items.get('name') != '':
|
||||
_LOGGER.debug("Remote actuator %s", items)
|
||||
dev.append(SmappeeSwitch(smappee,
|
||||
items.get('name'),
|
||||
location_id,
|
||||
items.get('id')))
|
||||
elif smappee.is_local_active:
|
||||
for items in smappee.local_devices:
|
||||
_LOGGER.debug("Local actuator %s", items)
|
||||
dev.append(SmappeeSwitch(smappee,
|
||||
items.get('value'),
|
||||
None,
|
||||
items.get('key')))
|
||||
add_devices(dev)
|
||||
|
||||
|
||||
class SmappeeSwitch(SwitchDevice):
|
||||
"""Representation of a Smappee Comport Plug."""
|
||||
|
||||
def __init__(self, smappee, name, location_id, switch_id):
|
||||
"""Initialize a new Smappee Comfort Plug."""
|
||||
self._name = name
|
||||
self._state = False
|
||||
self._smappee = smappee
|
||||
self._location_id = location_id
|
||||
self._switch_id = switch_id
|
||||
self._remoteswitch = True
|
||||
if location_id is None:
|
||||
self._remoteswitch = False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the switch."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if switch is on."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon to use in the frontend."""
|
||||
return ICON
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn on Comport Plug."""
|
||||
if self._smappee.actuator_on(self._location_id, self._switch_id,
|
||||
self._remoteswitch):
|
||||
self._state = True
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn off Comport Plug."""
|
||||
if self._smappee.actuator_off(self._location_id, self._switch_id,
|
||||
self._remoteswitch):
|
||||
self._state = False
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes of the device."""
|
||||
attr = {}
|
||||
if self._remoteswitch:
|
||||
attr['Location Id'] = self._location_id
|
||||
attr['Location Name'] = self._smappee.locations[self._location_id]
|
||||
attr['Switch Id'] = self._switch_id
|
||||
return attr
|
|
@ -1112,6 +1112,9 @@ sleekxmpp==1.3.2
|
|||
# homeassistant.components.sleepiq
|
||||
sleepyq==0.6
|
||||
|
||||
# homeassistant.components.smappee
|
||||
smappy==0.2.15
|
||||
|
||||
# homeassistant.components.raspihats
|
||||
# homeassistant.components.sensor.bh1750
|
||||
# homeassistant.components.sensor.bme280
|
||||
|
|
Loading…
Add table
Reference in a new issue