From 321a603bfe5bd843a5fe97942cdbcb2b4250f75f Mon Sep 17 00:00:00 2001 From: badele Date: Sun, 27 Sep 2015 11:13:49 +0200 Subject: [PATCH 01/15] Add a light & switch rfxtrx support --- homeassistant/components/light/rfxtrx.py | 102 ++++++++++++++++++++++ homeassistant/components/rfxtrx.py | 41 +++++++++ homeassistant/components/sensor/rfxtrx.py | 33 ++++--- homeassistant/components/switch/rfxtrx.py | 102 ++++++++++++++++++++++ 4 files changed, 261 insertions(+), 17 deletions(-) create mode 100644 homeassistant/components/light/rfxtrx.py create mode 100644 homeassistant/components/rfxtrx.py create mode 100644 homeassistant/components/switch/rfxtrx.py diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py new file mode 100644 index 00000000000..69ea23a6d4b --- /dev/null +++ b/homeassistant/components/light/rfxtrx.py @@ -0,0 +1,102 @@ +""" +homeassistant.components.light.rfxtrx +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Support for Rfxtrx lights. + +Configuration: + +To use Rfxtrx lights you will need to add the following to your +configuration.yaml file. + +light: + platform: rfxtrx + + devices: + ac09c4f1: Bedroom Light + ac09c4f2: Kitchen Light + ac09c4f3: Bathroom Light + +*Optional* + + # Automatic add new light + automatic_add: True + +""" +import logging +import homeassistant.components.rfxtrx as rfxtrx +from RFXtrx import LightingDevice + +from homeassistant.components.light import Light +from homeassistant.util import slugify + +REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + + 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] + +DOMAIN = "rfxtrx" + +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """ Setup the RFXtrx platform. """ + # Add light from config file + devices = config.get('devices') + for entity_id, entity_name in devices.items(): + if entity_id not in rfxtrx.RFX_DEVICES: + new_light = RfxtrxLight(entity_name, False) + rfxtrx.RFX_DEVICES[entity_id] = new_light + + add_devices_callback(rfxtrx.RFX_DEVICES.values()) + + def light_update(event): + """ Callback for sensor updates from the RFXtrx gateway. """ + if isinstance(event.device, LightingDevice): + entity_id = '%s-%s' % (event.device.type_string.lower(), slugify(event.device.id_string.lower())) + + # Add entity if not exist and the automatic_add is True + if entity_id not in rfxtrx.RFX_DEVICES: + automatic_add = config.get('automatic_add', False) + if automatic_add: + new_light = RfxtrxLight(entity_id, False) + rfxtrx.RFX_DEVICES[entity_id] = new_light + add_devices_callback([new_light]) + + # Check if entity exists (previous automatic added) + if entity_id in rfxtrx.RFX_DEVICES: + if event.values['Command'] == 'On' or event.values['Command'] == 'Off': + if event.values['Command'] == 'On': + rfxtrx.RFX_DEVICES[entity_id].turn_on() + else: + rfxtrx.RFX_DEVICES[entity_id].turn_off() + + if light_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS: + rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(light_update) + + +class RfxtrxLight(Light): + """ Provides a demo switch. """ + def __init__(self, name, state): + self._name = name + self._state = state + + @property + def should_poll(self): + """ No polling needed for a demo light. """ + return False + + @property + def name(self): + """ Returns the name of the device if any. """ + return self._name + + @property + def is_on(self): + """ True if device is on. """ + return self._state + + def turn_on(self, **kwargs): + """ Turn the device on. """ + self._state = True + self.update_ha_state() + + def turn_off(self, **kwargs): + """ Turn the device off. """ + self._state = False + self.update_ha_state() \ No newline at end of file diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py new file mode 100644 index 00000000000..788778debeb --- /dev/null +++ b/homeassistant/components/rfxtrx.py @@ -0,0 +1,41 @@ +""" +homeassistant.components.rfxtrx +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Connects Home Assistant to a RFXtrx device. +""" + +import logging + +DEPENDENCIES = [] +REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + + 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] + +DOMAIN = "rfxtrx" +CONF_DEVICE = 'device' +RECEIVED_EVT_SUBSCRIBERS = [] +RFX_DEVICES = {} + +def setup(hass, config): + """ Setup the Rfxtrx component. """ + + # Init logger + logger = logging.getLogger(__name__) + + # Declare the Handle event + def handle_receive(event): + """ Callback all subscribers for RFXtrx gateway. """ + for subscriber in RECEIVED_EVT_SUBSCRIBERS: + subscriber(event) + + # Try to load the RFXtrx module + try: + import RFXtrx as rfxtrxmod + except ImportError: + logger.exception("Failed to import rfxtrx") + return False + + # Init the rfxtrx module + device = config[DOMAIN][CONF_DEVICE] + rfxtrxmod.Core(device, handle_receive) + + return True \ No newline at end of file diff --git a/homeassistant/components/sensor/rfxtrx.py b/homeassistant/components/sensor/rfxtrx.py index 4cb8a939d5e..7dc6496555c 100644 --- a/homeassistant/components/sensor/rfxtrx.py +++ b/homeassistant/components/sensor/rfxtrx.py @@ -24,6 +24,9 @@ from collections import OrderedDict from homeassistant.const import (TEMP_CELCIUS) from homeassistant.helpers.entity import Entity +import homeassistant.components.rfxtrx as rfxtrx +from RFXtrx import SensorEvent +from homeassistant.util import slugify REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] @@ -36,7 +39,7 @@ DATA_TYPES = OrderedDict([ ('Rain rate', '')]) -def setup_platform(hass, config, add_devices, discovery_info=None): +def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup the RFXtrx platform. """ logger = logging.getLogger(__name__) @@ -44,23 +47,19 @@ def setup_platform(hass, config, add_devices, discovery_info=None): def sensor_update(event): """ Callback for sensor updates from the RFXtrx gateway. """ - if event.device.id_string in sensors: - sensors[event.device.id_string].event = event - else: - logger.info("adding new sensor: %s", event.device.type_string) - new_sensor = RfxtrxSensor(event) - sensors[event.device.id_string] = new_sensor - add_devices([new_sensor]) - try: - import RFXtrx as rfxtrx - except ImportError: - logger.exception( - "Failed to import rfxtrx") - return False - - device = config.get("device", "") - rfxtrx.Core(device, sensor_update) + if isinstance(event.device, SensorEvent): + entity_id = '%s-%s' % (event.device.type_string.lower(), slugify(event.device.id_string.lower())) + if entity_id in rfxtrx.RFX_DEVICES: + rfxtrx.RFX_DEVICES[entity_id].event = event + else: + automatic_add = config.get('automatic_add', False) + if automatic_add: + new_light = RfxtrxSensor(entity_id, False) + rfxtrx.RFX_DEVICES[entity_id] = new_light + add_devices_callback([new_light]) + if sensor_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS: + rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(sensor_update) class RfxtrxSensor(Entity): """ Represents a RFXtrx sensor. """ diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py new file mode 100644 index 00000000000..a7b39655249 --- /dev/null +++ b/homeassistant/components/switch/rfxtrx.py @@ -0,0 +1,102 @@ +""" +homeassistant.components.switch.rfxtrx +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Support for Rfxtrx switch. + +Configuration: + +To use Rfxtrx switchs you will need to add the following to your +configuration.yaml file. + +switch: + platform: rfxtrx + + devices: + ac09c4f1: Bedroom Door + ac09c4f2: Kitchen Door + ac09c4f3: Bathroom Door + +*Optional* + + # Automatic add new switch + automatic_add: True + +""" +import logging +import homeassistant.components.rfxtrx as rfxtrx +from RFXtrx import LightingDevice + +from homeassistant.components.switch import SwitchDevice +from homeassistant.util import slugify + +REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + + 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] + +DOMAIN = "rfxtrx" + +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """ Setup the RFXtrx platform. """ + # Add switch from config file + devices = config.get('devices') + for entity_id, entity_name in devices.items(): + if entity_id not in rfxtrx.RFX_DEVICES: + new_switch = RfxtrxSwitch(entity_name, False) + rfxtrx.RFX_DEVICES[entity_id] = new_switch + + add_devices_callback(rfxtrx.RFX_DEVICES.values()) + + def switch_update(event): + """ Callback for sensor updates from the RFXtrx gateway. """ + if isinstance(event.device, LightingDevice): + entity_id = '%s-%s' % (event.device.type_string.lower(), slugify(event.device.id_string.lower())) + + # Add entity if not exist and the automatic_add is True + if entity_id not in rfxtrx.RFX_DEVICES: + automatic_add = config.get('automatic_add', False) + if automatic_add: + new_switch = RfxtrxSwitch(entity_id, False) + rfxtrx.RFX_DEVICES[entity_id] = new_switch + add_devices_callback([new_switch]) + + # Check if entity exists (previous automatic added) + if entity_id in rfxtrx.RFX_DEVICES: + if event.values['Command'] == 'On' or event.values['Command'] == 'Off': + if event.values['Command'] == 'On': + rfxtrx.RFX_DEVICES[entity_id].turn_on() + else: + rfxtrx.RFX_DEVICES[entity_id].turn_off() + + if switch_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS: + rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(switch_update) + + +class RfxtrxSwitch(SwitchDevice): + """ Provides a demo switch. """ + def __init__(self, name, state): + self._name = name + self._state = state + + @property + def should_poll(self): + """ No polling needed for a demo switch. """ + return False + + @property + def name(self): + """ Returns the name of the device if any. """ + return self._name + + @property + def is_on(self): + """ True if device is on. """ + return self._state + + def turn_on(self, **kwargs): + """ Turn the device on. """ + self._state = True + self.update_ha_state() + + def turn_off(self, **kwargs): + """ Turn the device off. """ + self._state = False + self.update_ha_state() \ No newline at end of file From 174aeacd768bdbf85e6f9454f358e766a49d8f83 Mon Sep 17 00:00:00 2001 From: badele Date: Sun, 27 Sep 2015 23:51:19 +0200 Subject: [PATCH 02/15] Fix duplicate devices insertion --- homeassistant/components/light/rfxtrx.py | 10 ++++++++-- homeassistant/components/switch/rfxtrx.py | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index 69ea23a6d4b..ed9c8f99dfc 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -36,24 +36,30 @@ DOMAIN = "rfxtrx" def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup the RFXtrx platform. """ + logger = logging.getLogger(__name__) + # Add light from config file + lights = [] devices = config.get('devices') for entity_id, entity_name in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: + logger.info("Add %s rfxtrx.light" % entity_name) new_light = RfxtrxLight(entity_name, False) rfxtrx.RFX_DEVICES[entity_id] = new_light + lights.append(new_light) - add_devices_callback(rfxtrx.RFX_DEVICES.values()) + add_devices_callback(lights) def light_update(event): """ Callback for sensor updates from the RFXtrx gateway. """ if isinstance(event.device, LightingDevice): - entity_id = '%s-%s' % (event.device.type_string.lower(), slugify(event.device.id_string.lower())) + entity_id = slugify(event.device.id_string.lower()) # Add entity if not exist and the automatic_add is True if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: + logger.info("Automatic add %s rfxtrx.light" % entity_name) new_light = RfxtrxLight(entity_id, False) rfxtrx.RFX_DEVICES[entity_id] = new_light add_devices_callback([new_light]) diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index a7b39655249..3f2b957cc25 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -36,24 +36,30 @@ DOMAIN = "rfxtrx" def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup the RFXtrx platform. """ + logger = logging.getLogger(__name__) + # Add switch from config file + switchs = [] devices = config.get('devices') for entity_id, entity_name in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: + logger.info("Add %s rfxtrx.switch" % entity_name) new_switch = RfxtrxSwitch(entity_name, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch + switchs.append(new_switch) - add_devices_callback(rfxtrx.RFX_DEVICES.values()) + add_devices_callback(switchs) def switch_update(event): """ Callback for sensor updates from the RFXtrx gateway. """ if isinstance(event.device, LightingDevice): - entity_id = '%s-%s' % (event.device.type_string.lower(), slugify(event.device.id_string.lower())) + entity_id = slugify(event.device.id_string.lower()) # Add entity if not exist and the automatic_add is True if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: + logger.info("Automatic add %s rfxtrx.switch" % entity_name) new_switch = RfxtrxSwitch(entity_id, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch add_devices_callback([new_switch]) From d64f0ddd412b4a8bbcbe0ea5cc07df2355ad1633 Mon Sep 17 00:00:00 2001 From: badele Date: Tue, 29 Sep 2015 08:20:25 +0200 Subject: [PATCH 03/15] Refactoring the code for pylint & flake test --- homeassistant/components/light/rfxtrx.py | 12 +++++++----- homeassistant/components/rfxtrx.py | 9 ++++----- homeassistant/components/sensor/rfxtrx.py | 22 ++++++++++++---------- homeassistant/components/switch/rfxtrx.py | 12 +++++++----- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index ed9c8f99dfc..ad3fbb03d4a 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -33,17 +33,18 @@ REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] DOMAIN = "rfxtrx" +_LOGGER = logging.getLogger(__name__) + def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup the RFXtrx platform. """ - logger = logging.getLogger(__name__) # Add light from config file lights = [] devices = config.get('devices') for entity_id, entity_name in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: - logger.info("Add %s rfxtrx.light" % entity_name) + _LOGGER.info("Add %s rfxtrx.light", entity_name) new_light = RfxtrxLight(entity_name, False) rfxtrx.RFX_DEVICES[entity_id] = new_light lights.append(new_light) @@ -59,14 +60,15 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: - logger.info("Automatic add %s rfxtrx.light" % entity_name) + _LOGGER.info("Automatic add %s rfxtrx.light", entity_id) new_light = RfxtrxLight(entity_id, False) rfxtrx.RFX_DEVICES[entity_id] = new_light add_devices_callback([new_light]) # Check if entity exists (previous automatic added) if entity_id in rfxtrx.RFX_DEVICES: - if event.values['Command'] == 'On' or event.values['Command'] == 'Off': + if event.values['Command'] == 'On'\ + or event.values['Command'] == 'Off': if event.values['Command'] == 'On': rfxtrx.RFX_DEVICES[entity_id].turn_on() else: @@ -105,4 +107,4 @@ class RfxtrxLight(Light): def turn_off(self, **kwargs): """ Turn the device off. """ self._state = False - self.update_ha_state() \ No newline at end of file + self.update_ha_state() diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index 788778debeb..d72a9fe02ec 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -14,13 +14,12 @@ DOMAIN = "rfxtrx" CONF_DEVICE = 'device' RECEIVED_EVT_SUBSCRIBERS = [] RFX_DEVICES = {} +_LOGGER = logging.getLogger(__name__) + def setup(hass, config): """ Setup the Rfxtrx component. """ - # Init logger - logger = logging.getLogger(__name__) - # Declare the Handle event def handle_receive(event): """ Callback all subscribers for RFXtrx gateway. """ @@ -31,11 +30,11 @@ def setup(hass, config): try: import RFXtrx as rfxtrxmod except ImportError: - logger.exception("Failed to import rfxtrx") + _LOGGER.exception("Failed to import rfxtrx") return False # Init the rfxtrx module device = config[DOMAIN][CONF_DEVICE] rfxtrxmod.Core(device, handle_receive) - return True \ No newline at end of file + return True diff --git a/homeassistant/components/sensor/rfxtrx.py b/homeassistant/components/sensor/rfxtrx.py index 7dc6496555c..625fd50de84 100644 --- a/homeassistant/components/sensor/rfxtrx.py +++ b/homeassistant/components/sensor/rfxtrx.py @@ -37,30 +37,32 @@ DATA_TYPES = OrderedDict([ ('Barometer', ''), ('Wind direction', ''), ('Rain rate', '')]) +_LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup the RFXtrx platform. """ - logger = logging.getLogger(__name__) - - sensors = {} # keep track of sensors added to HA def sensor_update(event): """ Callback for sensor updates from the RFXtrx gateway. """ if isinstance(event.device, SensorEvent): - entity_id = '%s-%s' % (event.device.type_string.lower(), slugify(event.device.id_string.lower())) - if entity_id in rfxtrx.RFX_DEVICES: - rfxtrx.RFX_DEVICES[entity_id].event = event - else: + entity_id = slugify(event.device.id_string.lower()) + + # Add entity if not exist and the automatic_add is True + if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: - new_light = RfxtrxSensor(entity_id, False) - rfxtrx.RFX_DEVICES[entity_id] = new_light - add_devices_callback([new_light]) + _LOGGER.info("Automatic add %s rfxtrx.light", entity_id) + new_sensor = RfxtrxSensor(event) + rfxtrx.RFX_DEVICES[entity_id] = new_sensor + add_devices_callback([new_sensor]) + else: + rfxtrx.RFX_DEVICES[entity_id].event = event if sensor_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS: rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(sensor_update) + class RfxtrxSensor(Entity): """ Represents a RFXtrx sensor. """ diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index 3f2b957cc25..b64d0d9bf7a 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -33,17 +33,18 @@ REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] DOMAIN = "rfxtrx" +_LOGGER = logging.getLogger(__name__) + def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup the RFXtrx platform. """ - logger = logging.getLogger(__name__) # Add switch from config file switchs = [] devices = config.get('devices') for entity_id, entity_name in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: - logger.info("Add %s rfxtrx.switch" % entity_name) + _LOGGER.info("Add %s rfxtrx.switch", entity_name) new_switch = RfxtrxSwitch(entity_name, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch switchs.append(new_switch) @@ -59,14 +60,15 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: - logger.info("Automatic add %s rfxtrx.switch" % entity_name) + _LOGGER.info("Automatic add %s rfxtrx.switch", entity_id) new_switch = RfxtrxSwitch(entity_id, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch add_devices_callback([new_switch]) # Check if entity exists (previous automatic added) if entity_id in rfxtrx.RFX_DEVICES: - if event.values['Command'] == 'On' or event.values['Command'] == 'Off': + if event.values['Command'] == 'On'\ + or event.values['Command'] == 'Off': if event.values['Command'] == 'On': rfxtrx.RFX_DEVICES[entity_id].turn_on() else: @@ -105,4 +107,4 @@ class RfxtrxSwitch(SwitchDevice): def turn_off(self, **kwargs): """ Turn the device off. """ self._state = False - self.update_ha_state() \ No newline at end of file + self.update_ha_state() From cc47e39006bcacf1bb1d3e6c227d0586aa0ad079 Mon Sep 17 00:00:00 2001 From: badele Date: Tue, 29 Sep 2015 22:47:22 +0200 Subject: [PATCH 04/15] Add send capability --- homeassistant/components/light/rfxtrx.py | 23 +++++++++++++++++------ homeassistant/components/rfxtrx.py | 5 +++-- homeassistant/components/switch/rfxtrx.py | 21 +++++++++++++++------ 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index ad3fbb03d4a..190aae55da6 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -42,10 +42,10 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): # Add light from config file lights = [] devices = config.get('devices') - for entity_id, entity_name in devices.items(): + for entity_id, entity_info in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: - _LOGGER.info("Add %s rfxtrx.light", entity_name) - new_light = RfxtrxLight(entity_name, False) + _LOGGER.info("Add %s rfxtrx.light", entity_info['name']) + new_light = RfxtrxLight(entity_info['name'], None, False) rfxtrx.RFX_DEVICES[entity_id] = new_light lights.append(new_light) @@ -60,8 +60,12 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: - _LOGGER.info("Automatic add %s rfxtrx.light", entity_id) - new_light = RfxtrxLight(entity_id, False) + _LOGGER.info("Automatic add %s rfxtrx.light (class: %s subtype: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype + ) + new_light = RfxtrxLight(entity_id, event, False) rfxtrx.RFX_DEVICES[entity_id] = new_light add_devices_callback([new_light]) @@ -80,8 +84,9 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class RfxtrxLight(Light): """ Provides a demo switch. """ - def __init__(self, name, state): + def __init__(self, name, event, state): self._name = name + self._event = event self._state = state @property @@ -101,10 +106,16 @@ class RfxtrxLight(Light): def turn_on(self, **kwargs): """ Turn the device on. """ + + self._event.device.send_on(rfxtrx.RFXOBJECT.transport) + self._state = True self.update_ha_state() def turn_off(self, **kwargs): """ Turn the device off. """ + + self._event.device.send_off(rfxtrx.RFXOBJECT.transport) + self._state = False self.update_ha_state() diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index d72a9fe02ec..afd74c907d1 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -15,7 +15,7 @@ CONF_DEVICE = 'device' RECEIVED_EVT_SUBSCRIBERS = [] RFX_DEVICES = {} _LOGGER = logging.getLogger(__name__) - +RFXOBJECT = None def setup(hass, config): """ Setup the Rfxtrx component. """ @@ -34,7 +34,8 @@ def setup(hass, config): return False # Init the rfxtrx module + global RFXOBJECT device = config[DOMAIN][CONF_DEVICE] - rfxtrxmod.Core(device, handle_receive) + RFXOBJECT = rfxtrxmod.Core(device, handle_receive) return True diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index b64d0d9bf7a..cdc7f64f360 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -42,10 +42,10 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): # Add switch from config file switchs = [] devices = config.get('devices') - for entity_id, entity_name in devices.items(): + for entity_id, entity_info in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: - _LOGGER.info("Add %s rfxtrx.switch", entity_name) - new_switch = RfxtrxSwitch(entity_name, False) + _LOGGER.info("Add %s rfxtrx.switch", entity_info['name']) + new_switch = RfxtrxSwitch(entity_info['name'], None, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch switchs.append(new_switch) @@ -60,8 +60,12 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: - _LOGGER.info("Automatic add %s rfxtrx.switch", entity_id) - new_switch = RfxtrxSwitch(entity_id, False) + _LOGGER.info("Automatic add %s rfxtrx.switch (class: %s subtype: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype + ) + new_switch = RfxtrxSwitch(entity_id, event, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch add_devices_callback([new_switch]) @@ -80,8 +84,9 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class RfxtrxSwitch(SwitchDevice): """ Provides a demo switch. """ - def __init__(self, name, state): + def __init__(self, name, event, state): self._name = name + self._event = event self._state = state @property @@ -101,10 +106,14 @@ class RfxtrxSwitch(SwitchDevice): def turn_on(self, **kwargs): """ Turn the device on. """ + self._event.device.send_on(rfxtrx.RFXOBJECT.transport) + self._state = True self.update_ha_state() def turn_off(self, **kwargs): """ Turn the device off. """ + self._event.device.send_off(rfxtrx.RFXOBJECT.transport) + self._state = False self.update_ha_state() From db509ccf181a2488815ace2c663811dff938d12c Mon Sep 17 00:00:00 2001 From: badele Date: Fri, 2 Oct 2015 22:39:30 +0200 Subject: [PATCH 05/15] Add a light & switch rfxtrx sender capability --- homeassistant/components/light/rfxtrx.py | 31 +++++++++------- homeassistant/components/rfxtrx.py | 45 ++++++++++++++++++++++- homeassistant/components/sensor/rfxtrx.py | 2 +- homeassistant/components/switch/rfxtrx.py | 24 +++++++----- 4 files changed, 78 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index 190aae55da6..d4008682c4c 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -24,7 +24,7 @@ light: """ import logging import homeassistant.components.rfxtrx as rfxtrx -from RFXtrx import LightingDevice +import RFXtrx as rfxtrxmod from homeassistant.components.light import Light from homeassistant.util import slugify @@ -38,22 +38,23 @@ _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup the RFXtrx platform. """ - # Add light from config file lights = [] - devices = config.get('devices') - for entity_id, entity_info in devices.items(): - if entity_id not in rfxtrx.RFX_DEVICES: - _LOGGER.info("Add %s rfxtrx.light", entity_info['name']) - new_light = RfxtrxLight(entity_info['name'], None, False) - rfxtrx.RFX_DEVICES[entity_id] = new_light - lights.append(new_light) + devices = config.get('devices', None) + if devices: + for entity_id, entity_info in devices.items(): + if entity_id not in rfxtrx.RFX_DEVICES: + _LOGGER.info("Add %s rfxtrx.light", entity_info['name']) + rfxobject = rfxtrx.getRFXObject(entity_info['packetid']) + new_light = RfxtrxLight(entity_info['name'], rfxobject, False) + rfxtrx.RFX_DEVICES[entity_id] = new_light + lights.append(new_light) add_devices_callback(lights) def light_update(event): """ Callback for sensor updates from the RFXtrx gateway. """ - if isinstance(event.device, LightingDevice): + if isinstance(event.device, rfxtrxmod.LightingDevice): entity_id = slugify(event.device.id_string.lower()) # Add entity if not exist and the automatic_add is True @@ -65,7 +66,9 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): event.device.__class__.__name__, event.device.subtype ) - new_light = RfxtrxLight(entity_id, event, False) + packet_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%(entity_id)s : %(packet_id)s" % locals() + new_light = RfxtrxLight(entity_name, event, False) rfxtrx.RFX_DEVICES[entity_id] = new_light add_devices_callback([new_light]) @@ -107,7 +110,8 @@ class RfxtrxLight(Light): def turn_on(self, **kwargs): """ Turn the device on. """ - self._event.device.send_on(rfxtrx.RFXOBJECT.transport) + if self._event: + self._event.device.send_on(rfxtrx.RFXOBJECT.transport) self._state = True self.update_ha_state() @@ -115,7 +119,8 @@ class RfxtrxLight(Light): def turn_off(self, **kwargs): """ Turn the device off. """ - self._event.device.send_off(rfxtrx.RFXOBJECT.transport) + if self._event: + self._event.device.send_off(rfxtrx.RFXOBJECT.transport) self._state = False self.update_ha_state() diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index afd74c907d1..d4eb379b04f 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -4,6 +4,24 @@ homeassistant.components.rfxtrx Connects Home Assistant to a RFXtrx device. """ +""" +homeassistant.components.rfxtrx +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Connects Home Assistant to a RFXtrx device. + +Configuration: + +To use Rfxtrx device you will need to add the following to your +configuration.yaml file. + +rfxtrx: + device: /dev/serial/by-id/usb-RFXCOM_RFXtrx433_A1YVC1P0-if00-port0 + +*Optional* + + debug: True + +""" import logging DEPENDENCIES = [] @@ -12,6 +30,7 @@ REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + DOMAIN = "rfxtrx" CONF_DEVICE = 'device' +CONF_DEBUG = 'debug' RECEIVED_EVT_SUBSCRIBERS = [] RFX_DEVICES = {} _LOGGER = logging.getLogger(__name__) @@ -23,6 +42,7 @@ def setup(hass, config): # Declare the Handle event def handle_receive(event): """ Callback all subscribers for RFXtrx gateway. """ + for subscriber in RECEIVED_EVT_SUBSCRIBERS: subscriber(event) @@ -35,7 +55,30 @@ def setup(hass, config): # Init the rfxtrx module global RFXOBJECT + device = config[DOMAIN][CONF_DEVICE] - RFXOBJECT = rfxtrxmod.Core(device, handle_receive) + try: + debug = config[DOMAIN][CONF_DEBUG] + except KeyError: + debug = False + + RFXOBJECT = rfxtrxmod.Core(device, handle_receive, debug=debug) return True + +def getRFXObject(packetid): + """ return the RFXObject with the packetid""" + binarypacket = bytearray.fromhex(packetid) + + pkt = rfxtrxmod.lowlevel.parse(binarypacket) + if pkt is not None: + if isinstance(pkt, rfxtrxmod.lowlevel.SensorPacket): + obj = rfxtrxmod.SensorEvent(pkt) + elif isinstance(pkt, rfxtrxmod.lowlevel.Status): + obj = rfxtrxmod.StatusEvent(pkt) + else: + obj = rfxtrxmod.ControlEvent(pkt) + + return obj + + return None diff --git a/homeassistant/components/sensor/rfxtrx.py b/homeassistant/components/sensor/rfxtrx.py index 625fd50de84..d0514c93a51 100644 --- a/homeassistant/components/sensor/rfxtrx.py +++ b/homeassistant/components/sensor/rfxtrx.py @@ -50,7 +50,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): # Add entity if not exist and the automatic_add is True if entity_id not in rfxtrx.RFX_DEVICES: - automatic_add = config.get('automatic_add', False) + automatic_add = config.get('automatic_add', True) if automatic_add: _LOGGER.info("Automatic add %s rfxtrx.light", entity_id) new_sensor = RfxtrxSensor(event) diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index cdc7f64f360..d13e298f1b7 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -42,12 +42,14 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): # Add switch from config file switchs = [] devices = config.get('devices') - for entity_id, entity_info in devices.items(): - if entity_id not in rfxtrx.RFX_DEVICES: - _LOGGER.info("Add %s rfxtrx.switch", entity_info['name']) - new_switch = RfxtrxSwitch(entity_info['name'], None, False) - rfxtrx.RFX_DEVICES[entity_id] = new_switch - switchs.append(new_switch) + if devices: + for entity_id, entity_info in devices.items(): + if entity_id not in rfxtrx.RFX_DEVICES: + _LOGGER.info("Add %s rfxtrx.switch", entity_info['name']) + rfxobject = rfxtrx.getRFXObject(entity_info['packetid']) + new_switch = RfxtrxSwitch(entity_info['name'], rfxobject, False) + rfxtrx.RFX_DEVICES[entity_id] = new_switch + switchs.append(new_switch) add_devices_callback(switchs) @@ -65,7 +67,9 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): event.device.__class__.__name__, event.device.subtype ) - new_switch = RfxtrxSwitch(entity_id, event, False) + packet_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%(entity_id)s : %(packet_id)s" % locals() + new_switch = RfxtrxSwitch(entity_name, event, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch add_devices_callback([new_switch]) @@ -106,14 +110,16 @@ class RfxtrxSwitch(SwitchDevice): def turn_on(self, **kwargs): """ Turn the device on. """ - self._event.device.send_on(rfxtrx.RFXOBJECT.transport) + if self._event: + self._event.device.send_on(rfxtrx.RFXOBJECT.transport) self._state = True self.update_ha_state() def turn_off(self, **kwargs): """ Turn the device off. """ - self._event.device.send_off(rfxtrx.RFXOBJECT.transport) + if self._event: + self._event.device.send_off(rfxtrx.RFXOBJECT.transport) self._state = False self.update_ha_state() From 7f71706f08122e309ff04bf6e765513bcfde3658 Mon Sep 17 00:00:00 2001 From: badele Date: Sat, 3 Oct 2015 11:26:18 +0200 Subject: [PATCH 06/15] Log RFXCOM events --- homeassistant/components/rfxtrx.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index d4eb379b04f..2ec4fd3d25d 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -23,6 +23,7 @@ rfxtrx: """ import logging +from homeassistant.util import slugify DEPENDENCIES = [] REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + @@ -43,6 +44,13 @@ def setup(hass, config): def handle_receive(event): """ Callback all subscribers for RFXtrx gateway. """ + # Log RFXCOM event + entity_id = slugify(event.device.id_string.lower()) + packet_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%(entity_id)s : %(packet_id)s" % locals() + _LOGGER.info("Receive RFXCOM event from %s => %s" % (event.device, entity_name)) + + # Callback to HA registered components for subscriber in RECEIVED_EVT_SUBSCRIBERS: subscriber(event) @@ -68,6 +76,12 @@ def setup(hass, config): def getRFXObject(packetid): """ return the RFXObject with the packetid""" + try: + import RFXtrx as rfxtrxmod + except ImportError: + _LOGGER.exception("Failed to import rfxtrx") + return False + binarypacket = bytearray.fromhex(packetid) pkt = rfxtrxmod.lowlevel.parse(binarypacket) From 6d53944fa1f1c0fdb743f748ac85fbb59c6d1a72 Mon Sep 17 00:00:00 2001 From: Alan Bowman Date: Sun, 4 Oct 2015 20:28:11 +0100 Subject: [PATCH 07/15] Support RGB colors --- homeassistant/components/light/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 8d09910093b..c1b1579b4b5 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -246,6 +246,7 @@ def setup(hass, config): rgb_color = dat.get(ATTR_RGB_COLOR) if len(rgb_color) == 3: + params[ATTR_RGB_COLOR] = [int(val) for val in rgb_color] params[ATTR_XY_COLOR] = \ color_util.color_RGB_to_xy(int(rgb_color[0]), int(rgb_color[1]), From 32f1791c5ae50ba5ff2fcad3b4c614f7ae07ed12 Mon Sep 17 00:00:00 2001 From: badele Date: Tue, 6 Oct 2015 08:44:15 +0200 Subject: [PATCH 08/15] Check flake & pylint style --- homeassistant/components/light/rfxtrx.py | 15 ++++++++------- homeassistant/components/rfxtrx.py | 15 ++++++--------- homeassistant/components/switch/rfxtrx.py | 21 +++++++++++---------- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index d4008682c4c..7c8bdb7a93a 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -45,7 +45,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): for entity_id, entity_info in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: _LOGGER.info("Add %s rfxtrx.light", entity_info['name']) - rfxobject = rfxtrx.getRFXObject(entity_info['packetid']) + rfxobject = rfxtrx.get_rfx_object(entity_info['packetid']) new_light = RfxtrxLight(entity_info['name'], rfxobject, False) rfxtrx.RFX_DEVICES[entity_id] = new_light lights.append(new_light) @@ -61,13 +61,14 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: - _LOGGER.info("Automatic add %s rfxtrx.light (class: %s subtype: %s)", - entity_id, - event.device.__class__.__name__, - event.device.subtype + _LOGGER.info( + "Automatic add %s rfxtrx.light (Class: %s Sub: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype ) - packet_id = "".join("{0:02x}".format(x) for x in event.data) - entity_name = "%(entity_id)s : %(packet_id)s" % locals() + pkt_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%s : %s" % (entity_id, pkt_id) new_light = RfxtrxLight(entity_name, event, False) rfxtrx.RFX_DEVICES[entity_id] = new_light add_devices_callback([new_light]) diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index 2ec4fd3d25d..0c3f377150b 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -1,9 +1,3 @@ -""" -homeassistant.components.rfxtrx -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Connects Home Assistant to a RFXtrx device. -""" - """ homeassistant.components.rfxtrx ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -37,6 +31,7 @@ RFX_DEVICES = {} _LOGGER = logging.getLogger(__name__) RFXOBJECT = None + def setup(hass, config): """ Setup the Rfxtrx component. """ @@ -47,8 +42,9 @@ def setup(hass, config): # Log RFXCOM event entity_id = slugify(event.device.id_string.lower()) packet_id = "".join("{0:02x}".format(x) for x in event.data) - entity_name = "%(entity_id)s : %(packet_id)s" % locals() - _LOGGER.info("Receive RFXCOM event from %s => %s" % (event.device, entity_name)) + entity_name = "%s : %s" % (entity_id, packet_id) + _LOGGER.info("Receive RFXCOM event from %s => %s", + event.device, entity_name) # Callback to HA registered components for subscriber in RECEIVED_EVT_SUBSCRIBERS: @@ -74,7 +70,8 @@ def setup(hass, config): return True -def getRFXObject(packetid): + +def get_rfx_object(packetid): """ return the RFXObject with the packetid""" try: import RFXtrx as rfxtrxmod diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index d13e298f1b7..7eefc6fb229 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -46,10 +46,10 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): for entity_id, entity_info in devices.items(): if entity_id not in rfxtrx.RFX_DEVICES: _LOGGER.info("Add %s rfxtrx.switch", entity_info['name']) - rfxobject = rfxtrx.getRFXObject(entity_info['packetid']) - new_switch = RfxtrxSwitch(entity_info['name'], rfxobject, False) - rfxtrx.RFX_DEVICES[entity_id] = new_switch - switchs.append(new_switch) + rfxobject = rfxtrx.get_rfx_object(entity_info['packetid']) + newswitch = RfxtrxSwitch(entity_info['name'], rfxobject, False) + rfxtrx.RFX_DEVICES[entity_id] = newswitch + switchs.append(newswitch) add_devices_callback(switchs) @@ -62,13 +62,14 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) if automatic_add: - _LOGGER.info("Automatic add %s rfxtrx.switch (class: %s subtype: %s)", - entity_id, - event.device.__class__.__name__, - event.device.subtype + _LOGGER.info( + "Automatic add %s rfxtrx.switch (Class: %s Sub: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype ) - packet_id = "".join("{0:02x}".format(x) for x in event.data) - entity_name = "%(entity_id)s : %(packet_id)s" % locals() + pkt_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%s : %s" % (entity_id, pkt_id) new_switch = RfxtrxSwitch(entity_name, event, False) rfxtrx.RFX_DEVICES[entity_id] = new_switch add_devices_callback([new_switch]) From 047cff6596f50b29b3885eb88a44c91627645775 Mon Sep 17 00:00:00 2001 From: Alan Bowman Date: Tue, 29 Sep 2015 21:32:28 +0100 Subject: [PATCH 09/15] Add blinkstick support --- .coveragerc | 1 + .../components/light/blinksticklight.py | 72 +++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 76 insertions(+) create mode 100644 homeassistant/components/light/blinksticklight.py diff --git a/.coveragerc b/.coveragerc index 95816fa55a9..1cdbb2b4838 100644 --- a/.coveragerc +++ b/.coveragerc @@ -44,6 +44,7 @@ omit = homeassistant/components/keyboard.py homeassistant/components/light/hue.py homeassistant/components/light/limitlessled.py + homeassistant/components/light/blinksticklight.py homeassistant/components/media_player/cast.py homeassistant/components/media_player/denon.py homeassistant/components/media_player/itunes.py diff --git a/homeassistant/components/light/blinksticklight.py b/homeassistant/components/light/blinksticklight.py new file mode 100644 index 00000000000..364b5f030c6 --- /dev/null +++ b/homeassistant/components/light/blinksticklight.py @@ -0,0 +1,72 @@ +""" +homeassistant.components.light.blinksticklight +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Support for Blinkstick lights. +""" + +from blinkstick import blinkstick +import logging + +_LOGGER = logging.getLogger(__name__) + +from homeassistant.components.light import (Light, ATTR_RGB_COLOR) + +REQUIREMENTS = ["blinkstick==1.1.7"] +DEPENDENCIES = [] + +# pylint: disable=unused-argument + + +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """ Add device specified by serial number """ + stick = blinkstick.find_by_serial(config['serial']) + + add_devices_callback([BlinkStickLight(stick, config['name'])]) + + +class BlinkStickLight(Light): + """ Represents a BlinkStick light """ + + def __init__(self, stick, name): + """ Initialise """ + self._stick = stick + self._name = name + self._serial = stick.get_serial() + self._rgb_color = stick.get_color() + + @property + def should_poll(self): + return True + + @property + def name(self): + return self._name + + @property + def rgb_color(self): + """ Read back the color of the light """ + return self._rgb_color + + @property + def is_on(self): + """ Check whether any of the LEDs colors are non-zero """ + return sum(self._rgb_color) > 0 + + def update(self): + """ Read back the device state """ + self._rgb_color = self._stick.get_color() + + def turn_on(self, **kwargs): + """ Turn the device on. """ + if ATTR_RGB_COLOR in kwargs: + self._rgb_color = kwargs[ATTR_RGB_COLOR] + else: + self._rgb_color = [255, 255, 255] + + self._stick.set_color(red=self._rgb_color[0], + green=self._rgb_color[1], + blue=self._rgb_color[2]) + + def turn_off(self, **kwargs): + """ Turn the device off """ + self._stick.turn_off() diff --git a/requirements_all.txt b/requirements_all.txt index 4610100b161..1921f975996 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -137,3 +137,6 @@ SoCo==0.11.1 # PlexAPI (media_player.plex) https://github.com/adrienbrault/python-plexapi/archive/df2d0847e801d6d5cda920326d693cf75f304f1a.zip#python-plexapi==1.0.2 + +# Blinkstick +blinkstick==1.1.7 From 9d4aa7e519236f4da326a92f00114dc842d52bef Mon Sep 17 00:00:00 2001 From: Alan Bowman Date: Wed, 7 Oct 2015 13:58:21 +0100 Subject: [PATCH 10/15] Update tests for RGB color support --- tests/components/test_light.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/components/test_light.py b/tests/components/test_light.py index 515b79b6fc0..156ba51e59a 100644 --- a/tests/components/test_light.py +++ b/tests/components/test_light.py @@ -152,9 +152,13 @@ class TestLight(unittest.TestCase): data) method, data = dev2.last_call('turn_on') - self.assertEqual( - {light.ATTR_XY_COLOR: color_util.color_RGB_to_xy(255, 255, 255)}, - data) + self.assertEquals( + data[light.ATTR_XY_COLOR], + color_util.color_RGB_to_xy(255, 255, 255)) + + self.assertEquals( + data[light.ATTR_RGB_COLOR], + [255, 255, 255]) method, data = dev3.last_call('turn_on') self.assertEqual({light.ATTR_XY_COLOR: [.4, .6]}, data) From 11fc521e60a0618323e06bc351c86844286c8019 Mon Sep 17 00:00:00 2001 From: badele Date: Wed, 7 Oct 2015 19:04:03 +0200 Subject: [PATCH 11/15] Replace REQUIREMENTS by DEPENDENCIES variable --- homeassistant/components/light/rfxtrx.py | 3 +-- homeassistant/components/rfxtrx.py | 3 +-- homeassistant/components/sensor/rfxtrx.py | 3 +-- homeassistant/components/switch/rfxtrx.py | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index 7c8bdb7a93a..ceb6fe97f8c 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -29,8 +29,7 @@ import RFXtrx as rfxtrxmod from homeassistant.components.light import Light from homeassistant.util import slugify -REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + - 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] +DEPENDENCIES = ['rfxtrx'] DOMAIN = "rfxtrx" _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index 0c3f377150b..f2b962c7ba9 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -20,8 +20,7 @@ import logging from homeassistant.util import slugify DEPENDENCIES = [] -REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + - 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] +REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/0.2.zip#RFXtrx==0.2'] DOMAIN = "rfxtrx" CONF_DEVICE = 'device' diff --git a/homeassistant/components/sensor/rfxtrx.py b/homeassistant/components/sensor/rfxtrx.py index d0514c93a51..b09d9d4a09c 100644 --- a/homeassistant/components/sensor/rfxtrx.py +++ b/homeassistant/components/sensor/rfxtrx.py @@ -28,8 +28,7 @@ import homeassistant.components.rfxtrx as rfxtrx from RFXtrx import SensorEvent from homeassistant.util import slugify -REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + - 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] +DEPENDENCIES = ['rfxtrx'] DATA_TYPES = OrderedDict([ ('Temperature', TEMP_CELCIUS), diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index 7eefc6fb229..29120c7d93c 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -29,8 +29,7 @@ from RFXtrx import LightingDevice from homeassistant.components.switch import SwitchDevice from homeassistant.util import slugify -REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + - 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] +DEPENDENCIES = ['rfxtrx'] DOMAIN = "rfxtrx" _LOGGER = logging.getLogger(__name__) From 496e4cf78426328d72a5083ddddcd4036538f35b Mon Sep 17 00:00:00 2001 From: badele Date: Wed, 7 Oct 2015 19:07:19 +0200 Subject: [PATCH 12/15] Exclude rfxtrx component files --- .coveragerc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.coveragerc b/.coveragerc index 7ebab01d399..3b464e20269 100644 --- a/.coveragerc +++ b/.coveragerc @@ -69,7 +69,10 @@ omit = homeassistant/components/sensor/glances.py homeassistant/components/sensor/mysensors.py homeassistant/components/sensor/openweathermap.py + homeassistant/components/rfxtrx.py + homeassistant/components/light/rfxtrx.py homeassistant/components/sensor/rfxtrx.py + homeassistant/components/switch/rfxtrx.py homeassistant/components/sensor/rpi_gpio.py homeassistant/components/sensor/sabnzbd.py homeassistant/components/sensor/swiss_public_transport.py From 46f5ef54a19c0a02fef7ddd02bfad26aa3701b74 Mon Sep 17 00:00:00 2001 From: badele Date: Wed, 7 Oct 2015 19:15:50 +0200 Subject: [PATCH 13/15] Refactoring test instance type --- homeassistant/components/light/rfxtrx.py | 52 ++++++++++++----------- homeassistant/components/switch/rfxtrx.py | 50 +++++++++++----------- 2 files changed, 53 insertions(+), 49 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index ceb6fe97f8c..58ba3759f94 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -53,34 +53,36 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): def light_update(event): """ Callback for sensor updates from the RFXtrx gateway. """ - if isinstance(event.device, rfxtrxmod.LightingDevice): - entity_id = slugify(event.device.id_string.lower()) + if not isinstance(event.device, rfxtrxmod.LightingDevice): + return - # Add entity if not exist and the automatic_add is True - if entity_id not in rfxtrx.RFX_DEVICES: - automatic_add = config.get('automatic_add', False) - if automatic_add: - _LOGGER.info( - "Automatic add %s rfxtrx.light (Class: %s Sub: %s)", - entity_id, - event.device.__class__.__name__, - event.device.subtype - ) - pkt_id = "".join("{0:02x}".format(x) for x in event.data) - entity_name = "%s : %s" % (entity_id, pkt_id) - new_light = RfxtrxLight(entity_name, event, False) - rfxtrx.RFX_DEVICES[entity_id] = new_light - add_devices_callback([new_light]) + # Add entity if not exist and the automatic_add is True + entity_id = slugify(event.device.id_string.lower()) + if entity_id not in rfxtrx.RFX_DEVICES: + automatic_add = config.get('automatic_add', False) + if automatic_add: + _LOGGER.info( + "Automatic add %s rfxtrx.light (Class: %s Sub: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype + ) + pkt_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%s : %s" % (entity_id, pkt_id) + new_light = RfxtrxLight(entity_name, event, False) + rfxtrx.RFX_DEVICES[entity_id] = new_light + add_devices_callback([new_light]) - # Check if entity exists (previous automatic added) - if entity_id in rfxtrx.RFX_DEVICES: - if event.values['Command'] == 'On'\ - or event.values['Command'] == 'Off': - if event.values['Command'] == 'On': - rfxtrx.RFX_DEVICES[entity_id].turn_on() - else: - rfxtrx.RFX_DEVICES[entity_id].turn_off() + # Check if entity exists (previous automatic added) + if entity_id in rfxtrx.RFX_DEVICES: + if event.values['Command'] == 'On'\ + or event.values['Command'] == 'Off': + if event.values['Command'] == 'On': + rfxtrx.RFX_DEVICES[entity_id].turn_on() + else: + rfxtrx.RFX_DEVICES[entity_id].turn_off() + # Subscribe to main rfxtrx events if light_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS: rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(light_update) diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index 29120c7d93c..d97759d4e86 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -55,33 +55,35 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): def switch_update(event): """ Callback for sensor updates from the RFXtrx gateway. """ if isinstance(event.device, LightingDevice): - entity_id = slugify(event.device.id_string.lower()) + return - # Add entity if not exist and the automatic_add is True - if entity_id not in rfxtrx.RFX_DEVICES: - automatic_add = config.get('automatic_add', False) - if automatic_add: - _LOGGER.info( - "Automatic add %s rfxtrx.switch (Class: %s Sub: %s)", - entity_id, - event.device.__class__.__name__, - event.device.subtype - ) - pkt_id = "".join("{0:02x}".format(x) for x in event.data) - entity_name = "%s : %s" % (entity_id, pkt_id) - new_switch = RfxtrxSwitch(entity_name, event, False) - rfxtrx.RFX_DEVICES[entity_id] = new_switch - add_devices_callback([new_switch]) + # Add entity if not exist and the automatic_add is True + entity_id = slugify(event.device.id_string.lower()) + if entity_id not in rfxtrx.RFX_DEVICES: + automatic_add = config.get('automatic_add', False) + if automatic_add: + _LOGGER.info( + "Automatic add %s rfxtrx.switch (Class: %s Sub: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype + ) + pkt_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%s : %s" % (entity_id, pkt_id) + new_switch = RfxtrxSwitch(entity_name, event, False) + rfxtrx.RFX_DEVICES[entity_id] = new_switch + add_devices_callback([new_switch]) - # Check if entity exists (previous automatic added) - if entity_id in rfxtrx.RFX_DEVICES: - if event.values['Command'] == 'On'\ - or event.values['Command'] == 'Off': - if event.values['Command'] == 'On': - rfxtrx.RFX_DEVICES[entity_id].turn_on() - else: - rfxtrx.RFX_DEVICES[entity_id].turn_off() + # Check if entity exists (previous automatic added) + if entity_id in rfxtrx.RFX_DEVICES: + if event.values['Command'] == 'On'\ + or event.values['Command'] == 'Off': + if event.values['Command'] == 'On': + rfxtrx.RFX_DEVICES[entity_id].turn_on() + else: + rfxtrx.RFX_DEVICES[entity_id].turn_off() + # Subscribe to main rfxtrx events if switch_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS: rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(switch_update) From a5dae78155d8a6309fdd2a6906b0c82263911333 Mon Sep 17 00:00:00 2001 From: badele Date: Wed, 7 Oct 2015 19:57:40 +0200 Subject: [PATCH 14/15] Refactoring the rfxtrx components --- homeassistant/components/light/rfxtrx.py | 33 ++++++++++++----------- homeassistant/components/rfxtrx.py | 15 +++++++---- homeassistant/components/switch/rfxtrx.py | 29 ++++++++++---------- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/homeassistant/components/light/rfxtrx.py b/homeassistant/components/light/rfxtrx.py index 58ba3759f94..f76d9f7ed5b 100644 --- a/homeassistant/components/light/rfxtrx.py +++ b/homeassistant/components/light/rfxtrx.py @@ -31,7 +31,6 @@ from homeassistant.util import slugify DEPENDENCIES = ['rfxtrx'] -DOMAIN = "rfxtrx" _LOGGER = logging.getLogger(__name__) @@ -60,20 +59,22 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): entity_id = slugify(event.device.id_string.lower()) if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) - if automatic_add: - _LOGGER.info( - "Automatic add %s rfxtrx.light (Class: %s Sub: %s)", - entity_id, - event.device.__class__.__name__, - event.device.subtype - ) - pkt_id = "".join("{0:02x}".format(x) for x in event.data) - entity_name = "%s : %s" % (entity_id, pkt_id) - new_light = RfxtrxLight(entity_name, event, False) - rfxtrx.RFX_DEVICES[entity_id] = new_light - add_devices_callback([new_light]) + if not automatic_add: + return - # Check if entity exists (previous automatic added) + _LOGGER.info( + "Automatic add %s rfxtrx.light (Class: %s Sub: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype + ) + pkt_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%s : %s" % (entity_id, pkt_id) + new_light = RfxtrxLight(entity_name, event, False) + rfxtrx.RFX_DEVICES[entity_id] = new_light + add_devices_callback([new_light]) + + # Check if entity exists or previously added automatically if entity_id in rfxtrx.RFX_DEVICES: if event.values['Command'] == 'On'\ or event.values['Command'] == 'Off': @@ -112,7 +113,7 @@ class RfxtrxLight(Light): def turn_on(self, **kwargs): """ Turn the device on. """ - if self._event: + if hasattr(self, '_event') and self._event: self._event.device.send_on(rfxtrx.RFXOBJECT.transport) self._state = True @@ -121,7 +122,7 @@ class RfxtrxLight(Light): def turn_off(self, **kwargs): """ Turn the device off. """ - if self._event: + if hasattr(self, '_event') and self._event: self._event.device.send_off(rfxtrx.RFXOBJECT.transport) self._state = False diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index f2b962c7ba9..79378b85e78 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -20,7 +20,8 @@ import logging from homeassistant.util import slugify DEPENDENCIES = [] -REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/0.2.zip#RFXtrx==0.2'] +REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/0.2.zip' + + '#RFXtrx==0.2'] DOMAIN = "rfxtrx" CONF_DEVICE = 'device' @@ -59,11 +60,15 @@ def setup(hass, config): # Init the rfxtrx module global RFXOBJECT + if CONF_DEVICE not in config[DOMAIN]: + _LOGGER.exception( + "can found device parameter in %s YAML configuration section", + DOMAIN + ) + return False + device = config[DOMAIN][CONF_DEVICE] - try: - debug = config[DOMAIN][CONF_DEBUG] - except KeyError: - debug = False + debug = config[DOMAIN].get(CONF_DEBUG, False) RFXOBJECT = rfxtrxmod.Core(device, handle_receive, debug=debug) diff --git a/homeassistant/components/switch/rfxtrx.py b/homeassistant/components/switch/rfxtrx.py index d97759d4e86..98963beb769 100644 --- a/homeassistant/components/switch/rfxtrx.py +++ b/homeassistant/components/switch/rfxtrx.py @@ -31,7 +31,6 @@ from homeassistant.util import slugify DEPENDENCIES = ['rfxtrx'] -DOMAIN = "rfxtrx" _LOGGER = logging.getLogger(__name__) @@ -61,20 +60,22 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): entity_id = slugify(event.device.id_string.lower()) if entity_id not in rfxtrx.RFX_DEVICES: automatic_add = config.get('automatic_add', False) - if automatic_add: - _LOGGER.info( - "Automatic add %s rfxtrx.switch (Class: %s Sub: %s)", - entity_id, - event.device.__class__.__name__, - event.device.subtype - ) - pkt_id = "".join("{0:02x}".format(x) for x in event.data) - entity_name = "%s : %s" % (entity_id, pkt_id) - new_switch = RfxtrxSwitch(entity_name, event, False) - rfxtrx.RFX_DEVICES[entity_id] = new_switch - add_devices_callback([new_switch]) + if not automatic_add: + return - # Check if entity exists (previous automatic added) + _LOGGER.info( + "Automatic add %s rfxtrx.switch (Class: %s Sub: %s)", + entity_id, + event.device.__class__.__name__, + event.device.subtype + ) + pkt_id = "".join("{0:02x}".format(x) for x in event.data) + entity_name = "%s : %s" % (entity_id, pkt_id) + new_switch = RfxtrxSwitch(entity_name, event, False) + rfxtrx.RFX_DEVICES[entity_id] = new_switch + add_devices_callback([new_switch]) + + # Check if entity exists or previously added automatically if entity_id in rfxtrx.RFX_DEVICES: if event.values['Command'] == 'On'\ or event.values['Command'] == 'Off': From 17865c78c4474da0d0f0f9a33baa3da327802054 Mon Sep 17 00:00:00 2001 From: Carlo Costanzo Date: Wed, 7 Oct 2015 17:02:07 -0400 Subject: [PATCH 15/15] Added # comment for Sensor Comments for unique sensor labels. --- config/configuration.yaml.example | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/configuration.yaml.example b/config/configuration.yaml.example index ae9959a193d..fae945b05e4 100644 --- a/config/configuration.yaml.example +++ b/config/configuration.yaml.example @@ -134,6 +134,9 @@ automation: service: light.turn_off entity_id: group.all_lights +# Sensors need to be added into the configuration.yaml as sensor:, sensor 2:, sensor 3:, etc. +# Each sensor label should be unique or your sensors might not load correctly. + sensor: platform: systemmonitor resources: