Skip to content
Snippets Groups Projects
Commit f6d75f2d authored by Ryan Kraus's avatar Ryan Kraus
Browse files

Cleaned up ISY994 light and sensor code to use the same abstract class.

parent 57f27cc9
No related branches found
No related tags found
No related merge requests found
"""
Connects to an ISY-994 controller and loads relevant components to control its devices.
Connects to an ISY-994 controller and loads relevant components to control its
devices. Also contains the base classes for ISY Sensors, Lights, and Switches.
"""
# system imports
import logging
......@@ -14,26 +15,27 @@ from homeassistant.loader import get_component
from homeassistant.helpers import validate_config
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.const import (
CONF_HOST, CONF_USERNAME, CONF_PASSWORD,
EVENT_PLATFORM_DISCOVERED,
CONF_HOST, CONF_USERNAME, CONF_PASSWORD, EVENT_PLATFORM_DISCOVERED,
ATTR_SERVICE, ATTR_DISCOVERED, ATTR_FRIENDLY_NAME)
# homeassistant constants
DOMAIN = "isy994"
DEPENDENCIES = []
DISCOVER_LIGHTS = "isy994.lights"
#DISCOVER_SWITCHES = "isy994.switches"
# DISCOVER_SWITCHES = "isy994.switches"
DISCOVER_SENSORS = "isy994.sensors"
ISY = None
def setup(hass, config):
""" Sets up the ISY994 component. """
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# setup logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
def setup(hass, config):
# pull values from configuration file
if not validate_config(config,
{DOMAIN: [CONF_HOST, CONF_USERNAME, CONF_PASSWORD]}, logger):
if not validate_config(config,
{DOMAIN: [CONF_HOST, CONF_USERNAME, CONF_PASSWORD]},
logger):
return False
else:
user = config[DOMAIN][CONF_USERNAME]
......@@ -47,8 +49,8 @@ def setup(hass, config):
addr = addr.replace('https://', '')
https = True
else:
logger.error('isy994 host value in configuration ' +
'file is invalid.')
logger.error('isy994 host value in configuration ' +
'file is invalid.')
return False
port = host.port
addr = addr.replace(':{}'.format(port), '')
......@@ -64,11 +66,107 @@ def setup(hass, config):
('light', DISCOVER_LIGHTS))):
component = get_component(comp_name)
bootstrap.setup_component(hass, component.DOMAIN, config)
hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{
ATTR_SERVICE: discovery,
ATTR_DISCOVERED: {}
})
hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery,
ATTR_DISCOVERED: {}})
ISY.auto_update = True
return True
class ISYDeviceABC(ToggleEntity):
""" Abstract Class for an ISY device within home assistant. """
_attrs = {}
_onattrs = []
_states = []
_dtype = None
_domain = None
def __init__(self, node):
# setup properties
self.node = node
# track changes
self._changeHandler = self.node.status. \
subscribe('changed', self.onUpdate)
def __del__(self):
""" cleanup subscriptions because it is the right thing to do. """
self._changeHandler.unsubscribe()
@property
def domain(self):
return self._domain
@property
def dtype(self):
if self._dtype in ['analog', 'binary']:
return self._dtype
return 'binary' if self._units is None else 'analog'
@property
def should_poll(self):
return False
@property
def value(self):
""" returns the unclean value from the controller """
return self.node.status._val
@property
def state_attributes(self):
attr = {ATTR_FRIENDLY_NAME: self.name}
for name, prop in self._attrs.items():
attr[name] = getattr(self, prop)
return attr
@property
def unique_id(self):
""" Returns the id of this isy sensor """
return self.node._id
@property
def name(self):
""" Returns the name of the node if any. """
return self.node.name
def update(self):
""" Update state of the sensor. """
# ISY objects are automatically updated by the ISY's event stream
pass
def onUpdate(self, e):
""" Handles the update recieved event. """
self.update_ha_state()
@property
def is_on(self):
return self.value > 0
@property
def is_open(self):
return self.is_on
@property
def state(self):
""" Returns the state of the node. """
if len(self._states) > 0:
return self._states[0] if self.is_on else self._states[1]
return self.value
def turn_on(self, **kwargs):
""" turns the device on """
attrs = [kwargs.get(name) for name in self._onattrs]
self.node.on(*attrs)
def turn_off(self, **kwargs):
""" turns the device off """
self.node.off()
@property
def unit_of_measurement(self):
try:
return self.node.units
except AttributeError:
return None
""" Support for ISY994 sensors. """
""" Support for ISY994 lights. """
# system imports
import logging
# homeassistant imports
from ..isy994 import ISY
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.const import STATE_ON, STATE_OFF
from homeassistant.components.isy994 import ISYDeviceABC, ISY
from homeassistant.components.light import ATTR_BRIGHTNESS
from homeassistant.const import STATE_ON, STATE_OFF
def setup_platform(hass, config, add_devices, discovery_info=None):
""" Sets up the isy994 platform. """
print('************ RUNNING')
logger = logging.getLogger(__name__)
devs = []
# verify connection
......@@ -27,67 +25,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(devs)
class ISYLightDevice(ToggleEntity):
class ISYLightDevice(ISYDeviceABC):
""" represents as isy light within home assistant. """
domain = 'light'
def __init__(self, node):
# setup properties
self.node = node
#self.entity_id = self.domain + '.' + self.name.replace(' ', '_')
# track changes
self._changeHandler = self.node.status. \
subscribe('changed', self.onUpdate)
def __del__(self):
self._changeHandler.unsubscribe()
@property
def should_poll(self):
return False
@property
def dtype(self):
return 'analog'
@property
def value(self):
""" return the integer setting of the light (brightness) """
return self.node.status._val
@property
def is_on(self):
return self.value > 0
@property
def state_attributes(self):
return {ATTR_BRIGHTNESS: self.value}
@property
def unique_id(self):
""" Returns the id of this isy sensor """
return self.node._id
@property
def name(self):
""" Returns the name of the sensor if any. """
return self.node.name
def update(self):
""" Update state of the sensor. """
# ISY objects are automatically updated by the ISY's event stream
pass
def onUpdate(self, e):
self.update_ha_state()
def turn_on(self, **kwargs):
""" turns the device on """
brightness = kwargs.get(ATTR_BRIGHTNESS)
self.node.on(brightness)
def turn_off(self, **kwargs):
""" turns the device off """
self.node.off()
_domain = 'light'
_dtype = 'analog'
_attrs = {ATTR_BRIGHTNESS: 'value'}
_onattrs = [ATTR_BRIGHTNESS]
_states = [STATE_ON, STATE_OFF]
......@@ -3,7 +3,7 @@
import logging
# homeassistant imports
from ..isy994 import ISY
from homeassistant.components.isy994 import ISY, ISYDeviceABC
from homeassistant.helpers.entity import Entity
from homeassistant.const import STATE_OPEN, STATE_CLOSED
......@@ -21,80 +21,25 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if ISY.climate is not None:
for prop in ISY.climate._id2name:
if prop is not None:
devs.append(ISYSensorDevice('ISY.weather.' + prop, prop,
getattr(ISY.climate, prop),
getattr(ISY.climate, prop + '_units')))
node = WeatherPseudoNode('ISY.weather.' + prop, prop,
getattr(ISY.climate, prop),
getattr(ISY.climate, prop + '_units'))
devs.append(ISYSensorDevice(node))
add_devices(devs)
class ISYSensorDevice(Entity):
""" represents a isy sensor within home assistant. """
domain = 'sensor'
class WeatherPseudoNode(object):
""" This class allows weather variable to act as regular nodes. """
def __init__(self, device_id, name, source, units=None):
# setup properties
def __init__(self, device_id, name, status, units=None):
self._id = device_id
self._name = name
self.entity_id = self.domain + '.' + self.name.replace(' ', '_')
self._source = source
self._units = units
# track changes
self._changeHandler = self._source.subscribe('changed', self.onUpdate)
def __del__(self):
self._changeHandler.unsubscribe()
@property
def should_poll(self):
return False
@property
def dtype(self):
return 'binary' if self._units is None else 'analog'
self.name = name
self.status = status
self.units = units
@property
def state(self):
""" Returns the state. """
if self.dtype is 'binary':
return STATE_OPEN if self.is_open >= 255 else STATE_CLOSED
else:
return self.value
@property
def state_attributes(self):
return {}
@property
def unit_of_measurement(self):
return self._units
@property
def unique_id(self):
""" Returns the id of this isy sensor """
return self._id
@property
def name(self):
""" Returns the name of the sensor if any. """
return self._name
def update(self):
""" Update state of the sensor. """
# ISY objects are automatically updated by the ISY's event stream
pass
@property
def is_open(self):
""" True if door is open. """
return self.value >= 255
@property
def value(self):
return self._source._val
class ISYSensorDevice(ISYDeviceABC):
""" represents a isy sensor within home assistant. """
def onUpdate(self, e):
self.update_ha_state()
_domain = 'sensor'
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment