Fix PEEP257 issues

This commit is contained in:
Fabian Affolter 2016-03-08 17:55:57 +01:00
parent d784610c52
commit b534244e40
42 changed files with 335 additions and 308 deletions

View file

@ -1,16 +1,11 @@
""" """
homeassistant.components
~~~~~~~~~~~~~~~~~~~~~~~~
This package contains components that can be plugged into Home Assistant. This package contains components that can be plugged into Home Assistant.
Component design guidelines: Component design guidelines:
- Each component defines a constant DOMAIN that is equal to its filename.
Each component defines a constant DOMAIN that is equal to its filename. - Each component that tracks states should create state entity names in the
format "<DOMAIN>.<OBJECT_ID>".
Each component that tracks states should create state entity names in the - Each component should publish services only under its own domain.
format "<DOMAIN>.<OBJECT_ID>".
Each component should publish services only under its own domain.
""" """
import itertools as it import itertools as it
import logging import logging
@ -26,8 +21,10 @@ _LOGGER = logging.getLogger(__name__)
def is_on(hass, entity_id=None): def is_on(hass, entity_id=None):
""" Loads up the module to call the is_on method. """Load up the module to call the is_on method.
If there is no entity id given we will check all. """
If there is no entity id given we will check all.
"""
if entity_id: if entity_id:
group = get_component('group') group = get_component('group')
@ -53,7 +50,7 @@ def is_on(hass, entity_id=None):
def turn_on(hass, entity_id=None, **service_data): def turn_on(hass, entity_id=None, **service_data):
""" Turns specified entity on if possible. """ """Turn specified entity on if possible."""
if entity_id is not None: if entity_id is not None:
service_data[ATTR_ENTITY_ID] = entity_id service_data[ATTR_ENTITY_ID] = entity_id
@ -61,7 +58,7 @@ def turn_on(hass, entity_id=None, **service_data):
def turn_off(hass, entity_id=None, **service_data): def turn_off(hass, entity_id=None, **service_data):
""" Turns specified entity off. """ """Turn specified entity off."""
if entity_id is not None: if entity_id is not None:
service_data[ATTR_ENTITY_ID] = entity_id service_data[ATTR_ENTITY_ID] = entity_id
@ -69,7 +66,7 @@ def turn_off(hass, entity_id=None, **service_data):
def toggle(hass, entity_id=None, **service_data): def toggle(hass, entity_id=None, **service_data):
""" Toggles specified entity. """ """Toggle specified entity."""
if entity_id is not None: if entity_id is not None:
service_data[ATTR_ENTITY_ID] = entity_id service_data[ATTR_ENTITY_ID] = entity_id
@ -77,10 +74,9 @@ def toggle(hass, entity_id=None, **service_data):
def setup(hass, config): def setup(hass, config):
""" Setup general services related to homeassistant. """ """Setup general services related to Home Assistant."""
def handle_turn_service(service): def handle_turn_service(service):
""" Method to handle calls to homeassistant.turn_on/off. """ """Method to handle calls to homeassistant.turn_on/off."""
entity_ids = extract_entity_ids(hass, service) entity_ids = extract_entity_ids(hass, service)
# Generic turn on/off method requires entity id # Generic turn on/off method requires entity id

View file

@ -97,21 +97,24 @@ def _handle_alexa(handler, path_match, data):
class SpeechType(enum.Enum): class SpeechType(enum.Enum):
"""Alexa speech types.""" """The Alexa speech types."""
plaintext = "PlainText" plaintext = "PlainText"
ssml = "SSML" ssml = "SSML"
class CardType(enum.Enum): class CardType(enum.Enum):
"""Alexa card types.""" """The Alexa card types."""
simple = "Simple" simple = "Simple"
link_account = "LinkAccount" link_account = "LinkAccount"
class AlexaResponse(object): class AlexaResponse(object):
"""Helps generating the response for Alexa.""" """Help generating the response for Alexa."""
def __init__(self, hass, intent=None): def __init__(self, hass, intent=None):
"""Initialize the response."""
self.hass = hass self.hass = hass
self.speech = None self.speech = None
self.card = None self.card = None
@ -125,7 +128,7 @@ class AlexaResponse(object):
self.variables = {} self.variables = {}
def add_card(self, card_type, title, content): def add_card(self, card_type, title, content):
""" Add a card to the response. """ """Add a card to the response."""
assert self.card is None assert self.card is None
card = { card = {
@ -141,7 +144,7 @@ class AlexaResponse(object):
self.card = card self.card = card
def add_speech(self, speech_type, text): def add_speech(self, speech_type, text):
""" Add speech to the response. """ """Add speech to the response."""
assert self.speech is None assert self.speech is None
key = 'ssml' if speech_type == SpeechType.ssml else 'text' key = 'ssml' if speech_type == SpeechType.ssml else 'text'
@ -163,7 +166,7 @@ class AlexaResponse(object):
} }
def as_dict(self): def as_dict(self):
"""Returns response in an Alexa valid dict.""" """Return response in an Alexa valid dict."""
response = { response = {
'shouldEndSession': self.should_end_session 'shouldEndSession': self.should_end_session
} }

View file

@ -51,11 +51,14 @@ def setup(hass, config):
class APCUPSdData(object): class APCUPSdData(object):
"""Stores the data retrieved from APCUPSd.
For each entity to use, acts as the single point responsible for fetching
updates from the server.
""" """
Stores the data retrieved from APCUPSd for each entity to use, acts as the
single point responsible for fetching updates from the server.
"""
def __init__(self, host, port): def __init__(self, host, port):
"""Initialize the data oject."""
from apcaccess import status from apcaccess import status
self._host = host self._host = host
self._port = port self._port = port
@ -75,7 +78,5 @@ class APCUPSdData(object):
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self, **kwargs): def update(self, **kwargs):
""" """Fetch the latest status from APCUPSd."""
Fetch the latest status from APCUPSd and store it in self._status.
"""
self._status = self._get_status() self._status = self._get_status()

View file

@ -34,7 +34,6 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config): def setup(hass, config):
"""Register the API with the HTTP interface.""" """Register the API with the HTTP interface."""
# /api - for validation purposes # /api - for validation purposes
hass.http.register_path('GET', URL_API, _handle_get_api) hass.http.register_path('GET', URL_API, _handle_get_api)
@ -96,7 +95,7 @@ def setup(hass, config):
def _handle_get_api(handler, path_match, data): def _handle_get_api(handler, path_match, data):
"""Renders the debug interface.""" """Render the debug interface."""
handler.write_json_message("API running.") handler.write_json_message("API running.")
@ -114,7 +113,7 @@ def _handle_get_api_stream(handler, path_match, data):
restrict = restrict.split(',') restrict = restrict.split(',')
def write_message(payload): def write_message(payload):
"""Writes a message to the output.""" """Write a message to the output."""
with write_lock: with write_lock:
msg = "data: {}\n\n".format(payload) msg = "data: {}\n\n".format(payload)
@ -127,7 +126,7 @@ def _handle_get_api_stream(handler, path_match, data):
block.set() block.set()
def forward_events(event): def forward_events(event):
"""Forwards events to the open request.""" """Forward events to the open request."""
nonlocal gracefully_closed nonlocal gracefully_closed
if block.is_set() or event.event_type == EVENT_TIME_CHANGED: if block.is_set() or event.event_type == EVENT_TIME_CHANGED:
@ -171,17 +170,17 @@ def _handle_get_api_stream(handler, path_match, data):
def _handle_get_api_config(handler, path_match, data): def _handle_get_api_config(handler, path_match, data):
"""Returns the Home Assistant configuration.""" """Return the Home Assistant configuration."""
handler.write_json(handler.server.hass.config.as_dict()) handler.write_json(handler.server.hass.config.as_dict())
def _handle_get_api_states(handler, path_match, data): def _handle_get_api_states(handler, path_match, data):
"""Returns a dict containing all entity ids and their state.""" """Return a dict containing all entity ids and their state."""
handler.write_json(handler.server.hass.states.all()) handler.write_json(handler.server.hass.states.all())
def _handle_get_api_states_entity(handler, path_match, data): def _handle_get_api_states_entity(handler, path_match, data):
"""Returns the state of a specific entity.""" """Return the state of a specific entity."""
entity_id = path_match.group('entity_id') entity_id = path_match.group('entity_id')
state = handler.server.hass.states.get(entity_id) state = handler.server.hass.states.get(entity_id)
@ -193,7 +192,7 @@ def _handle_get_api_states_entity(handler, path_match, data):
def _handle_post_state_entity(handler, path_match, data): def _handle_post_state_entity(handler, path_match, data):
"""Handles updating the state of an entity. """Handle updating the state of an entity.
This handles the following paths: This handles the following paths:
/api/states/<entity_id> /api/states/<entity_id>
@ -240,15 +239,14 @@ def _handle_delete_state_entity(handler, path_match, data):
def _handle_get_api_events(handler, path_match, data): def _handle_get_api_events(handler, path_match, data):
"""Handles getting overview of event listeners.""" """Handle getting overview of event listeners."""
handler.write_json(events_json(handler.server.hass)) handler.write_json(events_json(handler.server.hass))
def _handle_api_post_events_event(handler, path_match, event_data): def _handle_api_post_events_event(handler, path_match, event_data):
"""Handles firing of an event. """Handle firing of an event.
This handles the following paths: This handles the following paths: /api/events/<event_type>
/api/events/<event_type>
Events from /api are threated as remote events. Events from /api are threated as remote events.
""" """
@ -276,16 +274,15 @@ def _handle_api_post_events_event(handler, path_match, event_data):
def _handle_get_api_services(handler, path_match, data): def _handle_get_api_services(handler, path_match, data):
"""Handles getting overview of services.""" """Handle getting overview of services."""
handler.write_json(services_json(handler.server.hass)) handler.write_json(services_json(handler.server.hass))
# pylint: disable=invalid-name # pylint: disable=invalid-name
def _handle_post_api_services_domain_service(handler, path_match, data): def _handle_post_api_services_domain_service(handler, path_match, data):
"""Handles calling a service. """Handle calling a service.
This handles the following paths: This handles the following paths: /api/services/<domain>/<service>
/api/services/<domain>/<service>
""" """
domain = path_match.group('domain') domain = path_match.group('domain')
service = path_match.group('service') service = path_match.group('service')
@ -298,7 +295,7 @@ def _handle_post_api_services_domain_service(handler, path_match, data):
# pylint: disable=invalid-name # pylint: disable=invalid-name
def _handle_post_api_event_forward(handler, path_match, data): def _handle_post_api_event_forward(handler, path_match, data):
"""Handles adding an event forwarding target.""" """Handle adding an event forwarding target."""
try: try:
host = data['host'] host = data['host']
api_password = data['api_password'] api_password = data['api_password']
@ -331,7 +328,7 @@ def _handle_post_api_event_forward(handler, path_match, data):
def _handle_delete_api_event_forward(handler, path_match, data): def _handle_delete_api_event_forward(handler, path_match, data):
"""Handles deleting an event forwarding target.""" """Handle deleting an event forwarding target."""
try: try:
host = data['host'] host = data['host']
except KeyError: except KeyError:
@ -354,12 +351,12 @@ def _handle_delete_api_event_forward(handler, path_match, data):
def _handle_get_api_components(handler, path_match, data): def _handle_get_api_components(handler, path_match, data):
"""Returns all the loaded components.""" """Return all the loaded components."""
handler.write_json(handler.server.hass.config.components) handler.write_json(handler.server.hass.config.components)
def _handle_get_api_error_log(handler, path_match, data): def _handle_get_api_error_log(handler, path_match, data):
"""Returns the logged errors for this session.""" """Return the logged errors for this session."""
handler.write_file(handler.server.hass.config.path(ERROR_LOG_FILENAME), handler.write_file(handler.server.hass.config.path(ERROR_LOG_FILENAME),
False) False)

View file

@ -49,8 +49,10 @@ def setup(hass, config):
class ArduinoBoard(object): class ArduinoBoard(object):
"""Represents an Arduino board.""" """Representation of an Arduino board."""
def __init__(self, port): def __init__(self, port):
"""Initialize the board."""
from PyMata.pymata import PyMata from PyMata.pymata import PyMata
self._port = port self._port = port
self._board = PyMata(self._port, verbose=False) self._board = PyMata(self._port, verbose=False)
@ -104,6 +106,6 @@ class ArduinoBoard(object):
return self._board.get_firmata_version() return self._board.get_firmata_version()
def disconnect(self): def disconnect(self):
"""Disconnects the board and closes the serial connection.""" """Disconnect the board and close the serial connection."""
self._board.reset() self._board.reset()
self._board.close() self._board.close()

View file

@ -30,7 +30,7 @@ DISCOVER_CAMERAS = 'bloomsky.camera'
# pylint: disable=unused-argument,too-few-public-methods # pylint: disable=unused-argument,too-few-public-methods
def setup(hass, config): def setup(hass, config):
""" Setup BloomSky component. """ """Setup BloomSky component."""
if not validate_config( if not validate_config(
config, config,
{DOMAIN: [CONF_API_KEY]}, {DOMAIN: [CONF_API_KEY]},
@ -55,13 +55,13 @@ def setup(hass, config):
class BloomSky(object): class BloomSky(object):
""" Handle all communication with the BloomSky API. """ """Handle all communication with the BloomSky API."""
# API documentation at http://weatherlution.com/bloomsky-api/ # API documentation at http://weatherlution.com/bloomsky-api/
API_URL = "https://api.bloomsky.com/api/skydata" API_URL = "https://api.bloomsky.com/api/skydata"
def __init__(self, api_key): def __init__(self, api_key):
"""Initialize the BookSky."""
self._api_key = api_key self._api_key = api_key
self.devices = {} self.devices = {}
_LOGGER.debug("Initial bloomsky device load...") _LOGGER.debug("Initial bloomsky device load...")
@ -69,10 +69,7 @@ class BloomSky(object):
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
def refresh_devices(self): def refresh_devices(self):
""" """Use the API to retreive a list of devices."""
Uses the API to retreive a list of devices associated with an
account along with all the sensors on the device.
"""
_LOGGER.debug("Fetching bloomsky update") _LOGGER.debug("Fetching bloomsky update")
response = requests.get(self.API_URL, response = requests.get(self.API_URL,
headers={"Authorization": self._api_key}, headers={"Authorization": self._api_key},
@ -82,7 +79,7 @@ class BloomSky(object):
elif response.status_code != 200: elif response.status_code != 200:
_LOGGER.error("Invalid HTTP response: %s", response.status_code) _LOGGER.error("Invalid HTTP response: %s", response.status_code)
return return
# create dictionary keyed off of the device unique id # Create dictionary keyed off of the device unique id
self.devices.update({ self.devices.update({
device["DeviceID"]: device for device in response.json() device["DeviceID"]: device for device in response.json()
}) })

View file

@ -10,9 +10,7 @@ SERVICE_BROWSE_URL = "browse_url"
def setup(hass, config): def setup(hass, config):
""" """Listen for browse_url events."""
Listen for browse_url events and open the url in the default web browser.
"""
import webbrowser import webbrowser
hass.services.register(DOMAIN, SERVICE_BROWSE_URL, hass.services.register(DOMAIN, SERVICE_BROWSE_URL,

View file

@ -36,6 +36,7 @@ def request_config(
hass, name, callback, description=None, description_image=None, hass, name, callback, description=None, description_image=None,
submit_caption=None, fields=None): submit_caption=None, fields=None):
"""Create a new request for configuration. """Create a new request for configuration.
Will return an ID to be used for sequent calls. Will return an ID to be used for sequent calls.
""" """
instance = _get_instance(hass) instance = _get_instance(hass)
@ -86,8 +87,10 @@ def _get_instance(hass):
class Configurator(object): class Configurator(object):
"""Class to keep track of current configuration requests.""" """The class to keep track of current configuration requests."""
def __init__(self, hass): def __init__(self, hass):
"""Initialize the configurator."""
self.hass = hass self.hass = hass
self._cur_id = 0 self._cur_id = 0
self._requests = {} self._requests = {}
@ -173,7 +176,7 @@ class Configurator(object):
callback(call.data.get(ATTR_FIELDS, {})) callback(call.data.get(ATTR_FIELDS, {}))
def _generate_unique_id(self): def _generate_unique_id(self):
"""Generates a unique configurator ID.""" """Generate a unique configurator ID."""
self._cur_id += 1 self._cur_id += 1
return "{}-{}".format(id(self), self._cur_id) return "{}-{}".format(id(self), self._cur_id)

View file

@ -23,19 +23,18 @@ REQUIREMENTS = ['fuzzywuzzy==0.8.0']
def setup(hass, config): def setup(hass, config):
"""Registers the process service.""" """Register the process service."""
from fuzzywuzzy import process as fuzzyExtract from fuzzywuzzy import process as fuzzyExtract
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def process(service): def process(service):
"""Parses text into commands.""" """Parse text into commands."""
if ATTR_TEXT not in service.data: if ATTR_TEXT not in service.data:
logger.error("Received process service call without a text") logger.error("Received process service call without a text")
return return
text = service.data[ATTR_TEXT].lower() text = service.data[ATTR_TEXT].lower()
match = REGEX_TURN_COMMAND.match(text) match = REGEX_TURN_COMMAND.match(text)
if not match: if not match:
@ -43,11 +42,8 @@ def setup(hass, config):
return return
name, command = match.groups() name, command = match.groups()
entities = {state.entity_id: state.name for state in hass.states.all()} entities = {state.entity_id: state.name for state in hass.states.all()}
entity_ids = fuzzyExtract.extractOne(name, entities,
entity_ids = fuzzyExtract.extractOne(name,
entities,
score_cutoff=65)[2] score_cutoff=65)[2]
if not entity_ids: if not entity_ids:

View file

@ -1,6 +1,5 @@
""" """
Provides functionality to turn on lights based on the state of the sun and Provides functionality to turn on lights based on the states.
devices home.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/device_sun_light_trigger/ https://home-assistant.io/components/device_sun_light_trigger/
@ -29,7 +28,7 @@ CONF_DEVICE_GROUP = 'device_group'
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
def setup(hass, config): def setup(hass, config):
"""Triggers to turn lights on or off based on device presence.""" """The triggers to turn lights on or off based on device presence."""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
device_tracker = get_component('device_tracker') device_tracker = get_component('device_tracker')
group = get_component('group') group = get_component('group')
@ -57,16 +56,20 @@ def setup(hass, config):
return False return False
def calc_time_for_light_when_sunset(): def calc_time_for_light_when_sunset():
""" Calculates the time when to start fading lights in when sun sets. """Calculate the time when to start fading lights in when sun sets.
Returns None if no next_setting data available. """
Returns None if no next_setting data available.
"""
next_setting = sun.next_setting(hass) next_setting = sun.next_setting(hass)
if not next_setting: if not next_setting:
return None return None
return next_setting - LIGHT_TRANSITION_TIME * len(light_ids) return next_setting - LIGHT_TRANSITION_TIME * len(light_ids)
def turn_light_on_before_sunset(light_id): def turn_light_on_before_sunset(light_id):
""" Helper function to turn on lights slowly if there """Helper function to turn on lights.
are devices home and the light is not on yet. """
Speed is slow if there are devices home and the light is not on yet.
"""
if not device_tracker.is_on(hass) or light.is_on(hass, light_id): if not device_tracker.is_on(hass) or light.is_on(hass, light_id):
return return
light.turn_on(hass, light_id, light.turn_on(hass, light_id,
@ -78,8 +81,8 @@ def setup(hass, config):
@track_state_change(sun.ENTITY_ID, sun.STATE_BELOW_HORIZON, @track_state_change(sun.ENTITY_ID, sun.STATE_BELOW_HORIZON,
sun.STATE_ABOVE_HORIZON) sun.STATE_ABOVE_HORIZON)
def schedule_lights_at_sun_set(hass, entity, old_state, new_state): def schedule_lights_at_sun_set(hass, entity, old_state, new_state):
""" """The moment sun sets we want to have all the lights on.
The moment sun sets we want to have all the lights on.
We will schedule to have each light start after one another We will schedule to have each light start after one another
and slowly transition in. and slowly transition in.
""" """
@ -88,10 +91,10 @@ def setup(hass, config):
return return
def turn_on(light_id): def turn_on(light_id):
""" """Lambda can keep track of function parameters.
Lambda can keep track of function parameters but not local
parameters. If we put the lambda directly in the below statement No local parameters. If we put the lambda directly in the below
only the last light will be turned on. statement only the last light will be turned on.
""" """
return lambda now: turn_light_on_before_sunset(light_id) return lambda now: turn_light_on_before_sunset(light_id)

View file

@ -37,8 +37,8 @@ SERVICE_HANDLERS = {
def listen(hass, service, callback): def listen(hass, service, callback):
""" """Setup listener for discovery of specific service.
Setup listener for discovery of specific service.
Service can be a string or a list/tuple. Service can be a string or a list/tuple.
""" """
if isinstance(service, str): if isinstance(service, str):
@ -70,7 +70,7 @@ def discover(hass, service, discovered=None, component=None, hass_config=None):
def setup(hass, config): def setup(hass, config):
"""Starts a discovery service.""" """Start a discovery service."""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from netdisco.service import DiscoveryService from netdisco.service import DiscoveryService

View file

@ -26,7 +26,7 @@ CONF_DOWNLOAD_DIR = 'download_dir'
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
def setup(hass, config): def setup(hass, config):
"""Listens for download events to download files.""" """Listen for download events to download files."""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
if not validate_config(config, {DOMAIN: [CONF_DOWNLOAD_DIR]}, logger): if not validate_config(config, {DOMAIN: [CONF_DOWNLOAD_DIR]}, logger):
@ -47,13 +47,13 @@ def setup(hass, config):
return False return False
def download_file(service): def download_file(service):
"""Starts thread to download file specified in the URL.""" """Start thread to download file specified in the URL."""
if ATTR_URL not in service.data: if ATTR_URL not in service.data:
logger.error("Service called but 'url' parameter not specified.") logger.error("Service called but 'url' parameter not specified.")
return return
def do_download(): def do_download():
"""Downloads the file.""" """Download the file."""
try: try:
url = service.data[ATTR_URL] url = service.data[ATTR_URL]

View file

@ -44,7 +44,7 @@ def request_configuration(network, hass, config):
# pylint: disable=unused-argument # pylint: disable=unused-argument
def ecobee_configuration_callback(callback_data): def ecobee_configuration_callback(callback_data):
"""Actions to do when our configuration callback is called.""" """The actions to do when our configuration callback is called."""
network.request_tokens() network.request_tokens()
network.update() network.update()
setup_ecobee(hass, network, config) setup_ecobee(hass, network, config)
@ -91,8 +91,10 @@ def setup_ecobee(hass, network, config):
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class EcobeeData(object): class EcobeeData(object):
"""Gets the latest data and update the states.""" """Get the latest data and update the states."""
def __init__(self, config_file): def __init__(self, config_file):
"""Initialize the Ecobee data object."""
from pyecobee import Ecobee from pyecobee import Ecobee
self.ecobee = Ecobee(config_file) self.ecobee = Ecobee(config_file)
@ -104,8 +106,8 @@ class EcobeeData(object):
def setup(hass, config): def setup(hass, config):
""" """Setup Ecobee.
Setup Ecobee.
Will automatically load thermostat and sensor components to support Will automatically load thermostat and sensor components to support
devices discovered on the network. devices discovered on the network.
""" """

View file

@ -1,6 +1,5 @@
""" """
Component that records all events and state changes and feeds the data to Component that sends data to aGraphite installation.
a Graphite installation.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/graphite/ https://home-assistant.io/components/graphite/
@ -35,8 +34,10 @@ def setup(hass, config):
class GraphiteFeeder(threading.Thread): class GraphiteFeeder(threading.Thread):
"""Feeds data to Graphite.""" """Feed data to Graphite."""
def __init__(self, hass, host, port, prefix): def __init__(self, hass, host, port, prefix):
"""Initialize the feeder."""
super(GraphiteFeeder, self).__init__(daemon=True) super(GraphiteFeeder, self).__init__(daemon=True)
self._hass = hass self._hass = hass
self._host = host self._host = host

View file

@ -106,7 +106,7 @@ def get_entity_ids(hass, entity_id, domain_filter=None):
def setup(hass, config): def setup(hass, config):
"""Set up all groups found definded in the configuration.""" """Setup all groups found definded in the configuration."""
for object_id, conf in config.get(DOMAIN, {}).items(): for object_id, conf in config.get(DOMAIN, {}).items():
if not isinstance(conf, dict): if not isinstance(conf, dict):
conf = {CONF_ENTITIES: conf} conf = {CONF_ENTITIES: conf}
@ -129,7 +129,6 @@ class Group(Entity):
"""Track a group of entity ids.""" """Track a group of entity ids."""
# pylint: disable=too-many-instance-attributes, too-many-arguments # pylint: disable=too-many-instance-attributes, too-many-arguments
def __init__(self, hass, name, entity_ids=None, user_defined=True, def __init__(self, hass, name, entity_ids=None, user_defined=True,
icon=None, view=False, object_id=None): icon=None, view=False, object_id=None):
"""Initialize a group.""" """Initialize a group."""
@ -160,30 +159,27 @@ class Group(Entity):
@property @property
def name(self): def name(self):
"""Name of the group.""" """Return the name of the group."""
return self._name return self._name
@property @property
def state(self): def state(self):
"""State of the group.""" """Return the state of the group."""
return self._state return self._state
@property @property
def icon(self): def icon(self):
"""Icon of the group.""" """Return the icon of the group."""
return self._icon return self._icon
@property @property
def hidden(self): def hidden(self):
"""If group should be hidden or not. """If group should be hidden or not."""
true if group is a view or not user defined.
"""
return not self._user_defined or self._view return not self._user_defined or self._view
@property @property
def state_attributes(self): def state_attributes(self):
"""State attributes for the group.""" """Return the state attributes for the group."""
data = { data = {
ATTR_ENTITY_ID: self.tracking, ATTR_ENTITY_ID: self.tracking,
ATTR_ORDER: self._order, ATTR_ORDER: self._order,
@ -215,7 +211,7 @@ class Group(Entity):
self.hass, self.tracking, self._state_changed_listener) self.hass, self.tracking, self._state_changed_listener)
def stop(self): def stop(self):
"""Unregisters the group from Home Assistant.""" """Unregister the group from Home Assistant."""
self.hass.states.remove(self.entity_id) self.hass.states.remove(self.entity_id)
self.hass.bus.remove_listener( self.hass.bus.remove_listener(
@ -233,7 +229,7 @@ class Group(Entity):
@property @property
def _tracking_states(self): def _tracking_states(self):
"""States that the group is tracking.""" """The states that the group is tracking."""
states = [] states = []
for entity_id in self.tracking: for entity_id in self.tracking:

View file

@ -70,9 +70,7 @@ def get_significant_states(start_time, end_time=None, entity_id=None):
def state_changes_during_period(start_time, end_time=None, entity_id=None): def state_changes_during_period(start_time, end_time=None, entity_id=None):
""" """Return states changes during UTC period start_time - end_time."""
Return states changes during UTC period start_time - end_time.
"""
where = "last_changed=last_updated AND last_changed > ? " where = "last_changed=last_updated AND last_changed > ? "
data = [start_time] data = [start_time]
@ -93,7 +91,7 @@ def state_changes_during_period(start_time, end_time=None, entity_id=None):
def get_states(utc_point_in_time, entity_ids=None, run=None): def get_states(utc_point_in_time, entity_ids=None, run=None):
"""Returns the states at a specific point in time.""" """Return the states at a specific point in time."""
if run is None: if run is None:
run = recorder.run_information(utc_point_in_time) run = recorder.run_information(utc_point_in_time)
@ -122,8 +120,7 @@ def get_states(utc_point_in_time, entity_ids=None, run=None):
def states_to_json(states, start_time, entity_id): def states_to_json(states, start_time, entity_id):
""" """Convert SQL results into JSON friendly data structure.
Converts SQL results into JSON friendly data structure.
This takes our state list and turns it into a JSON friendly data This takes our state list and turns it into a JSON friendly data
structure {'entity_id': [list of states], 'entity_id2': [list of states]} structure {'entity_id': [list of states], 'entity_id2': [list of states]}
@ -157,7 +154,7 @@ def get_state(utc_point_in_time, entity_id, run=None):
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup(hass, config): def setup(hass, config):
"""Setup history hooks.""" """Setup the history hooks."""
hass.http.register_path( hass.http.register_path(
'GET', 'GET',
re.compile( re.compile(
@ -204,8 +201,7 @@ def _api_history_period(handler, path_match, data):
def _is_significant(state): def _is_significant(state):
""" """Test if state is significant for history charts.
Test if state is significant for history charts.
Will only test for things that are not filtered out in SQL. Will only test for things that are not filtered out in SQL.
""" """

View file

@ -50,7 +50,7 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config): def setup(hass, config):
"""Sets up the HTTP API and debug interface.""" """Set up the HTTP API and debug interface."""
conf = config.get(DOMAIN, {}) conf = config.get(DOMAIN, {})
api_password = util.convert(conf.get(CONF_API_PASSWORD), str) api_password = util.convert(conf.get(CONF_API_PASSWORD), str)
@ -86,6 +86,7 @@ def setup(hass, config):
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle HTTP requests in a threaded fashion.""" """Handle HTTP requests in a threaded fashion."""
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
allow_reuse_address = True allow_reuse_address = True
daemon_threads = True daemon_threads = True
@ -93,6 +94,7 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
def __init__(self, server_address, request_handler_class, def __init__(self, server_address, request_handler_class,
hass, api_password, development, ssl_certificate, ssl_key): hass, api_password, development, ssl_certificate, ssl_key):
"""Initialize the server."""
super().__init__(server_address, request_handler_class) super().__init__(server_address, request_handler_class)
self.server_address = server_address self.server_address = server_address
@ -116,9 +118,9 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
self.socket = context.wrap_socket(self.socket, server_side=True) self.socket = context.wrap_socket(self.socket, server_side=True)
def start(self): def start(self):
"""Starts the HTTP server.""" """Start the HTTP server."""
def stop_http(event): def stop_http(event):
"""Stops the HTTP server.""" """Stop the HTTP server."""
self.shutdown() self.shutdown()
self.hass.bus.listen_once(ha.EVENT_HOMEASSISTANT_STOP, stop_http) self.hass.bus.listen_once(ha.EVENT_HOMEASSISTANT_STOP, stop_http)
@ -137,7 +139,7 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
self.serve_forever() self.serve_forever()
def register_path(self, method, url, callback, require_auth=True): def register_path(self, method, url, callback, require_auth=True):
"""Registers a path with the server.""" """Register a path with the server."""
self.paths.append((method, url, callback, require_auth)) self.paths.append((method, url, callback, require_auth))
def log_message(self, fmt, *args): def log_message(self, fmt, *args):
@ -148,16 +150,16 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
# pylint: disable=too-many-public-methods,too-many-locals # pylint: disable=too-many-public-methods,too-many-locals
class RequestHandler(SimpleHTTPRequestHandler): class RequestHandler(SimpleHTTPRequestHandler):
""" """Handle incoming HTTP requests.
Handles incoming HTTP requests
We extend from SimpleHTTPRequestHandler instead of Base so we We extend from SimpleHTTPRequestHandler instead of Base so we
can use the guess content type methods. can use the guess content type methods.
""" """
server_version = "HomeAssistant/1.0" server_version = "HomeAssistant/1.0"
def __init__(self, req, client_addr, server): def __init__(self, req, client_addr, server):
"""Contructor, call the base constructor and set up session.""" """Constructor, call the base constructor and set up session."""
# Track if this was an authenticated request # Track if this was an authenticated request
self.authenticated = False self.authenticated = False
SimpleHTTPRequestHandler.__init__(self, req, client_addr, server) SimpleHTTPRequestHandler.__init__(self, req, client_addr, server)
@ -172,7 +174,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
if isinstance(arg, str) else arg for arg in arguments)) if isinstance(arg, str) else arg for arg in arguments))
def _handle_request(self, method): # pylint: disable=too-many-branches def _handle_request(self, method): # pylint: disable=too-many-branches
"""Does some common checks and calls appropriate method.""" """Perform some common checks and call appropriate method."""
url = urlparse(self.path) url = urlparse(self.path)
# Read query input. parse_qs gives a list for each value, we want last # Read query input. parse_qs gives a list for each value, we want last
@ -302,7 +304,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
self.wfile.write(message.encode("UTF-8")) self.wfile.write(message.encode("UTF-8"))
def write_file(self, path, cache_headers=True): def write_file(self, path, cache_headers=True):
"""Returns a file to the user.""" """Return a file to the user."""
try: try:
with open(path, 'rb') as inp: with open(path, 'rb') as inp:
self.write_file_pointer(self.guess_type(path), inp, self.write_file_pointer(self.guess_type(path), inp,
@ -314,10 +316,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
_LOGGER.exception("Unable to serve %s", path) _LOGGER.exception("Unable to serve %s", path)
def write_file_pointer(self, content_type, inp, cache_headers=True): def write_file_pointer(self, content_type, inp, cache_headers=True):
""" """Helper function to write a file pointer to the user."""
Helper function to write a file pointer to the user.
Does not do error handling.
"""
do_gzip = 'gzip' in self.headers.get(HTTP_HEADER_ACCEPT_ENCODING, '') do_gzip = 'gzip' in self.headers.get(HTTP_HEADER_ACCEPT_ENCODING, '')
self.send_response(HTTP_OK) self.send_response(HTTP_OK)
@ -387,9 +386,9 @@ class RequestHandler(SimpleHTTPRequestHandler):
return self.get_cookie_session_id() is not None return self.get_cookie_session_id() is not None
def get_cookie_session_id(self): def get_cookie_session_id(self):
""" """Extract the current session ID from the cookie.
Extracts the current session id from the cookie or returns None if not
set or invalid. Return None if not set or invalid.
""" """
if 'Cookie' not in self.headers: if 'Cookie' not in self.headers:
return None return None
@ -413,7 +412,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
return None return None
def destroy_session(self): def destroy_session(self):
"""Destroys session.""" """Destroy the session."""
session_id = self.get_cookie_session_id() session_id = self.get_cookie_session_id()
if session_id is None: if session_id is None:
@ -430,6 +429,7 @@ def session_valid_time():
class SessionStore(object): class SessionStore(object):
"""Responsible for storing and retrieving HTTP sessions.""" """Responsible for storing and retrieving HTTP sessions."""
def __init__(self): def __init__(self):
"""Setup the session store.""" """Setup the session store."""
self._sessions = {} self._sessions = {}
@ -464,7 +464,7 @@ class SessionStore(object):
self._sessions.pop(key, None) self._sessions.pop(key, None)
def create(self): def create(self):
"""Creates a new session.""" """Create a new session."""
with self._lock: with self._lock:
session_id = util.get_random_string(20) session_id = util.get_random_string(20)

View file

@ -84,9 +84,10 @@ def setup(hass, config):
class InputBoolean(ToggleEntity): class InputBoolean(ToggleEntity):
"""Represent a boolean input.""" """Representation of a boolean input."""
def __init__(self, object_id, name, state, icon): def __init__(self, object_id, name, state, icon):
""" Initialize a boolean input. """ """Initialize a boolean input."""
self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.entity_id = ENTITY_ID_FORMAT.format(object_id)
self._name = name self._name = name
self._state = state self._state = state

View file

@ -90,10 +90,11 @@ def setup(hass, config):
class InputSelect(Entity): class InputSelect(Entity):
"""Represent a select input.""" """Representation of a select input."""
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
def __init__(self, object_id, name, state, options, icon): def __init__(self, object_id, name, state, options, icon):
""" Initialize a select input. """ """Initialize a select input."""
self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.entity_id = ENTITY_ID_FORMAT.format(object_id)
self._name = name self._name = name
self._current_option = state self._current_option = state

View file

@ -22,8 +22,8 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config): def setup(hass, config):
""" """Setup Insteon Hub component.
Setup Insteon Hub component.
This will automatically import associated lights. This will automatically import associated lights.
""" """
if not validate_config( if not validate_config(
@ -56,8 +56,10 @@ def setup(hass, config):
class InsteonToggleDevice(ToggleEntity): class InsteonToggleDevice(ToggleEntity):
""" An abstract Class for an Insteon node.""" """An abstract Class for an Insteon node."""
def __init__(self, node): def __init__(self, node):
"""Initialize the device."""
self.node = node self.node = node
self._value = 0 self._value = 0
@ -85,7 +87,9 @@ class InsteonToggleDevice(ToggleEntity):
return self._value != 0 return self._value != 0
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
"""Turn device on."""
self.node.send_command('on') self.node.send_command('on')
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
"""Turn device off."""
self.node.send_command('off') self.node.send_command('off')

View file

@ -29,8 +29,8 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config): def setup(hass, config):
""" """Setup ISY994 component.
Setup ISY994 component.
This will automatically import associated lights, switches, and sensors. This will automatically import associated lights, switches, and sensors.
""" """
import PyISY import PyISY
@ -97,6 +97,7 @@ def stop(event):
class ISYDeviceABC(ToggleEntity): class ISYDeviceABC(ToggleEntity):
"""An abstract Class for an ISY device.""" """An abstract Class for an ISY device."""
_attrs = {} _attrs = {}
_onattrs = [] _onattrs = []
_states = [] _states = []
@ -105,6 +106,7 @@ class ISYDeviceABC(ToggleEntity):
_name = None _name = None
def __init__(self, node): def __init__(self, node):
"""Initialize the device."""
# setup properties # setup properties
self.node = node self.node = node
@ -182,7 +184,7 @@ class ISYDeviceABC(ToggleEntity):
pass pass
def on_update(self, event): def on_update(self, event):
"""Handles the update received event.""" """Handle the update received event."""
self.update_ha_state() self.update_ha_state()
@property @property
@ -203,7 +205,7 @@ class ISYDeviceABC(ToggleEntity):
return self.value return self.value
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
"""Turns the device on.""" """Turn the device on."""
if self.domain is not 'sensor': if self.domain is not 'sensor':
attrs = [kwargs.get(name) for name in self._onattrs] attrs = [kwargs.get(name) for name in self._onattrs]
self.node.on(*attrs) self.node.on(*attrs)
@ -211,7 +213,7 @@ class ISYDeviceABC(ToggleEntity):
_LOGGER.error('ISY cannot turn on sensors.') _LOGGER.error('ISY cannot turn on sensors.')
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
"""Turns the device off.""" """Turn the device off."""
if self.domain is not 'sensor': if self.domain is not 'sensor':
self.node.off() self.node.off()
else: else:

View file

@ -39,7 +39,7 @@ def media_next_track(hass):
def media_prev_track(hass): def media_prev_track(hass):
"""Press the keyboard button for prev track. """ """Press the keyboard button for prev track."""
hass.services.call(DOMAIN, SERVICE_MEDIA_PREVIOUS_TRACK) hass.services.call(DOMAIN, SERVICE_MEDIA_PREVIOUS_TRACK)

View file

@ -41,7 +41,7 @@ ATTR_ENTITY_ID = 'entity_id'
def log_entry(hass, name, message, domain=None, entity_id=None): def log_entry(hass, name, message, domain=None, entity_id=None):
"""Adds an entry to the logbook.""" """Add an entry to the logbook."""
data = { data = {
ATTR_NAME: name, ATTR_NAME: name,
ATTR_MESSAGE: message ATTR_MESSAGE: message
@ -55,7 +55,7 @@ def log_entry(hass, name, message, domain=None, entity_id=None):
def setup(hass, config): def setup(hass, config):
"""Listens for download events to download files.""" """Listen for download events to download files."""
def log_message(service): def log_message(service):
"""Handle sending notification message service calls.""" """Handle sending notification message service calls."""
message = service.data.get(ATTR_MESSAGE) message = service.data.get(ATTR_MESSAGE)
@ -100,9 +100,11 @@ def _handle_get_logbook(handler, path_match, data):
class Entry(object): class Entry(object):
"""A human readable version of the log.""" """A human readable version of the log."""
# pylint: disable=too-many-arguments, too-few-public-methods # pylint: disable=too-many-arguments, too-few-public-methods
def __init__(self, when=None, name=None, message=None, domain=None, def __init__(self, when=None, name=None, message=None, domain=None,
entity_id=None): entity_id=None):
"""Initialize the entry."""
self.when = when self.when = when
self.name = name self.name = name
self.message = message self.message = message
@ -121,8 +123,7 @@ class Entry(object):
def humanify(events): def humanify(events):
""" """Generator that converts a list of events into Entry objects.
Generator that converts a list of events into Entry objects.
Will try to group events if possible: Will try to group events if possible:
- if 2+ sensor updates in GROUP_BY_MINUTES, show last - if 2+ sensor updates in GROUP_BY_MINUTES, show last

View file

@ -26,8 +26,10 @@ LOGGER_LOGS = 'logs'
class HomeAssistantLogFilter(logging.Filter): class HomeAssistantLogFilter(logging.Filter):
"""A log filter.""" """A log filter."""
# pylint: disable=no-init,too-few-public-methods # pylint: disable=no-init,too-few-public-methods
def __init__(self, logfilter): def __init__(self, logfilter):
"""Initialize the filter."""
super().__init__() super().__init__()
self.logfilter = logfilter self.logfilter = logfilter

View file

@ -1,7 +1,5 @@
""" """
homeassistant.components.modbus Support for Modbus.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modbus component, using pymodbus (python3 branch).
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/modbus/ https://home-assistant.io/components/modbus/
@ -38,8 +36,7 @@ TYPE = None
def setup(hass, config): def setup(hass, config):
""" Setup Modbus component. """ """Setup Modbus component."""
# Modbus connection type # Modbus connection type
# pylint: disable=global-statement, import-error # pylint: disable=global-statement, import-error
global TYPE global TYPE
@ -69,15 +66,14 @@ def setup(hass, config):
return False return False
def stop_modbus(event): def stop_modbus(event):
""" Stop Modbus service. """ """Stop Modbus service."""
NETWORK.close() NETWORK.close()
def start_modbus(event): def start_modbus(event):
""" Start Modbus service. """ """Start Modbus service."""
NETWORK.connect() NETWORK.connect()
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_modbus) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_modbus)
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_modbus) hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_modbus)
# Tells the bootstrapper that the component was successfully initialized
return True return True

View file

@ -62,10 +62,7 @@ def setup(hass, config):
# Process events from a remote server that are received on a queue. # Process events from a remote server that are received on a queue.
def _event_receiver(topic, payload, qos): def _event_receiver(topic, payload, qos):
""" """Receive events published by and fire them on this hass instance."""
Receive events published by the other HA instance and fire them on
this hass instance.
"""
event = json.loads(payload) event = json.loads(payload)
event_type = event.get('event_type') event_type = event.get('event_type')
event_data = event.get('event_data') event_data = event.get('event_data')

View file

@ -157,6 +157,7 @@ def pf_callback_factory(map_sv_types, devices, add_devices, entity_class):
class GatewayWrapper(object): class GatewayWrapper(object):
"""Gateway wrapper class.""" """Gateway wrapper class."""
def __init__(self, gateway, version, optimistic): def __init__(self, gateway, version, optimistic):
"""Setup class attributes on instantiation. """Setup class attributes on instantiation.

View file

@ -1,4 +1,6 @@
""" """
Support for tracking the proximity of a device.
Component to monitor the proximity of devices to a particular zone and the Component to monitor the proximity of devices to a particular zone and the
direction of travel. direction of travel.
@ -77,11 +79,13 @@ def setup(hass, config): # pylint: disable=too-many-locals,too-many-statements
class Proximity(Entity): # pylint: disable=too-many-instance-attributes class Proximity(Entity): # pylint: disable=too-many-instance-attributes
"""Represents a Proximity.""" """Representation of a Proximity."""
# pylint: disable=too-many-arguments
def __init__(self, hass, zone_friendly_name, dist_to, dir_of_travel, def __init__(self, hass, zone_friendly_name, dist_to, dir_of_travel,
nearest, ignored_zones, proximity_devices, tolerance, nearest, ignored_zones, proximity_devices, tolerance,
proximity_zone): proximity_zone):
# pylint: disable=too-many-arguments """Initialize the proximity."""
self.hass = hass self.hass = hass
self.friendly_name = zone_friendly_name self.friendly_name = zone_friendly_name
self.dist_to = dist_to self.dist_to = dist_to
@ -115,8 +119,8 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
ATTR_NEAREST: self.nearest, ATTR_NEAREST: self.nearest,
} }
# pylint: disable=too-many-branches,too-many-statements,too-many-locals
def check_proximity_state_change(self, entity, old_state, new_state): def check_proximity_state_change(self, entity, old_state, new_state):
# pylint: disable=too-many-branches,too-many-statements,too-many-locals
"""Function to perform the proximity checking.""" """Function to perform the proximity checking."""
entity_name = new_state.name entity_name = new_state.name
devices_to_calculate = False devices_to_calculate = False

View file

@ -1,4 +1,6 @@
""" """
Support for recording details.
Component that records all events and state changes. Allows other components Component that records all events and state changes. Allows other components
to query this database. to query this database.
@ -80,8 +82,9 @@ def row_to_event(row):
def run_information(point_in_time=None): def run_information(point_in_time=None):
""" """Return information about current run.
Returns information about current run or the run that covers point_in_time.
There is also the run that covers point_in_time.
""" """
_verify_instance() _verify_instance()
@ -106,8 +109,10 @@ def setup(hass, config):
class RecorderRun(object): class RecorderRun(object):
"""Represents a recorder run.""" """Representation of arecorder run."""
def __init__(self, row=None): def __init__(self, row=None):
"""Initialize the recorder run."""
self.end = None self.end = None
if row is None: if row is None:
@ -122,8 +127,8 @@ class RecorderRun(object):
self.closed_incorrect = bool(row[3]) self.closed_incorrect = bool(row[3])
def entity_ids(self, point_in_time=None): def entity_ids(self, point_in_time=None):
""" """Return the entity ids that existed in this run.
Return the entity ids that existed in this run.
Specify point_in_time if you want to know which existed at that point Specify point_in_time if you want to know which existed at that point
in time inside the run. in time inside the run.
""" """
@ -140,15 +145,18 @@ class RecorderRun(object):
@property @property
def where_after_start_run(self): def where_after_start_run(self):
""" """Return SQL WHERE clause.
Returns SQL WHERE clause to select rows created after the start of the
run. Selection of the rows created after the start of the run.
""" """
return "created >= {} ".format(_adapt_datetime(self.start)) return "created >= {} ".format(_adapt_datetime(self.start))
@property @property
def where_limit_to_run(self): def where_limit_to_run(self):
""" Return a SQL WHERE clause to limit results to this run. """ """Return a SQL WHERE clause.
For limiting the results to this run.
"""
where = self.where_after_start_run where = self.where_after_start_run
if self.end is not None: if self.end is not None:
@ -159,7 +167,9 @@ class RecorderRun(object):
class Recorder(threading.Thread): class Recorder(threading.Thread):
"""A threaded recorder class.""" """A threaded recorder class."""
def __init__(self, hass): def __init__(self, hass):
"""Initialize the recorder."""
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.hass = hass self.hass = hass
@ -206,14 +216,11 @@ class Recorder(threading.Thread):
self.queue.task_done() self.queue.task_done()
def event_listener(self, event): def event_listener(self, event):
""" """Listen for new events and put them in the process queue."""
Listens for new events on the EventBus and puts them in the process
queue.
"""
self.queue.put(event) self.queue.put(event)
def shutdown(self, event): def shutdown(self, event):
"""Tells the recorder to shut down.""" """Tell the recorder to shut down."""
self.queue.put(self.quit_object) self.queue.put(self.quit_object)
self.block_till_done() self.block_till_done()
@ -262,7 +269,7 @@ class Recorder(threading.Thread):
") VALUES (?, ?, ?, ?, ?, ?)", info, RETURN_LASTROWID) ") VALUES (?, ?, ?, ?, ?, ?)", info, RETURN_LASTROWID)
def query(self, sql_query, data=None, return_value=None): def query(self, sql_query, data=None, return_value=None):
""" Query the database. """ """Query the database."""
try: try:
with self.conn, self.lock: with self.conn, self.lock:
_LOGGER.debug("Running query %s", sql_query) _LOGGER.debug("Running query %s", sql_query)
@ -290,7 +297,7 @@ class Recorder(threading.Thread):
return [] return []
def block_till_done(self): def block_till_done(self):
"""Blocks till all events processed.""" """Block till all events processed."""
self.queue.join() self.queue.join()
def _setup_connection(self): def _setup_connection(self):
@ -474,6 +481,6 @@ def _adapt_datetime(datetimestamp):
def _verify_instance(): def _verify_instance():
"""Throws error if recorder not initialized.""" """Throw error if recorder not initialized."""
if _INSTANCE is None: if _INSTANCE is None:
raise RuntimeError("Recorder not initialized.") raise RuntimeError("Recorder not initialized.")

View file

@ -59,7 +59,7 @@ def read_input(port):
def edge_detect(port, event_callback, bounce): def edge_detect(port, event_callback, bounce):
"""Adds detection for RISING and FALLING events.""" """Add detection for RISING and FALLING events."""
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
GPIO.add_event_detect( GPIO.add_event_detect(
port, port,

View file

@ -1,4 +1,6 @@
""" """
Support for scripts.
Scripts are a sequence of actions that can be triggered manually Scripts are a sequence of actions that can be triggered manually
by the user or automatically based upon automation events, etc. by the user or automatically based upon automation events, etc.
@ -43,7 +45,7 @@ _LOGGER = logging.getLogger(__name__)
def is_on(hass, entity_id): def is_on(hass, entity_id):
"""Returns if the switch is on based on the statemachine.""" """Return if the switch is on based on the statemachine."""
return hass.states.is_state(entity_id, STATE_ON) return hass.states.is_state(entity_id, STATE_ON)
@ -60,7 +62,7 @@ def turn_off(hass, entity_id):
def toggle(hass, entity_id): def toggle(hass, entity_id):
"""Toggles script.""" """Toggle the script."""
hass.services.call(DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: entity_id}) hass.services.call(DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: entity_id})
@ -69,7 +71,7 @@ def setup(hass, config):
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
def service_handler(service): def service_handler(service):
""" Execute a service call to script.<script name>. """ """Execute a service call to script.<script name>."""
entity_id = ENTITY_ID_FORMAT.format(service.service) entity_id = ENTITY_ID_FORMAT.format(service.service)
script = component.entities.get(entity_id) script = component.entities.get(entity_id)
if not script: if not script:
@ -94,19 +96,19 @@ def setup(hass, config):
hass.services.register(DOMAIN, object_id, service_handler) hass.services.register(DOMAIN, object_id, service_handler)
def turn_on_service(service): def turn_on_service(service):
"""Calls a service to turn script on.""" """Call a service to turn script on."""
# We could turn on script directly here, but we only want to offer # We could turn on script directly here, but we only want to offer
# one way to do it. Otherwise no easy way to call invocations. # one way to do it. Otherwise no easy way to call invocations.
for script in component.extract_from_service(service): for script in component.extract_from_service(service):
turn_on(hass, script.entity_id) turn_on(hass, script.entity_id)
def turn_off_service(service): def turn_off_service(service):
"""Cancels a script.""" """Cancel a script."""
for script in component.extract_from_service(service): for script in component.extract_from_service(service):
script.turn_off() script.turn_off()
def toggle_service(service): def toggle_service(service):
"""Toggles a script.""" """Toggle a script."""
for script in component.extract_from_service(service): for script in component.extract_from_service(service):
script.toggle() script.toggle()
@ -118,9 +120,11 @@ def setup(hass, config):
class Script(ToggleEntity): class Script(ToggleEntity):
"""Represents a script.""" """Representation of a script."""
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
def __init__(self, object_id, name, sequence): def __init__(self, object_id, name, sequence):
"""Initialize the script."""
self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.entity_id = ENTITY_ID_FORMAT.format(object_id)
self._name = name self._name = name
self.sequence = sequence self.sequence = sequence
@ -153,7 +157,7 @@ class Script(ToggleEntity):
@property @property
def is_on(self): def is_on(self):
"""True if entity is on.""" """Return true if script is on."""
return self._cur != -1 return self._cur != -1
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
@ -179,7 +183,7 @@ class Script(ToggleEntity):
elif CONF_DELAY in action: elif CONF_DELAY in action:
# Call ourselves in the future to continue work # Call ourselves in the future to continue work
def script_delay(now): def script_delay(now):
""" Called after delay is done. """ """Called after delay is done."""
self._listener = None self._listener = None
self.turn_on() self.turn_on()
@ -206,7 +210,7 @@ class Script(ToggleEntity):
self._remove_listener() self._remove_listener()
def _call_service(self, action): def _call_service(self, action):
"""Calls the service specified in the action.""" """Call the service specified in the action."""
# Backwards compatibility # Backwards compatibility
if CONF_SERVICE not in action and CONF_SERVICE_OLD in action: if CONF_SERVICE not in action and CONF_SERVICE_OLD in action:
action[CONF_SERVICE] = action[CONF_SERVICE_OLD] action[CONF_SERVICE] = action[CONF_SERVICE_OLD]
@ -220,7 +224,7 @@ class Script(ToggleEntity):
call_from_config(self.hass, action, True) call_from_config(self.hass, action, True)
def _fire_event(self, action): def _fire_event(self, action):
"""Fires an event.""" """Fire an event."""
self._last_action = action.get(CONF_ALIAS, action[CONF_EVENT]) self._last_action = action.get(CONF_ALIAS, action[CONF_EVENT])
_LOGGER.info("Executing script %s step %s", self._name, _LOGGER.info("Executing script %s step %s", self._name,
self._last_action) self._last_action)

View file

@ -16,8 +16,10 @@ _LOGGER = logging.getLogger(__name__)
class SCSGate: class SCSGate:
"""Class dealing with the SCSGate device via scsgate.Reactor.""" """The class for dealing with the SCSGate device via scsgate.Reactor."""
def __init__(self, device, logger): def __init__(self, device, logger):
"""Initialize the SCSGate."""
self._logger = logger self._logger = logger
self._devices = {} self._devices = {}
self._devices_to_register = {} self._devices_to_register = {}
@ -69,16 +71,16 @@ class SCSGate:
@property @property
def devices(self): def devices(self):
""" """Dictionary with known devices.
Dictionary with known devices. Key is device ID, value is the device
itself. Key is device ID, value is the device itself.
""" """
return self._devices return self._devices
def add_device(self, device): def add_device(self, device):
""" """Add the specified device.
Adds the specified device to the list of the already registered ones.
The list contain already registered ones.
Beware: this is not what you usually want to do, take a look at Beware: this is not what you usually want to do, take a look at
`add_devices_to_register` `add_devices_to_register`
""" """
@ -92,7 +94,7 @@ class SCSGate:
self._activate_next_device() self._activate_next_device()
def _activate_next_device(self): def _activate_next_device(self):
"""Starts the activation of the first device.""" """Start the activation of the first device."""
from scsgate.tasks import GetStatusTask from scsgate.tasks import GetStatusTask
with self._devices_to_register_lock: with self._devices_to_register_lock:
@ -104,7 +106,7 @@ class SCSGate:
self._reactor.append_task(GetStatusTask(target=device.scs_id)) self._reactor.append_task(GetStatusTask(target=device.scs_id))
def is_device_registered(self, device_id): def is_device_registered(self, device_id):
"""Checks whether a device is already registered or not.""" """Check whether a device is already registered or not."""
with self._devices_to_register_lock: with self._devices_to_register_lock:
if device_id in self._devices_to_register.keys(): if device_id in self._devices_to_register.keys():
return False return False
@ -124,7 +126,7 @@ class SCSGate:
self._reactor.stop() self._reactor.stop()
def append_task(self, task): def append_task(self, task):
"""Registers a new task to be executed.""" """Register a new task to be executed."""
self._reactor.append_task(task) self._reactor.append_task(task)
@ -142,10 +144,7 @@ def setup(hass, config):
return False return False
def stop_monitor(event): def stop_monitor(event):
""" """Stop the SCSGate."""
Invoked when home-assistant is exiting. Performs the necessary
cleanups.
"""
_LOGGER.info("Stopping SCSGate monitor thread") _LOGGER.info("Stopping SCSGate monitor thread")
SCSGATE.stop() SCSGATE.stop()

View file

@ -15,7 +15,7 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config): def setup(hass, config):
"""Sets up the shell_command component.""" """Setup the shell_command component."""
conf = config.get(DOMAIN) conf = config.get(DOMAIN)
if not isinstance(conf, dict): if not isinstance(conf, dict):

View file

@ -1,6 +1,7 @@
""" """
A component which allows you to send data to an Splunk instance utilizing the Support to send data to an Splunk instance.
HTTP Event Collector.
Uses the HTTP Event Collector.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/splunk/ https://home-assistant.io/components/splunk/

View file

@ -1,5 +1,5 @@
""" """
Provides functionality to keep track of the sun. Support for functionality to keep track of the sun.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/sun/ https://home-assistant.io/components/sun/
@ -123,11 +123,12 @@ def setup(hass, config):
class Sun(Entity): class Sun(Entity):
"""Represents the Sun.""" """Representation of the Sun."""
entity_id = ENTITY_ID entity_id = ENTITY_ID
def __init__(self, hass, location): def __init__(self, hass, location):
"""Initialize the Sun."""
self.hass = hass self.hass = hass
self.location = location self.location = location
self._state = self.next_rising = self.next_setting = None self._state = self.next_rising = self.next_setting = None
@ -135,10 +136,12 @@ class Sun(Entity):
@property @property
def name(self): def name(self):
"""Return the name."""
return "Sun" return "Sun"
@property @property
def state(self): def state(self):
"""Return the state of the sun."""
if self.next_rising > self.next_setting: if self.next_rising > self.next_setting:
return STATE_ABOVE_HORIZON return STATE_ABOVE_HORIZON
@ -146,6 +149,7 @@ class Sun(Entity):
@property @property
def state_attributes(self): def state_attributes(self):
"""Return the state attributes of the sun."""
return { return {
STATE_ATTR_NEXT_RISING: STATE_ATTR_NEXT_RISING:
dt_util.datetime_to_str(self.next_rising), dt_util.datetime_to_str(self.next_rising),
@ -169,7 +173,7 @@ class Sun(Entity):
self.location.longitude) self.location.longitude)
def update_as_of(self, utc_point_in_time): def update_as_of(self, utc_point_in_time):
""" Calculate sun state at a point in UTC time. """ """Calculate sun state at a point in UTC time."""
mod = -1 mod = -1
while True: while True:
next_rising_dt = self.location.sunrise( next_rising_dt = self.location.sunrise(
@ -190,7 +194,7 @@ class Sun(Entity):
self.next_setting = next_setting_dt self.next_setting = next_setting_dt
def point_in_time_listener(self, now): def point_in_time_listener(self, now):
""" Called when the state of the sun has changed. """ """Called when the state of the sun has changed."""
self.update_as_of(now) self.update_as_of(now)
self.update_ha_state() self.update_ha_state()
@ -200,5 +204,5 @@ class Sun(Entity):
self.next_change + timedelta(seconds=1)) self.next_change + timedelta(seconds=1))
def timer_update(self, time): def timer_update(self, time):
""" Needed to update solar elevation. """ """Needed to update solar elevation."""
self.update_ha_state() self.update_ha_state()

View file

@ -61,8 +61,10 @@ def request_sensors():
class TelldusLiveData(object): class TelldusLiveData(object):
"""Gets the latest data and update the states.""" """Get the latest data and update the states."""
def __init__(self, hass, config): def __init__(self, hass, config):
"""Initialize the Tellus data object."""
public_key = config[DOMAIN].get(CONF_PUBLIC_KEY) public_key = config[DOMAIN].get(CONF_PUBLIC_KEY)
private_key = config[DOMAIN].get(CONF_PRIVATE_KEY) private_key = config[DOMAIN].get(CONF_PRIVATE_KEY)
token = config[DOMAIN].get(CONF_TOKEN) token = config[DOMAIN].get(CONF_TOKEN)
@ -111,7 +113,7 @@ class TelldusLiveData(object):
ATTR_DISCOVERED: found_devices}) ATTR_DISCOVERED: found_devices})
def request(self, what, **params): def request(self, what, **params):
"""Sends a request to the Tellstick Live API.""" """Send a request to the Tellstick Live API."""
from tellive.live import const from tellive.live import const
supported_methods = const.TELLSTICK_TURNON \ supported_methods = const.TELLSTICK_TURNON \

View file

@ -58,8 +58,10 @@ def setup(hass, config):
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
class VerisureHub(object): class VerisureHub(object):
"""A Verisure wrapper class.""" """A Verisure hub wrapper class."""
def __init__(self, domain_config, verisure): def __init__(self, domain_config, verisure):
"""Initialize the Verisure hub."""
self.alarm_status = {} self.alarm_status = {}
self.lock_status = {} self.lock_status = {}
self.climate_status = {} self.climate_status = {}
@ -93,41 +95,41 @@ class VerisureHub(object):
@Throttle(timedelta(seconds=1)) @Throttle(timedelta(seconds=1))
def update_alarms(self): def update_alarms(self):
"""Updates the status of the alarm.""" """Update the status of the alarm."""
self.update_component( self.update_component(
self.my_pages.alarm.get, self.my_pages.alarm.get,
self.alarm_status) self.alarm_status)
@Throttle(timedelta(seconds=1)) @Throttle(timedelta(seconds=1))
def update_locks(self): def update_locks(self):
"""Updates the status of the locks.""" """Update the status of the locks."""
self.update_component( self.update_component(
self.my_pages.lock.get, self.my_pages.lock.get,
self.lock_status) self.lock_status)
@Throttle(timedelta(seconds=60)) @Throttle(timedelta(seconds=60))
def update_climate(self): def update_climate(self):
"""Updates the status of the climate units.""" """Update the status of the climate units."""
self.update_component( self.update_component(
self.my_pages.climate.get, self.my_pages.climate.get,
self.climate_status) self.climate_status)
@Throttle(timedelta(seconds=60)) @Throttle(timedelta(seconds=60))
def update_mousedetection(self): def update_mousedetection(self):
"""Updates the status of the mouse detectors.""" """Update the status of the mouse detectors."""
self.update_component( self.update_component(
self.my_pages.mousedetection.get, self.my_pages.mousedetection.get,
self.mouse_status) self.mouse_status)
@Throttle(timedelta(seconds=1)) @Throttle(timedelta(seconds=1))
def update_smartplugs(self): def update_smartplugs(self):
"""Updates the status of the smartplugs.""" """Update the status of the smartplugs."""
self.update_component( self.update_component(
self.my_pages.smartplug.get, self.my_pages.smartplug.get,
self.smartplug_status) self.smartplug_status)
def update_component(self, get_function, status): def update_component(self, get_function, status):
"""Updates the status of Verisure components.""" """Update the status of Verisure components."""
if self._wrong_password_given: if self._wrong_password_given:
_LOGGER.error('Wrong password for Verisure, update config') _LOGGER.error('Wrong password for Verisure, update config')
return return

View file

@ -35,8 +35,10 @@ def setup(hass, config):
class Link(Entity): class Link(Entity):
"""Represent a link.""" """Representation of a link."""
def __init__(self, hass, name, url, icon): def __init__(self, hass, name, url, icon):
"""Initialize the link."""
self.hass = hass self.hass = hass
self._name = name self._name = name
self._url = url self._url = url

View file

@ -64,7 +64,9 @@ def setup(hass, config):
class WinkToggleDevice(ToggleEntity): class WinkToggleDevice(ToggleEntity):
"""Represents a Wink toggle (switch) device.""" """Represents a Wink toggle (switch) device."""
def __init__(self, wink): def __init__(self, wink):
"""Initialize the Wink device."""
self.wink = wink self.wink = wink
@property @property
@ -79,15 +81,15 @@ class WinkToggleDevice(ToggleEntity):
@property @property
def is_on(self): def is_on(self):
"""True if decive is on.""" """Return true if device is on."""
return self.wink.state() return self.wink.state()
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
"""Turns the device on.""" """Turn the device on."""
self.wink.set_state(True) self.wink.set_state(True)
def turn_off(self): def turn_off(self):
"""Turns the device off.""" """Turn the device off."""
self.wink.set_state(False) self.wink.set_state(False)
def update(self): def update(self):

View file

@ -34,10 +34,7 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config): def setup(hass, config):
""" """Setup the connection to the ZigBee device."""
Set up the connection to the ZigBee device and instantiate the helper
class for it.
"""
global DEVICE global DEVICE
global GPIO_DIGITAL_OUTPUT_LOW global GPIO_DIGITAL_OUTPUT_LOW
global GPIO_DIGITAL_OUTPUT_HIGH global GPIO_DIGITAL_OUTPUT_HIGH
@ -69,27 +66,27 @@ def setup(hass, config):
def close_serial_port(*args): def close_serial_port(*args):
""" Close the serial port we're using to communicate with the ZigBee. """ """Close the serial port we're using to communicate with the ZigBee."""
DEVICE.zb.serial.close() DEVICE.zb.serial.close()
class ZigBeeConfig(object): class ZigBeeConfig(object):
""" """Handle the fetching of configuration from the config file."""
Handles the fetching of configuration from the config file for any ZigBee
entity.
"""
def __init__(self, config): def __init__(self, config):
"""Initialize the configuration."""
self._config = config self._config = config
self._should_poll = config.get("poll", True) self._should_poll = config.get("poll", True)
@property @property
def name(self): def name(self):
""" The name given to the entity. """ """The name given to the entity."""
return self._config["name"] return self._config["name"]
@property @property
def address(self): def address(self):
""" """The address of the device.
If an address has been provided, unhexlify it, otherwise return None If an address has been provided, unhexlify it, otherwise return None
as we're talking to our local ZigBee device. as we're talking to our local ZigBee device.
""" """
@ -100,38 +97,33 @@ class ZigBeeConfig(object):
@property @property
def should_poll(self): def should_poll(self):
""" """No polling needed."""
A bool depicting whether HA should repeatedly poll this device for its
value.
"""
return self._should_poll return self._should_poll
class ZigBeePinConfig(ZigBeeConfig): class ZigBeePinConfig(ZigBeeConfig):
""" """Handle the fetching of configuration from the config file."""
Handles the fetching of configuration from the config file for a ZigBee
GPIO pin.
"""
@property @property
def pin(self): def pin(self):
""" The GPIO pin number. """ """The GPIO pin number."""
return self._config["pin"] return self._config["pin"]
class ZigBeeDigitalPinConfig(ZigBeePinConfig): class ZigBeeDigitalPinConfig(ZigBeePinConfig):
""" """Handle the fetching of configuration from the config file."""
Handles the fetching of configuration from the config file for a ZigBee
GPIO pin set to digital in or out.
"""
def __init__(self, config): def __init__(self, config):
"""Initialize the configuration."""
super(ZigBeeDigitalPinConfig, self).__init__(config) super(ZigBeeDigitalPinConfig, self).__init__(config)
self._bool2state, self._state2bool = self.boolean_maps self._bool2state, self._state2bool = self.boolean_maps
@property @property
def boolean_maps(self): def boolean_maps(self):
""" """Create dicts to map booleans to pin high/low and vice versa.
Create dicts to map booleans to pin high/low and vice versa. Depends on
the config item "on_state" which should be set to "low" or "high". Depends on the config item "on_state" which should be set to "low"
or "high".
""" """
if self._config.get("on_state", "").lower() == "low": if self._config.get("on_state", "").lower() == "low":
bool2state = { bool2state = {
@ -148,17 +140,17 @@ class ZigBeeDigitalPinConfig(ZigBeePinConfig):
@property @property
def bool2state(self): def bool2state(self):
""" """A dictionary mapping booleans to GPIOSetting objects.
A dictionary mapping booleans to GPIOSetting objects to translate
on/off as being pin high or low. For the translation of on/off as being pin high or low.
""" """
return self._bool2state return self._bool2state
@property @property
def state2bool(self): def state2bool(self):
""" """A dictionary mapping GPIOSetting objects to booleans.
A dictionary mapping GPIOSetting objects to booleans to translate
pin high/low as being on or off. For the translation of pin high/low as being on or off.
""" """
return self._state2bool return self._state2bool
@ -167,30 +159,32 @@ ZigBeeDigitalInConfig = ZigBeeDigitalPinConfig
class ZigBeeDigitalOutConfig(ZigBeeDigitalPinConfig): class ZigBeeDigitalOutConfig(ZigBeeDigitalPinConfig):
"""A subclass of ZigBeeDigitalPinConfig.
Set _should_poll to default as False instead of True. The value will
still be overridden by the presence of a 'poll' config entry.
""" """
A subclass of ZigBeeDigitalPinConfig which sets _should_poll to default as
False instead of True. The value will still be overridden by the presence
of a 'poll' config entry.
"""
def __init__(self, config): def __init__(self, config):
"""Initialize the ZigBee Digital out."""
super(ZigBeeDigitalOutConfig, self).__init__(config) super(ZigBeeDigitalOutConfig, self).__init__(config)
self._should_poll = config.get("poll", False) self._should_poll = config.get("poll", False)
class ZigBeeAnalogInConfig(ZigBeePinConfig): class ZigBeeAnalogInConfig(ZigBeePinConfig):
""" """Representation of a ZigBee GPIO pin set to analog in."""
Handles the fetching of configuration from the config file for a ZigBee
GPIO pin set to analog in.
"""
@property @property
def max_voltage(self): def max_voltage(self):
""" The voltage at which the ADC will report its highest value. """ """The voltage at which the ADC will report its highest value."""
return float(self._config.get("max_volts", DEFAULT_ADC_MAX_VOLTS)) return float(self._config.get("max_volts", DEFAULT_ADC_MAX_VOLTS))
class ZigBeeDigitalIn(Entity): class ZigBeeDigitalIn(Entity):
""" Represents a GPIO pin configured as a digital input. """ """Representation of a GPIO pin configured as a digital input."""
def __init__(self, hass, config): def __init__(self, hass, config):
"""Initialize the device."""
self._config = config self._config = config
self._state = False self._state = False
# Get initial state # Get initial state
@ -199,21 +193,21 @@ class ZigBeeDigitalIn(Entity):
@property @property
def name(self): def name(self):
""" The name of the input. """ """Return the name of the input."""
return self._config.name return self._config.name
@property @property
def should_poll(self): def should_poll(self):
""" State of the polling, if needed. """ """Return the state of the polling, if needed."""
return self._config.should_poll return self._config.should_poll
@property @property
def is_on(self): def is_on(self):
""" Returns True if the Entity is on, else False. """ """Return True if the Entity is on, else False."""
return self._state return self._state
def update(self): def update(self):
""" Ask the ZigBee device what its output is set to. """ """Ask the ZigBee device what its output is set to."""
try: try:
pin_state = DEVICE.get_gpio_pin( pin_state = DEVICE.get_gpio_pin(
self._config.pin, self._config.pin,
@ -231,8 +225,10 @@ class ZigBeeDigitalIn(Entity):
class ZigBeeDigitalOut(ZigBeeDigitalIn): class ZigBeeDigitalOut(ZigBeeDigitalIn):
""" Adds functionality to ZigBeeDigitalIn to control an output. """ """Representation of a GPIO pin configured as a digital input."""
def _set_state(self, state): def _set_state(self, state):
"""Initialize the ZigBee digital out device."""
try: try:
DEVICE.set_gpio_pin( DEVICE.set_gpio_pin(
self._config.pin, self._config.pin,
@ -252,17 +248,19 @@ class ZigBeeDigitalOut(ZigBeeDigitalIn):
self.update_ha_state() self.update_ha_state()
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
""" Set the digital output to its 'on' state. """ """Set the digital output to its 'on' state."""
self._set_state(True) self._set_state(True)
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
""" Set the digital output to its 'off' state. """ """Set the digital output to its 'off' state."""
self._set_state(False) self._set_state(False)
class ZigBeeAnalogIn(Entity): class ZigBeeAnalogIn(Entity):
""" Represents a GPIO pin configured as an analog input. """ """Representation of a GPIO pin configured as an analog input."""
def __init__(self, hass, config): def __init__(self, hass, config):
"""Initialize the ZigBee analog in device."""
self._config = config self._config = config
self._value = None self._value = None
# Get initial state # Get initial state
@ -271,26 +269,26 @@ class ZigBeeAnalogIn(Entity):
@property @property
def name(self): def name(self):
""" The name of the input. """ """The name of the input."""
return self._config.name return self._config.name
@property @property
def should_poll(self): def should_poll(self):
""" State of the polling, if needed. """ """The state of the polling, if needed."""
return self._config.should_poll return self._config.should_poll
@property @property
def state(self): def state(self):
""" Returns the state of the entity. """ """Return the state of the entity."""
return self._value return self._value
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):
""" Unit this state is expressed in. """ """Return the unit this state is expressed in."""
return "%" return "%"
def update(self): def update(self):
""" Get the latest reading from the ADC. """ """Get the latest reading from the ADC."""
try: try:
self._value = DEVICE.read_analog_pin( self._value = DEVICE.read_analog_pin(
self._config.pin, self._config.pin,

View file

@ -106,9 +106,11 @@ def setup(hass, config):
class Zone(Entity): class Zone(Entity):
"""Represents a Zone.""" """Representation of a Zone."""
# pylint: disable=too-many-arguments, too-many-instance-attributes # pylint: disable=too-many-arguments, too-many-instance-attributes
def __init__(self, hass, name, latitude, longitude, radius, icon, passive): def __init__(self, hass, name, latitude, longitude, radius, icon, passive):
"""Initialize the zone."""
self.hass = hass self.hass = hass
self._name = name self._name = name
self._latitude = latitude self._latitude = latitude
@ -119,7 +121,7 @@ class Zone(Entity):
@property @property
def name(self): def name(self):
""" Return the name of the zone.""" """Return the name of the zone."""
return self._name return self._name
@property @property
@ -134,7 +136,7 @@ class Zone(Entity):
@property @property
def state_attributes(self): def state_attributes(self):
""" Return the state attributes of the zone.""" """Return the state attributes of the zone."""
data = { data = {
ATTR_HIDDEN: True, ATTR_HIDDEN: True,
ATTR_LATITUDE: self._latitude, ATTR_LATITUDE: self._latitude,

View file

@ -91,25 +91,26 @@ NETWORK = None
def _obj_to_dict(obj): def _obj_to_dict(obj):
"""Converts an obj into a hash for debug.""" """Convert an object into a hash for debug."""
return {key: getattr(obj, key) for key return {key: getattr(obj, key) for key
in dir(obj) in dir(obj)
if key[0] != '_' and not hasattr(getattr(obj, key), '__call__')} if key[0] != '_' and not hasattr(getattr(obj, key), '__call__')}
def _node_name(node): def _node_name(node):
"""Returns the name of the node.""" """Return the name of the node."""
return node.name or "{} {}".format( return node.name or "{} {}".format(
node.manufacturer_name, node.product_name) node.manufacturer_name, node.product_name)
def _value_name(value): def _value_name(value):
"""Returns the name of the value.""" """Return the name of the value."""
return "{} {}".format(_node_name(value.node), value.label) return "{} {}".format(_node_name(value.node), value.label)
def _object_id(value): def _object_id(value):
"""Returns the object_id of the device value. """Return the object_id of the device value.
The object_id contains node_id and value instance id The object_id contains node_id and value instance id
to not collide with other entity_ids. to not collide with other entity_ids.
""" """
@ -124,7 +125,7 @@ def _object_id(value):
def nice_print_node(node): def nice_print_node(node):
"""Prints a nice formatted node to the output (debug method).""" """Print a nice formatted node to the output (debug method)."""
node_dict = _obj_to_dict(node) node_dict = _obj_to_dict(node)
node_dict['values'] = {value_id: _obj_to_dict(value) node_dict['values'] = {value_id: _obj_to_dict(value)
for value_id, value in node.values.items()} for value_id, value in node.values.items()}
@ -136,7 +137,7 @@ def nice_print_node(node):
def get_config_value(node, value_index): def get_config_value(node, value_index):
"""Returns the current configuration value for a specific index.""" """Return the current configuration value for a specific index."""
try: try:
for value in node.values.values(): for value in node.values.values():
# 112 == config command class # 112 == config command class
@ -149,8 +150,8 @@ def get_config_value(node, value_index):
def setup(hass, config): def setup(hass, config):
""" """Setup Z-Wave.
Setup Z-wave.
Will automatically load components to support devices found on the network. Will automatically load components to support devices found on the network.
""" """
# pylint: disable=global-statement, import-error # pylint: disable=global-statement, import-error
@ -178,7 +179,7 @@ def setup(hass, config):
if use_debug: if use_debug:
def log_all(signal, value=None): def log_all(signal, value=None):
""" Log all the signals. """ """Log all the signals."""
print("") print("")
print("SIGNAL *****", signal) print("SIGNAL *****", signal)
if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED, if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
@ -249,11 +250,11 @@ def setup(hass, config):
NETWORK.controller.begin_command_remove_device() NETWORK.controller.begin_command_remove_device()
def stop_zwave(event): def stop_zwave(event):
"""Stop Z-wave.""" """Stop Z-Wave."""
NETWORK.stop() NETWORK.stop()
def start_zwave(event): def start_zwave(event):
"""Startup """ """Startup Z-Wave."""
NETWORK.start() NETWORK.start()
polling_interval = convert( polling_interval = convert(
@ -274,8 +275,10 @@ def setup(hass, config):
class ZWaveDeviceEntity: class ZWaveDeviceEntity:
"""Represents a Z-Wave node entity.""" """Representation of a Z-Wave node entity."""
def __init__(self, value, domain): def __init__(self, value, domain):
"""Initialize the z-Wave device."""
self._value = value self._value = value
self.entity_id = "{}.{}".format(domain, self._object_id()) self.entity_id = "{}.{}".format(domain, self._object_id())
@ -286,25 +289,26 @@ class ZWaveDeviceEntity:
@property @property
def unique_id(self): def unique_id(self):
"""Returns a unique id.""" """Return an unique ID."""
return "ZWAVE-{}-{}".format(self._value.node.node_id, return "ZWAVE-{}-{}".format(self._value.node.node_id,
self._value.object_id) self._value.object_id)
@property @property
def name(self): def name(self):
"""Returns the name of the device.""" """Return the name of the device."""
return _value_name(self._value) return _value_name(self._value)
def _object_id(self): def _object_id(self):
""" """Return the object_id of the device value.
Returns the object_id of the device value. The object_id contains
node_id and value instance id to not collide with other entity_ids. The object_id contains node_id and value instance id to not collide
with other entity_ids.
""" """
return _object_id(self._value) return _object_id(self._value)
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return device specific state attributes.""" """Return the device specific state attributes."""
attrs = { attrs = {
ATTR_NODE_ID: self._value.node.node_id, ATTR_NODE_ID: self._value.node.node_id,
} }