diff --git a/.coveragerc b/.coveragerc index c68572f9070..4122d60e574 100644 --- a/.coveragerc +++ b/.coveragerc @@ -4,8 +4,6 @@ source = homeassistant omit = homeassistant/__main__.py - homeassistant/external/* - # omit pieces of code that rely on external devices being present homeassistant/components/arduino.py homeassistant/components/*/arduino.py diff --git a/.gitmodules b/.gitmodules index a627e522d8f..ad28a4e2c8a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,3 @@ -[submodule "homeassistant/external/noop"] - path = homeassistant/external/noop - url = https://github.com/balloob/noop.git -[submodule "homeassistant/external/vera"] - path = homeassistant/external/vera - url = https://github.com/jamespcole/home-assistant-vera-api.git -[submodule "homeassistant/external/nzbclients"] - path = homeassistant/external/nzbclients - url = https://github.com/jamespcole/home-assistant-nzb-clients.git [submodule "homeassistant/components/frontend/www_static/home-assistant-polymer"] path = homeassistant/components/frontend/www_static/home-assistant-polymer url = https://github.com/balloob/home-assistant-polymer.git diff --git a/.travis.yml b/.travis.yml index 65e417fffb6..339ed48d424 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ install: - pip install -r requirements_all.txt - pip install flake8 pylint coveralls script: - - flake8 homeassistant --exclude bower_components,external + - flake8 homeassistant - pylint homeassistant - coverage run -m unittest discover tests after_success: diff --git a/config/custom_components/example.py b/config/custom_components/example.py index 5bfb03353e0..ee7f18f437a 100644 --- a/config/custom_components/example.py +++ b/config/custom_components/example.py @@ -12,7 +12,7 @@ Example component to target an entity_id to: Configuration: To use the Example custom component you will need to add the following to -your config/configuration.yaml +your configuration.yaml file. example: target: TARGET_ENTITY diff --git a/config/custom_components/hello_world.py b/config/custom_components/hello_world.py index 96d9a788b6b..a3d4ce762bb 100644 --- a/config/custom_components/hello_world.py +++ b/config/custom_components/hello_world.py @@ -1,16 +1,14 @@ """ custom_components.hello_world ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Implements the bare minimum that a component should implement. Configuration: To use the hello_word component you will need to add the following to your -config/configuration.yaml +configuration.yaml file. hello_world: - """ # The domain of your component. Should be equal to the name of your component diff --git a/config/custom_components/mqtt_example.py b/config/custom_components/mqtt_example.py index 5b54226cb7c..98e16b6bfa9 100644 --- a/config/custom_components/mqtt_example.py +++ b/config/custom_components/mqtt_example.py @@ -1,7 +1,6 @@ """ custom_components.mqtt_example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Shows how to communicate with MQTT. Follows a topic on MQTT and updates the state of an entity to the last message received on that topic. @@ -12,7 +11,7 @@ example payload {"new_state": "some new state"}. Configuration: To use the mqtt_example component you will need to add the following to your -config/configuration.yaml +configuration.yaml file. mqtt_example: topic: home-assistant/mqtt_example diff --git a/homeassistant/components/arduino.py b/homeassistant/components/arduino.py index db91c5e0d9c..cbb319e2541 100644 --- a/homeassistant/components/arduino.py +++ b/homeassistant/components/arduino.py @@ -7,7 +7,7 @@ runs with the Firmata firmware. Configuration: To use the Arduino board you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. arduino: port: /dev/ttyACM0 diff --git a/homeassistant/components/camera/generic.py b/homeassistant/components/camera/generic.py index f7cf5654f46..7e4a24ffdfe 100644 --- a/homeassistant/components/camera/generic.py +++ b/homeassistant/components/camera/generic.py @@ -1,4 +1,6 @@ """ +homeassistant.components.camera.generic +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Support for IP Cameras. This component provides basic support for IP cameras. For the basic support to @@ -7,11 +9,11 @@ need to specify the "still_image_url" parameter which should be the location of the JPEG image. As part of the basic support the following features will be provided: --MJPEG video streaming --Saving a snapshot --Recording(JPEG frame capture) +- MJPEG video streaming +- Saving a snapshot +- Recording(JPEG frame capture) -To use this component, add the following to your config/configuration.yaml: +To use this component, add the following to your configuration.yaml file. camera: platform: generic @@ -20,29 +22,24 @@ camera: password: YOUR_PASSWORD still_image_url: http://YOUR_CAMERA_IP_AND_PORT/image.jpg - -VARIABLES: - -These are the variables for the device_data array: +Variables: still_image_url *Required -The URL your camera serves the image on. -Example: http://192.168.1.21:2112/ +The URL your camera serves the image on, eg. http://192.168.1.21:2112/ name *Optional -This parameter allows you to override the name of your camera in homeassistant +This parameter allows you to override the name of your camera in Home +Assistant. username *Optional -THe username for acessing your camera +The username for accessing your camera. password *Optional -the password for accessing your camera - - +The password for accessing your camera. """ import logging from requests.auth import HTTPBasicAuth @@ -78,7 +75,7 @@ class GenericCamera(Camera): self._still_image_url = device_info['still_image_url'] def camera_image(self): - """ Return a still image reponse from the camera """ + """ Return a still image reponse from the camera. """ if self._username and self._password: response = requests.get( self._still_image_url, @@ -90,5 +87,5 @@ class GenericCamera(Camera): @property def name(self): - """ Return the name of this device """ + """ Return the name of this device. """ return self._name diff --git a/homeassistant/components/device_tracker/actiontec.py b/homeassistant/components/device_tracker/actiontec.py index a922da9fe88..f926b182983 100644 --- a/homeassistant/components/device_tracker/actiontec.py +++ b/homeassistant/components/device_tracker/actiontec.py @@ -1,6 +1,6 @@ """ homeassistant.components.device_tracker.actiontec -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Device tracker platform that supports scanning an Actiontec MI424WR (Verizon FIOS) router for device presence. @@ -9,10 +9,9 @@ This device tracker needs telnet to be enabled on the router. Configuration: To use the Actiontec tracker you will need to add something like the -following to your config/configuration.yaml. If you experience disconnects +following to your configuration.yaml file. If you experience disconnects you can modify the home_interval variable. - device_tracker: platform: actiontec host: YOUR_ROUTER_IP @@ -69,7 +68,7 @@ _LEASES_REGEX = re.compile( # pylint: disable=unused-argument def get_scanner(hass, config): - """ Validates config and returns a DD-WRT scanner. """ + """ Validates config and returns an Actiontec scanner. """ if not validate_config(config, {DOMAIN: [CONF_HOST, CONF_USERNAME, CONF_PASSWORD]}, _LOGGER): @@ -83,8 +82,9 @@ Device = namedtuple("Device", ["mac", "ip", "last_update"]) class ActiontecDeviceScanner(object): - """ This class queries a an actiontec router - for connected devices. Adapted from DD-WRT scanner. + """ + This class queries a an actiontec router for connected devices. + Adapted from DD-WRT scanner. """ def __init__(self, config): @@ -106,8 +106,9 @@ class ActiontecDeviceScanner(object): _LOGGER.info("home_interval set to: %s", self.home_interval) def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device ids. + """ self._update_info() return [client.mac for client in self.last_results] @@ -123,8 +124,10 @@ class ActiontecDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the Actiontec MI424WR router is up - to date. Returns boolean if scanning successful. """ + """ + Ensures the information from the Actiontec MI424WR router is up + to date. Returns boolean if scanning successful. + """ _LOGGER.info("Scanning") if not self.success_init: return False @@ -155,7 +158,7 @@ class ActiontecDeviceScanner(object): return True def get_actiontec_data(self): - """ Retrieve data from Actiontec MI424WR and return parsed result. """ + """ Retrieve data from Actiontec MI424WR and return parsed result. """ try: telnet = telnetlib.Telnet(self.host) telnet.read_until(b'Username: ') diff --git a/homeassistant/components/device_tracker/aruba.py b/homeassistant/components/device_tracker/aruba.py index 5ee7b69e693..68ff8390216 100644 --- a/homeassistant/components/device_tracker/aruba.py +++ b/homeassistant/components/device_tracker/aruba.py @@ -9,8 +9,8 @@ This device tracker needs telnet to be enabled on the router. Configuration: To use the Aruba tracker you will need to add something like the following -to your config/configuration.yaml. You also need to enable Telnet in the -configuration pages. +to your configuration.yaml file. You also need to enable Telnet in the +configuration page of your router. device_tracker: platform: aruba @@ -83,8 +83,9 @@ class ArubaDeviceScanner(object): self.success_init = data is not None def scan_devices(self): - """ Scans for new devices and return a list containing found device - ids. """ + """ + Scans for new devices and return a list containing found device IDs. + """ self._update_info() return [client['mac'] for client in self.last_results] @@ -100,8 +101,10 @@ class ArubaDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the Aruba Access Point is up to date. - Returns boolean if scanning successful. """ + """ + Ensures the information from the Aruba Access Point is up to date. + Returns boolean if scanning successful. + """ if not self.success_init: return False @@ -114,8 +117,7 @@ class ArubaDeviceScanner(object): return True def get_aruba_data(self): - """ Retrieve data from Aruba Access Point and return parsed - result. """ + """ Retrieve data from Aruba Access Point and return parsed result. """ try: telnet = telnetlib.Telnet(self.host) telnet.read_until(b'User: ') diff --git a/homeassistant/components/device_tracker/asuswrt.py b/homeassistant/components/device_tracker/asuswrt.py index fdf2ca70eaa..c0b29ab420f 100644 --- a/homeassistant/components/device_tracker/asuswrt.py +++ b/homeassistant/components/device_tracker/asuswrt.py @@ -9,7 +9,7 @@ This device tracker needs telnet to be enabled on the router. Configuration: To use the ASUSWRT tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: asuswrt @@ -63,7 +63,7 @@ _IP_NEIGH_REGEX = re.compile( # pylint: disable=unused-argument def get_scanner(hass, config): - """ Validates config and returns a DD-WRT scanner. """ + """ Validates config and returns an ASUS-WRT scanner. """ if not validate_config(config, {DOMAIN: [CONF_HOST, CONF_USERNAME, CONF_PASSWORD]}, _LOGGER): @@ -75,7 +75,8 @@ def get_scanner(hass, config): class AsusWrtDeviceScanner(object): - """ This class queries a router running ASUSWRT firmware + """ + This class queries a router running ASUSWRT firmware for connected devices. Adapted from DD-WRT scanner. """ @@ -93,8 +94,9 @@ class AsusWrtDeviceScanner(object): self.success_init = data is not None def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device IDs. + """ self._update_info() return [client['mac'] for client in self.last_results] @@ -110,8 +112,10 @@ class AsusWrtDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the ASUSWRT router is up to date. - Returns boolean if scanning successful. """ + """ + Ensures the information from the ASUSWRT router is up to date. + Returns boolean if scanning successful. + """ if not self.success_init: return False @@ -129,7 +133,7 @@ class AsusWrtDeviceScanner(object): return True def get_asuswrt_data(self): - """ Retrieve data from ASUSWRT and return parsed result. """ + """ Retrieve data from ASUSWRT and return parsed result. """ try: telnet = telnetlib.Telnet(self.host) telnet.read_until(b'login: ') diff --git a/homeassistant/components/device_tracker/ddwrt.py b/homeassistant/components/device_tracker/ddwrt.py index 2c69746fab0..a9a4ac8e3f5 100644 --- a/homeassistant/components/device_tracker/ddwrt.py +++ b/homeassistant/components/device_tracker/ddwrt.py @@ -1,14 +1,13 @@ """ homeassistant.components.device_tracker.ddwrt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Device tracker platform that supports scanning a DD-WRT router for device presence. Configuration: To use the DD-WRT tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: ddwrt @@ -64,7 +63,8 @@ def get_scanner(hass, config): # pylint: disable=too-many-instance-attributes class DdWrtDeviceScanner(object): - """ This class queries a wireless router running DD-WRT firmware + """ + This class queries a wireless router running DD-WRT firmware for connected devices. Adapted from Tomato scanner. """ @@ -85,8 +85,9 @@ class DdWrtDeviceScanner(object): self.success_init = data is not None def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device ids. + """ self._update_info() @@ -124,8 +125,10 @@ class DdWrtDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the DD-WRT router is up to date. - Returns boolean if scanning successful. """ + """ + Ensures the information from the DD-WRT router is up to date. + Returns boolean if scanning successful. + """ if not self.success_init: return False @@ -163,7 +166,7 @@ class DdWrtDeviceScanner(object): return False def get_ddwrt_data(self, url): - """ Retrieve data from DD-WRT and return parsed result. """ + """ Retrieve data from DD-WRT and return parsed result. """ try: response = requests.get( url, diff --git a/homeassistant/components/device_tracker/luci.py b/homeassistant/components/device_tracker/luci.py index 893c9070526..4cbc6a2d492 100644 --- a/homeassistant/components/device_tracker/luci.py +++ b/homeassistant/components/device_tracker/luci.py @@ -1,18 +1,16 @@ """ homeassistant.components.device_tracker.luci ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Device tracker platform that supports scanning a OpenWRT router for device presence. - It's required that the luci RPC package is installed on the OpenWRT router: # opkg install luci-mod-rpc Configuration: To use the Luci tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: luci @@ -66,7 +64,8 @@ def get_scanner(hass, config): # pylint: disable=too-many-instance-attributes class LuciDeviceScanner(object): - """ This class queries a wireless router running OpenWrt firmware + """ + This class queries a wireless router running OpenWrt firmware for connected devices. Adapted from Tomato scanner. # opkg install luci-mod-rpc @@ -95,8 +94,9 @@ class LuciDeviceScanner(object): self.success_init = self.token is not None def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device ids. + """ self._update_info() @@ -124,8 +124,10 @@ class LuciDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the Luci router is up to date. - Returns boolean if scanning successful. """ + """ + Ensures the information from the Luci router is up to date. + Returns boolean if scanning successful. + """ if not self.success_init: return False @@ -179,6 +181,6 @@ def _req_json_rpc(url, method, *args, **kwargs): def _get_token(host, username, password): - """ Get authentication token for the given host+username+password """ + """ Get authentication token for the given host+username+password. """ url = 'http://{}/cgi-bin/luci/rpc/auth'.format(host) return _req_json_rpc(url, 'login', username, password) diff --git a/homeassistant/components/device_tracker/netgear.py b/homeassistant/components/device_tracker/netgear.py index 346fbb37d37..88fd7aed78a 100644 --- a/homeassistant/components/device_tracker/netgear.py +++ b/homeassistant/components/device_tracker/netgear.py @@ -1,14 +1,13 @@ """ homeassistant.components.device_tracker.netgear ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Device tracker platform that supports scanning a Netgear router for device presence. Configuration: To use the Netgear tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: netgear @@ -90,8 +89,9 @@ class NetgearDeviceScanner(object): _LOGGER.error("Failed to Login") def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device ids. + """ self._update_info() return (device.mac for device in self.last_results) @@ -106,8 +106,10 @@ class NetgearDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Retrieves latest information from the Netgear router. - Returns boolean if scanning successful. """ + """ + Retrieves latest information from the Netgear router. + Returns boolean if scanning successful. + """ if not self.success_init: return diff --git a/homeassistant/components/device_tracker/nmap_tracker.py b/homeassistant/components/device_tracker/nmap_tracker.py index 484574b312f..5c619e001a3 100644 --- a/homeassistant/components/device_tracker/nmap_tracker.py +++ b/homeassistant/components/device_tracker/nmap_tracker.py @@ -1,13 +1,12 @@ """ homeassistant.components.device_tracker.nmap ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Device tracker platform that supports scanning a network with nmap. Configuration: To use the nmap tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: nmap_tracker @@ -74,7 +73,7 @@ def _arp(ip_address): class NmapDeviceScanner(object): - """ This class scans for devices using nmap """ + """ This class scans for devices using nmap. """ def __init__(self, config): self.last_results = [] @@ -87,8 +86,9 @@ class NmapDeviceScanner(object): _LOGGER.info("nmap scanner initialized") def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device ids. + """ self._update_info() @@ -107,8 +107,10 @@ class NmapDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Scans the network for devices. - Returns boolean if scanning successful. """ + """ + Scans the network for devices. + Returns boolean if scanning successful. + """ _LOGGER.info("Scanning") from nmap import PortScanner, PortScannerError diff --git a/homeassistant/components/device_tracker/thomson.py b/homeassistant/components/device_tracker/thomson.py index ffe1a7f64c2..408daa94d81 100644 --- a/homeassistant/components/device_tracker/thomson.py +++ b/homeassistant/components/device_tracker/thomson.py @@ -9,7 +9,7 @@ This device tracker needs telnet to be enabled on the router. Configuration: To use the THOMSON tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: thomson @@ -71,7 +71,8 @@ def get_scanner(hass, config): class ThomsonDeviceScanner(object): - """ This class queries a router running THOMSON firmware + """ + This class queries a router running THOMSON firmware for connected devices. Adapted from ASUSWRT scanner. """ @@ -107,8 +108,10 @@ class ThomsonDeviceScanner(object): @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the THOMSON router is up to date. - Returns boolean if scanning successful. """ + """ + Ensures the information from the THOMSON router is up to date. + Returns boolean if scanning successful. + """ if not self.success_init: return False @@ -125,7 +128,7 @@ class ThomsonDeviceScanner(object): return True def get_thomson_data(self): - """ Retrieve data from THOMSON and return parsed result. """ + """ Retrieve data from THOMSON and return parsed result. """ try: telnet = telnetlib.Telnet(self.host) telnet.read_until(b'Username : ') diff --git a/homeassistant/components/device_tracker/tomato.py b/homeassistant/components/device_tracker/tomato.py index 1a189a08396..a23b7b80ff0 100644 --- a/homeassistant/components/device_tracker/tomato.py +++ b/homeassistant/components/device_tracker/tomato.py @@ -1,14 +1,13 @@ """ homeassistant.components.device_tracker.tomato ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Device tracker platform that supports scanning a Tomato router for device presence. Configuration: To use the Tomato tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: tomato diff --git a/homeassistant/components/device_tracker/tplink.py b/homeassistant/components/device_tracker/tplink.py index 8e556e47e8a..6b12000cf45 100755 --- a/homeassistant/components/device_tracker/tplink.py +++ b/homeassistant/components/device_tracker/tplink.py @@ -1,14 +1,13 @@ """ homeassistant.components.device_tracker.tplink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Device tracker platform that supports scanning a TP-Link router for device presence. Configuration: To use the TP-Link tracker you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. device_tracker: platform: tplink @@ -29,7 +28,6 @@ The username of an user with administrative privileges, usually 'admin'. password *Required The password for your given admin account. - """ import base64 import logging @@ -65,7 +63,8 @@ def get_scanner(hass, config): class TplinkDeviceScanner(object): - """ This class queries a wireless router running TP-Link firmware + """ + This class queries a wireless router running TP-Link firmware for connected devices. """ @@ -85,8 +84,9 @@ class TplinkDeviceScanner(object): self.success_init = self._update_info() def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device ids. + """ self._update_info() @@ -94,15 +94,18 @@ class TplinkDeviceScanner(object): # pylint: disable=no-self-use def get_device_name(self, device): - """ The TP-Link firmware doesn't save the name of the wireless - device. """ + """ + The TP-Link firmware doesn't save the name of the wireless device. + """ return None @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the TP-Link router is up to date. - Returns boolean if scanning successful. """ + """ + Ensures the information from the TP-Link router is up to date. + Returns boolean if scanning successful. + """ with self.lock: _LOGGER.info("Loading wireless clients...") @@ -122,28 +125,33 @@ class TplinkDeviceScanner(object): class Tplink2DeviceScanner(TplinkDeviceScanner): - """ This class queries a wireless router running newer version of TP-Link + """ + This class queries a wireless router running newer version of TP-Link firmware for connected devices. """ def scan_devices(self): - """ Scans for new devices and return a - list containing found device ids. """ + """ + Scans for new devices and return a list containing found device ids. + """ self._update_info() return self.last_results.keys() # pylint: disable=no-self-use def get_device_name(self, device): - """ The TP-Link firmware doesn't save the name of the wireless - device. """ + """ + The TP-Link firmware doesn't save the name of the wireless device. + """ return self.last_results.get(device) @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): - """ Ensures the information from the TP-Link router is up to date. - Returns boolean if scanning successful. """ + """ + Ensures the information from the TP-Link router is up to date. + Returns boolean if scanning successful. + """ with self.lock: _LOGGER.info("Loading wireless clients...") diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index 8fdb525d4e0..9096bb32a10 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -15,7 +15,7 @@ Support for LimitlessLED bulbs, also known as... Configuration: To use limitlessled you will need to add the following to your -config/configuration.yaml. +configuration.yaml file. light: platform: limitlessled @@ -24,7 +24,6 @@ light: group_2_name: Bedroom group_3_name: Office group_4_name: Kitchen - """ import logging @@ -107,7 +106,7 @@ class LimitlessLED(Light): return self._xy_color def _xy_to_led_color(self, xy_color): - """ Convert an XY color to the closest LedController color string """ + """ Convert an XY color to the closest LedController color string. """ def abs_dist_squared(p_0, p_1): """ Returns the absolute value of the squared distance """ return abs((p_0[0] - p_1[0])**2 + (p_0[1] - p_1[1])**2) diff --git a/homeassistant/components/light/vera.py b/homeassistant/components/light/vera.py index f25c110cc46..f41bfb56685 100644 --- a/homeassistant/components/light/vera.py +++ b/homeassistant/components/light/vera.py @@ -1,7 +1,6 @@ """ homeassistant.components.light.vera ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Support for Vera lights. This component is useful if you wish for switches connected to your Vera controller to appear as lights in Home Assistant. All switches will be added as a light unless you exclude them in the config. @@ -9,17 +8,17 @@ All switches will be added as a light unless you exclude them in the config. Configuration: To use the Vera lights you will need to add something like the following to -your config/configuration.yaml. +your configuration.yaml file. light: - platform: vera - vera_controller_url: http://YOUR_VERA_IP:3480/ - device_data: - 12: - name: My awesome switch - exclude: true - 13: - name: Another switch + platform: vera + vera_controller_url: http://YOUR_VERA_IP:3480/ + device_data: + 12: + name: My awesome switch + exclude: true + 13: + name: Another switch Variables: @@ -52,8 +51,10 @@ it should be set to "true" if you want this device excluded. import logging from requests.exceptions import RequestException from homeassistant.components.switch.vera import VeraSwitch -# pylint: disable=no-name-in-module, import-error -import homeassistant.external.vera.vera as veraApi + +REQUIREMENTS = ['https://github.com/balloob/home-assistant-vera-api/archive/' + 'a8f823066ead6c7da6fb5e7abaf16fef62e63364.zip' + '#python-vera==0.1'] _LOGGER = logging.getLogger(__name__) @@ -61,6 +62,7 @@ _LOGGER = logging.getLogger(__name__) # pylint: disable=unused-argument def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Find and return Vera lights. """ + import pyvera as veraApi base_url = config.get('vera_controller_url') if not base_url: diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index a576898de59..61223446e5f 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -1,10 +1,24 @@ """ homeassistant.components.media_player.chromecast ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Provides functionality to interact with Cast devices on the network. -WARNING: This platform is currently not working due to a changed Cast API +WARNING: This platform is currently not working due to a changed Cast API. + +Configuration: + +To use the chromecast integration you will need to add something like the +following to your configuration.yaml file. + +media_player: + platform: chromecast + host: 192.168.1.9 + +Variables: + +host +*Optional +Use only if you don't want to scan for devices. """ import logging diff --git a/homeassistant/components/media_player/demo.py b/homeassistant/components/media_player/demo.py index 24f1e91c3ec..2a7bc5bde1b 100644 --- a/homeassistant/components/media_player/demo.py +++ b/homeassistant/components/media_player/demo.py @@ -1,9 +1,7 @@ """ homeassistant.components.media_player.demo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Demo implementation of the media player. - """ from homeassistant.const import ( STATE_PLAYING, STATE_PAUSED, STATE_OFF) diff --git a/homeassistant/components/media_player/kodi.py b/homeassistant/components/media_player/kodi.py index dfc2f64a2a8..ab8af7787c3 100644 --- a/homeassistant/components/media_player/kodi.py +++ b/homeassistant/components/media_player/kodi.py @@ -6,7 +6,7 @@ Provides an interface to the XBMC/Kodi JSON-RPC API Configuration: To use the Kodi you will need to add something like the following to -your config/configuration.yaml. +your configuration.yaml file. media_player: platform: kodi @@ -74,7 +74,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): def _get_image_url(kodi_url): - """ Helper function that parses the thumbnail URLs used by Kodi """ + """ Helper function that parses the thumbnail URLs used by Kodi. """ url_components = urllib.parse.urlparse(kodi_url) if url_components.scheme == 'image': @@ -235,7 +235,7 @@ class KodiDevice(MediaPlayerDevice): self.update_ha_state() def _set_play_state(self, state): - """ Helper method for play/pause/toggle """ + """ Helper method for play/pause/toggle. """ players = self._get_players() if len(players) != 0: @@ -256,7 +256,7 @@ class KodiDevice(MediaPlayerDevice): self._set_play_state(False) def _goto(self, direction): - """ Helper method used for previous/next track """ + """ Helper method used for previous/next track. """ players = self._get_players() if len(players) != 0: diff --git a/homeassistant/components/media_player/mpd.py b/homeassistant/components/media_player/mpd.py index 58d0d9a731e..8cc22f9b982 100644 --- a/homeassistant/components/media_player/mpd.py +++ b/homeassistant/components/media_player/mpd.py @@ -1,13 +1,12 @@ """ homeassistant.components.media_player.mpd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Provides functionality to interact with a Music Player Daemon. Configuration: To use MPD you will need to add something like the following to your -config/configuration.yaml +configuration.yaml file. media_player: platform: mpd diff --git a/homeassistant/components/media_player/squeezebox.py b/homeassistant/components/media_player/squeezebox.py index 8cbc087c50c..940aa890f3a 100644 --- a/homeassistant/components/media_player/squeezebox.py +++ b/homeassistant/components/media_player/squeezebox.py @@ -1,12 +1,12 @@ """ homeassistant.components.media_player.squeezebox ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Provides an interface to the Logitech SqueezeBox API Configuration: -To use SqueezeBox add something like this to your configuration: +To use SqueezeBox add something something like the following to your +configuration.yaml file. media_player: platform: squeezebox @@ -19,19 +19,19 @@ Variables: host *Required -The host name or address of the Logitech Media Server +The host name or address of the Logitech Media Server. port *Optional -Telnet port to Logitech Media Server, default 9090 +Telnet port to Logitech Media Server, default 9090. usermame *Optional -Username, if password protection is enabled +Username, if password protection is enabled. password *Optional -Password, if password protection is enabled +Password, if password protection is enabled. """ import logging @@ -91,7 +91,7 @@ class LogitechMediaServer(object): self.init_success = True if self.http_port else False def _get_http_port(self): - """ Get http port from media server, it is used to get cover art """ + """ Get http port from media server, it is used to get cover art. """ http_port = None try: http_port = self.query('pref', 'httpport', '?') @@ -111,7 +111,7 @@ class LogitechMediaServer(object): return def create_players(self): - """ Create a list of SqueezeBoxDevices connected to the LMS """ + """ Create a list of SqueezeBoxDevices connected to the LMS. """ players = [] count = self.query('player', 'count', '?') for index in range(0, int(count)): @@ -121,7 +121,7 @@ class LogitechMediaServer(object): return players def query(self, *parameters): - """ Send request and await response from server """ + """ Send request and await response from server. """ telnet = telnetlib.Telnet(self.host, self.port) if self._username and self._password: telnet.write('login {username} {password}\n'.format( @@ -138,7 +138,7 @@ class LogitechMediaServer(object): return urllib.parse.unquote(response) def get_player_status(self, player): - """ Get ithe status of a player """ + """ Get ithe status of a player. """ # (title) : Song title # Requested Information # a (artist): Artist name 'artist' @@ -195,7 +195,7 @@ class SqueezeBoxDevice(MediaPlayerDevice): def update(self): """ Retrieve latest state. """ - self._status = self._lms.get_player_status(self._name) + self._status = self._lms.get_player_status(self._id) @property def volume_level(self): diff --git a/homeassistant/components/modbus.py b/homeassistant/components/modbus.py index e6c3f1cfcee..844e59ea189 100644 --- a/homeassistant/components/modbus.py +++ b/homeassistant/components/modbus.py @@ -1,17 +1,12 @@ """ homeassistant.components.modbus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Modbus component, using pymodbus (python3 branch) - -Configuration: - -To use the Forecast sensor you will need to add something like the -following to your config/configuration.yaml +Modbus component, using pymodbus (python3 branch). Configuration: To use the Modbus component you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. #Modbus TCP modbus: @@ -38,8 +33,8 @@ from homeassistant.const import (EVENT_HOMEASSISTANT_START, DOMAIN = "modbus" DEPENDENCIES = [] -REQUIREMENTS = ['https://github.com/bashwork/pymodbus/archive/' + - 'd7fc4f1cc975631e0a9011390e8017f64b612661.zip'] +REQUIREMENTS = ['https://github.com/bashwork/pymodbus/archive/' + 'd7fc4f1cc975631e0a9011390e8017f64b612661.zip#pymodbus==1.2.0'] # Type of network MEDIUM = "type" diff --git a/homeassistant/components/mqtt.py b/homeassistant/components/mqtt.py index 474b5ebb53e..e157f15f84b 100644 --- a/homeassistant/components/mqtt.py +++ b/homeassistant/components/mqtt.py @@ -60,7 +60,6 @@ MQTT_CLIENT = None DEFAULT_PORT = 1883 DEFAULT_KEEPALIVE = 60 -DEFAULT_QOS = 0 SERVICE_PUBLISH = 'publish' EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED' @@ -75,16 +74,17 @@ CONF_KEEPALIVE = 'keepalive' CONF_USERNAME = 'username' CONF_PASSWORD = 'password' -ATTR_QOS = 'qos' ATTR_TOPIC = 'topic' ATTR_PAYLOAD = 'payload' +ATTR_QOS = 'qos' -def publish(hass, topic, payload): +def publish(hass, topic, payload, qos=0): """ Send an MQTT message. """ data = { ATTR_TOPIC: topic, ATTR_PAYLOAD: payload, + ATTR_QOS: qos, } hass.services.call(DOMAIN, SERVICE_PUBLISH, data) @@ -141,9 +141,10 @@ def setup(hass, config): """ Handle MQTT publish service calls. """ msg_topic = call.data.get(ATTR_TOPIC) payload = call.data.get(ATTR_PAYLOAD) + qos = call.data.get(ATTR_QOS) if msg_topic is None or payload is None: return - MQTT_CLIENT.publish(msg_topic, payload) + MQTT_CLIENT.publish(msg_topic, payload, qos) hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_mqtt) @@ -177,9 +178,9 @@ class MQTT(object): # pragma: no cover self._mqttc.on_message = self._mqtt_on_message self._mqttc.connect(broker, port, keepalive) - def publish(self, topic, payload): + def publish(self, topic, payload, qos): """ Publish a MQTT message. """ - self._mqttc.publish(topic, payload) + self._mqttc.publish(topic, payload, qos) def unsubscribe(self, topic): """ Unsubscribe from topic. """ diff --git a/homeassistant/components/notify/file.py b/homeassistant/components/notify/file.py index 186bc53ca98..9c0beca14ac 100644 --- a/homeassistant/components/notify/file.py +++ b/homeassistant/components/notify/file.py @@ -1,13 +1,12 @@ """ homeassistant.components.notify.file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - File notification service. Configuration: To use the File notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: platform: file diff --git a/homeassistant/components/notify/instapush.py b/homeassistant/components/notify/instapush.py index 531ef758e05..95ff0d41435 100644 --- a/homeassistant/components/notify/instapush.py +++ b/homeassistant/components/notify/instapush.py @@ -1,13 +1,12 @@ """ homeassistant.components.notify.instapush ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Instapush notification service. Configuration: To use the Instapush notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: platform: instapush @@ -16,7 +15,7 @@ notify: event: YOUR_EVENT tracker: YOUR_TRACKER -VARIABLES: +Variables: api_key *Required @@ -50,7 +49,6 @@ curl -X POST \ https://api.instapush.im/v1/post Details for the API : https://instapush.im/developer/rest - """ import logging import json diff --git a/homeassistant/components/notify/nma.py b/homeassistant/components/notify/nma.py index db6c91d8fed..bf8fb2162a8 100644 --- a/homeassistant/components/notify/nma.py +++ b/homeassistant/components/notify/nma.py @@ -1,19 +1,18 @@ """ homeassistant.components.notify.nma ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - NMA (Notify My Android) notification service. Configuration: To use the NMA notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: platform: nma api_key: YOUR_API_KEY -VARIABLES: +Variables: api_key *Required @@ -21,7 +20,6 @@ Enter the API key for NMA. Go to https://www.notifymyandroid.com and create a new API key to use with Home Assistant. Details for the API : https://www.notifymyandroid.com/api.jsp - """ import logging import xml.etree.ElementTree as ET diff --git a/homeassistant/components/notify/pushbullet.py b/homeassistant/components/notify/pushbullet.py index 58462954d2e..76eaf5c0c37 100644 --- a/homeassistant/components/notify/pushbullet.py +++ b/homeassistant/components/notify/pushbullet.py @@ -1,13 +1,12 @@ """ homeassistant.components.notify.pushbullet ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - PushBullet platform for notify component. Configuration: To use the PushBullet notifier you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. notify: platform: pushbullet @@ -32,7 +31,7 @@ REQUIREMENTS = ['pushbullet.py==0.7.1'] def get_service(hass, config): - """ Get the pushbullet notification service. """ + """ Get the PushBullet notification service. """ if not validate_config(config, {DOMAIN: [CONF_API_KEY]}, diff --git a/homeassistant/components/notify/pushover.py b/homeassistant/components/notify/pushover.py index 0df035a4a6e..c52e430ac9f 100644 --- a/homeassistant/components/notify/pushover.py +++ b/homeassistant/components/notify/pushover.py @@ -1,18 +1,17 @@ """ homeassistant.components.notify.pushover ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Pushover platform for notify component. Configuration: To use the Pushover notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: - platform: pushover - api_key: ABCDEFGHJKLMNOPQRSTUVXYZ - user_key: ABCDEFGHJKLMNOPQRSTUVXYZ + platform: pushover + api_key: ABCDEFGHJKLMNOPQRSTUVXYZ + user_key: ABCDEFGHJKLMNOPQRSTUVXYZ Variables: @@ -33,7 +32,6 @@ https://home-assistant.io/images/favicon-192x192.png user_key *Required To retrieve this value log into your account at https://pushover.net - """ import logging diff --git a/homeassistant/components/notify/slack.py b/homeassistant/components/notify/slack.py index d604cffb754..bd3a2b71c0c 100644 --- a/homeassistant/components/notify/slack.py +++ b/homeassistant/components/notify/slack.py @@ -6,7 +6,7 @@ Slack platform for notify component. Configuration: To use the Slack notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: platform: slack diff --git a/homeassistant/components/notify/smtp.py b/homeassistant/components/notify/smtp.py index 998391c81b4..0530ac4072d 100644 --- a/homeassistant/components/notify/smtp.py +++ b/homeassistant/components/notify/smtp.py @@ -1,13 +1,12 @@ """ homeassistant.components.notify.mail ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Mail notification service. +Mail (SMTP) notification service. Configuration: To use the Mail notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: platform: mail diff --git a/homeassistant/components/notify/syslog.py b/homeassistant/components/notify/syslog.py index 6673ba23a08..5d246f2fd0d 100644 --- a/homeassistant/components/notify/syslog.py +++ b/homeassistant/components/notify/syslog.py @@ -1,13 +1,12 @@ """ homeassistant.components.notify.syslog ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Syslog notification service. Configuration: To use the Syslog notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: platform: syslog diff --git a/homeassistant/components/notify/xmpp.py b/homeassistant/components/notify/xmpp.py index 81268c734b7..1d72f6a262b 100644 --- a/homeassistant/components/notify/xmpp.py +++ b/homeassistant/components/notify/xmpp.py @@ -6,7 +6,7 @@ Jabber (XMPP) notification service. Configuration: To use the Jabber notifier you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. notify: platform: xmpp diff --git a/homeassistant/components/sensor/arduino.py b/homeassistant/components/sensor/arduino.py index 4210a064d13..f6c44d3f60e 100644 --- a/homeassistant/components/sensor/arduino.py +++ b/homeassistant/components/sensor/arduino.py @@ -6,6 +6,9 @@ supported. Configuration: +To use the arduino sensor you will need to add something like the following +to your configuration.yaml file. + sensor: platform: arduino pins: @@ -46,7 +49,7 @@ _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_devices, discovery_info=None): """ Sets up the Arduino platform. """ - # Verify that Arduino board is present + # Verify that the Arduino board is present if arduino.BOARD is None: _LOGGER.error('A connection has not been made to the Arduino board.') return False diff --git a/homeassistant/components/sensor/arest.py b/homeassistant/components/sensor/arest.py new file mode 100644 index 00000000000..78d173ef283 --- /dev/null +++ b/homeassistant/components/sensor/arest.py @@ -0,0 +1,150 @@ +""" +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 +} +""" +import logging +from requests import get, exceptions +from datetime import timedelta + +from homeassistant.util import Throttle +from homeassistant.helpers.entity import Entity + +_LOGGER = logging.getLogger(__name__) + +# Return cached results if last scan was less then this time ago +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """ Get the aREST sensor. """ + + resource = config.get('resource', None) + + try: + response = get(resource) + except exceptions.MissingSchema: + _LOGGER.error("Missing resource or schema in configuration. " + "Add http:// to your URL.") + return False + except exceptions.ConnectionError: + _LOGGER.error("No route to device. " + "Please check the IP address in the configuration file.") + return False + + rest = ArestData(resource) + + dev = [] + for variable in config['monitored_variables']: + if 'unit' not in variable: + variable['unit'] = ' ' + if variable['name'] not in response.json()['variables']: + _LOGGER.error('Variable: "%s" does not exist', variable['name']) + else: + dev.append(ArestSensor(rest, + response.json()['name'], + variable['name'], + variable['unit'])) + + add_devices(dev) + + +class ArestSensor(Entity): + """ Implements an aREST sensor. """ + + def __init__(self, rest, location, variable, unit_of_measurement): + self.rest = rest + self._name = '{} {}'.format(location.title(), variable.title()) + self._variable = variable + self._state = 'n/a' + self._unit_of_measurement = unit_of_measurement + self.update() + + @property + def name(self): + """ The name of the sensor. """ + return self._name + + @property + def unit_of_measurement(self): + """ Unit the value is expressed in. """ + return self._unit_of_measurement + + @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 + + if 'error' in values: + self._state = values['error'] + else: + self._state = values[self._variable] + + +# pylint: disable=too-few-public-methods +class ArestData(object): + """ Class for handling the data retrieval. """ + + def __init__(self, resource): + self.resource = resource + self.data = dict() + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """ Gets the latest data from aREST device. """ + try: + response = get(self.resource) + if 'error' in self.data: + del self.data['error'] + self.data = response.json()['variables'] + except exceptions.ConnectionError: + _LOGGER.error("No route to device. Is device offline?") + self.data['error'] = 'n/a' diff --git a/homeassistant/components/sensor/bitcoin.py b/homeassistant/components/sensor/bitcoin.py index b30886448ad..60a8a9172b7 100644 --- a/homeassistant/components/sensor/bitcoin.py +++ b/homeassistant/components/sensor/bitcoin.py @@ -1,7 +1,6 @@ """ homeassistant.components.sensor.bitcoin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Bitcoin information service that uses blockchain.info and its online wallet. Configuration: @@ -12,7 +11,7 @@ check 'Enable Api Access'. You will get an email message from blockchain.info where you must authorize the API access. To use the Bitcoin sensor you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. sensor: platform: bitcoin diff --git a/homeassistant/components/sensor/demo.py b/homeassistant/components/sensor/demo.py index 218860290b0..333a0564dfb 100644 --- a/homeassistant/components/sensor/demo.py +++ b/homeassistant/components/sensor/demo.py @@ -1,9 +1,7 @@ """ homeassistant.components.sensor.demo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Demo platform that has two fake sensors. - +Demo platform that has a couple of fake sensors. """ from homeassistant.helpers.entity import Entity from homeassistant.const import TEMP_CELCIUS, ATTR_BATTERY_LEVEL diff --git a/homeassistant/components/sensor/dht.py b/homeassistant/components/sensor/dht.py index 7949a7a44fa..2ce0b12be38 100644 --- a/homeassistant/components/sensor/dht.py +++ b/homeassistant/components/sensor/dht.py @@ -1,6 +1,6 @@ """ homeassistant.components.sensor.dht -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Adafruit DHT temperature and humidity sensor. You need a Python3 compatible version of the Adafruit_Python_DHT library (e.g. https://github.com/mala-zaba/Adafruit_Python_DHT, @@ -10,8 +10,8 @@ as root. Configuration: -To use the Adafruit DHT sensor you will need to -add something like the following to your config/configuration.yaml: +To use the Adafruit DHT sensor you will need to add something like the +following to your configuration.yaml file. sensor: platform: dht @@ -44,8 +44,10 @@ from homeassistant.const import TEMP_FAHRENHEIT from homeassistant.helpers.entity import Entity # update this requirement to upstream as soon as it supports python3 -REQUIREMENTS = ['http://github.com/mala-zaba/Adafruit_Python_DHT/archive/' + - '4101340de8d2457dd194bca1e8d11cbfc237e919.zip'] +REQUIREMENTS = ['http://github.com/mala-zaba/Adafruit_Python_DHT/archive/' + '4101340de8d2457dd194bca1e8d11cbfc237e919.zip' + '#Adafruit_DHT==1.1.0'] + _LOGGER = logging.getLogger(__name__) SENSOR_TYPES = { 'temperature': ['Temperature', ''], @@ -102,7 +104,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # pylint: disable=too-few-public-methods class DHTSensor(Entity): - """ Implements an DHT sensor. """ def __init__(self, dht_client, sensor_type, temp_unit): @@ -144,7 +145,6 @@ class DHTSensor(Entity): class DHTClient(object): - """ Gets the latest data from the DHT sensor. """ def __init__(self, adafruit_dht, sensor, pin): diff --git a/homeassistant/components/sensor/efergy.py b/homeassistant/components/sensor/efergy.py index 893c4403d71..aed685dce67 100644 --- a/homeassistant/components/sensor/efergy.py +++ b/homeassistant/components/sensor/efergy.py @@ -7,7 +7,7 @@ Monitors home energy use as measured by an efergy engage hub using its Configuration: To use the efergy sensor you will need to add something like the following -to your config/configuration.yaml +to your configuration.yaml file. sensor: platform: efergy @@ -61,7 +61,7 @@ SENSOR_TYPES = { def setup_platform(hass, config, add_devices, discovery_info=None): - """ Sets up the efergy sensor. """ + """ Sets up the Efergy sensor. """ app_token = config.get("app_token") if not app_token: _LOGGER.error( @@ -118,7 +118,7 @@ class EfergySensor(Entity): return self._unit_of_measurement def update(self): - """ Gets the efergy monitor data from the web service """ + """ Gets the Efergy monitor data from the web service. """ if self.type == 'instant_readings': url_string = _RESOURCE + 'getInstant?token=' + self.app_token response = get(url_string) diff --git a/homeassistant/components/sensor/forecast.py b/homeassistant/components/sensor/forecast.py index b56432ab89b..2c966530967 100644 --- a/homeassistant/components/sensor/forecast.py +++ b/homeassistant/components/sensor/forecast.py @@ -1,12 +1,12 @@ """ homeassistant.components.sensor.forecast ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Forecast.io service. +Forecast.io weather service. Configuration: To use the Forecast sensor you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. sensor: platform: forecast @@ -37,11 +37,9 @@ monitored_conditions *Required An array specifying the conditions to monitor. -These are the variables for the monitored_conditions array: - -type +monitored_conditions *Required -The condition you wish to monitor, see the configuration example above for a +Conditions to monitor. See the configuration example above for a list of all available conditions to monitor. Details for the API : https://developer.forecast.io/docs/v2 @@ -73,7 +71,7 @@ SENSOR_TYPES = { 'humidity': ['Humidity', '%'], 'pressure': ['Pressure', 'mBar'], 'visibility': ['Visibility', 'km'], - 'ozone': ['Ozone', ''], + 'ozone': ['Ozone', 'DU'], } # Return cached results if last scan was less then this time ago diff --git a/homeassistant/components/sensor/isy994.py b/homeassistant/components/sensor/isy994.py index 7a242c044f7..c30f618f715 100644 --- a/homeassistant/components/sensor/isy994.py +++ b/homeassistant/components/sensor/isy994.py @@ -1,7 +1,6 @@ """ homeassistant.components.sensor.isy994 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Support for ISY994 sensors. """ import logging diff --git a/homeassistant/components/sensor/modbus.py b/homeassistant/components/sensor/modbus.py index c1cbf101dc2..ac2a5e444d1 100644 --- a/homeassistant/components/sensor/modbus.py +++ b/homeassistant/components/sensor/modbus.py @@ -4,8 +4,9 @@ homeassistant.components.modbus Support for Modbus sensors. Configuration: + To use the Modbus sensors you will need to add something like the following to -your config/configuration.yaml +your configuration.yaml file. sensor: platform: modbus @@ -47,7 +48,6 @@ Note: - Each named register will create an integer sensor. - Each named bit will create a boolean sensor. """ - import logging import homeassistant.components.modbus as modbus @@ -61,7 +61,7 @@ DEPENDENCIES = ['modbus'] def setup_platform(hass, config, add_devices, discovery_info=None): - """ Read config and create Modbus devices """ + """ Read config and create Modbus devices. """ sensors = [] slave = config.get("slave", None) if modbus.TYPE == "serial" and not slave: @@ -97,7 +97,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class ModbusSensor(Entity): # pylint: disable=too-many-arguments - """ Represents a Modbus Sensor """ + """ Represents a Modbus Sensor. """ def __init__(self, name, slave, register, bit=None, unit=None, coil=False): self._name = name @@ -113,8 +113,10 @@ class ModbusSensor(Entity): @property def should_poll(self): - """ We should poll, because slaves are not allowed to - initiate communication on Modbus networks""" + """ + We should poll, because slaves are not allowed to + initiate communication on Modbus networks. + """ return True @property diff --git a/homeassistant/components/sensor/mqtt.py b/homeassistant/components/sensor/mqtt.py index d5dc192e450..37540820fcc 100644 --- a/homeassistant/components/sensor/mqtt.py +++ b/homeassistant/components/sensor/mqtt.py @@ -13,6 +13,7 @@ sensor: platform: mqtt name: "MQTT Sensor" state_topic: "home/bedroom/temperature" + qos: 0 unit_of_measurement: "ºC" Variables: @@ -25,6 +26,10 @@ state_topic *Required The MQTT topic subscribed to receive sensor values. +qos +*Optional +The maximum QoS level of the state topic. Default is 0. + unit_of_measurement *Optional Defines the units of measurement of the sensor, if any. @@ -38,6 +43,7 @@ import homeassistant.components.mqtt as mqtt _LOGGER = logging.getLogger(__name__) DEFAULT_NAME = "MQTT Sensor" +DEFAULT_QOS = 0 DEPENDENCIES = ['mqtt'] @@ -54,16 +60,19 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): hass, config.get('name', DEFAULT_NAME), config.get('state_topic'), + config.get('qos', DEFAULT_QOS), config.get('unit_of_measurement'))]) +# pylint: disable=too-many-arguments, too-many-instance-attributes class MqttSensor(Entity): """ Represents a sensor that can be updated using MQTT """ - def __init__(self, hass, name, state_topic, unit_of_measurement): + def __init__(self, hass, name, state_topic, qos, unit_of_measurement): self._state = "-" self._hass = hass self._name = name self._state_topic = state_topic + self._qos = qos self._unit_of_measurement = unit_of_measurement def message_received(topic, payload, qos): @@ -71,7 +80,7 @@ class MqttSensor(Entity): self._state = payload self.update_ha_state() - mqtt.subscribe(hass, self._state_topic, message_received) + mqtt.subscribe(hass, self._state_topic, message_received, self._qos) @property def should_poll(self): diff --git a/homeassistant/components/sensor/mysensors.py b/homeassistant/components/sensor/mysensors.py index 994b110a585..60e84059cad 100644 --- a/homeassistant/components/sensor/mysensors.py +++ b/homeassistant/components/sensor/mysensors.py @@ -1,13 +1,12 @@ """ homeassistant.components.sensor.mysensors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Support for MySensors sensors. Configuration: To use the MySensors sensor you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. sensor: platform: mysensors @@ -36,8 +35,9 @@ ATTR_NODE_ID = "node_id" ATTR_CHILD_ID = "child_id" _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['https://github.com/theolind/pymysensors/archive/' + - '35b87d880147a34107da0d40cb815d75e6cb4af7.zip'] +REQUIREMENTS = ['https://github.com/theolind/pymysensors/archive/' + '35b87d880147a34107da0d40cb815d75e6cb4af7.zip' + '#pymysensors==0.2'] def setup_platform(hass, config, add_devices, discovery_info=None): diff --git a/homeassistant/components/sensor/openweathermap.py b/homeassistant/components/sensor/openweathermap.py index 537fc9f59b5..5ca292a599f 100644 --- a/homeassistant/components/sensor/openweathermap.py +++ b/homeassistant/components/sensor/openweathermap.py @@ -6,7 +6,7 @@ OpenWeatherMap (OWM) service. Configuration: To use the OpenWeatherMap sensor you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. sensor: platform: openweathermap @@ -33,7 +33,7 @@ forecast Enables the forecast. The default is to display the current conditions. monitored_conditions -*Optional +*Required Conditions to monitor. See the configuration example above for a list of all available conditions to monitor. diff --git a/homeassistant/components/sensor/rfxtrx.py b/homeassistant/components/sensor/rfxtrx.py index 8e5a1ad3dca..4cb8a939d5e 100644 --- a/homeassistant/components/sensor/rfxtrx.py +++ b/homeassistant/components/sensor/rfxtrx.py @@ -4,10 +4,9 @@ homeassistant.components.sensor.rfxtrx Shows sensor values from RFXtrx sensors. Configuration: -To use the rfxtrx sensors you will need to add something like the following to -your config/configuration.yaml -Example: +To use the rfxtrx sensors you will need to add something like the following to +your configuration.yaml file. sensor: platform: rfxtrx @@ -27,7 +26,7 @@ from homeassistant.const import (TEMP_CELCIUS) from homeassistant.helpers.entity import Entity REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' + - 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip'] + 'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15'] DATA_TYPES = OrderedDict([ ('Temperature', TEMP_CELCIUS), @@ -102,4 +101,5 @@ class RfxtrxSensor(Entity): @property def unit_of_measurement(self): + """ Unit this state is expressed in. """ return self._unit_of_measurement diff --git a/homeassistant/components/sensor/rpi_gpio.py b/homeassistant/components/sensor/rpi_gpio.py index f973b24a301..e8482ea56ac 100644 --- a/homeassistant/components/sensor/rpi_gpio.py +++ b/homeassistant/components/sensor/rpi_gpio.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ homeassistant.components.sensor.rpi_gpio -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Allows to configure a binary state sensor using RPi GPIO. Note: To use RPi GPIO, Home Assistant must be run as root. @@ -35,11 +35,10 @@ The time in milliseconds for port debouncing. Default is 50ms. ports *Required An array specifying the GPIO ports to use and the name to use in the frontend. - """ - import logging from homeassistant.helpers.entity import Entity + try: import RPi.GPIO as GPIO except ImportError: @@ -119,12 +118,12 @@ class RPiGPIOSensor(Entity): @property def should_poll(self): - """ No polling needed """ + """ No polling needed. """ return False @property def name(self): - """ The name of the sensor """ + """ The name of the sensor. """ return self._name @property diff --git a/homeassistant/components/sensor/sabnzbd.py b/homeassistant/components/sensor/sabnzbd.py index cc37bd96b6f..b372e777478 100644 --- a/homeassistant/components/sensor/sabnzbd.py +++ b/homeassistant/components/sensor/sabnzbd.py @@ -1,13 +1,12 @@ """ homeassistant.components.sensor.sabnzbd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Monitors SABnzbd NZB client API Configuration: To use the SABnzbd sensor you will need to add something like the following to -your config/configuration.yaml +your configuration.yaml file. sensor: platform: sabnzbd @@ -27,11 +26,11 @@ Variables: base_url *Required This is the base URL of your SABnzbd instance including the port number if not -running on 80. Example: http://192.168.1.32:8124/ +running on 80, e.g. http://192.168.1.32:8124/ name *Optional -The name to use when displaying this SABnzbd instance +The name to use when displaying this SABnzbd instance. monitored_variables *Required @@ -44,17 +43,17 @@ type The variable you wish to monitor, see the configuration example above for a list of all available variables. """ - from homeassistant.util import Throttle from datetime import timedelta from homeassistant.helpers.entity import Entity -# pylint: disable=no-name-in-module, import-error -from homeassistant.external.nzbclients.sabnzbd import SabnzbdApi -from homeassistant.external.nzbclients.sabnzbd import SabnzbdApiException import logging +REQUIREMENTS = ['https://github.com/jamespcole/home-assistant-nzb-clients/' + 'archive/616cad59154092599278661af17e2a9f2cf5e2a9.zip' + '#python-sabnzbd==0.1'] + SENSOR_TYPES = { 'current_status': ['Status', ''], 'speed': ['Speed', 'MB/s'], @@ -71,7 +70,9 @@ _THROTTLED_REFRESH = None # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): - """ Sets up the sensors. """ + """ Sets up the SABnzbd sensors. """ + from pysabnzbd import SabnzbdApi, SabnzbdApiException + api_key = config.get("api_key") base_url = config.get("base_url") name = config.get("name", "SABnzbd") @@ -105,7 +106,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class SabnzbdSensor(Entity): - """ A Sabnzbd sensor """ + """ Represents an SABnzbd sensor. """ def __init__(self, sensor_type, sabnzb_client, client_name): self._name = SENSOR_TYPES[sensor_type][0] @@ -132,6 +133,7 @@ class SabnzbdSensor(Entity): def refresh_sabnzbd_data(self): """ Calls the throttled SABnzbd refresh method. """ if _THROTTLED_REFRESH is not None: + from pysabnzbd import SabnzbdApiException try: _THROTTLED_REFRESH() except SabnzbdApiException: diff --git a/homeassistant/components/sensor/swiss_public_transport.py b/homeassistant/components/sensor/swiss_public_transport.py index bd2d336d8ed..440c7f8ad28 100644 --- a/homeassistant/components/sensor/swiss_public_transport.py +++ b/homeassistant/components/sensor/swiss_public_transport.py @@ -1,14 +1,13 @@ """ homeassistant.components.sensor.swiss_public_transport ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - The Swiss public transport sensor will give you the next two departure times from a given location to another one. This sensor is limited to Switzerland. Configuration: To use the Swiss public transport sensor you will need to add something like -the following to your config/configuration.yaml +the following to your configuration.yaml file. sensor: platform: swiss_public_transport diff --git a/homeassistant/components/sensor/systemmonitor.py b/homeassistant/components/sensor/systemmonitor.py index b473cc27283..ff7e908ccf1 100644 --- a/homeassistant/components/sensor/systemmonitor.py +++ b/homeassistant/components/sensor/systemmonitor.py @@ -1,13 +1,12 @@ """ homeassistant.components.sensor.systemmonitor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Shows system monitor values such as: disk, memory and processor use +Shows system monitor values such as: disk, memory, and processor use. Configuration: To use the System monitor sensor you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. sensor: platform: systemmonitor diff --git a/homeassistant/components/sensor/tellstick.py b/homeassistant/components/sensor/tellstick.py index e93c6e4c97f..7ee0fc19a99 100644 --- a/homeassistant/components/sensor/tellstick.py +++ b/homeassistant/components/sensor/tellstick.py @@ -1,8 +1,7 @@ """ homeassistant.components.sensor.tellstick ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Shows sensor values from tellstick sensors. +Shows sensor values from Tellstick sensors. Possible config keys: diff --git a/homeassistant/components/sensor/temper.py b/homeassistant/components/sensor/temper.py index 8579a922661..c7943f0cc06 100644 --- a/homeassistant/components/sensor/temper.py +++ b/homeassistant/components/sensor/temper.py @@ -4,10 +4,9 @@ homeassistant.components.sensor.temper Support for getting temperature from TEMPer devices. Configuration: -To use the temper sensors you will need to add something like the following to -your config/configuration.yaml -Example: +To use the temper sensors you will need to add something like the following to +your configuration.yaml file. sensor: platform: temper @@ -18,8 +17,9 @@ from homeassistant.const import CONF_NAME, DEVICE_DEFAULT_NAME _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['https://github.com/rkabadi/temper-python/archive/' + - '3dbdaf2d87b8db9a3cd6e5585fc704537dd2d09b.zip'] +REQUIREMENTS = ['https://github.com/rkabadi/temper-python/archive/' + '3dbdaf2d87b8db9a3cd6e5585fc704537dd2d09b.zip' + '#temperusb==1.2.3'] # pylint: disable=unused-argument diff --git a/homeassistant/components/sensor/time_date.py b/homeassistant/components/sensor/time_date.py index 149730d4b5b..77011c3afad 100644 --- a/homeassistant/components/sensor/time_date.py +++ b/homeassistant/components/sensor/time_date.py @@ -1,13 +1,12 @@ """ homeassistant.components.sensor.time_date ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Date and Time service. Configuration: To use the Date and Time sensor you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. sensor: platform: time_date diff --git a/homeassistant/components/sensor/transmission.py b/homeassistant/components/sensor/transmission.py index 587f5131d9d..992a8838f3f 100644 --- a/homeassistant/components/sensor/transmission.py +++ b/homeassistant/components/sensor/transmission.py @@ -1,31 +1,30 @@ """ homeassistant.components.sensor.transmission ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Monitors Transmission BitTorrent client API +Monitors Transmission BitTorrent client API. Configuration: To use the Transmission sensor you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. sensor: - platform: transmission - name: Transmission - host: 192.168.1.26 - port: 9091 - username: YOUR_USERNAME - password: YOUR_PASSWORD - monitored_variables: - - type: 'current_status' - - type: 'download_speed' - - type: 'upload_speed' + platform: transmission + name: Transmission + host: 192.168.1.26 + port: 9091 + username: YOUR_USERNAME + password: YOUR_PASSWORD + monitored_variables: + - 'current_status' + - 'download_speed' + - 'upload_speed' Variables: host *Required -This is the IP address of your Transmission daemon. Example: 192.168.1.32 +This is the IP address of your Transmission daemon, e.g. 192.168.1.32 port *Optional @@ -33,11 +32,11 @@ The port your Transmission daemon uses, defaults to 9091. Example: 8080 username *Required -Your Transmission username +Your Transmission username. password *Required -Your Transmission password +Your Transmission password. name *Optional @@ -45,16 +44,9 @@ The name to use when displaying this Transmission instance. monitored_variables *Required -An array specifying the variables to monitor. - -These are the variables for the monitored_variables array: - -type -*Required -The variable you wish to monitor, see the configuration example above for a -list of all available variables. +Variables to monitor. See the configuration example above for a +list of all available variables to monitor. """ - from homeassistant.util import Throttle from datetime import timedelta from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD @@ -81,7 +73,7 @@ _THROTTLED_REFRESH = None # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): - """ Sets up the sensors. """ + """ Sets up the Transmission sensors. """ host = config.get(CONF_HOST) username = config.get(CONF_USERNAME, None) password = config.get(CONF_PASSWORD, None) @@ -110,11 +102,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): dev = [] for variable in config['monitored_variables']: - if variable['type'] not in SENSOR_TYPES: - _LOGGER.error('Sensor type: "%s" does not exist', variable['type']) + if variable not in SENSOR_TYPES: + _LOGGER.error('Sensor type: "%s" does not exist', variable) else: dev.append(TransmissionSensor( - variable['type'], transmission_api, name)) + variable, transmission_api, name)) add_devices(dev) diff --git a/homeassistant/components/sensor/vera.py b/homeassistant/components/sensor/vera.py index 89b2a1a2964..b02e3acdea0 100644 --- a/homeassistant/components/sensor/vera.py +++ b/homeassistant/components/sensor/vera.py @@ -1,13 +1,12 @@ """ homeassistant.components.sensor.vera ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Support for Vera sensors. Configuration: To use the Vera sensors you will need to add something like the following to -your config/configuration.yaml +your configuration.yaml file. sensor: platform: vera @@ -24,8 +23,7 @@ Variables: vera_controller_url *Required This is the base URL of your vera controller including the port number if not -running on 80 -Example: http://192.168.1.21:3480/ +running on 80, e.g. http://192.168.1.21:3480/ device_data @@ -33,7 +31,7 @@ device_data This contains an array additional device info for your Vera devices. It is not required and if not specified all sensors configured in your Vera controller will be added with default values. You should use the id of your vera device -as the key for the device within device_data +as the key for the device within device_data. These are the variables for the device_data array: @@ -41,14 +39,12 @@ name *Optional This parameter allows you to override the name of your Vera device in the HA interface, if not specified the value configured for the device in your Vera -will be used - +will be used. exclude *Optional -This parameter allows you to exclude the specified device from homeassistant, -it should be set to "true" if you want this device excluded - +This parameter allows you to exclude the specified device from Home Assistant, +it should be set to "true" if you want this device excluded. """ import logging from requests.exceptions import RequestException @@ -58,8 +54,10 @@ from homeassistant.helpers.entity import Entity from homeassistant.const import ( ATTR_BATTERY_LEVEL, ATTR_TRIPPED, ATTR_ARMED, ATTR_LAST_TRIP_TIME, TEMP_CELCIUS, TEMP_FAHRENHEIT) -# pylint: disable=no-name-in-module, import-error -import homeassistant.external.vera.vera as veraApi + +REQUIREMENTS = ['https://github.com/balloob/home-assistant-vera-api/archive/' + 'a8f823066ead6c7da6fb5e7abaf16fef62e63364.zip' + '#python-vera==0.1'] _LOGGER = logging.getLogger(__name__) @@ -67,6 +65,7 @@ _LOGGER = logging.getLogger(__name__) # pylint: disable=unused-argument def get_devices(hass, config): """ Find and return Vera Sensors. """ + import pyvera as veraApi base_url = config.get('vera_controller_url') if not base_url: diff --git a/homeassistant/components/switch/arduino.py b/homeassistant/components/switch/arduino.py index 367e7378b27..bb962c08f72 100644 --- a/homeassistant/components/switch/arduino.py +++ b/homeassistant/components/switch/arduino.py @@ -6,6 +6,9 @@ supported. Configuration: +To use the arduino switch you will need to add something like the following +to your configuration.yaml file. + switch: platform: arduino pins: @@ -62,7 +65,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class ArduinoSwitch(SwitchDevice): - """ Represents an Arduino Switch. """ + """ Represents an Arduino switch. """ def __init__(self, name, pin, pin_type): self._pin = pin self._name = name or DEVICE_DEFAULT_NAME diff --git a/homeassistant/components/switch/command_switch.py b/homeassistant/components/switch/command_switch.py index 7cc51a1f9b9..4d5aeba94f5 100644 --- a/homeassistant/components/switch/command_switch.py +++ b/homeassistant/components/switch/command_switch.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ homeassistant.components.switch.command_switch -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Allows to configure custom shell commands to turn a switch on/off. """ @@ -30,7 +30,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class CommandSwitch(SwitchDevice): - """ Represents a switch that can be togggled using shell commands """ + """ Represents a switch that can be togggled using shell commands. """ def __init__(self, name, command_on, command_off): self._name = name self._state = False @@ -39,7 +39,7 @@ class CommandSwitch(SwitchDevice): @staticmethod def _switch(command): - """ Execute the actual commands """ + """ Execute the actual commands. """ _LOGGER.info('Running command: %s', command) success = (subprocess.call(command, shell=True) == 0) @@ -51,12 +51,12 @@ class CommandSwitch(SwitchDevice): @property def should_poll(self): - """ No polling needed """ + """ No polling needed. """ return False @property def name(self): - """ The name of the switch """ + """ The name of the switch. """ return self._name @property diff --git a/homeassistant/components/switch/demo.py b/homeassistant/components/switch/demo.py index c097722ac4d..4ee1dc82413 100644 --- a/homeassistant/components/switch/demo.py +++ b/homeassistant/components/switch/demo.py @@ -3,7 +3,6 @@ homeassistant.components.switch.demo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Demo platform that has two fake switches. - """ from homeassistant.components.switch import SwitchDevice from homeassistant.const import DEVICE_DEFAULT_NAME diff --git a/homeassistant/components/switch/edimax.py b/homeassistant/components/switch/edimax.py index 200c5746e27..2f38084ed9d 100644 --- a/homeassistant/components/switch/edimax.py +++ b/homeassistant/components/switch/edimax.py @@ -6,7 +6,7 @@ Support for Edimax switches. Configuration: To use the Edimax switch you will need to add something like the following to -your config/configuration.yaml. +your configuration.yaml file. switch: platform: edimax @@ -44,8 +44,8 @@ from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD,\ DEFAULT_USERNAME = 'admin' DEFAULT_PASSWORD = '1234' DEVICE_DEFAULT_NAME = 'Edimax Smart Plug' -REQUIREMENTS = ['https://github.com/rkabadi/pyedimax/archive/' + - '365301ce3ff26129a7910c501ead09ea625f3700.zip'] +REQUIREMENTS = ['https://github.com/rkabadi/pyedimax/archive/' + '365301ce3ff26129a7910c501ead09ea625f3700.zip#pyedimax==0.1'] # setup logger _LOGGER = logging.getLogger(__name__) @@ -89,7 +89,7 @@ class SmartPlugSwitch(SwitchDevice): @property def current_power_mwh(self): - """ Current power usage in mwh. """ + """ Current power usage in mWh. """ try: return float(self.smartplug.now_power) / 1000000.0 except ValueError: @@ -97,7 +97,7 @@ class SmartPlugSwitch(SwitchDevice): @property def today_power_mw(self): - """ Today total power usage in mw. """ + """ Today total power usage in mW. """ try: return float(self.smartplug.now_energy_day) / 1000.0 except ValueError: diff --git a/homeassistant/components/switch/modbus.py b/homeassistant/components/switch/modbus.py index dbf9bc83aad..5a00b9cb174 100644 --- a/homeassistant/components/switch/modbus.py +++ b/homeassistant/components/switch/modbus.py @@ -1,12 +1,12 @@ """ homeassistant.components.switch.modbus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Support for Modbus switches. Configuration: + To use the Modbus switches you will need to add something like the following to -your config/configuration.yaml +your configuration.yaml file. sensor: platform: modbus @@ -42,7 +42,7 @@ DEPENDENCIES = ['modbus'] def setup_platform(hass, config, add_devices, discovery_info=None): - """ Read config and create Modbus devices """ + """ Read configuration and create Modbus devices. """ switches = [] slave = config.get("slave", None) if modbus.TYPE == "serial" and not slave: @@ -87,8 +87,10 @@ class ModbusSwitch(ToggleEntity): @property def should_poll(self): - """ We should poll, because slaves are not allowed to - initiate communication on Modbus networks""" + """ + We should poll, because slaves are not allowed to initiate + communication on Modbus networks. + """ return True @property diff --git a/homeassistant/components/switch/mqtt.py b/homeassistant/components/switch/mqtt.py index c6ebdaa2ad6..73618bd9277 100644 --- a/homeassistant/components/switch/mqtt.py +++ b/homeassistant/components/switch/mqtt.py @@ -26,6 +26,7 @@ switch: name: "Bedroom Switch" state_topic: "home/bedroom/switch1" command_topic: "home/bedroom/switch1/set" + qos: 0 payload_on: "ON" payload_off: "OFF" optimistic: false @@ -45,6 +46,11 @@ command_topic *Required The MQTT topic to publish commands to change the switch state. +qos +*Optional +The maximum QoS level of the state topic. Default is 0. +This QoS will also be used to publishing messages. + payload_on *Optional The payload that represents enabled state. Default is "ON". @@ -66,6 +72,7 @@ from homeassistant.components.switch import SwitchDevice _LOGGER = logging.getLogger(__name__) DEFAULT_NAME = "MQTT Switch" +DEFAULT_QOS = 0 DEFAULT_PAYLOAD_ON = "ON" DEFAULT_PAYLOAD_OFF = "OFF" DEFAULT_OPTIMISTIC = False @@ -86,6 +93,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): config.get('name', DEFAULT_NAME), config.get('state_topic'), config.get('command_topic'), + config.get('qos', DEFAULT_QOS), config.get('payload_on', DEFAULT_PAYLOAD_ON), config.get('payload_off', DEFAULT_PAYLOAD_OFF), config.get('optimistic', DEFAULT_OPTIMISTIC))]) @@ -94,13 +102,14 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): # pylint: disable=too-many-arguments, too-many-instance-attributes class MqttSwitch(SwitchDevice): """ Represents a switch that can be togggled using MQTT """ - def __init__(self, hass, name, state_topic, command_topic, + def __init__(self, hass, name, state_topic, command_topic, qos, payload_on, payload_off, optimistic): self._state = False self._hass = hass self._name = name self._state_topic = state_topic self._command_topic = command_topic + self._qos = qos self._payload_on = payload_on self._payload_off = payload_off self._optimistic = optimistic @@ -119,7 +128,8 @@ class MqttSwitch(SwitchDevice): self._optimistic = True else: # subscribe the state_topic - mqtt.subscribe(hass, self._state_topic, message_received) + mqtt.subscribe(hass, self._state_topic, message_received, + self._qos) @property def should_poll(self): @@ -138,7 +148,8 @@ class MqttSwitch(SwitchDevice): def turn_on(self, **kwargs): """ Turn the device on. """ - mqtt.publish(self.hass, self._command_topic, self._payload_on) + mqtt.publish(self.hass, self._command_topic, self._payload_on, + self._qos) if self._optimistic: # optimistically assume that switch has changed state self._state = True @@ -146,7 +157,8 @@ class MqttSwitch(SwitchDevice): def turn_off(self, **kwargs): """ Turn the device off. """ - mqtt.publish(self.hass, self._command_topic, self._payload_off) + mqtt.publish(self.hass, self._command_topic, self._payload_off, + self._qos) if self._optimistic: # optimistically assume that switch has changed state self._state = False diff --git a/homeassistant/components/switch/rpi_gpio.py b/homeassistant/components/switch/rpi_gpio.py index 4afa38aa80a..08c7ff35255 100644 --- a/homeassistant/components/switch/rpi_gpio.py +++ b/homeassistant/components/switch/rpi_gpio.py @@ -2,10 +2,14 @@ homeassistant.components.switch.rpi_gpio ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Allows to control the GPIO pins of a Raspberry Pi. + Note: To use RPi GPIO, Home Assistant must be run as root. Configuration: +To use the Raspberry GPIO switches you will need to add something like the +following to your configuration.yaml file. + switch: platform: rpi_gpio invert_logic: false diff --git a/homeassistant/components/switch/tellstick.py b/homeassistant/components/switch/tellstick.py index 230151382e7..ae064d4fdb8 100644 --- a/homeassistant/components/switch/tellstick.py +++ b/homeassistant/components/switch/tellstick.py @@ -1,7 +1,6 @@ """ homeassistant.components.switch.tellstick ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Support for Tellstick switches. Because the tellstick sends its actions via radio and from most @@ -47,7 +46,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class TellstickSwitchDevice(ToggleEntity): - """ Represents a Tellstick switch within Home Assistant. """ + """ Represents a Tellstick switch. """ last_sent_command_mask = (tellcore_constants.TELLSTICK_TURNON | tellcore_constants.TELLSTICK_TURNOFF) diff --git a/homeassistant/components/switch/transmission.py b/homeassistant/components/switch/transmission.py index d5cf716c770..8288ed8456b 100644 --- a/homeassistant/components/switch/transmission.py +++ b/homeassistant/components/switch/transmission.py @@ -6,15 +6,15 @@ Enable or disable Transmission BitTorrent client Turtle Mode. Configuration: To use the Transmission switch you will need to add something like the -following to your config/configuration.yaml +following to your configuration.yaml file. switch: - platform: transmission - name: Transmission - host: 192.168.1.26 - port: 9091 - username: YOUR_USERNAME - password: YOUR_PASSWORD + platform: transmission + name: Transmission + host: 192.168.1.26 + port: 9091 + username: YOUR_USERNAME + password: YOUR_PASSWORD Variables: diff --git a/homeassistant/components/switch/vera.py b/homeassistant/components/switch/vera.py index 77b49ebf826..bb7f43522f4 100644 --- a/homeassistant/components/switch/vera.py +++ b/homeassistant/components/switch/vera.py @@ -5,7 +5,7 @@ Support for Vera switches. Configuration: To use the Vera lights you will need to add something like the following to -your config/configuration.yaml. +your configuration.yaml file. switch: platform: vera @@ -52,8 +52,10 @@ import homeassistant.util.dt as dt_util from homeassistant.helpers.entity import ToggleEntity from homeassistant.const import ( ATTR_BATTERY_LEVEL, ATTR_TRIPPED, ATTR_ARMED, ATTR_LAST_TRIP_TIME) -# pylint: disable=no-name-in-module, import-error -import homeassistant.external.vera.vera as veraApi + +REQUIREMENTS = ['https://github.com/balloob/home-assistant-vera-api/archive/' + 'a8f823066ead6c7da6fb5e7abaf16fef62e63364.zip' + '#python-vera==0.1'] _LOGGER = logging.getLogger(__name__) @@ -61,6 +63,7 @@ _LOGGER = logging.getLogger(__name__) # pylint: disable=unused-argument def get_devices(hass, config): """ Find and return Vera switches. """ + import pyvera as veraApi base_url = config.get('vera_controller_url') if not base_url: diff --git a/homeassistant/components/switch/verisure.py b/homeassistant/components/switch/verisure.py index 6c8f0352c3f..7840defdfc4 100644 --- a/homeassistant/components/switch/verisure.py +++ b/homeassistant/components/switch/verisure.py @@ -1,7 +1,7 @@ """ homeassistant.components.switch.verisure -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Support for Verisure Smartplugs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Support for Verisure Smartplugs. """ import logging @@ -12,7 +12,7 @@ _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_devices, discovery_info=None): - """ Sets up the Arduino platform. """ + """ Sets up the Verisure platform. """ if not verisure.MY_PAGES: _LOGGER.error('A connection has not been made to Verisure mypages.') @@ -48,13 +48,13 @@ class VerisureSmartplug(SwitchDevice): return plug_status == self.status_on def turn_on(self): - """ Set smartplug status on """ + """ Set smartplug status on. """ verisure.MY_PAGES.set_smartplug_status( self._id, self.status_on) def turn_off(self): - """ Set smartplug status off """ + """ Set smartplug status off. """ verisure.MY_PAGES.set_smartplug_status( self._id, self.status_off) diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index 98c6ed5aa01..1a78a7d6725 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -36,7 +36,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class WemoSwitch(SwitchDevice): - """ Represents a WeMo switch within Home Assistant. """ + """ Represents a WeMo switch. """ def __init__(self, wemo): self.wemo = wemo self.insight_params = None diff --git a/homeassistant/components/thermostat/demo.py b/homeassistant/components/thermostat/demo.py index 0ecbd889edd..9ad9e8995cd 100644 --- a/homeassistant/components/thermostat/demo.py +++ b/homeassistant/components/thermostat/demo.py @@ -3,7 +3,6 @@ homeassistant.components.thermostat.demo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Demo platform that offers a fake thermostat. - """ from homeassistant.components.thermostat import ThermostatDevice from homeassistant.const import TEMP_CELCIUS, TEMP_FAHRENHEIT @@ -19,7 +18,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # pylint: disable=too-many-arguments class DemoThermostat(ThermostatDevice): - """ Represents a HeatControl within Home Assistant. """ + """ Represents a HeatControl thermostat. """ def __init__(self, name, target_temperature, unit_of_measurement, away, current_temperature): @@ -60,7 +59,7 @@ class DemoThermostat(ThermostatDevice): return self._away def set_temperature(self, temperature): - """ Set new target temperature """ + """ Set new target temperature. """ self._target_temperature = temperature def turn_away_mode_on(self): diff --git a/homeassistant/components/thermostat/heat_control.py b/homeassistant/components/thermostat/heat_control.py index 7eb3030f0d4..f77d4285544 100644 --- a/homeassistant/components/thermostat/heat_control.py +++ b/homeassistant/components/thermostat/heat_control.py @@ -1,4 +1,6 @@ """ +homeassistant.components.thermostat.heat_control +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Adds support for a thermostat. Specify a start time, end time and a target temperature. @@ -12,8 +14,8 @@ temperature (min_temp in config). The min temperature is also used as target temperature when no other temperature is specified. If the heater is manually turned on, the target temperature will -be sat to 100*C. Meaning -the thermostat probably will never turn off the heater. +be sat to 100*C. Meaning the thermostat probably will never turn +off the heater. If the heater is manually turned off, the target temperature will be sat according to normal rules. (Based on target temperature for given time intervals and the min temperature.) @@ -21,7 +23,6 @@ for given time intervals and the min temperature.) A target temperature sat with the set_temperature function will override all other rules for the target temperature. - Config: [thermostat] @@ -55,9 +56,7 @@ target temperature will be 17*C. Between 0745 and 1500 no temperature is specified. so the min_temp of 10*C will be used. From 1500 to 1850 the target temperature is 20*, but if away mode is true the target temperature will be sat to 10*C - """ - import logging import datetime import homeassistant.components as core @@ -80,7 +79,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # pylint: disable=too-many-instance-attributes class HeatControl(ThermostatDevice): - """ Represents a HeatControl within Home Assistant. """ + """ Represents a HeatControl device. """ def __init__(self, hass, config, logger): @@ -150,14 +149,14 @@ class HeatControl(ThermostatDevice): return self.min_temp def set_temperature(self, temperature): - """ Set new target temperature """ + """ Set new target temperature. """ if temperature is None: self._manual_sat_temp = None else: self._manual_sat_temp = float(temperature) def update(self): - """ Update current thermostat """ + """ Update current thermostat. """ heater = self.hass.states.get(self.heater_entity_id) if heater is None: self.logger.error("No heater available") @@ -178,7 +177,7 @@ class HeatControl(ThermostatDevice): core.turn_on(self.hass, self.heater_entity_id) def _heater_turned_on(self, entity_id, old_state, new_state): - """ heater is turned on""" + """ Heater is turned on. """ if not self._heater_manual_changed: pass else: @@ -187,7 +186,7 @@ class HeatControl(ThermostatDevice): self._heater_manual_changed = True def _heater_turned_off(self, entity_id, old_state, new_state): - """ heater is turned off""" + """ Heater is turned off. """ if self._heater_manual_changed: self.set_temperature(None) diff --git a/homeassistant/components/thermostat/nest.py b/homeassistant/components/thermostat/nest.py index d165e8e7820..72f10033a91 100644 --- a/homeassistant/components/thermostat/nest.py +++ b/homeassistant/components/thermostat/nest.py @@ -1,4 +1,6 @@ """ +homeassistant.components.thermostat.nest +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Adds support for Nest thermostats. """ import logging @@ -41,7 +43,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class NestThermostat(ThermostatDevice): - """ Represents a Nest thermostat within Home Assistant. """ + """ Represents a Nest thermostat. """ def __init__(self, structure, device): self.structure = structure diff --git a/homeassistant/components/verisure.py b/homeassistant/components/verisure.py index d716c8c46ad..c7bc7c205e8 100644 --- a/homeassistant/components/verisure.py +++ b/homeassistant/components/verisure.py @@ -1,11 +1,13 @@ """ components.verisure -~~~~~~~~~~~~~~~~~~ - -Provides support for verisure components +~~~~~~~~~~~~~~~~~~~ +Provides support for verisure components. Configuration: +To use the Verisure component you will need to add something like the +following to your configuration.yaml file. + verisure: username: user@example.com password: password @@ -14,32 +16,31 @@ verisure: smartplugs: 1 thermometers: 0 - Variables: username *Required -Username to verisure mypages +Username to Verisure mypages. password *Required -Password to verisure mypages +Password to Verisure mypages. alarm -*Opional -Set to 1 to show alarm, 0 to disable. Default 1 +*Optional +Set to 1 to show alarm, 0 to disable. Default 1. hygrometers -*Opional -Set to 1 to show hygrometers, 0 to disable. Default 1 +*Optional +Set to 1 to show hygrometers, 0 to disable. Default 1. smartplugs -*Opional -Set to 1 to show smartplugs, 0 to disable. Default 1 +*Optional +Set to 1 to show smartplugs, 0 to disable. Default 1. thermometers -*Opional -Set to 1 to show thermometers, 0 to disable. Default 1 +*Optional +Set to 1 to show thermometers, 0 to disable. Default 1. """ import logging from datetime import timedelta @@ -61,9 +62,9 @@ DISCOVER_SWITCHES = 'verisure.switches' DEPENDENCIES = [] REQUIREMENTS = [ - 'https://github.com/persandstrom/python-verisure/archive/' + - '9873c4527f01b1ba1f72ae60f7f35854390d59be.zip' - ] + 'https://github.com/persandstrom/python-verisure/archive/' + '9873c4527f01b1ba1f72ae60f7f35854390d59be.zip#python-verisure==0.2.6' +] _LOGGER = logging.getLogger(__name__) @@ -135,22 +136,22 @@ def setup(hass, config): def get_alarm_status(): - ''' return a list of status overviews for alarm components ''' + """ Return a list of status overviews for alarm components. """ return STATUS[MY_PAGES.DEVICE_ALARM] def get_climate_status(): - ''' return a list of status overviews for alarm components ''' + """ Return a list of status overviews for alarm components. """ return STATUS[MY_PAGES.DEVICE_CLIMATE] def get_smartplug_status(): - ''' return a list of status overviews for alarm components ''' + """ Return a list of status overviews for alarm components. """ return STATUS[MY_PAGES.DEVICE_SMARTPLUG] def reconnect(): - ''' reconnect to verisure mypages ''' + """ Reconnect to verisure mypages. """ try: MY_PAGES.login() except VERISURE_LOGIN_ERROR as ex: @@ -163,7 +164,7 @@ def reconnect(): @Throttle(MIN_TIME_BETWEEN_REQUESTS) def update(): - ''' Updates the status of verisure components ''' + """ Updates the status of verisure components. """ if WRONG_PASSWORD_GIVEN: # Is there any way to inform user? return diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index eb2beac508a..c05d9502ca7 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -1,8 +1,22 @@ """ homeassistant.components.wink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Connects to a Wink hub and loads relevant components to control its devices. + +Configuration: + +To use the Wink component you will need to add something like the following +to your configuration.yaml file. + +wink: + access_token: YOUR_ACCESS_TOKEN + +Variables: + +access_token +*Required +Please check https://home-assistant.io/components/wink.html for further +details. """ import logging @@ -16,8 +30,9 @@ from homeassistant.const import ( DOMAIN = "wink" DEPENDENCIES = [] -REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/' + - 'c2b700e8ca866159566ecf5e644d9c297f69f257.zip'] +REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/' + 'c2b700e8ca866159566ecf5e644d9c297f69f257.zip' + '#python-wink==0.1'] DISCOVER_LIGHTS = "wink.lights" DISCOVER_SWITCHES = "wink.switches" diff --git a/homeassistant/config.py b/homeassistant/config.py index 511ef9ad0db..2ec706e4512 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -124,7 +124,7 @@ def load_yaml_config_file(config_path): def parse(fname): """ Parse a YAML file. """ try: - with open(fname) as conf_file: + with open(fname, encoding='utf-8') as conf_file: # If configuration file is empty YAML returns None # We convert that to an empty dict return yaml.load(conf_file) or {} diff --git a/homeassistant/const.py b/homeassistant/const.py index 1e1d7161599..539043bf61e 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,6 +1,6 @@ """ Constants used by Home Assistant components. """ -__version__ = "0.7.2-pre" +__version__ = "0.7.2rc0" # Can be used to specify a catch all when registering state or event listeners. MATCH_ALL = '*' diff --git a/homeassistant/external/noop b/homeassistant/external/noop deleted file mode 160000 index 4eaeb3367f9..00000000000 --- a/homeassistant/external/noop +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4eaeb3367f9ada05dae3319cf24ab1da5de1aa89 diff --git a/homeassistant/external/nzbclients b/homeassistant/external/nzbclients deleted file mode 160000 index f01997498fe..00000000000 --- a/homeassistant/external/nzbclients +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f01997498fe190d6ac2a2c375a739024843bd44d diff --git a/homeassistant/external/vera b/homeassistant/external/vera deleted file mode 160000 index 30c59781d63..00000000000 --- a/homeassistant/external/vera +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 30c59781d63322db2160ff00a4b99f16ead40b85 diff --git a/homeassistant/util/package.py b/homeassistant/util/package.py index 802e3834b90..5d32c087efe 100644 --- a/homeassistant/util/package.py +++ b/homeassistant/util/package.py @@ -1,19 +1,58 @@ """Helpers to install PyPi packages.""" import os +import logging +import pkg_resources import subprocess import sys +import threading +from urllib.parse import urlparse + +_LOGGER = logging.getLogger(__name__) +INSTALL_LOCK = threading.Lock() -def install_package(package, upgrade=False, target=None): +def install_package(package, upgrade=True, target=None): """Install a package on PyPi. Accepts pip compatible package strings. Return boolean if install successfull.""" # Not using 'import pip; pip.main([])' because it breaks the logger args = [sys.executable, '-m', 'pip', 'install', '--quiet', package] + if upgrade: args.append('--upgrade') if target: args += ['--target', os.path.abspath(target)] + + with INSTALL_LOCK: + if check_package_exists(package, target): + return True + + _LOGGER.info('Attempting install of %s', package) + try: + return 0 == subprocess.call(args) + except subprocess.SubprocessError: + return False + + +def check_package_exists(package, target=None): + """Check if a package exists. + Returns True when the requirement is met. + Returns False when the package is not installed or doesn't meet req.""" try: - return 0 == subprocess.call(args) - except subprocess.SubprocessError: + req = pkg_resources.Requirement.parse(package) + except ValueError: + # This is a zip file + req = pkg_resources.Requirement.parse(urlparse(package).fragment) + + if target: + work_set = pkg_resources.WorkingSet([target]) + search_fun = work_set.find + + else: + search_fun = pkg_resources.get_distribution + + try: + result = search_fun(req) + except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict): return False + + return bool(result) diff --git a/pylintrc b/pylintrc index 888fb50ee0f..e8455cf4245 100644 --- a/pylintrc +++ b/pylintrc @@ -1,5 +1,4 @@ [MASTER] -ignore=external,setup.py reports=no # Reasons disabled: diff --git a/requirements_all.txt b/requirements_all.txt index 0a71552b2c4..f44b14d9ba7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -77,10 +77,10 @@ python-forecastio==1.3.3 PyMata==2.07a # Rfxtrx sensor (sensor.rfxtrx) -https://github.com/Danielhiversen/pyRFXtrx/archive/ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip +https://github.com/Danielhiversen/pyRFXtrx/archive/ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip#RFXtrx==0.15 # Mysensors -https://github.com/theolind/pymysensors/archive/35b87d880147a34107da0d40cb815d75e6cb4af7.zip +https://github.com/theolind/pymysensors/archive/35b87d880147a34107da0d40cb815d75e6cb4af7.zip#pymysensors==0.2 # Netgear (device_tracker.netgear) pynetgear==0.3 @@ -92,33 +92,41 @@ netdisco==0.3 pywemo==0.3 # Wink (*.wink) -https://github.com/balloob/python-wink/archive/c2b700e8ca866159566ecf5e644d9c297f69f257.zip +https://github.com/balloob/python-wink/archive/c2b700e8ca866159566ecf5e644d9c297f69f257.zip#python-wink==0.1 # Slack notifier (notify.slack) slacker==0.6.8 # Temper sensors (sensor.temper) -https://github.com/rkabadi/temper-python/archive/3dbdaf2d87b8db9a3cd6e5585fc704537dd2d09b.zip +https://github.com/rkabadi/temper-python/archive/3dbdaf2d87b8db9a3cd6e5585fc704537dd2d09b.zip#temperusb==1.2.3 # PyEdimax -https://github.com/rkabadi/pyedimax/archive/365301ce3ff26129a7910c501ead09ea625f3700.zip +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 +# RPi.GPIO==0.5.11 # Adafruit temperature/humidity sensor # uncomment on a Raspberry Pi / Beaglebone -# http://github.com/mala-zaba/Adafruit_Python_DHT/archive/4101340de8d2457dd194bca1e8d11cbfc237e919.zip +# http://github.com/mala-zaba/Adafruit_Python_DHT/archive/4101340de8d2457dd194bca1e8d11cbfc237e919.zip#Adafruit_DHT==1.1.0 # PAHO MQTT Binding (mqtt) paho-mqtt==1.1 # PyModbus (modbus) -https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b612661.zip +https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b612661.zip#pymodbus==1.2.0 # Verisure (verisure) -https://github.com/persandstrom/python-verisure/archive/9873c4527f01b1ba1f72ae60f7f35854390d59be.zip +https://github.com/persandstrom/python-verisure/archive/9873c4527f01b1ba1f72ae60f7f35854390d59be.zip#python-verisure==0.2.6 # Python tools for interacting with IFTTT Maker Channel (ifttt) pyfttt==0.3 + +# sensor.sabnzbd +https://github.com/balloob/home-assistant-nzb-clients/archive/616cad59154092599278661af17e2a9f2cf5e2a9.zip#python-sabnzbd==0.1 + +# switch.vera +# sensor.vera +# light.vera +https://github.com/balloob/home-assistant-vera-api/archive/a8f823066ead6c7da6fb5e7abaf16fef62e63364.zip#python-vera==0.1 diff --git a/scripts/check_style b/scripts/check_style index cacebba15a1..5fc8861b91a 100755 --- a/scripts/check_style +++ b/scripts/check_style @@ -5,5 +5,5 @@ if [ ${PWD##*/} == "scripts" ]; then cd .. fi +flake8 homeassistant pylint homeassistant -flake8 homeassistant --exclude bower_components,external diff --git a/setup.py b/setup.py index f906df64965..ce8a75072ac 100755 --- a/setup.py +++ b/setup.py @@ -1,17 +1,13 @@ import os -import re from setuptools import setup, find_packages +from homeassistant.const import __version__ PACKAGE_NAME = 'homeassistant' HERE = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(HERE, PACKAGE_NAME, 'const.py')) as fp: - VERSION = re.search("__version__ = ['\"]([^']+)['\"]\n", fp.read()).group(1) -DOWNLOAD_URL = \ - 'https://github.com/balloob/home-assistant/archive/{}.zip'.format(VERSION) +DOWNLOAD_URL = ('https://github.com/balloob/home-assistant/archive/' + '{}.zip'.format(__version__)) -PACKAGES = find_packages(exclude=['tests', 'tests.*']) + \ - ['homeassistant.external', 'homeassistant.external.noop', - 'homeassistant.external.nzbclients', 'homeassistant.external.vera'] +PACKAGES = find_packages(exclude=['tests', 'tests.*']) PACKAGE_DATA = \ {'homeassistant.components.frontend': ['index.html.template'], @@ -27,7 +23,7 @@ REQUIRES = [ setup( name=PACKAGE_NAME, - version=VERSION, + version=__version__, license='MIT License', url='https://home-assistant.io/', download_url=DOWNLOAD_URL,