From 45f0911640455384359a508bc246dcfdd75e5a2c Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Thu, 8 Oct 2015 20:37:59 -0400 Subject: [PATCH 01/23] move play_media to the top so it catches first --- homeassistant/helpers/state.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/helpers/state.py b/homeassistant/helpers/state.py index 6526fe2d90b..24a37c5b5ea 100644 --- a/homeassistant/helpers/state.py +++ b/homeassistant/helpers/state.py @@ -59,14 +59,14 @@ def reproduce_state(hass, states, blocking=False): state.entity_id) continue - if state.domain == 'media_player' and state.state == STATE_PAUSED: - service = SERVICE_MEDIA_PAUSE - elif state.domain == 'media_player' and state.state == STATE_PLAYING: - service = SERVICE_MEDIA_PLAY - elif state.domain == 'media_player' and state.attributes and \ + if state.domain == 'media_player' and state.attributes and \ 'media_type' in state.attributes and \ 'media_id' in state.attributes: service = SERVICE_PLAY_MEDIA + elif state.domain == 'media_player' and state.state == STATE_PAUSED: + service = SERVICE_MEDIA_PAUSE + elif state.domain == 'media_player' and state.state == STATE_PLAYING: + service = SERVICE_MEDIA_PLAY elif state.state == STATE_ON: service = SERVICE_TURN_ON elif state.state == STATE_OFF: From dc5f0ef314b049551215d5463bec6756c26dcfa5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Oct 2015 21:01:38 -0700 Subject: [PATCH 02/23] NMap: fix hostname resolver Fixes #482 --- homeassistant/components/device_tracker/nmap_tracker.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/device_tracker/nmap_tracker.py b/homeassistant/components/device_tracker/nmap_tracker.py index 8d9c2e72c20..247cbbfe7e8 100644 --- a/homeassistant/components/device_tracker/nmap_tracker.py +++ b/homeassistant/components/device_tracker/nmap_tracker.py @@ -123,9 +123,9 @@ class NmapDeviceScanner(object): for host in self.last_results: if host.last_update + self.home_interval > now: exclude_targets.add(host) - if len(exclude_targets) > 0: - target_list = [t.ip for t in exclude_targets] - options += " --exclude {}".format(",".join(target_list)) + if exclude_targets: + options += " --exclude {}".format(",".join(t.ip for t + in exclude_targets)) try: result = scanner.scan(hosts=self.hosts, arguments=options) @@ -137,7 +137,7 @@ class NmapDeviceScanner(object): for ipv4, info in result['scan'].items(): if info['status']['state'] != 'up': continue - name = info['hostnames'][0] if info['hostnames'] else ipv4 + name = info['hostnames'][0]['name'] if info['hostnames'] else ipv4 # Mac address only returned if nmap ran as root mac = info['addresses'].get('mac') or _arp(ipv4) if mac is None: From 0624725e21f0f26e1989c063ee8653b0bfffd8ab Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Oct 2015 21:45:51 -0700 Subject: [PATCH 03/23] Ignore nmap style issue - pylint bug --- .../components/device_tracker/nmap_tracker.py | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/device_tracker/nmap_tracker.py b/homeassistant/components/device_tracker/nmap_tracker.py index 247cbbfe7e8..6f993f0fc7e 100644 --- a/homeassistant/components/device_tracker/nmap_tracker.py +++ b/homeassistant/components/device_tracker/nmap_tracker.py @@ -117,15 +117,18 @@ class NmapDeviceScanner(object): scanner = PortScanner() options = "-F --host-timeout 5" - exclude_targets = set() + if self.home_interval: - now = dt_util.now() - for host in self.last_results: - if host.last_update + self.home_interval > now: - exclude_targets.add(host) - if exclude_targets: - options += " --exclude {}".format(",".join(t.ip for t - in exclude_targets)) + boundary = dt_util.now() - self.home_interval + last_results = [device for device in self.last_results + if device.last_update > boundary] + if last_results: + # Pylint is confused here. + # pylint: disable=no-member + options += " --exclude {}".format(",".join(device.ip for device + in last_results)) + else: + last_results = [] try: result = scanner.scan(hosts=self.hosts, arguments=options) @@ -133,7 +136,6 @@ class NmapDeviceScanner(object): return False now = dt_util.now() - self.last_results = [] for ipv4, info in result['scan'].items(): if info['status']['state'] != 'up': continue @@ -142,9 +144,9 @@ class NmapDeviceScanner(object): mac = info['addresses'].get('mac') or _arp(ipv4) if mac is None: continue - device = Device(mac.upper(), name, ipv4, now) - self.last_results.append(device) - self.last_results.extend(exclude_targets) + last_results.append(Device(mac.upper(), name, ipv4, now)) + + self.last_results = last_results _LOGGER.info("nmap scan successful") return True From 9f33b8f541cd2de14abfb7021c3f19acaf1a81c4 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Oct 2015 22:15:12 -0700 Subject: [PATCH 04/23] DDWRT - match multiple output variants Fixes #481 --- .../components/device_tracker/ddwrt.py | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/device_tracker/ddwrt.py b/homeassistant/components/device_tracker/ddwrt.py index a9a4ac8e3f5..947876c85b5 100644 --- a/homeassistant/components/device_tracker/ddwrt.py +++ b/homeassistant/components/device_tracker/ddwrt.py @@ -46,6 +46,7 @@ MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5) _LOGGER = logging.getLogger(__name__) _DDWRT_DATA_REGEX = re.compile(r'\{(\w+)::([^\}]*)\}') +_MAC_REGEX = re.compile(r'(([0-9A-Fa-f]{1,2}\:){5}[0-9A-Fa-f]{1,2})') # pylint: disable=unused-argument @@ -77,7 +78,7 @@ class DdWrtDeviceScanner(object): self.last_results = {} - self.mac2name = None + self.mac2name = {} # Test the router is accessible url = 'http://{}/Status_Wireless.live.asp'.format(self.host) @@ -98,30 +99,33 @@ class DdWrtDeviceScanner(object): with self.lock: # if not initialised and not already scanned and not found - if self.mac2name is None or device not in self.mac2name: + if device not in self.mac2name: url = 'http://{}/Status_Lan.live.asp'.format(self.host) data = self.get_ddwrt_data(url) if not data: - return + return None dhcp_leases = data.get('dhcp_leases', None) - if dhcp_leases: - # remove leading and trailing single quotes - cleaned_str = dhcp_leases.strip().strip('"') - elements = cleaned_str.split('","') - num_clients = int(len(elements)/5) - self.mac2name = {} - for idx in range(0, num_clients): - # this is stupid but the data is a single array - # every 5 elements represents one hosts, the MAC - # is the third element and the name is the first - mac_index = (idx * 5) + 2 - if mac_index < len(elements): - mac = elements[mac_index] - self.mac2name[mac] = elements[idx * 5] - return self.mac2name.get(device, None) + if not dhcp_leases: + return None + + # remove leading and trailing single quotes + cleaned_str = dhcp_leases.strip().strip('"') + elements = cleaned_str.split('","') + num_clients = int(len(elements)/5) + self.mac2name = {} + for idx in range(0, num_clients): + # this is stupid but the data is a single array + # every 5 elements represents one hosts, the MAC + # is the third element and the name is the first + mac_index = (idx * 5) + 2 + if mac_index < len(elements): + mac = elements[mac_index] + self.mac2name[mac] = elements[idx * 5] + + return self.mac2name.get(device) @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): @@ -141,29 +145,25 @@ class DdWrtDeviceScanner(object): if not data: return False - if data: - self.last_results = [] - active_clients = data.get('active_wireless', None) - if active_clients: - # This is really lame, instead of using JSON the DD-WRT UI - # uses its own data format for some reason and then - # regex's out values so I guess I have to do the same, - # LAME!!! + self.last_results = [] - # remove leading and trailing single quotes - clean_str = active_clients.strip().strip("'") - elements = clean_str.split("','") + active_clients = data.get('active_wireless', None) + if not active_clients: + return False - num_clients = int(len(elements)/9) - for idx in range(0, num_clients): - # get every 9th element which is the MAC address - index = idx * 9 - if index < len(elements): - self.last_results.append(elements[index]) + # This is really lame, instead of using JSON the DD-WRT UI + # uses its own data format for some reason and then + # regex's out values so I guess I have to do the same, + # LAME!!! - return True + # remove leading and trailing single quotes + clean_str = active_clients.strip().strip("'") + elements = clean_str.split("','") - return False + self.last_results.extend(item for item in elements + if _MAC_REGEX.match(item)) + + return True def get_ddwrt_data(self, url): """ Retrieve data from DD-WRT and return parsed result. """ From 8a04e1f5f40612ee9dfb398d837ed1ed101e8db3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Oct 2015 22:19:15 -0700 Subject: [PATCH 05/23] Device tracker configuration fix Fixes #498 --- homeassistant/components/device_tracker/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index 55359b393ec..9fe18585418 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -114,6 +114,8 @@ def setup(hass, config): os.remove(csv_path) conf = config.get(DOMAIN, {}) + if isinstance(conf, list): + conf = conf[0] consider_home = timedelta( seconds=util.convert(conf.get(CONF_CONSIDER_HOME), int, DEFAULT_CONSIDER_HOME)) From 47fc1deecbd29b9154cbcdf03f165299a8af642c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Oct 2015 23:49:55 -0700 Subject: [PATCH 06/23] Fix throttle to work on instance-level --- homeassistant/util/__init__.py | 31 +++++++++++++++++++------------ tests/util/test_init.py | 11 +++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/homeassistant/util/__init__.py b/homeassistant/util/__init__.py index 805937376a0..2d449285493 100644 --- a/homeassistant/util/__init__.py +++ b/homeassistant/util/__init__.py @@ -233,35 +233,42 @@ class Throttle(object): self.limit_no_throttle = limit_no_throttle def __call__(self, method): - lock = threading.Lock() - if self.limit_no_throttle is not None: method = Throttle(self.limit_no_throttle)(method) + # We want to be able to differentiate between function and method calls + # All methods have the classname in their qualname seperated by a '.' + # Functions have a '.' in their qualname if defined inline, but will + # be prefixed by '..' so we strip that out. + is_func = '.' not in method.__qualname__.split('..')[-1] + @wraps(method) def wrapper(*args, **kwargs): """ Wrapper that allows wrapped to be called only once per min_time. If we cannot acquire the lock, it is running so return None. """ - if not lock.acquire(False): + # pylint: disable=protected-access + host = wrapper if is_func else args[0] + if not hasattr(host, '_throttle_lock'): + host._throttle_lock = threading.Lock() + + if not host._throttle_lock.acquire(False): return None + + last_call = getattr(host, '_throttle_last_call', None) + # Check if method is never called or no_throttle is given + force = not last_call or kwargs.pop('no_throttle', False) + try: - last_call = wrapper.last_call - - # Check if method is never called or no_throttle is given - force = not last_call or kwargs.pop('no_throttle', False) - if force or utcnow() - last_call > self.min_time: result = method(*args, **kwargs) - wrapper.last_call = utcnow() + host._throttle_last_call = utcnow() return result else: return None finally: - lock.release() - - wrapper.last_call = None + host._throttle_lock.release() return wrapper diff --git a/tests/util/test_init.py b/tests/util/test_init.py index 94358f5eb51..2bf917f4e25 100644 --- a/tests/util/test_init.py +++ b/tests/util/test_init.py @@ -218,3 +218,14 @@ class TestUtil(unittest.TestCase): self.assertEqual(3, len(calls1)) self.assertEqual(2, len(calls2)) + + def test_throttle_per_instance(self): + """ Test that the throttle method is done per instance of a class. """ + + class Tester(object): + @util.Throttle(timedelta(seconds=1)) + def hello(self): + return True + + self.assertTrue(Tester().hello()) + self.assertTrue(Tester().hello()) From be8089bcde5f28a531fd086e47deb4d564766562 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 8 Oct 2015 23:50:04 -0700 Subject: [PATCH 07/23] Cleanup arest --- homeassistant/components/sensor/arest.py | 63 +++++++++++++----------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/homeassistant/components/sensor/arest.py b/homeassistant/components/sensor/arest.py index cfe88e0f0d6..7d2192e8920 100644 --- a/homeassistant/components/sensor/arest.py +++ b/homeassistant/components/sensor/arest.py @@ -47,7 +47,7 @@ Format of a default JSON response by aREST: } """ import logging -from requests import get, exceptions +import requests from datetime import timedelta from homeassistant.util import Throttle @@ -58,36 +58,42 @@ _LOGGER = logging.getLogger(__name__) # Return cached results if last scan was less then this time ago MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) +CONF_RESOURCE = 'resource' +CONF_MONITORED_VARIABLES = 'monitored_variables' + def setup_platform(hass, config, add_devices, discovery_info=None): """ Get the aREST sensor. """ - resource = config.get('resource', None) + resource = config.get(CONF_RESOURCE) + var_conf = config.get(CONF_MONITORED_VARIABLES) + + if None in (resource, var_conf): + _LOGGER.error('Not all required config keys present: %s', + ', '.join((CONF_RESOURCE, CONF_MONITORED_VARIABLES))) + return False try: - response = get(resource, timeout=10) - except exceptions.MissingSchema: + response = requests.get(resource, timeout=10).json() + except requests.exceptions.MissingSchema: _LOGGER.error("Missing resource or schema in configuration. " "Add http:// to your URL.") return False - except exceptions.ConnectionError: + except requests.exceptions.ConnectionError: _LOGGER.error("No route to device. " "Please check the IP address in the configuration file.") return False - rest = ArestData(resource) + arest = ArestData(resource) dev = [] for variable in config['monitored_variables']: - if 'unit' not in variable: - variable['unit'] = ' ' - if variable['name'] not in response.json()['variables']: + if variable['name'] not in response['variables']: _LOGGER.error('Variable: "%s" does not exist', variable['name']) - else: - dev.append(ArestSensor(rest, - response.json()['name'], - variable['name'], - variable['unit'])) + continue + + dev.append(ArestSensor(arest, response['name'], variable['name'], + variable.get('unit'))) add_devices(dev) @@ -95,8 +101,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class ArestSensor(Entity): """ Implements an aREST sensor. """ - def __init__(self, rest, location, variable, unit_of_measurement): - self.rest = rest + def __init__(self, arest, location, variable, unit_of_measurement): + self.arest = arest self._name = '{} {}'.format(location.title(), variable.title()) self._variable = variable self._state = 'n/a' @@ -116,17 +122,16 @@ class ArestSensor(Entity): @property def state(self): """ Returns the state of the device. """ - return self._state - - def update(self): - """ Gets the latest data from aREST API and updates the state. """ - self.rest.update() - values = self.rest.data + values = self.arest.data if 'error' in values: - self._state = values['error'] + return values['error'] else: - self._state = values[self._variable] + return values.get(self._variable, 'n/a') + + def update(self): + """ Gets the latest data from aREST API. """ + self.arest.update() # pylint: disable=too-few-public-methods @@ -135,16 +140,14 @@ class ArestData(object): def __init__(self, resource): self.resource = resource - self.data = dict() + self.data = {} @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): """ Gets the latest data from aREST device. """ try: - response = get(self.resource, timeout=10) - if 'error' in self.data: - del self.data['error'] + response = requests.get(self.resource, timeout=10) self.data = response.json()['variables'] - except exceptions.ConnectionError: + except requests.exceptions.ConnectionError: _LOGGER.error("No route to device. Is device offline?") - self.data['error'] = 'n/a' + self.data = {'error': 'error fetching'} From fe5bb89a686ac7e5d129190a4cb5b610a6ed7b43 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 14:04:29 +0200 Subject: [PATCH 08/23] Add telegram notifier --- homeassistant/components/notify/telegram.py | 66 +++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 homeassistant/components/notify/telegram.py diff --git a/homeassistant/components/notify/telegram.py b/homeassistant/components/notify/telegram.py new file mode 100644 index 00000000000..c65d9ccf6cb --- /dev/null +++ b/homeassistant/components/notify/telegram.py @@ -0,0 +1,66 @@ +""" +homeassistant.components.notify.telegram +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Telegram platform for notify component. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/notify.xmpp.html +""" +import logging +import urllib + +from homeassistant.helpers import validate_config +from homeassistant.components.notify import ( + DOMAIN, ATTR_TITLE, BaseNotificationService) +from homeassistant.const import CONF_API_KEY + +_LOGGER = logging.getLogger(__name__) +REQUIREMENTS = ['python-telegram-bot==2.8.7'] + + +def get_service(hass, config): + """ Get the Telegram notification service. """ + + if not validate_config(config, + {DOMAIN: [CONF_API_KEY, 'chat_id']}, + _LOGGER): + return None + + try: + import telegram + except ImportError: + _LOGGER.exception( + "Unable to import python-telegram-bot. " + "Did you maybe not install the 'python-telegram-bot' package?") + return None + + try: + bot = telegram.Bot(token=config[DOMAIN][CONF_API_KEY]) + username = bot.getMe()['username'] + _LOGGER.info("Telegram bot is' %s'", username) + except urllib.error.HTTPError: + _LOGGER.error("Please check your access token.") + return None + + return TelegramNotificationService( + config[DOMAIN][CONF_API_KEY], + config[DOMAIN]['chat_id']) + + +# pylint: disable=too-few-public-methods +class TelegramNotificationService(BaseNotificationService): + """ Implements notification service for Telegram. """ + + def __init__(self, api_key, chat_id): + import telegram + self._api_key = api_key + self._chat_id = chat_id + self.bot = telegram.Bot(token=self._api_key) + + def send_message(self, message="", **kwargs): + """ Send a message to a user. """ + + title = kwargs.get(ATTR_TITLE) + + self.bot.sendMessage(chat_id=self._chat_id, + text=title + " " + message) From 3ef5e7c16143fc2d3750ae04a01c0ab08ae3259e Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 14:12:49 +0200 Subject: [PATCH 09/23] Add telegram --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index 26fae1ba3f9..2364cb4d8d1 100644 --- a/.coveragerc +++ b/.coveragerc @@ -65,6 +65,7 @@ omit = homeassistant/components/notify/slack.py homeassistant/components/notify/smtp.py homeassistant/components/notify/syslog.py + homeassistant/components/notify/telegram.py homeassistant/components/notify/xmpp.py homeassistant/components/sensor/arest.py homeassistant/components/sensor/bitcoin.py From 9f6ce868e23e8d28606a144bbfd289ab1d61dd73 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 14:13:05 +0200 Subject: [PATCH 10/23] Add telegram --- requirements_all.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requirements_all.txt b/requirements_all.txt index e78effedfb8..5fa48f3c10d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -143,3 +143,6 @@ pysnmp==4.2.5 # Blinkstick blinkstick==1.1.7 + +# Telegram (notify.telegram) +python-telegram-bot==2.8.7 From e29f857f43328790446b88e1723acc96319048ea Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 14:40:48 +0200 Subject: [PATCH 11/23] Update header (docstring) --- homeassistant/components/rfxtrx.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index f6bb5c6bc71..d381fac0f61 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -1,20 +1,10 @@ """ 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 +Provides support for RFXtrx components. +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/switch.rfxtrx.html """ import logging from homeassistant.util import slugify From 526a163563ff53426d45aab04572e8a143e088b2 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 14:41:35 +0200 Subject: [PATCH 12/23] Update link --- homeassistant/components/rfxtrx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index d381fac0f61..0788986c91d 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -4,7 +4,7 @@ homeassistant.components.rfxtrx Provides support for RFXtrx components. For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/switch.rfxtrx.html +https://home-assistant.io/components/rfxtrx.html """ import logging from homeassistant.util import slugify From db53e46705cf64af4daaa172302a16417d00b5af Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 14:44:59 +0200 Subject: [PATCH 13/23] Add link to docs and remove configuration details --- homeassistant/components/switch/arest.py | 33 ++---------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/homeassistant/components/switch/arest.py b/homeassistant/components/switch/arest.py index 239e24a4925..ec04e3c210f 100644 --- a/homeassistant/components/switch/arest.py +++ b/homeassistant/components/switch/arest.py @@ -3,38 +3,9 @@ homeassistant.components.switch.arest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The arest switch can control the digital pins of a device running with the aREST RESTful framework for Arduino, the ESP8266, and the Raspberry Pi. -Only tested with Arduino boards so far. -Configuration: - -To use the arest switch you will need to add something like the following -to your configuration.yaml file. - -sensor: - platform: arest - resource: http://IP_ADDRESS - pins: - 11: - name: Fan Office - 12: - name: Light Desk - -Variables: - -resource: -*Required -IP address of the device that is exposing an aREST API. - -pins: -The number of the digital pin to switch. - -These are the variables for the pins array: - -name -*Required -The name for the pin that will be used in the frontend. - -Details for the API: http://arest.io +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/switch.arest.html """ import logging from requests import get, exceptions From f8efe3f00f9d0346e1e9686992ac6c447949c844 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 14:48:58 +0200 Subject: [PATCH 14/23] Update link to docs --- homeassistant/components/notify/telegram.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/notify/telegram.py b/homeassistant/components/notify/telegram.py index c65d9ccf6cb..23b915baf1e 100644 --- a/homeassistant/components/notify/telegram.py +++ b/homeassistant/components/notify/telegram.py @@ -4,7 +4,7 @@ homeassistant.components.notify.telegram Telegram platform for notify component. For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/notify.xmpp.html +https://home-assistant.io/components/notify.telegram.html """ import logging import urllib From 8fc2f5fe36e512e03ec72d1a569ac32b9b44bc07 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 17:41:07 +0200 Subject: [PATCH 15/23] Update and equalize comments --- requirements_all.txt | 56 +++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/requirements_all.txt b/requirements_all.txt index 5fa48f3c10d..c9afec10ad0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -10,77 +10,77 @@ vincenty==0.1.2 # Sun (sun) astral==0.8.1 -# Philips Hue library (lights.hue) +# Philips Hue (lights.hue) phue==0.8 -# Limitlessled/Easybulb/Milight library (lights.limitlessled) +# Limitlessled/Easybulb/Milight (lights.limitlessled) ledcontroller==1.1.0 -# Chromecast bindings (media_player.cast) +# Chromecast (media_player.cast) pychromecast==0.6.12 # Keyboard (keyboard) pyuserinput==0.1.9 -# Tellstick bindings (*.tellstick) +# Tellstick (*.tellstick) tellcore-py==1.1.2 -# Nmap bindings (device_tracker.nmap) +# Nmap (device_tracker.nmap) python-nmap==0.4.3 -# PushBullet bindings (notify.pushbullet) +# PushBullet (notify.pushbullet) pushbullet.py==0.7.1 -# Nest Thermostat bindings (thermostat.nest) +# Nest Thermostat (thermostat.nest) python-nest==2.6.0 # Z-Wave (*.zwave) pydispatcher==2.0.5 -# ISY994 bindings (*.isy994) +# ISY994 (isy994) PyISY==1.0.5 # PSutil (sensor.systemmonitor) psutil==3.0.0 -# Pushover bindings (notify.pushover) +# Pushover (notify.pushover) python-pushover==0.2 # Transmission Torrent Client (*.transmission) transmissionrpc==0.11 -# OpenWeatherMap Web API (sensor.openweathermap) +# OpenWeatherMap (sensor.openweathermap) pyowm==2.2.1 -# XMPP Bindings (notify.xmpp) +# XMPP (notify.xmpp) sleekxmpp==1.3.1 dnspython3==1.12.0 # Blockchain (sensor.bitcoin) blockchain==1.1.2 -# MPD Bindings (media_player.mpd) +# Music Player Daemon (media_player.mpd) python-mpd2==0.5.4 # Hikvision (switch.hikvisioncam) hikvision==0.4 -# console log coloring +# Console log coloring colorlog==2.6.0 # JSON-RPC interface (media_player.kodi) jsonrpc-requests==0.1 -# Forecast.io Bindings (sensor.forecast) +# Forecast.io (sensor.forecast) python-forecastio==1.3.3 -# Firmata Bindings (*.arduino) +# Firmata (*.arduino) PyMata==2.07a -# Rfxtrx sensor (sensor.rfxtrx) +# Rfxtrx (rfxtrx) https://github.com/Danielhiversen/pyRFXtrx/archive/ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15 -# Mysensors +# Mysensors (sensor.mysensors) https://github.com/theolind/pymysensors/archive/35b87d880147a34107da0d40cb815d75e6cb4af7.zip#pymysensors==0.2 # Netgear (device_tracker.netgear) @@ -101,18 +101,18 @@ slacker==0.6.8 # Temper sensors (sensor.temper) https://github.com/rkabadi/temper-python/archive/3dbdaf2d87b8db9a3cd6e5585fc704537dd2d09b.zip#temperusb==1.2.3 -# PyEdimax +# PyEdimax (switch.edimax) https://github.com/rkabadi/pyedimax/archive/365301ce3ff26129a7910c501ead09ea625f3700.zip#pyedimax==0.1 # RPI-GPIO platform (*.rpi_gpio) # Uncomment for Raspberry Pi # RPi.GPIO==0.5.11 -# Adafruit temperature/humidity sensor -# uncomment on a Raspberry Pi / Beaglebone +# Adafruit temperature/humidity sensor (sensor.dht) +# Uncomment on a Raspberry Pi / Beaglebone # http://github.com/mala-zaba/Adafruit_Python_DHT/archive/4101340de8d2457dd194bca1e8d11cbfc237e919.zip#Adafruit_DHT==1.1.0 -# PAHO MQTT Binding (mqtt) +# PAHO MQTT (mqtt) paho-mqtt==1.1 # PyModbus (modbus) @@ -121,27 +121,25 @@ https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b6 # Verisure (verisure) https://github.com/persandstrom/python-verisure/archive/9873c4527f01b1ba1f72ae60f7f35854390d59be.zip#python-verisure==0.2.6 -# Python tools for interacting with IFTTT Maker Channel (ifttt) +# IFTTT Maker Channel (ifttt) pyfttt==0.3 -# sensor.sabnzbd +# SABnzbd (sensor.sabnzbd) https://github.com/balloob/home-assistant-nzb-clients/archive/616cad59154092599278661af17e2a9f2cf5e2a9.zip#python-sabnzbd==0.1 -# switch.vera -# sensor.vera -# light.vera +# Vera (*.vera) https://github.com/balloob/home-assistant-vera-api/archive/a8f823066ead6c7da6fb5e7abaf16fef62e63364.zip#python-vera==0.1 -# Sonos bindings (media_player.sonos) +# Sonos (media_player.sonos) SoCo==0.11.1 # PlexAPI (media_player.plex) https://github.com/adrienbrault/python-plexapi/archive/df2d0847e801d6d5cda920326d693cf75f304f1a.zip#python-plexapi==1.0.2 -# python-pysnmp (device_tracker.snmp) +# SNMP (device_tracker.snmp) pysnmp==4.2.5 -# Blinkstick +# Blinkstick (light.blinksticklight) blinkstick==1.1.7 # Telegram (notify.telegram) From a8a172c8b730d79372199a81f3158c5cc0b265b4 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 23:24:26 +0200 Subject: [PATCH 16/23] Add link to docs and remove configuration details from file header --- homeassistant/components/sensor/arest.py | 44 ++---------------------- 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/homeassistant/components/sensor/arest.py b/homeassistant/components/sensor/arest.py index 7d2192e8920..6a11aa7189c 100644 --- a/homeassistant/components/sensor/arest.py +++ b/homeassistant/components/sensor/arest.py @@ -3,48 +3,8 @@ homeassistant.components.sensor.arest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The arest sensor will consume an exposed aREST API of a device. -Configuration: - -To use the arest sensor you will need to add something like the following -to your configuration.yaml file. - -sensor: - platform: arest - resource: http://IP_ADDRESS - monitored_variables: - - name: temperature - unit: '°C' - - name: humidity - unit: '%' - -Variables: - -resource: -*Required -IP address of the device that is exposing an aREST API. - -These are the variables for the monitored_variables array: - -name -*Required -The name of the variable you wish to monitor. - -unit -*Optional -Defines the units of measurement of the sensor, if any. - -Details for the API: http://arest.io - -Format of a default JSON response by aREST: -{ - "variables":{ - "temperature":21, - "humidity":89 - }, - "id":"device008", - "name":"Bedroom", - "connected":true -} +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.arest.html """ import logging import requests From 47f994b86791653e1d6c6277940f805e19e0e696 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 23:33:59 +0200 Subject: [PATCH 17/23] Move configuration details to docs --- homeassistant/components/media_player/plex.py | 48 +++++-------------- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/media_player/plex.py b/homeassistant/components/media_player/plex.py index 46eb8947d99..5fac9ecb0f0 100644 --- a/homeassistant/components/media_player/plex.py +++ b/homeassistant/components/media_player/plex.py @@ -1,34 +1,11 @@ """ homeassistant.components.media_player.plex ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Provides an interface to the Plex API. -Provides an interface to the Plex API - -Configuration: - -To use Plex add something like this to your configuration: - -media_player: - platform: plex - name: plex_server - user: plex - password: my_secure_password - -Variables: - -name -*Required -The name of the backend device (Under Plex Media Server > settings > server). - -user -*Required -The Plex username - -password -*Required -The Plex password +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/media_player.plex.html """ - import logging from datetime import timedelta @@ -49,10 +26,8 @@ _LOGGER = logging.getLogger(__name__) SUPPORT_PLEX = SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK -# pylint: disable=abstract-method -# pylint: disable=unused-argument - +# pylint: disable=abstract-method, unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): """ Sets up the plex platform. """ from plexapi.myplex import MyPlexUser @@ -68,7 +43,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) def update_devices(): - """ Updates the devices objects """ + """ Updates the devices objects. """ try: devices = plexuser.devices() except BadRequest: @@ -94,7 +69,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) def update_sessions(): - """ Updates the sessions objects """ + """ Updates the sessions objects. """ try: sessions = plexserver.sessions() except BadRequest: @@ -113,7 +88,6 @@ class PlexClient(MediaPlayerDevice): """ Represents a Plex device. """ # pylint: disable=too-many-public-methods - def __init__(self, device, plex_sessions, update_devices, update_sessions): self.plex_sessions = plex_sessions self.update_devices = update_devices @@ -121,12 +95,12 @@ class PlexClient(MediaPlayerDevice): self.set_device(device) def set_device(self, device): - """ Sets the device property """ + """ Sets the device property. """ self.device = device @property def session(self): - """ Returns the session, if any """ + """ Returns the session, if any. """ if self.device.clientIdentifier not in self.plex_sessions: return None @@ -196,21 +170,21 @@ class PlexClient(MediaPlayerDevice): @property def media_season(self): - """ Season of curent playing media. (TV Show only) """ + """ Season of curent playing media (TV Show only). """ from plexapi.video import Show if isinstance(self.session, Show): return self.session.seasons()[0].index @property def media_series_title(self): - """ Series title of current playing media. (TV Show only)""" + """ Series title of current playing media (TV Show only). """ from plexapi.video import Show if isinstance(self.session, Show): return self.session.grandparentTitle @property def media_episode(self): - """ Episode of current playing media. (TV Show only) """ + """ Episode of current playing media (TV Show only). """ from plexapi.video import Show if isinstance(self.session, Show): return self.session.index From f07d07432d021cf1db599e8fea1fb000772e2892 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 23:38:28 +0200 Subject: [PATCH 18/23] Add telegram --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d1baa5c50f..0079cdaf14b 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Built home automation on top of your devices: * Turn on lights slowly during sun set to compensate for less light * Turn off all lights and devices when everybody leaves the house * Offers a [REST API](https://home-assistant.io/developers/api.html) and can interface with MQTT for easy integration with other projects - * Allow sending notifications using [Instapush](https://instapush.im), [Notify My Android (NMA)](http://www.notifymyandroid.com/), [PushBullet](https://www.pushbullet.com/), [PushOver](https://pushover.net/), [Slack](https://slack.com/), and [Jabber (XMPP)](http://xmpp.org) + * Allow sending notifications using [Instapush](https://instapush.im), [Notify My Android (NMA)](http://www.notifymyandroid.com/), [PushBullet](https://www.pushbullet.com/), [PushOver](https://pushover.net/), [Slack](https://slack.com/), [Telegram](https://telegram.org/), and [Jabber (XMPP)](http://xmpp.org) The system is built modular so support for other devices or actions can be implemented easily. See also the [section on architecture](https://home-assistant.io/developers/architecture.html) and the [section on creating your own components](https://home-assistant.io/developers/creating_components.html). From c3de67041aafd929ffc6c9d72660183ec5355cd6 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 23:40:06 +0200 Subject: [PATCH 19/23] Add plex --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0079cdaf14b..1d5dd5711b2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Examples of devices it can interface it: * Monitoring connected devices to a wireless router: [OpenWrt](https://openwrt.org/), [Tomato](http://www.polarcloud.com/tomato), [Netgear](http://netgear.com), [DD-WRT](http://www.dd-wrt.com/site/index), [TPLink](http://www.tp-link.us/), [ASUSWRT](http://event.asus.com/2013/nw/ASUSWRT/) and any SNMP capable WAP/WRT * [Philips Hue](http://meethue.com) lights, [WeMo](http://www.belkin.com/us/Products/home-automation/c/wemo-home-automation/) switches, [Edimax](http://www.edimax.com/) switches, [Efergy](https://efergy.com) energy monitoring, RFXtrx sensors, and [Tellstick](http://www.telldus.se/products/tellstick) devices and sensors - * [Google Chromecasts](http://www.google.com/intl/en/chrome/devices/chromecast), [Music Player Daemon](http://www.musicpd.org/), [Logitech Squeezebox](https://en.wikipedia.org/wiki/Squeezebox_%28network_music_player%29), [Kodi (XBMC)](http://kodi.tv/), and iTunes (by way of [itunes-api](https://github.com/maddox/itunes-api)) + * [Google Chromecasts](http://www.google.com/intl/en/chrome/devices/chromecast), [Music Player Daemon](http://www.musicpd.org/), [Logitech Squeezebox](https://en.wikipedia.org/wiki/Squeezebox_%28network_music_player%29), [Plex](https://plex.tv/), [Kodi (XBMC)](http://kodi.tv/), and iTunes (by way of [itunes-api](https://github.com/maddox/itunes-api)) * Support for [ISY994](https://www.universal-devices.com/residential/isy994i-series/) (Insteon and X10 devices), [Z-Wave](http://www.z-wave.com/), [Nest Thermostats](https://nest.com/), [Arduino](https://www.arduino.cc/), [Raspberry Pi](https://www.raspberrypi.org/), and [Modbus](http://www.modbus.org/) * Integrate data from the [Bitcoin](https://bitcoin.org) network, meteorological data from [OpenWeatherMap](http://openweathermap.org/) and [Forecast.io](https://forecast.io/), [Transmission](http://www.transmissionbt.com/), or [SABnzbd](http://sabnzbd.org). * [See full list of supported devices](https://home-assistant.io/components/) From d3c472252920b76feddd4bec3b7bb16794be0bdc Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 9 Oct 2015 23:45:36 +0200 Subject: [PATCH 20/23] Add some other components --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1d5dd5711b2..36777acc517 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,12 @@ Check out [the website](https://home-assistant.io) for [a demo][demo], installat Examples of devices it can interface it: - * Monitoring connected devices to a wireless router: [OpenWrt](https://openwrt.org/), [Tomato](http://www.polarcloud.com/tomato), [Netgear](http://netgear.com), [DD-WRT](http://www.dd-wrt.com/site/index), [TPLink](http://www.tp-link.us/), [ASUSWRT](http://event.asus.com/2013/nw/ASUSWRT/) and any SNMP capable WAP/WRT + * Monitoring connected devices to a wireless router: [OpenWrt](https://openwrt.org/), [Tomato](http://www.polarcloud.com/tomato), [Netgear](http://netgear.com), [DD-WRT](http://www.dd-wrt.com/site/index), [TPLink](http://www.tp-link.us/), [ASUSWRT](http://event.asus.com/2013/nw/ASUSWRT/) and any SNMP capable Linksys WAP/WRT + * * [Philips Hue](http://meethue.com) lights, [WeMo](http://www.belkin.com/us/Products/home-automation/c/wemo-home-automation/) switches, [Edimax](http://www.edimax.com/) switches, [Efergy](https://efergy.com) energy monitoring, RFXtrx sensors, and [Tellstick](http://www.telldus.se/products/tellstick) devices and sensors * [Google Chromecasts](http://www.google.com/intl/en/chrome/devices/chromecast), [Music Player Daemon](http://www.musicpd.org/), [Logitech Squeezebox](https://en.wikipedia.org/wiki/Squeezebox_%28network_music_player%29), [Plex](https://plex.tv/), [Kodi (XBMC)](http://kodi.tv/), and iTunes (by way of [itunes-api](https://github.com/maddox/itunes-api)) - * Support for [ISY994](https://www.universal-devices.com/residential/isy994i-series/) (Insteon and X10 devices), [Z-Wave](http://www.z-wave.com/), [Nest Thermostats](https://nest.com/), [Arduino](https://www.arduino.cc/), [Raspberry Pi](https://www.raspberrypi.org/), and [Modbus](http://www.modbus.org/) + * Support for [ISY994](https://www.universal-devices.com/residential/isy994i-series/) (Insteon and X10 devices), [Z-Wave](http://www.z-wave.com/), [Nest Thermostats](https://nest.com/), [RFXtrx](http://www.rfxcom.com/), [Arduino](https://www.arduino.cc/), [Raspberry Pi](https://www.raspberrypi.org/), and [Modbus](http://www.modbus.org/) + * Interaction with [IFTTT](https://ifttt.com/) * Integrate data from the [Bitcoin](https://bitcoin.org) network, meteorological data from [OpenWeatherMap](http://openweathermap.org/) and [Forecast.io](https://forecast.io/), [Transmission](http://www.transmissionbt.com/), or [SABnzbd](http://sabnzbd.org). * [See full list of supported devices](https://home-assistant.io/components/) @@ -29,7 +31,7 @@ Built home automation on top of your devices: * Turn on the lights when people get home after sun set * Turn on lights slowly during sun set to compensate for less light * Turn off all lights and devices when everybody leaves the house - * Offers a [REST API](https://home-assistant.io/developers/api.html) and can interface with MQTT for easy integration with other projects + * Offers a [REST API](https://home-assistant.io/developers/api.html) and can interface with MQTT for easy integration with other projects like [OwnTracks](http://owntracks.org/) * Allow sending notifications using [Instapush](https://instapush.im), [Notify My Android (NMA)](http://www.notifymyandroid.com/), [PushBullet](https://www.pushbullet.com/), [PushOver](https://pushover.net/), [Slack](https://slack.com/), [Telegram](https://telegram.org/), and [Jabber (XMPP)](http://xmpp.org) The system is built modular so support for other devices or actions can be implemented easily. See also the [section on architecture](https://home-assistant.io/developers/architecture.html) and the [section on creating your own components](https://home-assistant.io/developers/creating_components.html). From 3a3b8bbb45541ee4a94f87c522093ed8da81c19a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 10 Oct 2015 10:33:09 -0700 Subject: [PATCH 21/23] Fix packaging issues --- MANIFEST.in | 7 +++++-- .../components/frontend/www_static/__init__.py | 0 .../frontend/www_static/images/__init__.py | 0 homeassistant/const.py | 2 +- homeassistant/startup/__init__.py | 0 setup.py | 13 +++++++------ 6 files changed, 13 insertions(+), 9 deletions(-) delete mode 100644 homeassistant/components/frontend/www_static/__init__.py delete mode 100644 homeassistant/components/frontend/www_static/images/__init__.py delete mode 100644 homeassistant/startup/__init__.py diff --git a/MANIFEST.in b/MANIFEST.in index 53d3a9e22a9..8233015e646 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,5 @@ -recursive-exclude tests * -recursive-include homeassistant services.yaml +include README.md +include LICENSE +graft homeassistant +prune homeassistant/components/frontend/www_static/home-assistant-polymer +recursive-exclude * *.py[co] diff --git a/homeassistant/components/frontend/www_static/__init__.py b/homeassistant/components/frontend/www_static/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/homeassistant/components/frontend/www_static/images/__init__.py b/homeassistant/components/frontend/www_static/images/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/homeassistant/const.py b/homeassistant/const.py index 35e3e2c93ae..0573a0cbbf7 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ # coding: utf-8 """ Constants used by Home Assistant components. """ -__version__ = "0.7.5dev0" +__version__ = "0.7.5.dev0" # Can be used to specify a catch all when registering state or event listeners. MATCH_ALL = '*' diff --git a/homeassistant/startup/__init__.py b/homeassistant/startup/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/setup.py b/setup.py index 044d5428809..b9b5cdd0d5d 100755 --- a/setup.py +++ b/setup.py @@ -9,11 +9,12 @@ DOWNLOAD_URL = ('https://github.com/balloob/home-assistant/archive/' PACKAGES = find_packages(exclude=['tests', 'tests.*']) -PACKAGE_DATA = \ - {'homeassistant.components.frontend': ['index.html.template'], - 'homeassistant.components.frontend.www_static': ['*.*'], - 'homeassistant.components.frontend.www_static.images': ['*.*'], - 'homeassistant.startup': ['*.*']} +# PACKAGE_DATA = \ +# {'homeassistant.components.frontend': ['index.html.template'], +# 'homeassistant.components.frontend.www_static': ['*.*'], +# 'homeassistant.components.frontend.www_static.images': ['*.*'], +# 'homeassistant.components.mqtt': ['*.crt'], +# 'homeassistant.startup': ['*.*']} REQUIRES = [ 'requests>=2,<3', @@ -23,6 +24,7 @@ REQUIRES = [ 'vincenty==0.1.2' ] + # package_data=PACKAGE_DATA, setup( name=PACKAGE_NAME, version=__version__, @@ -34,7 +36,6 @@ setup( description='Open-source home automation platform running on Python 3.', packages=PACKAGES, include_package_data=True, - package_data=PACKAGE_DATA, zip_safe=False, platforms='any', install_requires=REQUIRES, From 6a18205d2ea8f97a9c8509e87e679ce98fdca00e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 10 Oct 2015 11:39:29 -0700 Subject: [PATCH 22/23] Update to version 0.7.5 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 0573a0cbbf7..a84f4571b8e 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ # coding: utf-8 """ Constants used by Home Assistant components. """ -__version__ = "0.7.5.dev0" +__version__ = "0.7.5" # Can be used to specify a catch all when registering state or event listeners. MATCH_ALL = '*' From 94df5acbf334c4cd13c127d9287406f396ae2a8a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 10 Oct 2015 11:45:25 -0700 Subject: [PATCH 23/23] Version bump to 0.7.6.dev0 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index a84f4571b8e..278ffea218a 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ # coding: utf-8 """ Constants used by Home Assistant components. """ -__version__ = "0.7.5" +__version__ = "0.7.6.dev0" # Can be used to specify a catch all when registering state or event listeners. MATCH_ALL = '*'