From fcf60e740daaf62dd43b9077c63f01383e58f8d5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 21 Jun 2017 09:08:20 -0700 Subject: [PATCH 1/6] Version bump to 0.47.1 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index ed7584c83ef1a3..d7588f08021b44 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 47 -PATCH_VERSION = '0' +PATCH_VERSION = '1' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) From b74217bec25a3c9666553fe059c73abedc5576f8 Mon Sep 17 00:00:00 2001 From: Tsvi Mostovicz Date: Mon, 19 Jun 2017 10:54:13 +0300 Subject: [PATCH 2/6] Fix lights issue #8098 (#8101) * Fix lights issue #8098 * Don't check self._color to decide whether to calll get_color() self._color is None on init, so get_color() will never be called. --- homeassistant/components/light/vera.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/vera.py b/homeassistant/components/light/vera.py index ad24c1872f5afb..3d19c3fcea2f39 100644 --- a/homeassistant/components/light/vera.py +++ b/homeassistant/components/light/vera.py @@ -79,5 +79,8 @@ def is_on(self): def update(self): """Call to update state.""" self._state = self.vera_device.is_switched_on() - self._brightness = self.vera_device.get_brightness() - self._color = self.vera_device.get_color() + if self.vera_device.is_dimmable: + # If it is dimmable, both functions exist. In case color + # is not supported, it will return None + self._brightness = self.vera_device.get_brightness() + self._color = self.vera_device.get_color() From cb5fa798353bb72d2d3b49012fcb607303f67843 Mon Sep 17 00:00:00 2001 From: Charles Blonde Date: Mon, 19 Jun 2017 23:50:27 +0200 Subject: [PATCH 3/6] Fix Dyson async_add_job (#8113) --- homeassistant/components/fan/dyson.py | 2 +- homeassistant/components/sensor/dyson.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/fan/dyson.py b/homeassistant/components/fan/dyson.py index f879c250a16a86..b8f330fd1f40fc 100644 --- a/homeassistant/components/fan/dyson.py +++ b/homeassistant/components/fan/dyson.py @@ -75,7 +75,7 @@ def __init__(self, hass, device): def async_added_to_hass(self): """Callback when entity is added to hass.""" self.hass.async_add_job( - self._device.add_message_listener(self.on_message)) + self._device.add_message_listener, self.on_message) def on_message(self, message): """Called when new messages received from the fan.""" diff --git a/homeassistant/components/sensor/dyson.py b/homeassistant/components/sensor/dyson.py index d2c872c668cc13..2f324519566fbd 100644 --- a/homeassistant/components/sensor/dyson.py +++ b/homeassistant/components/sensor/dyson.py @@ -38,7 +38,7 @@ def __init__(self, hass, device): def async_added_to_hass(self): """Callback when entity is added to hass.""" self.hass.async_add_job( - self._device.add_message_listener(self.on_message)) + self._device.add_message_listener, self.on_message) def on_message(self, message): """Called when new messages received from the fan.""" From b45c386fd6898327ada575fc86927e2c1c58072b Mon Sep 17 00:00:00 2001 From: Phil Hawthorne Date: Tue, 20 Jun 2017 15:53:13 +1000 Subject: [PATCH 4/6] Update InfluxDB to handle datetime objects and multiple decimal points (#8080) * Update InfluxDB to handle datetime objects Updates the InfluxDB regex to ignore datetime objects being coverted into float values. Adds tests to the component to ensure datetime objects are corectly handled. * Fix Hound errors Fixes errors from Hound bot * Update InfluxDB to handle multiple decimal points Changes the way InfluxDB handles values such as 1.2.3.4 to be 1.234 so it stores in InfluxDB as a valid float value * Fix lint issues Reduce the size of a line for the linter * Update InfluxDB to pass on unknown variable If we get an error trying to convert a variable to a float, let's ignore it completely * Make InfluxDB Regex constants Makes the Regex's used by InfluxDB constants so they don't need to be compiled each time * cleanup * fix lint * Update regex * fix tests * Fix JSON body missing new line character * fix exceptions --- homeassistant/components/influxdb.py | 13 ++++++++----- tests/components/test_influxdb.py | 17 ++++++++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/influxdb.py b/homeassistant/components/influxdb.py index 37aeeee41b7bb7..6b8cd6734dd34b 100644 --- a/homeassistant/components/influxdb.py +++ b/homeassistant/components/influxdb.py @@ -58,6 +58,9 @@ }), }, extra=vol.ALLOW_EXTRA) +RE_DIGIT_TAIL = re.compile(r'^[^\.]*\d+\.?\d+[^\.]*$') +RE_DECIMAL = re.compile(r'[^\d.]+') + def setup(hass, config): """Set up the InfluxDB component.""" @@ -149,8 +152,6 @@ def influx_event_listener(event): } ] - non_digit_tail = re.compile(r'[\d.]+') - non_decimal = re.compile(r'[^\d.]+') for key, value in state.attributes.items(): if key != 'unit_of_measurement': # If the key is already in fields @@ -164,10 +165,12 @@ def influx_event_listener(event): json_body[0]['fields'][key] = float(value) except (ValueError, TypeError): new_key = "{}_str".format(key) - json_body[0]['fields'][new_key] = str(value) - if non_digit_tail.match(json_body[0]['fields'][new_key]): + new_value = str(value) + json_body[0]['fields'][new_key] = new_value + + if RE_DIGIT_TAIL.match(new_value): json_body[0]['fields'][key] = float( - non_decimal.sub('', value)) + RE_DECIMAL.sub('', new_value)) json_body[0]['tags'].update(tags) diff --git a/tests/components/test_influxdb.py b/tests/components/test_influxdb.py index 301c4c7b9b1ecf..896ee4699ccb00 100644 --- a/tests/components/test_influxdb.py +++ b/tests/components/test_influxdb.py @@ -1,5 +1,6 @@ """The tests for the InfluxDB component.""" import unittest +import datetime from unittest import mock import influxdb as influx_client @@ -123,7 +124,9 @@ def test_event_listener(self, mock_client): 'latitude': '2.2', 'battery_level': '99%', 'temperature': '20c', - 'last_seen': 'Last seen 23 minutes ago' + 'last_seen': 'Last seen 23 minutes ago', + 'updated_at': datetime.datetime(2017, 1, 1, 0, 0), + 'multi_periods': '0.120.240.2023873' } state = mock.MagicMock( state=in_, domain='fake', object_id='entity', attributes=attrs) @@ -144,7 +147,11 @@ def test_event_listener(self, mock_client): 'battery_level': 99.0, 'temperature_str': '20c', 'temperature': 20.0, - 'last_seen_str': 'Last seen 23 minutes ago' + 'last_seen_str': 'Last seen 23 minutes ago', + 'last_seen': 23.0, + 'updated_at_str': '2017-01-01 00:00:00', + 'updated_at': 20170101000000, + 'multi_periods_str': '0.120.240.2023873' }, }] @@ -164,7 +171,11 @@ def test_event_listener(self, mock_client): 'battery_level': 99.0, 'temperature_str': '20c', 'temperature': 20.0, - 'last_seen_str': 'Last seen 23 minutes ago' + 'last_seen_str': 'Last seen 23 minutes ago', + 'last_seen': 23.0, + 'updated_at_str': '2017-01-01 00:00:00', + 'updated_at': 20170101000000, + 'multi_periods_str': '0.120.240.2023873' }, }] self.handler_method(event) From 4b1dcad7ae618f970458a8e3873ae92873358805 Mon Sep 17 00:00:00 2001 From: Alan Fischer Date: Tue, 20 Jun 2017 07:26:19 -0600 Subject: [PATCH 5/6] Fixed iTach command parsing with empty data (#8104) * Fixed iTach command parsing with empty data * Switched to using format --- homeassistant/components/remote/itach.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/remote/itach.py b/homeassistant/components/remote/itach.py index e5a013a5dcf5a5..9feb2d1141db2b 100644 --- a/homeassistant/components/remote/itach.py +++ b/homeassistant/components/remote/itach.py @@ -62,10 +62,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): name = data.get(CONF_NAME) modaddr = int(data.get(CONF_MODADDR, 1)) connaddr = int(data.get(CONF_CONNADDR, 1)) - cmddata = "" + cmddatas = "" for cmd in data.get(CONF_COMMANDS): - cmddata += cmd[CONF_NAME] + "\n" + cmd[CONF_DATA] + "\n" - itachip2ir.addDevice(name, modaddr, connaddr, cmddata) + cmdname = cmd[CONF_NAME].strip() + if not cmdname: + cmdname = '""' + cmddata = cmd[CONF_DATA].strip() + if not cmddata: + cmddata = '""' + cmddatas += "{}\n{}\n".format(cmdname, cmddata) + itachip2ir.addDevice(name, modaddr, connaddr, cmddatas) devices.append(ITachIP2IRRemote(itachip2ir, name)) add_devices(devices, True) return True From 8d76e2679d7bbcd35ae4cc55697555771f0cfb19 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 21 Jun 2017 04:32:50 -0700 Subject: [PATCH 6/6] Allow iteration in python_script (#8134) * Allow iteration in python_script * Add tests --- homeassistant/components/python_script.py | 1 + tests/components/test_python_script.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/homeassistant/components/python_script.py b/homeassistant/components/python_script.py index 3892540996a0a7..2a82689bcd13bf 100644 --- a/homeassistant/components/python_script.py +++ b/homeassistant/components/python_script.py @@ -92,6 +92,7 @@ def protected_getattr(obj, name, default=None): '_print_': StubPrinter, '_getattr_': protected_getattr, '_write_': full_write_guard, + '_getiter_': iter, } logger = logging.getLogger('{}.{}'.format(__name__, filename)) local = { diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index bd62513599e68f..78142e06cf3a39 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -149,3 +149,18 @@ def test_accessing_forbidden_methods(hass, caplog): yield from hass.async_block_till_done() assert "Not allowed to access HomeAssistant.stop" in caplog.text + + +@asyncio.coroutine +def test_iterating(hass): + """Test compile error logs error.""" + source = """ +for i in [1, 2]: + hass.states.set('hello.{}'.format(i), 'world') + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert hass.states.is_state('hello.1', 'world') + assert hass.states.is_state('hello.2', 'world')