Update docstrings to match PEP257
This commit is contained in:
parent
7ff9aecd4e
commit
b8a40457ee
40 changed files with 371 additions and 483 deletions
|
@ -1,8 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.apcupsd
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sets up and provides access to the status output of APCUPSd via its Network
|
||||
Information Server (NIS).
|
||||
Support for status output of APCUPSd via its Network Information Server (NIS).
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/apcupsd/
|
||||
|
@ -34,7 +31,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Use config values to set up a function enabling status retrieval. """
|
||||
"""Use config values to set up a function enabling status retrieval."""
|
||||
global DATA
|
||||
|
||||
host = config[DOMAIN].get(CONF_HOST, DEFAULT_HOST)
|
||||
|
@ -68,12 +65,12 @@ class APCUPSdData(object):
|
|||
|
||||
@property
|
||||
def status(self):
|
||||
""" Get latest update if throttle allows. Return status. """
|
||||
"""Get latest update if throttle allows. Return status."""
|
||||
self.update()
|
||||
return self._status
|
||||
|
||||
def _get_status(self):
|
||||
""" Get the status from APCUPSd and parse it into a dict. """
|
||||
"""Get the status from APCUPSd and parse it into a dict."""
|
||||
return self._parse(self._get(host=self._host, port=self._port))
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
"""
|
||||
components.arduino
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Arduino component that connects to a directly attached Arduino board which
|
||||
runs with the Firmata firmware.
|
||||
Support for Arduino boards running with the Firmata firmware.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/arduino/
|
||||
|
@ -20,8 +17,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the Arduino component. """
|
||||
|
||||
"""Setup the Arduino component."""
|
||||
if not validate_config(config,
|
||||
{DOMAIN: ['port']},
|
||||
_LOGGER):
|
||||
|
@ -40,11 +36,11 @@ def setup(hass, config):
|
|||
return False
|
||||
|
||||
def stop_arduino(event):
|
||||
""" Stop the Arduino service. """
|
||||
"""Stop the Arduino service."""
|
||||
BOARD.disconnect()
|
||||
|
||||
def start_arduino(event):
|
||||
""" Start the Arduino service. """
|
||||
"""Start the Arduino service."""
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_arduino)
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_arduino)
|
||||
|
@ -53,15 +49,14 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class ArduinoBoard(object):
|
||||
""" Represents an Arduino board. """
|
||||
|
||||
"""Represents an Arduino board."""
|
||||
def __init__(self, port):
|
||||
from PyMata.pymata import PyMata
|
||||
self._port = port
|
||||
self._board = PyMata(self._port, verbose=False)
|
||||
|
||||
def set_mode(self, pin, direction, mode):
|
||||
""" Sets the mode and the direction of a given pin. """
|
||||
"""Set the mode and the direction of a given pin."""
|
||||
if mode == 'analog' and direction == 'in':
|
||||
self._board.set_pin_mode(pin,
|
||||
self._board.INPUT,
|
||||
|
@ -84,31 +79,31 @@ class ArduinoBoard(object):
|
|||
self._board.PWM)
|
||||
|
||||
def get_analog_inputs(self):
|
||||
""" Get the values from the pins. """
|
||||
"""Get the values from the pins."""
|
||||
self._board.capability_query()
|
||||
return self._board.get_analog_response_table()
|
||||
|
||||
def set_digital_out_high(self, pin):
|
||||
""" Sets a given digital pin to high. """
|
||||
"""Set a given digital pin to high."""
|
||||
self._board.digital_write(pin, 1)
|
||||
|
||||
def set_digital_out_low(self, pin):
|
||||
""" Sets a given digital pin to low. """
|
||||
"""Set a given digital pin to low."""
|
||||
self._board.digital_write(pin, 0)
|
||||
|
||||
def get_digital_in(self, pin):
|
||||
""" Gets the value from a given digital pin. """
|
||||
"""Get the value from a given digital pin."""
|
||||
self._board.digital_read(pin)
|
||||
|
||||
def get_analog_in(self, pin):
|
||||
""" Gets the value from a given analog pin. """
|
||||
"""Get the value from a given analog pin."""
|
||||
self._board.analog_read(pin)
|
||||
|
||||
def get_firmata(self):
|
||||
""" Return the version of the Firmata firmware. """
|
||||
"""Return the version of the Firmata firmware."""
|
||||
return self._board.get_firmata_version()
|
||||
|
||||
def disconnect(self):
|
||||
""" Disconnects the board and closes the serial connection. """
|
||||
"""Disconnects the board and closes the serial connection."""
|
||||
self._board.reset()
|
||||
self._board.close()
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.bloomsky
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Support for BloomSky weather station.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.configurator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A component to allow pieces of code to request configuration from the user.
|
||||
Support to allow pieces of code to request configuration from the user.
|
||||
|
||||
Initiate a request by calling the `request_config` method with a callback.
|
||||
This will return a request id that has to be used for future calls.
|
||||
|
@ -38,9 +35,9 @@ _LOGGER = logging.getLogger(__name__)
|
|||
def request_config(
|
||||
hass, name, callback, description=None, description_image=None,
|
||||
submit_caption=None, fields=None):
|
||||
""" Create a new request for config.
|
||||
Will return an ID to be used for sequent calls. """
|
||||
|
||||
"""Create a new request for configuration.
|
||||
Will return an ID to be used for sequent calls.
|
||||
"""
|
||||
instance = _get_instance(hass)
|
||||
|
||||
request_id = instance.request_config(
|
||||
|
@ -53,7 +50,7 @@ def request_config(
|
|||
|
||||
|
||||
def notify_errors(request_id, error):
|
||||
""" Add errors to a config request. """
|
||||
"""Add errors to a config request."""
|
||||
try:
|
||||
_REQUESTS[request_id].notify_errors(request_id, error)
|
||||
except KeyError:
|
||||
|
@ -62,7 +59,7 @@ def notify_errors(request_id, error):
|
|||
|
||||
|
||||
def request_done(request_id):
|
||||
""" Mark a config request as done. """
|
||||
"""Mark a configuration request as done."""
|
||||
try:
|
||||
_REQUESTS.pop(request_id).request_done(request_id)
|
||||
except KeyError:
|
||||
|
@ -71,12 +68,12 @@ def request_done(request_id):
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Set up Configurator. """
|
||||
"""Setup the configurator component."""
|
||||
return True
|
||||
|
||||
|
||||
def _get_instance(hass):
|
||||
""" Get an instance per hass object. """
|
||||
"""Get an instance per hass object."""
|
||||
try:
|
||||
return _INSTANCES[hass]
|
||||
except KeyError:
|
||||
|
@ -89,10 +86,7 @@ def _get_instance(hass):
|
|||
|
||||
|
||||
class Configurator(object):
|
||||
"""
|
||||
Class to keep track of current configuration requests.
|
||||
"""
|
||||
|
||||
"""Class to keep track of current configuration requests."""
|
||||
def __init__(self, hass):
|
||||
self.hass = hass
|
||||
self._cur_id = 0
|
||||
|
@ -104,8 +98,7 @@ class Configurator(object):
|
|||
def request_config(
|
||||
self, name, callback,
|
||||
description, description_image, submit_caption, fields):
|
||||
""" Setup a request for configuration. """
|
||||
|
||||
"""Setup a request for configuration."""
|
||||
entity_id = generate_entity_id(ENTITY_ID_FORMAT, name, hass=self.hass)
|
||||
|
||||
if fields is None:
|
||||
|
@ -133,7 +126,7 @@ class Configurator(object):
|
|||
return request_id
|
||||
|
||||
def notify_errors(self, request_id, error):
|
||||
""" Update the state with errors. """
|
||||
"""Update the state with errors."""
|
||||
if not self._validate_request_id(request_id):
|
||||
return
|
||||
|
||||
|
@ -147,7 +140,7 @@ class Configurator(object):
|
|||
self.hass.states.set(entity_id, STATE_CONFIGURE, new_data)
|
||||
|
||||
def request_done(self, request_id):
|
||||
""" Remove the config request. """
|
||||
"""Remove the configuration request."""
|
||||
if not self._validate_request_id(request_id):
|
||||
return
|
||||
|
||||
|
@ -160,13 +153,13 @@ class Configurator(object):
|
|||
self.hass.states.set(entity_id, STATE_CONFIGURED)
|
||||
|
||||
def deferred_remove(event):
|
||||
""" Remove the request state. """
|
||||
"""Remove the request state."""
|
||||
self.hass.states.remove(entity_id)
|
||||
|
||||
self.hass.bus.listen_once(EVENT_TIME_CHANGED, deferred_remove)
|
||||
|
||||
def handle_service_call(self, call):
|
||||
""" Handle a configure service call. """
|
||||
"""Handle a configure service call."""
|
||||
request_id = call.data.get(ATTR_CONFIGURE_ID)
|
||||
|
||||
if not self._validate_request_id(request_id):
|
||||
|
@ -180,10 +173,10 @@ class Configurator(object):
|
|||
callback(call.data.get(ATTR_FIELDS, {}))
|
||||
|
||||
def _generate_unique_id(self):
|
||||
""" Generates a unique configurator id. """
|
||||
"""Generates a unique configurator ID."""
|
||||
self._cur_id += 1
|
||||
return "{}-{}".format(id(self), self._cur_id)
|
||||
|
||||
def _validate_request_id(self, request_id):
|
||||
""" Validate that the request belongs to this instance. """
|
||||
"""Validate that the request belongs to this instance."""
|
||||
return request_id in self._requests
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.conversation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Provides functionality to have conversations with Home Assistant.
|
||||
Support for functionality to have conversations with Home Assistant.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/conversation/
|
||||
|
@ -25,13 +23,13 @@ REQUIREMENTS = ['fuzzywuzzy==0.8.0']
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Registers the process service. """
|
||||
"""Registers the process service."""
|
||||
from fuzzywuzzy import process as fuzzyExtract
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def process(service):
|
||||
""" Parses text into commands for Home Assistant. """
|
||||
"""Parses text into commands."""
|
||||
if ATTR_TEXT not in service.data:
|
||||
logger.error("Received process service call without a text")
|
||||
return
|
||||
|
|
|
@ -29,7 +29,7 @@ CONF_DEVICE_GROUP = 'device_group'
|
|||
|
||||
# pylint: disable=too-many-locals
|
||||
def setup(hass, config):
|
||||
""" Triggers to turn lights on or off based on device precense. """
|
||||
"""Triggers to turn lights on or off based on device presence."""
|
||||
logger = logging.getLogger(__name__)
|
||||
device_tracker = get_component('device_tracker')
|
||||
group = get_component('group')
|
||||
|
@ -78,26 +78,29 @@ def setup(hass, config):
|
|||
@track_state_change(sun.ENTITY_ID, sun.STATE_BELOW_HORIZON,
|
||||
sun.STATE_ABOVE_HORIZON)
|
||||
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
|
||||
and slowly transition in."""
|
||||
|
||||
and slowly transition in.
|
||||
"""
|
||||
start_point = calc_time_for_light_when_sunset()
|
||||
if not start_point:
|
||||
return
|
||||
|
||||
def turn_on(light_id):
|
||||
""" Lambda can keep track of function parameters but not local
|
||||
"""
|
||||
Lambda can keep track of function parameters but not local
|
||||
parameters. If we put the lambda directly in the below statement
|
||||
only the last light will be turned on.. """
|
||||
only the last light will be turned on.
|
||||
"""
|
||||
return lambda now: turn_light_on_before_sunset(light_id)
|
||||
|
||||
for index, light_id in enumerate(light_ids):
|
||||
track_point_in_time(hass, turn_on(light_id),
|
||||
start_point + index * LIGHT_TRANSITION_TIME)
|
||||
|
||||
# If the sun is already above horizon
|
||||
# schedule the time-based pre-sun set event
|
||||
# If the sun is already above horizon schedule the time-based pre-sun set
|
||||
# event.
|
||||
if sun.is_on(hass):
|
||||
schedule_lights_at_sun_set(hass, None, None, None)
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ SERVICE_HANDLERS = {
|
|||
|
||||
|
||||
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.
|
||||
"""
|
||||
if isinstance(service, str):
|
||||
|
@ -55,10 +55,7 @@ def listen(hass, service, callback):
|
|||
|
||||
|
||||
def discover(hass, service, discovered=None, component=None, hass_config=None):
|
||||
"""Fire discovery event.
|
||||
|
||||
Can ensure a component is loaded.
|
||||
"""
|
||||
"""Fire discovery event. Can ensure a component is loaded."""
|
||||
if component is not None:
|
||||
bootstrap.setup_component(hass, component, hass_config)
|
||||
|
||||
|
@ -73,7 +70,7 @@ def discover(hass, service, discovered=None, component=None, hass_config=None):
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Starts a discovery service. """
|
||||
"""Starts a discovery service."""
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from netdisco.service import DiscoveryService
|
||||
|
@ -84,13 +81,13 @@ def setup(hass, config):
|
|||
lock = threading.Lock()
|
||||
|
||||
def new_service_listener(service, info):
|
||||
""" Called when a new service is found. """
|
||||
"""Called when a new service is found."""
|
||||
with lock:
|
||||
logger.info("Found new service: %s %s", service, info)
|
||||
|
||||
component = SERVICE_HANDLERS.get(service)
|
||||
|
||||
# We do not know how to handle this service
|
||||
# We do not know how to handle this service.
|
||||
if not component:
|
||||
return
|
||||
|
||||
|
@ -105,7 +102,7 @@ def setup(hass, config):
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def start_discovery(event):
|
||||
""" Start discovering. """
|
||||
"""Start discovering."""
|
||||
netdisco = DiscoveryService(SCAN_INTERVAL)
|
||||
netdisco.add_listener(new_service_listener)
|
||||
netdisco.start()
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.downloader
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Provides functionality to download files.
|
||||
Support for functionality to download files.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/downloader/
|
||||
|
@ -28,8 +26,7 @@ CONF_DOWNLOAD_DIR = 'download_dir'
|
|||
|
||||
# pylint: disable=too-many-branches
|
||||
def setup(hass, config):
|
||||
""" Listens for download events to download files. """
|
||||
|
||||
"""Listens for download events to download files."""
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if not validate_config(config, {DOMAIN: [CONF_DOWNLOAD_DIR]}, logger):
|
||||
|
@ -50,14 +47,13 @@ def setup(hass, config):
|
|||
return False
|
||||
|
||||
def download_file(service):
|
||||
""" Starts thread to download file specified in the url. """
|
||||
|
||||
"""Starts thread to download file specified in the URL."""
|
||||
if ATTR_URL not in service.data:
|
||||
logger.error("Service called but 'url' parameter not specified.")
|
||||
return
|
||||
|
||||
def do_download():
|
||||
""" Downloads the file. """
|
||||
"""Downloads the file."""
|
||||
try:
|
||||
url = service.data[ATTR_URL]
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.ecobee
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Ecobee component
|
||||
Support for Ecobee.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/ecobee/
|
||||
|
@ -31,12 +29,12 @@ _LOGGER = logging.getLogger(__name__)
|
|||
ECOBEE_CONFIG_FILE = 'ecobee.conf'
|
||||
_CONFIGURING = {}
|
||||
|
||||
# Return cached results if last scan was less then this time ago
|
||||
# Return cached results if last scan was less then this time ago.
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180)
|
||||
|
||||
|
||||
def request_configuration(network, hass, config):
|
||||
""" Request configuration steps from the user. """
|
||||
"""Request configuration steps from the user."""
|
||||
configurator = get_component('configurator')
|
||||
if 'ecobee' in _CONFIGURING:
|
||||
configurator.notify_errors(
|
||||
|
@ -46,7 +44,7 @@ def request_configuration(network, hass, config):
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def ecobee_configuration_callback(callback_data):
|
||||
""" Actions to do when our configuration callback is called. """
|
||||
"""Actions to do when our configuration callback is called."""
|
||||
network.request_tokens()
|
||||
network.update()
|
||||
setup_ecobee(hass, network, config)
|
||||
|
@ -62,7 +60,7 @@ def request_configuration(network, hass, config):
|
|||
|
||||
|
||||
def setup_ecobee(hass, network, config):
|
||||
""" Setup Ecobee thermostat. """
|
||||
"""Setup Ecobee thermostat."""
|
||||
# If ecobee has a PIN then it needs to be configured.
|
||||
if network.pin is not None:
|
||||
request_configuration(network, hass, config)
|
||||
|
@ -93,15 +91,14 @@ def setup_ecobee(hass, network, config):
|
|||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class EcobeeData(object):
|
||||
""" Gets the latest data and update the states. """
|
||||
|
||||
"""Gets the latest data and update the states."""
|
||||
def __init__(self, config_file):
|
||||
from pyecobee import Ecobee
|
||||
self.ecobee = Ecobee(config_file)
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
""" Get the latest data from pyecobee. """
|
||||
"""Get the latest data from pyecobee."""
|
||||
self.ecobee.update()
|
||||
_LOGGER.info("ecobee data updated successfully.")
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.history
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Provide pre-made queries on top of the recorder component.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
|
@ -26,7 +24,7 @@ URL_HISTORY_PERIOD = re.compile(
|
|||
|
||||
|
||||
def last_5_states(entity_id):
|
||||
""" Return the last 5 states for entity_id. """
|
||||
"""Return the last 5 states for entity_id."""
|
||||
entity_id = entity_id.lower()
|
||||
|
||||
query = """
|
||||
|
@ -39,12 +37,12 @@ def last_5_states(entity_id):
|
|||
|
||||
|
||||
def get_significant_states(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.
|
||||
|
||||
Significant states are all states where there is a state change,
|
||||
as well as all states from certain domains (for instance
|
||||
thermostat so that we get current temperature in our graphs).
|
||||
|
||||
"""
|
||||
where = """
|
||||
(domain IN ({}) OR last_changed=last_updated)
|
||||
|
@ -95,7 +93,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):
|
||||
""" Returns the states at a specific point in time. """
|
||||
"""Returns the states at a specific point in time."""
|
||||
if run is None:
|
||||
run = recorder.run_information(utc_point_in_time)
|
||||
|
||||
|
@ -124,7 +122,8 @@ def get_states(utc_point_in_time, entity_ids=None, run=None):
|
|||
|
||||
|
||||
def states_to_json(states, start_time, entity_id):
|
||||
"""Converts 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
|
||||
structure {'entity_id': [list of states], 'entity_id2': [list of states]}
|
||||
|
@ -133,7 +132,6 @@ def states_to_json(states, start_time, entity_id):
|
|||
each list of states, otherwise our graphs won't start on the Y
|
||||
axis correctly.
|
||||
"""
|
||||
|
||||
result = defaultdict(list)
|
||||
|
||||
entity_ids = [entity_id] if entity_id is not None else None
|
||||
|
@ -151,7 +149,7 @@ def states_to_json(states, start_time, entity_id):
|
|||
|
||||
|
||||
def get_state(utc_point_in_time, entity_id, run=None):
|
||||
""" Return a state at a specific point in time. """
|
||||
"""Return a state at a specific point in time."""
|
||||
states = get_states(utc_point_in_time, (entity_id,), run)
|
||||
|
||||
return states[0] if states else None
|
||||
|
@ -159,7 +157,7 @@ def get_state(utc_point_in_time, entity_id, run=None):
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup(hass, config):
|
||||
""" Setup history hooks. """
|
||||
"""Setup history hooks."""
|
||||
hass.http.register_path(
|
||||
'GET',
|
||||
re.compile(
|
||||
|
@ -175,14 +173,14 @@ def setup(hass, config):
|
|||
# pylint: disable=unused-argument
|
||||
# pylint: disable=invalid-name
|
||||
def _api_last_5_states(handler, path_match, data):
|
||||
""" Return the last 5 states for an entity id as JSON. """
|
||||
"""Return the last 5 states for an entity id as JSON."""
|
||||
entity_id = path_match.group('entity_id')
|
||||
|
||||
handler.write_json(last_5_states(entity_id))
|
||||
|
||||
|
||||
def _api_history_period(handler, path_match, data):
|
||||
""" Return history over a period of time. """
|
||||
"""Return history over a period of time."""
|
||||
date_str = path_match.group('date')
|
||||
one_day = timedelta(seconds=86400)
|
||||
|
||||
|
@ -206,7 +204,8 @@ def _api_history_period(handler, path_match, data):
|
|||
|
||||
|
||||
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.
|
||||
"""
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.http
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
This module provides an API and a HTTP interface for debug purposes.
|
||||
|
||||
For more details about the RESTful API, please refer to the documentation at
|
||||
|
@ -52,7 +50,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Sets up the HTTP API and debug interface. """
|
||||
"""Sets up the HTTP API and debug interface."""
|
||||
conf = config.get(DOMAIN, {})
|
||||
|
||||
api_password = util.convert(conf.get(CONF_API_PASSWORD), str)
|
||||
|
@ -87,9 +85,8 @@ def setup(hass, config):
|
|||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
|
||||
""" Handle HTTP requests in a threaded fashion. """
|
||||
"""Handle HTTP requests in a threaded fashion."""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
allow_reuse_address = True
|
||||
daemon_threads = True
|
||||
|
||||
|
@ -119,9 +116,9 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
|
|||
self.socket = context.wrap_socket(self.socket, server_side=True)
|
||||
|
||||
def start(self):
|
||||
""" Starts the HTTP server. """
|
||||
"""Starts the HTTP server."""
|
||||
def stop_http(event):
|
||||
""" Stops the HTTP server. """
|
||||
"""Stops the HTTP server."""
|
||||
self.shutdown()
|
||||
|
||||
self.hass.bus.listen_once(ha.EVENT_HOMEASSISTANT_STOP, stop_http)
|
||||
|
@ -140,11 +137,11 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer):
|
|||
self.serve_forever()
|
||||
|
||||
def register_path(self, method, url, callback, require_auth=True):
|
||||
""" Registers a path with the server. """
|
||||
"""Registers a path with the server."""
|
||||
self.paths.append((method, url, callback, require_auth))
|
||||
|
||||
def log_message(self, fmt, *args):
|
||||
""" Redirect built-in log to HA logging """
|
||||
"""Redirect built-in log to HA logging."""
|
||||
# pylint: disable=no-self-use
|
||||
_LOGGER.info(fmt, *args)
|
||||
|
||||
|
@ -157,17 +154,16 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
We extend from SimpleHTTPRequestHandler instead of Base so we
|
||||
can use the guess content type methods.
|
||||
"""
|
||||
|
||||
server_version = "HomeAssistant/1.0"
|
||||
|
||||
def __init__(self, req, client_addr, server):
|
||||
""" Contructor, call the base constructor and set up session """
|
||||
"""Contructor, call the base constructor and set up session."""
|
||||
# Track if this was an authenticated request
|
||||
self.authenticated = False
|
||||
SimpleHTTPRequestHandler.__init__(self, req, client_addr, server)
|
||||
|
||||
def log_message(self, fmt, *arguments):
|
||||
""" Redirect built-in log to HA logging """
|
||||
"""Redirect built-in log to HA logging."""
|
||||
if self.server.api_password is None:
|
||||
_LOGGER.info(fmt, *arguments)
|
||||
else:
|
||||
|
@ -176,7 +172,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
if isinstance(arg, str) else arg for arg in arguments))
|
||||
|
||||
def _handle_request(self, method): # pylint: disable=too-many-branches
|
||||
""" Does some common checks and calls appropriate method. """
|
||||
"""Does some common checks and calls appropriate method."""
|
||||
url = urlparse(self.path)
|
||||
|
||||
# Read query input. parse_qs gives a list for each value, we want last
|
||||
|
@ -254,31 +250,31 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
self.end_headers()
|
||||
|
||||
def do_HEAD(self): # pylint: disable=invalid-name
|
||||
""" HEAD request handler. """
|
||||
"""HEAD request handler."""
|
||||
self._handle_request('HEAD')
|
||||
|
||||
def do_GET(self): # pylint: disable=invalid-name
|
||||
""" GET request handler. """
|
||||
"""GET request handler."""
|
||||
self._handle_request('GET')
|
||||
|
||||
def do_POST(self): # pylint: disable=invalid-name
|
||||
""" POST request handler. """
|
||||
"""POST request handler."""
|
||||
self._handle_request('POST')
|
||||
|
||||
def do_PUT(self): # pylint: disable=invalid-name
|
||||
""" PUT request handler. """
|
||||
"""PUT request handler."""
|
||||
self._handle_request('PUT')
|
||||
|
||||
def do_DELETE(self): # pylint: disable=invalid-name
|
||||
""" DELETE request handler. """
|
||||
"""DELETE request handler."""
|
||||
self._handle_request('DELETE')
|
||||
|
||||
def write_json_message(self, message, status_code=HTTP_OK):
|
||||
""" Helper method to return a message to the caller. """
|
||||
"""Helper method to return a message to the caller."""
|
||||
self.write_json({'message': message}, status_code=status_code)
|
||||
|
||||
def write_json(self, data=None, status_code=HTTP_OK, location=None):
|
||||
""" Helper method to return JSON to the caller. """
|
||||
"""Helper method to return JSON to the caller."""
|
||||
self.send_response(status_code)
|
||||
self.send_header(HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_JSON)
|
||||
|
||||
|
@ -295,7 +291,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
cls=rem.JSONEncoder).encode("UTF-8"))
|
||||
|
||||
def write_text(self, message, status_code=HTTP_OK):
|
||||
""" Helper method to return a text message to the caller. """
|
||||
"""Helper method to return a text message to the caller."""
|
||||
self.send_response(status_code)
|
||||
self.send_header(HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_TEXT_PLAIN)
|
||||
|
||||
|
@ -306,7 +302,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
self.wfile.write(message.encode("UTF-8"))
|
||||
|
||||
def write_file(self, path, cache_headers=True):
|
||||
""" Returns a file to the user. """
|
||||
"""Returns a file to the user."""
|
||||
try:
|
||||
with open(path, 'rb') as inp:
|
||||
self.write_file_pointer(self.guess_type(path), inp,
|
||||
|
@ -354,7 +350,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
self.copyfile(inp, self.wfile)
|
||||
|
||||
def set_cache_header(self):
|
||||
""" Add cache headers if not in development """
|
||||
"""Add cache headers if not in development."""
|
||||
if self.server.development:
|
||||
return
|
||||
|
||||
|
@ -369,7 +365,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
self.date_time_string(time.time()+cache_time))
|
||||
|
||||
def set_session_cookie_header(self):
|
||||
""" Add the header for the session cookie and return session id. """
|
||||
"""Add the header for the session cookie and return session ID."""
|
||||
if not self.authenticated:
|
||||
return None
|
||||
|
||||
|
@ -387,13 +383,13 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
return session_id
|
||||
|
||||
def verify_session(self):
|
||||
""" Verify that we are in a valid session. """
|
||||
"""Verify that we are in a valid session."""
|
||||
return self.get_cookie_session_id() is not None
|
||||
|
||||
def get_cookie_session_id(self):
|
||||
"""
|
||||
Extracts the current session id from the
|
||||
cookie or returns None if not set or invalid
|
||||
Extracts the current session id from the cookie or returns None if not
|
||||
set or invalid.
|
||||
"""
|
||||
if 'Cookie' not in self.headers:
|
||||
return None
|
||||
|
@ -417,7 +413,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
return None
|
||||
|
||||
def destroy_session(self):
|
||||
""" Destroys session. """
|
||||
"""Destroys session."""
|
||||
session_id = self.get_cookie_session_id()
|
||||
|
||||
if session_id is None:
|
||||
|
@ -428,27 +424,27 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
|
||||
|
||||
def session_valid_time():
|
||||
""" Time till when a session will be valid. """
|
||||
"""Time till when a session will be valid."""
|
||||
return date_util.utcnow() + timedelta(seconds=SESSION_TIMEOUT_SECONDS)
|
||||
|
||||
|
||||
class SessionStore(object):
|
||||
""" Responsible for storing and retrieving http sessions """
|
||||
"""Responsible for storing and retrieving HTTP sessions."""
|
||||
def __init__(self):
|
||||
""" Set up the session store """
|
||||
"""Setup the session store."""
|
||||
self._sessions = {}
|
||||
self._lock = threading.RLock()
|
||||
|
||||
@util.Throttle(SESSION_CLEAR_INTERVAL)
|
||||
def _remove_expired(self):
|
||||
""" Remove any expired sessions. """
|
||||
"""Remove any expired sessions."""
|
||||
now = date_util.utcnow()
|
||||
for key in [key for key, valid_time in self._sessions.items()
|
||||
if valid_time < now]:
|
||||
self._sessions.pop(key)
|
||||
|
||||
def is_valid(self, key):
|
||||
""" Return True if a valid session is given. """
|
||||
"""Return True if a valid session is given."""
|
||||
with self._lock:
|
||||
self._remove_expired()
|
||||
|
||||
|
@ -456,19 +452,19 @@ class SessionStore(object):
|
|||
self._sessions[key] > date_util.utcnow())
|
||||
|
||||
def extend_validation(self, key):
|
||||
""" Extend a session validation time. """
|
||||
"""Extend a session validation time."""
|
||||
with self._lock:
|
||||
if key not in self._sessions:
|
||||
return
|
||||
self._sessions[key] = session_valid_time()
|
||||
|
||||
def destroy(self, key):
|
||||
""" Destroy a session by key. """
|
||||
"""Destroy a session by key."""
|
||||
with self._lock:
|
||||
self._sessions.pop(key, None)
|
||||
|
||||
def create(self):
|
||||
""" Creates a new session. """
|
||||
"""Creates a new session."""
|
||||
with self._lock:
|
||||
session_id = util.get_random_string(20)
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.ifttt
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
This component enable you to trigger Maker IFTTT recipes.
|
||||
Support to trigger Maker IFTTT recipes.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/ifttt/
|
||||
|
@ -27,7 +25,7 @@ REQUIREMENTS = ['pyfttt==0.3']
|
|||
|
||||
|
||||
def trigger(hass, event, value1=None, value2=None, value3=None):
|
||||
""" Trigger a Maker IFTTT recipe. """
|
||||
"""Trigger a Maker IFTTT recipe."""
|
||||
data = {
|
||||
ATTR_EVENT: event,
|
||||
ATTR_VALUE1: value1,
|
||||
|
@ -38,15 +36,14 @@ def trigger(hass, event, value1=None, value2=None, value3=None):
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the ifttt service component. """
|
||||
|
||||
"""Setup the IFTTT service component."""
|
||||
if not validate_config(config, {DOMAIN: ['key']}, _LOGGER):
|
||||
return False
|
||||
|
||||
key = config[DOMAIN]['key']
|
||||
|
||||
def trigger_service(call):
|
||||
""" Handle ifttt trigger service calls. """
|
||||
"""Handle IFTTT trigger service calls."""
|
||||
event = call.data.get(ATTR_EVENT)
|
||||
value1 = call.data.get(ATTR_VALUE1)
|
||||
value2 = call.data.get(ATTR_VALUE2)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.input_boolean
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component to keep track of user controlled booleans for within automation.
|
||||
|
||||
For more details about this component, please refer to the documentation
|
||||
|
@ -41,7 +39,7 @@ def turn_off(hass, entity_id):
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Set up input boolean. """
|
||||
"""Set up input boolean."""
|
||||
if not isinstance(config.get(DOMAIN), dict):
|
||||
_LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
|
||||
return False
|
||||
|
@ -68,7 +66,7 @@ def setup(hass, config):
|
|||
return False
|
||||
|
||||
def toggle_service(service):
|
||||
""" Handle a calls to the input boolean services. """
|
||||
"""Handle a calls to the input boolean services."""
|
||||
target_inputs = component.extract_from_service(service)
|
||||
|
||||
for input_b in target_inputs:
|
||||
|
@ -86,8 +84,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class InputBoolean(ToggleEntity):
|
||||
""" Represent a boolean input. """
|
||||
|
||||
"""Represent a boolean input."""
|
||||
def __init__(self, object_id, name, state, icon):
|
||||
""" Initialize a boolean input. """
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
|
||||
|
@ -97,22 +94,22 @@ class InputBoolean(ToggleEntity):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""If entitiy should be polled."""
|
||||
"""If entity should be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Name of the boolean input."""
|
||||
"""Return name of the boolean input."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon to be used for this entity."""
|
||||
"""Returh the icon to be used for this entity."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if entity is on."""
|
||||
"""Return true if entity is on."""
|
||||
return self._state
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.input_select
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component to offer a way to select an option from a list.
|
||||
|
||||
For more details about this component, please refer to the documentation
|
||||
|
@ -29,7 +27,7 @@ SERVICE_SELECT_OPTION = 'select_option'
|
|||
|
||||
|
||||
def select_option(hass, entity_id, option):
|
||||
""" Set input_select to False. """
|
||||
"""Set input_select to False."""
|
||||
hass.services.call(DOMAIN, SERVICE_SELECT_OPTION, {
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
ATTR_OPTION: option,
|
||||
|
@ -37,7 +35,7 @@ def select_option(hass, entity_id, option):
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Set up input select. """
|
||||
"""Setup input select."""
|
||||
if not isinstance(config.get(DOMAIN), dict):
|
||||
_LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
|
||||
return False
|
||||
|
@ -77,7 +75,7 @@ def setup(hass, config):
|
|||
return False
|
||||
|
||||
def select_option_service(call):
|
||||
""" Handle a calls to the input select services. """
|
||||
"""Handle a calls to the input select services."""
|
||||
target_inputs = component.extract_from_service(call)
|
||||
|
||||
for input_select in target_inputs:
|
||||
|
@ -92,8 +90,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class InputSelect(Entity):
|
||||
""" Represent a select input. """
|
||||
|
||||
"""Represent a select input."""
|
||||
# pylint: disable=too-many-arguments
|
||||
def __init__(self, object_id, name, state, options, icon):
|
||||
""" Initialize a select input. """
|
||||
|
@ -105,33 +102,33 @@ class InputSelect(Entity):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
""" If entity should be polled. """
|
||||
"""If entity should be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Name of the select input. """
|
||||
"""Return the name of the select input."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
""" Icon to be used for this entity. """
|
||||
"""Return the icon to be used for this entity."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
""" State of the component. """
|
||||
"""Return the state of the component."""
|
||||
return self._current_option
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
""" State attributes. """
|
||||
"""Return the state attributes."""
|
||||
return {
|
||||
ATTR_OPTIONS: self._options,
|
||||
}
|
||||
|
||||
def select_option(self, option):
|
||||
""" Select new option. """
|
||||
"""Select new option."""
|
||||
if option not in self._options:
|
||||
_LOGGER.warning('Invalid option: %s (possible options: %s)',
|
||||
option, ', '.join(self._options))
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.insteon_hub
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Support for Insteon Hub.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
|
@ -58,24 +56,23 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class InsteonToggleDevice(ToggleEntity):
|
||||
""" Abstract Class for an Insteon node. """
|
||||
|
||||
""" An abstract Class for an Insteon node."""
|
||||
def __init__(self, node):
|
||||
self.node = node
|
||||
self._value = 0
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Returns the name of the node. """
|
||||
"""Return the the name of the node."""
|
||||
return self.node.DeviceName
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
""" Returns the id of this insteon node. """
|
||||
"""Return the ID of this insteon node."""
|
||||
return self.node.DeviceID
|
||||
|
||||
def update(self):
|
||||
""" Update state of the sensor. """
|
||||
"""Update state of the sensor."""
|
||||
resp = self.node.send_command('get_status', wait=True)
|
||||
try:
|
||||
self._value = resp['response']['level']
|
||||
|
@ -84,7 +81,7 @@ class InsteonToggleDevice(ToggleEntity):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
""" Returns boolean response if the node is on. """
|
||||
"""Return the boolean response if the node is on."""
|
||||
return self._value != 0
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.introduction
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component that will help guide the user taking its first steps.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
|
@ -12,7 +10,7 @@ DOMAIN = 'introduction'
|
|||
|
||||
|
||||
def setup(hass, config=None):
|
||||
""" Setup the introduction component. """
|
||||
"""Setup the introduction component."""
|
||||
log = logging.getLogger(__name__)
|
||||
log.info("""
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.isy994
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Connects to an ISY-994 controller and loads relevant components to control its
|
||||
devices. Also contains the base classes for ISY Sensors, Lights, and Switches.
|
||||
Support the ISY-994 controllers.
|
||||
|
||||
For configuration details please visit the documentation for this component at
|
||||
https://home-assistant.io/components/isy994/
|
||||
|
@ -45,7 +42,7 @@ def setup(hass, config):
|
|||
_LOGGER):
|
||||
return False
|
||||
|
||||
# pull and parse standard configuration
|
||||
# Pull and parse standard configuration.
|
||||
user = config[DOMAIN][CONF_USERNAME]
|
||||
password = config[DOMAIN][CONF_PASSWORD]
|
||||
host = urlparse(config[DOMAIN][CONF_HOST])
|
||||
|
@ -62,24 +59,24 @@ def setup(hass, config):
|
|||
port = host.port
|
||||
addr = addr.replace(':{}'.format(port), '')
|
||||
|
||||
# pull and parse optional configuration
|
||||
# Pull and parse optional configuration.
|
||||
global SENSOR_STRING
|
||||
global HIDDEN_STRING
|
||||
SENSOR_STRING = str(config[DOMAIN].get('sensor_string', SENSOR_STRING))
|
||||
HIDDEN_STRING = str(config[DOMAIN].get('hidden_string', HIDDEN_STRING))
|
||||
tls_version = config[DOMAIN].get(CONF_TLS_VER, None)
|
||||
|
||||
# connect to ISY controller
|
||||
# Connect to ISY controller.
|
||||
global ISY
|
||||
ISY = PyISY.ISY(addr, port, user, password, use_https=https,
|
||||
tls_ver=tls_version, log=_LOGGER)
|
||||
if not ISY.connected:
|
||||
return False
|
||||
|
||||
# listen for HA stop to disconnect
|
||||
# Listen for HA stop to disconnect.
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop)
|
||||
|
||||
# Load components for the devices in the ISY controller that we support
|
||||
# Load components for the devices in the ISY controller that we support.
|
||||
for comp_name, discovery in ((('sensor', DISCOVER_SENSORS),
|
||||
('light', DISCOVER_LIGHTS),
|
||||
('switch', DISCOVER_SWITCHES))):
|
||||
|
@ -94,13 +91,12 @@ def setup(hass, config):
|
|||
|
||||
|
||||
def stop(event):
|
||||
""" Cleanup the ISY subscription. """
|
||||
"""Cleanup the ISY subscription."""
|
||||
ISY.auto_update = False
|
||||
|
||||
|
||||
class ISYDeviceABC(ToggleEntity):
|
||||
""" Abstract Class for an ISY device. """
|
||||
|
||||
"""An abstract Class for an ISY device."""
|
||||
_attrs = {}
|
||||
_onattrs = []
|
||||
_states = []
|
||||
|
@ -117,35 +113,35 @@ class ISYDeviceABC(ToggleEntity):
|
|||
subscribe('changed', self.on_update)
|
||||
|
||||
def __del__(self):
|
||||
""" cleanup subscriptions because it is the right thing to do. """
|
||||
"""Cleanup subscriptions because it is the right thing to do."""
|
||||
self._change_handler.unsubscribe()
|
||||
|
||||
@property
|
||||
def domain(self):
|
||||
""" Returns the domain of the entity. """
|
||||
"""Return the domain of the entity."""
|
||||
return self._domain
|
||||
|
||||
@property
|
||||
def dtype(self):
|
||||
""" Returns the data type of the entity (binary or analog). """
|
||||
"""Return the data type of the entity (binary or analog)."""
|
||||
if self._dtype in ['analog', 'binary']:
|
||||
return self._dtype
|
||||
return 'binary' if self.unit_of_measurement is None else 'analog'
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
""" Tells Home Assistant not to poll this entity. """
|
||||
"""No polling needed."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
""" Returns the unclean value from the controller. """
|
||||
"""Return the unclean value from the controller."""
|
||||
# pylint: disable=protected-access
|
||||
return self.node.status._val
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
""" Returns the state attributes for the node. """
|
||||
"""Return the state attributes for the node."""
|
||||
attr = {}
|
||||
for name, prop in self._attrs.items():
|
||||
attr[name] = getattr(self, prop)
|
||||
|
@ -153,61 +149,61 @@ class ISYDeviceABC(ToggleEntity):
|
|||
return attr
|
||||
|
||||
def _attr_filter(self, attr):
|
||||
""" Placeholder for attribute filters. """
|
||||
"""A Placeholder for attribute filters."""
|
||||
# pylint: disable=no-self-use
|
||||
return attr
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
""" Returns the id of this ISY sensor. """
|
||||
"""Return the ID of this ISY sensor."""
|
||||
# pylint: disable=protected-access
|
||||
return self.node._id
|
||||
|
||||
@property
|
||||
def raw_name(self):
|
||||
""" Returns the unclean node name. """
|
||||
"""Return the unclean node name."""
|
||||
return str(self._name) \
|
||||
if self._name is not None else str(self.node.name)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Returns the cleaned name of the node. """
|
||||
"""Return the cleaned name of the node."""
|
||||
return self.raw_name.replace(HIDDEN_STRING, '').strip() \
|
||||
.replace('_', ' ')
|
||||
|
||||
@property
|
||||
def hidden(self):
|
||||
""" Suggestion if the entity should be hidden from UIs. """
|
||||
"""Suggestion if the entity should be hidden from UIs."""
|
||||
return HIDDEN_STRING in self.raw_name
|
||||
|
||||
def update(self):
|
||||
""" Update state of the sensor. """
|
||||
"""Update state of the sensor."""
|
||||
# ISY objects are automatically updated by the ISY's event stream
|
||||
pass
|
||||
|
||||
def on_update(self, event):
|
||||
""" Handles the update received event. """
|
||||
"""Handles the update received event."""
|
||||
self.update_ha_state()
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
""" Returns boolean response if the node is on. """
|
||||
"""Return a boolean response if the node is on."""
|
||||
return bool(self.value)
|
||||
|
||||
@property
|
||||
def is_open(self):
|
||||
""" Returns boolean respons if the node is open. On = Open. """
|
||||
"""Return boolean response if the node is open. On = Open."""
|
||||
return self.is_on
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
""" Returns the state of the node. """
|
||||
"""Return the state of the node."""
|
||||
if len(self._states) > 0:
|
||||
return self._states[0] if self.is_on else self._states[1]
|
||||
return self.value
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
""" Turns the device on. """
|
||||
"""Turns the device on."""
|
||||
if self.domain is not 'sensor':
|
||||
attrs = [kwargs.get(name) for name in self._onattrs]
|
||||
self.node.on(*attrs)
|
||||
|
@ -215,7 +211,7 @@ class ISYDeviceABC(ToggleEntity):
|
|||
_LOGGER.error('ISY cannot turn on sensors.')
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
""" Turns the device off. """
|
||||
"""Turns the device off."""
|
||||
if self.domain is not 'sensor':
|
||||
self.node.off()
|
||||
else:
|
||||
|
@ -223,7 +219,7 @@ class ISYDeviceABC(ToggleEntity):
|
|||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
""" Returns the defined units of measurement or None. """
|
||||
"""Return the defined units of measurement or None."""
|
||||
try:
|
||||
return self.node.units
|
||||
except AttributeError:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.keyboard
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Provides functionality to emulate keyboard presses on host machine.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
|
@ -16,37 +14,37 @@ REQUIREMENTS = ['pyuserinput==0.1.9']
|
|||
|
||||
|
||||
def volume_up(hass):
|
||||
""" Press the keyboard button for volume up. """
|
||||
"""Press the keyboard button for volume up."""
|
||||
hass.services.call(DOMAIN, SERVICE_VOLUME_UP)
|
||||
|
||||
|
||||
def volume_down(hass):
|
||||
""" Press the keyboard button for volume down. """
|
||||
"""Press the keyboard button for volume down."""
|
||||
hass.services.call(DOMAIN, SERVICE_VOLUME_DOWN)
|
||||
|
||||
|
||||
def volume_mute(hass):
|
||||
""" Press the keyboard button for muting volume. """
|
||||
"""Press the keyboard button for muting volume."""
|
||||
hass.services.call(DOMAIN, SERVICE_VOLUME_MUTE)
|
||||
|
||||
|
||||
def media_play_pause(hass):
|
||||
""" Press the keyboard button for play/pause. """
|
||||
"""Press the keyboard button for play/pause."""
|
||||
hass.services.call(DOMAIN, SERVICE_MEDIA_PLAY_PAUSE)
|
||||
|
||||
|
||||
def media_next_track(hass):
|
||||
""" Press the keyboard button for next track. """
|
||||
"""Press the keyboard button for next track."""
|
||||
hass.services.call(DOMAIN, SERVICE_MEDIA_NEXT_TRACK)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Listen for keyboard events. """
|
||||
"""Listen for keyboard events."""
|
||||
import pykeyboard
|
||||
|
||||
keyboard = pykeyboard.PyKeyboard()
|
||||
|
|
|
@ -56,7 +56,6 @@ def log_entry(hass, name, message, domain=None, entity_id=None):
|
|||
|
||||
def setup(hass, config):
|
||||
"""Listens for download events to download files."""
|
||||
|
||||
def log_message(service):
|
||||
"""Handle sending notification message service calls."""
|
||||
message = service.data.get(ATTR_MESSAGE)
|
||||
|
@ -101,7 +100,6 @@ def _handle_get_logbook(handler, path_match, data):
|
|||
|
||||
class Entry(object):
|
||||
"""A human readable version of the log."""
|
||||
|
||||
# pylint: disable=too-many-arguments, too-few-public-methods
|
||||
def __init__(self, when=None, name=None, message=None, domain=None,
|
||||
entity_id=None):
|
||||
|
@ -237,7 +235,6 @@ def _entry_message_from_state(domain, state):
|
|||
"""Convert a state to a message for the logbook."""
|
||||
# We pass domain in so we don't have to split entity_id again
|
||||
# pylint: disable=too-many-return-statements
|
||||
|
||||
if domain == 'device_tracker':
|
||||
if state.state == STATE_NOT_HOME:
|
||||
return 'is away'
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.logger
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component that will help set the level of logging for components.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
|
@ -27,16 +25,15 @@ LOGGER_LOGS = 'logs'
|
|||
|
||||
|
||||
class HomeAssistantLogFilter(logging.Filter):
|
||||
""" A log filter. """
|
||||
"""A log filter."""
|
||||
# pylint: disable=no-init,too-few-public-methods
|
||||
|
||||
def __init__(self, logfilter):
|
||||
super().__init__()
|
||||
|
||||
self.logfilter = logfilter
|
||||
|
||||
def filter(self, record):
|
||||
|
||||
"""A filter to use."""
|
||||
# Log with filtered severity
|
||||
if LOGGER_LOGS in self.logfilter:
|
||||
for filtername in self.logfilter[LOGGER_LOGS]:
|
||||
|
@ -50,8 +47,7 @@ class HomeAssistantLogFilter(logging.Filter):
|
|||
|
||||
|
||||
def setup(hass, config=None):
|
||||
""" Setup the logger component. """
|
||||
|
||||
"""Setup the logger component."""
|
||||
logfilter = dict()
|
||||
|
||||
# Set default log severity
|
||||
|
|
|
@ -157,7 +157,6 @@ def pf_callback_factory(map_sv_types, devices, add_devices, entity_class):
|
|||
|
||||
class GatewayWrapper(object):
|
||||
"""Gateway wrapper class."""
|
||||
|
||||
def __init__(self, gateway, version, optimistic):
|
||||
"""Setup class attributes on instantiation.
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.thermostat.nest
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Adds support for Nest thermostats.
|
||||
Support for Nest thermostats.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/thermostat.nest/
|
||||
|
@ -18,7 +16,7 @@ NEST = None
|
|||
|
||||
# pylint: disable=unused-argument
|
||||
def setup(hass, config):
|
||||
""" Sets up the nest thermostat. """
|
||||
"""Setup the Nest thermostat component."""
|
||||
global NEST
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.proximity
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component to monitor the proximity of devices to a particular zone and the
|
||||
direction of travel.
|
||||
|
||||
|
@ -32,13 +30,13 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup(hass, config): # pylint: disable=too-many-locals,too-many-statements
|
||||
""" Get the zones and offsets from configuration.yaml. """
|
||||
"""Get the zones and offsets from configuration.yaml."""
|
||||
ignored_zones = []
|
||||
if 'ignored_zones' in config[DOMAIN]:
|
||||
for variable in config[DOMAIN]['ignored_zones']:
|
||||
ignored_zones.append(variable)
|
||||
|
||||
# Get the devices from configuration.yaml
|
||||
# Get the devices from configuration.yaml.
|
||||
if 'devices' not in config[DOMAIN]:
|
||||
_LOGGER.error('devices not found in config')
|
||||
return False
|
||||
|
@ -47,10 +45,10 @@ def setup(hass, config): # pylint: disable=too-many-locals,too-many-statements
|
|||
for variable in config[DOMAIN]['devices']:
|
||||
proximity_devices.append(variable)
|
||||
|
||||
# Get the direction of travel tolerance from configuration.yaml
|
||||
# Get the direction of travel tolerance from configuration.yaml.
|
||||
tolerance = config[DOMAIN].get('tolerance', DEFAULT_TOLERANCE)
|
||||
|
||||
# Get the zone to monitor proximity to from configuration.yaml
|
||||
# Get the zone to monitor proximity to from configuration.yaml.
|
||||
proximity_zone = config[DOMAIN].get('zone', DEFAULT_PROXIMITY_ZONE)
|
||||
|
||||
entity_id = DOMAIN + '.' + proximity_zone
|
||||
|
@ -59,7 +57,7 @@ def setup(hass, config): # pylint: disable=too-many-locals,too-many-statements
|
|||
state = hass.states.get(proximity_zone)
|
||||
zone_friendly_name = (state.name).lower()
|
||||
|
||||
# set the default values
|
||||
# Set the default values.
|
||||
dist_to_zone = 'not set'
|
||||
dir_of_travel = 'not set'
|
||||
nearest = 'not set'
|
||||
|
@ -71,7 +69,7 @@ def setup(hass, config): # pylint: disable=too-many-locals,too-many-statements
|
|||
|
||||
proximity.update_ha_state()
|
||||
|
||||
# Main command to monitor proximity of devices
|
||||
# Main command to monitor proximity of devices.
|
||||
track_state_change(hass, proximity_devices,
|
||||
proximity.check_proximity_state_change)
|
||||
|
||||
|
@ -79,7 +77,7 @@ def setup(hass, config): # pylint: disable=too-many-locals,too-many-statements
|
|||
|
||||
|
||||
class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
||||
""" Represents a Proximity. """
|
||||
"""Represents a Proximity."""
|
||||
def __init__(self, hass, zone_friendly_name, dist_to, dir_of_travel,
|
||||
nearest, ignored_zones, proximity_devices, tolerance,
|
||||
proximity_zone):
|
||||
|
@ -101,17 +99,17 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
|
||||
@property
|
||||
def state(self):
|
||||
""" Returns the state. """
|
||||
"""Return the state."""
|
||||
return self.dist_to
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
""" Unit of measurement of this entity. """
|
||||
"""Return the unit of measurement of this entity."""
|
||||
return "km"
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
""" Returns the state attributes. """
|
||||
"""Return the state attributes."""
|
||||
return {
|
||||
ATTR_DIR_OF_TRAVEL: self.dir_of_travel,
|
||||
ATTR_NEAREST: self.nearest,
|
||||
|
@ -119,7 +117,7 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
|
||||
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
|
||||
devices_to_calculate = False
|
||||
devices_in_zone = ''
|
||||
|
@ -128,21 +126,21 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
proximity_latitude = zone_state.attributes.get('latitude')
|
||||
proximity_longitude = zone_state.attributes.get('longitude')
|
||||
|
||||
# Check for devices in the monitored zone
|
||||
# Check for devices in the monitored zone.
|
||||
for device in self.proximity_devices:
|
||||
device_state = self.hass.states.get(device)
|
||||
|
||||
if device_state.state not in self.ignored_zones:
|
||||
devices_to_calculate = True
|
||||
|
||||
# Check the location of all devices
|
||||
# Check the location of all devices.
|
||||
if (device_state.state).lower() == (self.friendly_name).lower():
|
||||
device_friendly = device_state.name
|
||||
if devices_in_zone != '':
|
||||
devices_in_zone = devices_in_zone + ', '
|
||||
devices_in_zone = devices_in_zone + device_friendly
|
||||
|
||||
# No-one to track so reset the entity
|
||||
# No-one to track so reset the entity.
|
||||
if not devices_to_calculate:
|
||||
self.dist_to = 'not set'
|
||||
self.dir_of_travel = 'not set'
|
||||
|
@ -150,7 +148,7 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
self.update_ha_state()
|
||||
return
|
||||
|
||||
# At least one device is in the monitored zone so update the entity
|
||||
# At least one device is in the monitored zone so update the entity.
|
||||
if devices_in_zone != '':
|
||||
self.dist_to = 0
|
||||
self.dir_of_travel = 'arrived'
|
||||
|
@ -158,32 +156,33 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
self.update_ha_state()
|
||||
return
|
||||
|
||||
# We can't check proximity because latitude and longitude don't exist
|
||||
# We can't check proximity because latitude and longitude don't exist.
|
||||
if 'latitude' not in new_state.attributes:
|
||||
return
|
||||
|
||||
# Collect distances to the zone for all devices
|
||||
# Collect distances to the zone for all devices.
|
||||
distances_to_zone = {}
|
||||
for device in self.proximity_devices:
|
||||
# Ignore devices in an ignored zone
|
||||
# Ignore devices in an ignored zone.
|
||||
device_state = self.hass.states.get(device)
|
||||
if device_state.state in self.ignored_zones:
|
||||
continue
|
||||
|
||||
# Ignore devices if proximity cannot be calculated
|
||||
# Ignore devices if proximity cannot be calculated.
|
||||
if 'latitude' not in device_state.attributes:
|
||||
continue
|
||||
|
||||
# Calculate the distance to the proximity zone
|
||||
# Calculate the distance to the proximity zone.
|
||||
dist_to_zone = distance(proximity_latitude,
|
||||
proximity_longitude,
|
||||
device_state.attributes['latitude'],
|
||||
device_state.attributes['longitude'])
|
||||
|
||||
# Add the device and distance to a dictionary
|
||||
# Add the device and distance to a dictionary.
|
||||
distances_to_zone[device] = round(dist_to_zone / 1000, 1)
|
||||
|
||||
# Loop through each of the distances collected and work out the closest
|
||||
# Loop through each of the distances collected and work out the
|
||||
# closest.
|
||||
closest_device = ''
|
||||
dist_to_zone = 1000000
|
||||
|
||||
|
@ -192,7 +191,7 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
closest_device = device
|
||||
dist_to_zone = distances_to_zone[device]
|
||||
|
||||
# If the closest device is one of the other devices
|
||||
# If the closest device is one of the other devices.
|
||||
if closest_device != entity:
|
||||
self.dist_to = round(distances_to_zone[closest_device])
|
||||
self.dir_of_travel = 'unknown'
|
||||
|
@ -202,7 +201,7 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
return
|
||||
|
||||
# Stop if we cannot calculate the direction of travel (i.e. we don't
|
||||
# have a previous state and a current LAT and LONG)
|
||||
# have a previous state and a current LAT and LONG).
|
||||
if old_state is None or 'latitude' not in old_state.attributes:
|
||||
self.dist_to = round(distances_to_zone[entity])
|
||||
self.dir_of_travel = 'unknown'
|
||||
|
@ -213,7 +212,7 @@ class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
|||
# Reset the variables
|
||||
distance_travelled = 0
|
||||
|
||||
# Calculate the distance travelled
|
||||
# Calculate the distance travelled.
|
||||
old_distance = distance(proximity_latitude, proximity_longitude,
|
||||
old_state.attributes['latitude'],
|
||||
old_state.attributes['longitude'])
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.recorder
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component that records all events and state changes. Allows other components
|
||||
to query this database.
|
||||
|
||||
|
@ -35,14 +33,14 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def query(sql_query, arguments=None):
|
||||
""" Query the database. """
|
||||
"""Query the database."""
|
||||
_verify_instance()
|
||||
|
||||
return _INSTANCE.query(sql_query, arguments)
|
||||
|
||||
|
||||
def query_states(state_query, arguments=None):
|
||||
""" Query the database and return a list of states. """
|
||||
"""Query the database and return a list of states."""
|
||||
return [
|
||||
row for row in
|
||||
(row_to_state(row) for row in query(state_query, arguments))
|
||||
|
@ -50,7 +48,7 @@ def query_states(state_query, arguments=None):
|
|||
|
||||
|
||||
def query_events(event_query, arguments=None):
|
||||
""" Query the database and return a list of states. """
|
||||
"""Query the database and return a list of states."""
|
||||
return [
|
||||
row for row in
|
||||
(row_to_event(row) for row in query(event_query, arguments))
|
||||
|
@ -58,7 +56,7 @@ def query_events(event_query, arguments=None):
|
|||
|
||||
|
||||
def row_to_state(row):
|
||||
""" Convert a database row to a state. """
|
||||
"""Convert a database row to a state."""
|
||||
try:
|
||||
return State(
|
||||
row[1], row[2], json.loads(row[3]),
|
||||
|
@ -71,7 +69,7 @@ def row_to_state(row):
|
|||
|
||||
|
||||
def row_to_event(row):
|
||||
""" Convert a databse row to an event. """
|
||||
"""Convert a databse row to an event."""
|
||||
try:
|
||||
return Event(row[1], json.loads(row[2]), EventOrigin(row[3]),
|
||||
dt_util.utc_from_timestamp(row[5]))
|
||||
|
@ -98,7 +96,7 @@ def run_information(point_in_time=None):
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the recorder. """
|
||||
"""Setup the recorder."""
|
||||
# pylint: disable=global-statement
|
||||
global _INSTANCE
|
||||
|
||||
|
@ -108,7 +106,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class RecorderRun(object):
|
||||
""" Represents a recorder run. """
|
||||
"""Represents a recorder run."""
|
||||
def __init__(self, row=None):
|
||||
self.end = None
|
||||
|
||||
|
@ -160,7 +158,7 @@ class RecorderRun(object):
|
|||
|
||||
|
||||
class Recorder(threading.Thread):
|
||||
""" Threaded recorder class """
|
||||
"""A threaded recorder class."""
|
||||
def __init__(self, hass):
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
|
@ -173,7 +171,7 @@ class Recorder(threading.Thread):
|
|||
self.utc_offset = dt_util.now().utcoffset().total_seconds()
|
||||
|
||||
def start_recording(event):
|
||||
""" Start recording. """
|
||||
"""Start recording."""
|
||||
self.start()
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_recording)
|
||||
|
@ -181,7 +179,7 @@ class Recorder(threading.Thread):
|
|||
hass.bus.listen(MATCH_ALL, self.event_listener)
|
||||
|
||||
def run(self):
|
||||
""" Start processing events to save. """
|
||||
"""Start processing events to save."""
|
||||
self._setup_connection()
|
||||
self._setup_run()
|
||||
|
||||
|
@ -215,12 +213,12 @@ class Recorder(threading.Thread):
|
|||
self.queue.put(event)
|
||||
|
||||
def shutdown(self, event):
|
||||
""" Tells the recorder to shut down. """
|
||||
"""Tells the recorder to shut down."""
|
||||
self.queue.put(self.quit_object)
|
||||
self.block_till_done()
|
||||
|
||||
def record_state(self, entity_id, state, event_id):
|
||||
""" Save a state to the database. """
|
||||
"""Save a state to the database."""
|
||||
now = dt_util.utcnow()
|
||||
|
||||
# State got deleted
|
||||
|
@ -251,7 +249,7 @@ class Recorder(threading.Thread):
|
|||
info)
|
||||
|
||||
def record_event(self, event):
|
||||
""" Save an event to the database. """
|
||||
"""Save an event to the database."""
|
||||
info = (
|
||||
event.event_type, json.dumps(event.data, cls=JSONEncoder),
|
||||
str(event.origin), dt_util.utcnow(), event.time_fired,
|
||||
|
@ -292,11 +290,11 @@ class Recorder(threading.Thread):
|
|||
return []
|
||||
|
||||
def block_till_done(self):
|
||||
""" Blocks till all events processed. """
|
||||
"""Blocks till all events processed."""
|
||||
self.queue.join()
|
||||
|
||||
def _setup_connection(self):
|
||||
""" Ensure database is ready to fly. """
|
||||
"""Ensure database is ready to fly."""
|
||||
db_path = self.hass.config.path(DB_FILE)
|
||||
self.conn = sqlite3.connect(db_path, check_same_thread=False)
|
||||
self.conn.row_factory = sqlite3.Row
|
||||
|
@ -305,15 +303,15 @@ class Recorder(threading.Thread):
|
|||
# without the STOP event being fired.
|
||||
atexit.register(self._close_connection)
|
||||
|
||||
# Have datetime objects be saved as integers
|
||||
# Have datetime objects be saved as integers.
|
||||
sqlite3.register_adapter(date, _adapt_datetime)
|
||||
sqlite3.register_adapter(datetime, _adapt_datetime)
|
||||
|
||||
# Validate we are on the correct schema or that we have to migrate
|
||||
# Validate we are on the correct schema or that we have to migrate.
|
||||
cur = self.conn.cursor()
|
||||
|
||||
def save_migration(migration_id):
|
||||
""" Save and commit a migration to the database. """
|
||||
"""Save and commit a migration to the database."""
|
||||
cur.execute('INSERT INTO schema_version VALUES (?, ?)',
|
||||
(migration_id, dt_util.utcnow()))
|
||||
self.conn.commit()
|
||||
|
@ -324,7 +322,7 @@ class Recorder(threading.Thread):
|
|||
migration_id = cur.fetchone()[0] or 0
|
||||
|
||||
except sqlite3.OperationalError:
|
||||
# The table does not exist
|
||||
# The table does not exist.
|
||||
cur.execute('CREATE TABLE schema_version ('
|
||||
'migration_id integer primary key, performed integer)')
|
||||
migration_id = 0
|
||||
|
@ -399,7 +397,7 @@ class Recorder(threading.Thread):
|
|||
save_migration(3)
|
||||
|
||||
if migration_id < 4:
|
||||
# We had a bug where we did not save utc offset for recorder runs
|
||||
# We had a bug where we did not save utc offset for recorder runs.
|
||||
cur.execute(
|
||||
"""UPDATE recorder_runs SET utc_offset=?
|
||||
WHERE utc_offset IS NULL""", [self.utc_offset])
|
||||
|
@ -412,15 +410,15 @@ class Recorder(threading.Thread):
|
|||
save_migration(4)
|
||||
|
||||
if migration_id < 5:
|
||||
# Add domain so that thermostat graphs look right
|
||||
# Add domain so that thermostat graphs look right.
|
||||
try:
|
||||
cur.execute("""
|
||||
ALTER TABLE states
|
||||
ADD COLUMN domain text
|
||||
""")
|
||||
except sqlite3.OperationalError:
|
||||
# We had a bug in this migration for a while on dev
|
||||
# Without this, dev-users will have to throw away their db
|
||||
# We had a bug in this migration for a while on dev.
|
||||
# Without this, dev-users will have to throw away their db.
|
||||
pass
|
||||
|
||||
# TravisCI has Python compiled against an old version of SQLite3
|
||||
|
@ -429,13 +427,13 @@ class Recorder(threading.Thread):
|
|||
"instr", 2,
|
||||
lambda string, substring: string.find(substring) + 1)
|
||||
|
||||
# populate domain with defaults
|
||||
# Populate domain with defaults.
|
||||
cur.execute("""
|
||||
UPDATE states
|
||||
set domain=substr(entity_id, 0, instr(entity_id, '.'))
|
||||
""")
|
||||
|
||||
# add indexes we are going to use a lot on selects
|
||||
# Add indexes we are going to use a lot on selects.
|
||||
cur.execute("""
|
||||
CREATE INDEX states__state_changes ON
|
||||
states (last_changed, last_updated, entity_id)""")
|
||||
|
@ -445,13 +443,13 @@ class Recorder(threading.Thread):
|
|||
save_migration(5)
|
||||
|
||||
def _close_connection(self):
|
||||
""" Close connection to the database. """
|
||||
"""Close connection to the database."""
|
||||
_LOGGER.info("Closing database")
|
||||
atexit.unregister(self._close_connection)
|
||||
self.conn.close()
|
||||
|
||||
def _setup_run(self):
|
||||
""" Log the start of the current run. """
|
||||
"""Log the start of the current run."""
|
||||
if self.query("""UPDATE recorder_runs SET end=?, closed_incorrect=1
|
||||
WHERE end IS NULL""", (self.recording_start, ),
|
||||
return_value=RETURN_ROWCOUNT):
|
||||
|
@ -464,18 +462,18 @@ class Recorder(threading.Thread):
|
|||
(self.recording_start, dt_util.utcnow(), self.utc_offset))
|
||||
|
||||
def _close_run(self):
|
||||
""" Save end time for current run. """
|
||||
"""Save end time for current run."""
|
||||
self.query(
|
||||
"UPDATE recorder_runs SET end=? WHERE start=?",
|
||||
(dt_util.utcnow(), self.recording_start))
|
||||
|
||||
|
||||
def _adapt_datetime(datetimestamp):
|
||||
""" Turn a datetime into an integer for in the DB. """
|
||||
"""Turn a datetime into an integer for in the DB."""
|
||||
return dt_util.as_utc(datetimestamp.replace(microsecond=0)).timestamp()
|
||||
|
||||
|
||||
def _verify_instance():
|
||||
""" Throws error if recorder not initialized. """
|
||||
"""Throws error if recorder not initialized."""
|
||||
if _INSTANCE is None:
|
||||
raise RuntimeError("Recorder not initialized.")
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.rfxtrx
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Provides support for RFXtrx components.
|
||||
Support for RFXtrx components.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/rfxtrx/
|
||||
|
@ -33,11 +31,10 @@ RFXOBJECT = None
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the RFXtrx component. """
|
||||
|
||||
"""Setup the RFXtrx component."""
|
||||
# Declare the Handle event
|
||||
def handle_receive(event):
|
||||
""" Callback all subscribers for RFXtrx gateway. """
|
||||
"""Callback all subscribers for RFXtrx gateway."""
|
||||
# Log RFXCOM event
|
||||
if not event.device.id_string:
|
||||
return
|
||||
|
@ -47,14 +44,14 @@ def setup(hass, config):
|
|||
_LOGGER.info("Receive RFXCOM event from %s => %s",
|
||||
event.device, entity_name)
|
||||
|
||||
# Callback to HA registered components
|
||||
# Callback to HA registered components.
|
||||
for subscriber in RECEIVED_EVT_SUBSCRIBERS:
|
||||
subscriber(event)
|
||||
|
||||
# Try to load the RFXtrx module
|
||||
# Try to load the RFXtrx module.
|
||||
import RFXtrx as rfxtrxmod
|
||||
|
||||
# Init the rfxtrx module
|
||||
# Init the rfxtrx module.
|
||||
global RFXOBJECT
|
||||
|
||||
if ATTR_DEVICE not in config[DOMAIN]:
|
||||
|
@ -79,7 +76,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
def get_rfx_object(packetid):
|
||||
""" Return the RFXObject with the packetid. """
|
||||
"""Return the RFXObject with the packetid."""
|
||||
import RFXtrx as rfxtrxmod
|
||||
|
||||
binarypacket = bytearray.fromhex(packetid)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.rpi_gpio
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Allows to control the GPIO pins of a Raspberry Pi.
|
||||
Support for controlling GPIO pins of a Raspberry Pi.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/rpi_gpio/
|
||||
|
@ -19,15 +17,15 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
# pylint: disable=no-member
|
||||
def setup(hass, config):
|
||||
""" Sets up the Raspberry PI GPIO component. """
|
||||
"""Setup the Raspberry PI GPIO component."""
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
def cleanup_gpio(event):
|
||||
""" Stuff to do before stop home assistant. """
|
||||
"""Stuff to do before stopping."""
|
||||
GPIO.cleanup()
|
||||
|
||||
def prepare_gpio(event):
|
||||
""" Stuff to do when home assistant starts. """
|
||||
"""Stuff to do when home assistant starts."""
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_gpio)
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, prepare_gpio)
|
||||
|
@ -36,32 +34,32 @@ def setup(hass, config):
|
|||
|
||||
|
||||
def setup_output(port):
|
||||
""" Setup a GPIO as output. """
|
||||
"""Setup a GPIO as output."""
|
||||
import RPi.GPIO as GPIO
|
||||
GPIO.setup(port, GPIO.OUT)
|
||||
|
||||
|
||||
def setup_input(port, pull_mode):
|
||||
""" Setup a GPIO as input. """
|
||||
"""Setup a GPIO as input."""
|
||||
import RPi.GPIO as GPIO
|
||||
GPIO.setup(port, GPIO.IN,
|
||||
GPIO.PUD_DOWN if pull_mode == 'DOWN' else GPIO.PUD_UP)
|
||||
|
||||
|
||||
def write_output(port, value):
|
||||
""" Write a value to a GPIO. """
|
||||
"""Write a value to a GPIO."""
|
||||
import RPi.GPIO as GPIO
|
||||
GPIO.output(port, value)
|
||||
|
||||
|
||||
def read_input(port):
|
||||
""" Read a value from a GPIO. """
|
||||
"""Read a value from a GPIO."""
|
||||
import RPi.GPIO as GPIO
|
||||
return GPIO.input(port)
|
||||
|
||||
|
||||
def edge_detect(port, event_callback, bounce):
|
||||
""" Adds detection for RISING and FALLING events. """
|
||||
"""Adds detection for RISING and FALLING events."""
|
||||
import RPi.GPIO as GPIO
|
||||
GPIO.add_event_detect(
|
||||
port,
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.script
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Scripts are a sequence of actions that can be triggered manually
|
||||
by the user or automatically based upon automation events, etc.
|
||||
|
||||
|
@ -45,30 +43,29 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def is_on(hass, entity_id):
|
||||
""" Returns if the switch is on based on the statemachine. """
|
||||
"""Returns if the switch is on based on the statemachine."""
|
||||
return hass.states.is_state(entity_id, STATE_ON)
|
||||
|
||||
|
||||
def turn_on(hass, entity_id):
|
||||
""" Turn script on. """
|
||||
"""Turn script on."""
|
||||
_, object_id = split_entity_id(entity_id)
|
||||
|
||||
hass.services.call(DOMAIN, object_id)
|
||||
|
||||
|
||||
def turn_off(hass, entity_id):
|
||||
""" Turn script on. """
|
||||
"""Turn script on."""
|
||||
hass.services.call(DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id})
|
||||
|
||||
|
||||
def toggle(hass, entity_id):
|
||||
""" Toggles script. """
|
||||
"""Toggles script."""
|
||||
hass.services.call(DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: entity_id})
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Load the scripts from the configuration. """
|
||||
|
||||
"""Load the scripts from the configuration."""
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
def service_handler(service):
|
||||
|
@ -97,19 +94,19 @@ def setup(hass, config):
|
|||
hass.services.register(DOMAIN, object_id, service_handler)
|
||||
|
||||
def turn_on_service(service):
|
||||
""" Calls a service to turn script on. """
|
||||
"""Calls a service to turn script on."""
|
||||
# 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.
|
||||
for script in component.extract_from_service(service):
|
||||
turn_on(hass, script.entity_id)
|
||||
|
||||
def turn_off_service(service):
|
||||
""" Cancels a script. """
|
||||
"""Cancels a script."""
|
||||
for script in component.extract_from_service(service):
|
||||
script.turn_off()
|
||||
|
||||
def toggle_service(service):
|
||||
""" Toggles a script. """
|
||||
"""Toggles a script."""
|
||||
for script in component.extract_from_service(service):
|
||||
script.toggle()
|
||||
|
||||
|
@ -121,7 +118,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class Script(ToggleEntity):
|
||||
""" Represents a script. """
|
||||
"""Represents a script."""
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
def __init__(self, object_id, name, sequence):
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
|
||||
|
@ -136,16 +133,17 @@ class Script(ToggleEntity):
|
|||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Returns the name of the entity. """
|
||||
"""Return the name of the entity."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
""" Returns the state attributes. """
|
||||
"""Return the state attributes."""
|
||||
attrs = {}
|
||||
if self._can_cancel:
|
||||
attrs[ATTR_CAN_CANCEL] = self._can_cancel
|
||||
|
@ -155,11 +153,11 @@ class Script(ToggleEntity):
|
|||
|
||||
@property
|
||||
def is_on(self):
|
||||
""" True if entity is on. """
|
||||
"""True if entity is on."""
|
||||
return self._cur != -1
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
""" Turn the entity on. """
|
||||
"""Turn the entity on."""
|
||||
_LOGGER.info("Executing script %s", self._name)
|
||||
with self._lock:
|
||||
if self._cur == -1:
|
||||
|
@ -197,7 +195,7 @@ class Script(ToggleEntity):
|
|||
self.update_ha_state()
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
""" Turn script off. """
|
||||
"""Turn script off."""
|
||||
_LOGGER.info("Cancelled script %s", self._name)
|
||||
with self._lock:
|
||||
if self._cur == -1:
|
||||
|
@ -208,7 +206,7 @@ class Script(ToggleEntity):
|
|||
self._remove_listener()
|
||||
|
||||
def _call_service(self, action):
|
||||
""" Calls the service specified in the action. """
|
||||
"""Calls the service specified in the action."""
|
||||
# Backwards compatibility
|
||||
if CONF_SERVICE not in action and CONF_SERVICE_OLD in action:
|
||||
action[CONF_SERVICE] = action[CONF_SERVICE_OLD]
|
||||
|
@ -222,14 +220,14 @@ class Script(ToggleEntity):
|
|||
call_from_config(self.hass, action, True)
|
||||
|
||||
def _fire_event(self, action):
|
||||
""" Fires an event. """
|
||||
"""Fires an event."""
|
||||
self._last_action = action.get(CONF_ALIAS, action[CONF_EVENT])
|
||||
_LOGGER.info("Executing script %s step %s", self._name,
|
||||
self._last_action)
|
||||
self.hass.bus.fire(action[CONF_EVENT], action.get(CONF_EVENT_DATA))
|
||||
|
||||
def _remove_listener(self):
|
||||
""" Remove point in time listener, if any. """
|
||||
"""Remove point in time listener, if any."""
|
||||
if self._listener:
|
||||
self.hass.bus.remove_listener(EVENT_TIME_CHANGED,
|
||||
self._listener)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.scsgate
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Provides support for SCSGate components.
|
||||
Support for SCSGate components.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/scsgate/
|
||||
|
@ -18,8 +16,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
class SCSGate:
|
||||
""" Class dealing with the SCSGate device via scsgate.Reactor. """
|
||||
|
||||
"""Class dealing with the SCSGate device via scsgate.Reactor."""
|
||||
def __init__(self, device, logger):
|
||||
self._logger = logger
|
||||
self._devices = {}
|
||||
|
@ -38,7 +35,7 @@ class SCSGate:
|
|||
handle_message=self.handle_message)
|
||||
|
||||
def handle_message(self, message):
|
||||
""" Method called whenever a message is seen on the bus. """
|
||||
"""Method called whenever a message is seen on the bus."""
|
||||
from scsgate.messages import StateMessage, ScenarioTriggeredMessage
|
||||
|
||||
self._logger.debug("Received message {}".format(message))
|
||||
|
@ -88,14 +85,14 @@ class SCSGate:
|
|||
self._devices[device.scs_id] = device
|
||||
|
||||
def add_devices_to_register(self, devices):
|
||||
""" List of devices to be registered. """
|
||||
"""List of devices to be registered."""
|
||||
with self._devices_to_register_lock:
|
||||
for device in devices:
|
||||
self._devices_to_register[device.scs_id] = device
|
||||
self._activate_next_device()
|
||||
|
||||
def _activate_next_device(self):
|
||||
""" Starts the activation of the first device. """
|
||||
"""Starts the activation of the first device."""
|
||||
from scsgate.tasks import GetStatusTask
|
||||
|
||||
with self._devices_to_register_lock:
|
||||
|
@ -107,7 +104,7 @@ class SCSGate:
|
|||
self._reactor.append_task(GetStatusTask(target=device.scs_id))
|
||||
|
||||
def is_device_registered(self, device_id):
|
||||
""" Checks whether a device is already registered or not. """
|
||||
"""Checks whether a device is already registered or not."""
|
||||
with self._devices_to_register_lock:
|
||||
if device_id in self._devices_to_register.keys():
|
||||
return False
|
||||
|
@ -119,20 +116,20 @@ class SCSGate:
|
|||
return True
|
||||
|
||||
def start(self):
|
||||
""" Start the scsgate.Reactor. """
|
||||
"""Start the scsgate.Reactor."""
|
||||
self._reactor.start()
|
||||
|
||||
def stop(self):
|
||||
""" Stop the scsgate.Reactor. """
|
||||
"""Stop the scsgate.Reactor."""
|
||||
self._reactor.stop()
|
||||
|
||||
def append_task(self, task):
|
||||
""" Registers a new task to be executed. """
|
||||
"""Registers a new task to be executed."""
|
||||
self._reactor.append_task(task)
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the SCSGate component. """
|
||||
"""Setup the SCSGate component."""
|
||||
device = config['scsgate']['device']
|
||||
global SCSGATE
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.shell_command
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Exposes regular shell commands as services.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
|
@ -17,7 +15,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Sets up the shell_command component. """
|
||||
"""Sets up the shell_command component."""
|
||||
conf = config.get(DOMAIN)
|
||||
|
||||
if not isinstance(conf, dict):
|
||||
|
@ -31,7 +29,7 @@ def setup(hass, config):
|
|||
return False
|
||||
|
||||
def service_handler(call):
|
||||
""" Execute a shell command service. """
|
||||
"""Execute a shell command service."""
|
||||
try:
|
||||
subprocess.call(conf[call.service], shell=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
|
|
|
@ -51,7 +51,6 @@ def setup(hass, config):
|
|||
|
||||
def statsd_event_listener(event):
|
||||
"""Listen for new messages on the bus and sends them to StatsD."""
|
||||
|
||||
state = event.data.get('new_state')
|
||||
|
||||
if state is None:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
homeassistant.components.sun
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Provides functionality to keep track of the sun.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.tellduslive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Tellduslive Component.
|
||||
Support for Telldus Live.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/tellduslive/
|
||||
|
@ -41,10 +39,10 @@ NETWORK = None
|
|||
|
||||
@Throttle(MIN_TIME_BETWEEN_SWITCH_UPDATES)
|
||||
def request_switches():
|
||||
""" make request to online service """
|
||||
"""Make request to online service."""
|
||||
_LOGGER.debug("Updating switches from Telldus Live")
|
||||
switches = NETWORK.request("devices/list")["device"]
|
||||
# filter out any group of switches
|
||||
# Filter out any group of switches.
|
||||
switches = {switch["id"]: switch for switch in switches
|
||||
if switch["type"] == "device"}
|
||||
return switches
|
||||
|
@ -52,10 +50,10 @@ def request_switches():
|
|||
|
||||
@Throttle(MIN_TIME_BETWEEN_SENSOR_UPDATES)
|
||||
def request_sensors():
|
||||
""" make request to online service """
|
||||
"""Make request to online service."""
|
||||
_LOGGER.debug("Updating sensors from Telldus Live")
|
||||
units = NETWORK.request("sensors/list")["sensor"]
|
||||
# one unit can contain many sensors
|
||||
# One unit can contain many sensors.
|
||||
sensors = {unit["id"]+sensor["name"]: dict(unit, data=sensor)
|
||||
for unit in units
|
||||
for sensor in unit["data"]}
|
||||
|
@ -63,8 +61,7 @@ def request_sensors():
|
|||
|
||||
|
||||
class TelldusLiveData(object):
|
||||
""" Gets the latest data and update the states. """
|
||||
|
||||
"""Gets the latest data and update the states."""
|
||||
def __init__(self, hass, config):
|
||||
public_key = config[DOMAIN].get(CONF_PUBLIC_KEY)
|
||||
private_key = config[DOMAIN].get(CONF_PRIVATE_KEY)
|
||||
|
@ -85,18 +82,17 @@ class TelldusLiveData(object):
|
|||
access_secret=token_secret)
|
||||
|
||||
def validate_session(self):
|
||||
""" Make a dummy request to see if the session is valid """
|
||||
"""Make a dummy request to see if the session is valid."""
|
||||
response = self.request("user/profile")
|
||||
return response and 'email' in response
|
||||
|
||||
def discover(self):
|
||||
""" Update states, will trigger discover """
|
||||
"""Update states, will trigger discover."""
|
||||
self.update_sensors()
|
||||
self.update_switches()
|
||||
|
||||
def _discover(self, found_devices, component_name):
|
||||
""" Send discovery event if component not yet discovered """
|
||||
|
||||
"""Send discovery event if component not yet discovered."""
|
||||
if not len(found_devices):
|
||||
return
|
||||
|
||||
|
@ -115,7 +111,7 @@ class TelldusLiveData(object):
|
|||
ATTR_DISCOVERED: found_devices})
|
||||
|
||||
def request(self, what, **params):
|
||||
""" Sends a request to the tellstick live API """
|
||||
"""Sends a request to the Tellstick Live API."""
|
||||
from tellive.live import const
|
||||
|
||||
supported_methods = const.TELLSTICK_TURNON \
|
||||
|
@ -149,12 +145,8 @@ class TelldusLiveData(object):
|
|||
_LOGGER.error("failed to make request to Tellduslive servers")
|
||||
return None
|
||||
|
||||
def update_devices(self,
|
||||
local_devices,
|
||||
remote_devices,
|
||||
component_name):
|
||||
""" update local device list and discover new devices """
|
||||
|
||||
def update_devices(self, local_devices, remote_devices, component_name):
|
||||
"""Update local device list and discover new devices."""
|
||||
if remote_devices is None:
|
||||
return local_devices
|
||||
|
||||
|
@ -172,48 +164,46 @@ class TelldusLiveData(object):
|
|||
return remote_devices
|
||||
|
||||
def update_sensors(self):
|
||||
""" update local list of sensors """
|
||||
"""Update local list of sensors."""
|
||||
self._sensors = self.update_devices(self._sensors,
|
||||
request_sensors(),
|
||||
"sensor")
|
||||
|
||||
def update_switches(self):
|
||||
""" update local list of switches """
|
||||
"""Update local list of switches."""
|
||||
self._switches = self.update_devices(self._switches,
|
||||
request_switches(),
|
||||
"switch")
|
||||
|
||||
def _check_request(self, what, **params):
|
||||
""" Make request, check result if successful """
|
||||
"""Make request, check result if successful."""
|
||||
response = self.request(what, **params)
|
||||
return response and response.get('status') == 'success'
|
||||
|
||||
def get_switch(self, switch_id):
|
||||
""" return switch representation """
|
||||
"""Return the switch representation."""
|
||||
return self._switches[switch_id]
|
||||
|
||||
def get_sensor(self, sensor_id):
|
||||
""" return sensor representation """
|
||||
"""Return the sensor representation."""
|
||||
return self._sensors[sensor_id]
|
||||
|
||||
def turn_switch_on(self, switch_id):
|
||||
""" Turn switch off. """
|
||||
"""Turn switch off."""
|
||||
if self._check_request("device/turnOn", id=switch_id):
|
||||
from tellive.live import const
|
||||
self.get_switch(switch_id)["state"] = const.TELLSTICK_TURNON
|
||||
|
||||
def turn_switch_off(self, switch_id):
|
||||
""" Turn switch on. """
|
||||
"""Turn switch on."""
|
||||
if self._check_request("device/turnOff", id=switch_id):
|
||||
from tellive.live import const
|
||||
self.get_switch(switch_id)["state"] = const.TELLSTICK_TURNOFF
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the Telldus Live component. """
|
||||
|
||||
# fixme: aquire app key and provide authentication
|
||||
# using username + password
|
||||
"""Setup the Telldus Live component."""
|
||||
# FIXME: aquire app key and provide authentication using username+password
|
||||
if not validate_config(config,
|
||||
{DOMAIN: [CONF_PUBLIC_KEY,
|
||||
CONF_PRIVATE_KEY,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.updater
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component that checks for available updates.
|
||||
Support to check for available updates.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
at https://home-assistant.io/components/updater/
|
||||
|
@ -21,10 +19,9 @@ ENTITY_ID = 'updater.updater'
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the updater component. """
|
||||
|
||||
"""Setup the updater component."""
|
||||
def check_newest_version(_=None):
|
||||
""" Check if a new version is available and report if one is. """
|
||||
"""Check if a new version is available and report if one is."""
|
||||
newest = get_newest_version()
|
||||
|
||||
if newest != CURRENT_VERSION and newest is not None:
|
||||
|
@ -40,7 +37,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
def get_newest_version():
|
||||
""" Get the newest Home Assistant version from PyPI. """
|
||||
"""Get the newest Home Assistant version from PyPI."""
|
||||
try:
|
||||
req = requests.get(PYPI_URL)
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
components.verisure
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Provides support for verisure components.
|
||||
Support for Verisure components.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/verisure/
|
||||
|
@ -33,8 +31,7 @@ HUB = None
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup the Verisure component. """
|
||||
|
||||
"""Setup the Verisure component."""
|
||||
if not validate_config(config,
|
||||
{DOMAIN: [CONF_USERNAME, CONF_PASSWORD]},
|
||||
_LOGGER):
|
||||
|
@ -46,7 +43,6 @@ def setup(hass, config):
|
|||
if not HUB.login():
|
||||
return False
|
||||
|
||||
# Load components for the devices in the ISY controller that we support
|
||||
for comp_name, discovery in ((('sensor', DISCOVER_SENSORS),
|
||||
('switch', DISCOVER_SWITCHES),
|
||||
('alarm_control_panel', DISCOVER_ALARMS),
|
||||
|
@ -62,8 +58,7 @@ def setup(hass, config):
|
|||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
class VerisureHub(object):
|
||||
""" Verisure wrapper class """
|
||||
|
||||
"""A Verisure wrapper class."""
|
||||
def __init__(self, domain_config, verisure):
|
||||
self.alarm_status = {}
|
||||
self.lock_status = {}
|
||||
|
@ -88,7 +83,7 @@ class VerisureHub(object):
|
|||
domain_config[CONF_PASSWORD])
|
||||
|
||||
def login(self):
|
||||
""" Login to MyPages """
|
||||
"""Login to Verisure MyPages."""
|
||||
try:
|
||||
self.my_pages.login()
|
||||
except self._verisure.Error as ex:
|
||||
|
@ -98,41 +93,41 @@ class VerisureHub(object):
|
|||
|
||||
@Throttle(timedelta(seconds=1))
|
||||
def update_alarms(self):
|
||||
""" Updates the status of the alarm. """
|
||||
"""Updates the status of the alarm."""
|
||||
self.update_component(
|
||||
self.my_pages.alarm.get,
|
||||
self.alarm_status)
|
||||
|
||||
@Throttle(timedelta(seconds=1))
|
||||
def update_locks(self):
|
||||
""" Updates the status of the alarm. """
|
||||
"""Updates the status of the locks."""
|
||||
self.update_component(
|
||||
self.my_pages.lock.get,
|
||||
self.lock_status)
|
||||
|
||||
@Throttle(timedelta(seconds=60))
|
||||
def update_climate(self):
|
||||
""" Updates the status of the smartplugs. """
|
||||
"""Updates the status of the climate units."""
|
||||
self.update_component(
|
||||
self.my_pages.climate.get,
|
||||
self.climate_status)
|
||||
|
||||
@Throttle(timedelta(seconds=60))
|
||||
def update_mousedetection(self):
|
||||
""" Updates the status of the smartplugs. """
|
||||
"""Updates the status of the mouse detectors."""
|
||||
self.update_component(
|
||||
self.my_pages.mousedetection.get,
|
||||
self.mouse_status)
|
||||
|
||||
@Throttle(timedelta(seconds=1))
|
||||
def update_smartplugs(self):
|
||||
""" Updates the status of the smartplugs. """
|
||||
"""Updates the status of the smartplugs."""
|
||||
self.update_component(
|
||||
self.my_pages.smartplug.get,
|
||||
self.smartplug_status)
|
||||
|
||||
def update_component(self, get_function, status):
|
||||
""" Updates the status of verisure components. """
|
||||
"""Updates the status of Verisure components."""
|
||||
if self._wrong_password_given:
|
||||
_LOGGER.error('Wrong password for Verisure, update config')
|
||||
return
|
||||
|
@ -147,7 +142,7 @@ class VerisureHub(object):
|
|||
self.reconnect()
|
||||
|
||||
def reconnect(self):
|
||||
""" Reconnect to verisure mypages. """
|
||||
"""Reconnect to Verisure MyPages."""
|
||||
if self._reconnect_timeout > time.time():
|
||||
return
|
||||
if not self._lock.acquire(blocking=False):
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
homeassistant.components.weblink
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Adds links to external webpages.
|
||||
Support for links to external web pages.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/weblink/
|
||||
|
@ -23,8 +20,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup weblink component. """
|
||||
|
||||
"""Setup weblink component."""
|
||||
links = config.get(DOMAIN)
|
||||
|
||||
for link in links.get('entities'):
|
||||
|
@ -39,8 +35,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class Link(Entity):
|
||||
""" Represent a link. """
|
||||
|
||||
"""Represent a link."""
|
||||
def __init__(self, hass, name, url, icon):
|
||||
self.hass = hass
|
||||
self._name = name
|
||||
|
@ -51,15 +46,15 @@ class Link(Entity):
|
|||
|
||||
@property
|
||||
def icon(self):
|
||||
""" Icon to use in the frontend, if any. """
|
||||
"""Return the icon to use in the frontend, if any."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Returns the name of the URL. """
|
||||
"""Return the name of the URL."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
""" Returns the URL. """
|
||||
"""Return the URL."""
|
||||
return self._url
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.wemo
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
WeMo device discovery.
|
||||
Support for WeMo device discovery.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/wemo/
|
||||
|
@ -18,7 +16,7 @@ DISCOVER_LIGHTS = 'wemo.light'
|
|||
DISCOVER_MOTION = 'wemo.motion'
|
||||
DISCOVER_SWITCHES = 'wemo.switch'
|
||||
|
||||
# mapping from Wemo model_name to service
|
||||
# Mapping from Wemo model_name to service.
|
||||
WEMO_MODEL_DISPATCH = {
|
||||
'Bridge': DISCOVER_LIGHTS,
|
||||
'Insight': DISCOVER_SWITCHES,
|
||||
|
@ -41,7 +39,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
# pylint: disable=unused-argument, too-many-function-args
|
||||
def setup(hass, config):
|
||||
"""Common set up for WeMo devices."""
|
||||
"""Common setup for WeMo devices."""
|
||||
import pywemo
|
||||
|
||||
global SUBSCRIPTION_REGISTRY
|
||||
|
@ -77,7 +75,7 @@ def setup(hass, config):
|
|||
_LOGGER.info("Scanning for WeMo devices.")
|
||||
devices = [(device.host, device) for device in pywemo.discover_devices()]
|
||||
|
||||
# Add static devices from the config file
|
||||
# Add static devices from the config file.
|
||||
devices.extend((address, None)
|
||||
for address in config.get(DOMAIN, {}).get('static', []))
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""
|
||||
homeassistant.components.wink
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Connects to a Wink hub and loads relevant components to control its devices.
|
||||
Support for Wink hubs.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/wink/
|
||||
"""
|
||||
|
@ -27,7 +26,7 @@ DISCOVER_GARAGE_DOORS = "wink.garage_doors"
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Sets up the Wink component. """
|
||||
"""Setup the Wink component."""
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if not validate_config(config, {DOMAIN: [CONF_ACCESS_TOKEN]}, logger):
|
||||
|
@ -64,34 +63,33 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class WinkToggleDevice(ToggleEntity):
|
||||
""" Represents a Wink toogle (switch) device. """
|
||||
|
||||
"""Represents a Wink toggle (switch) device."""
|
||||
def __init__(self, wink):
|
||||
self.wink = wink
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
""" Returns the id of this Wink switch. """
|
||||
"""Return the ID of this Wink device."""
|
||||
return "{}.{}".format(self.__class__, self.wink.device_id())
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Returns the name of the light if any. """
|
||||
"""Return the name of the device."""
|
||||
return self.wink.name()
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
""" True if light is on. """
|
||||
"""True if decive is on."""
|
||||
return self.wink.state()
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
""" Turns the switch on. """
|
||||
"""Turns the device on."""
|
||||
self.wink.set_state(True)
|
||||
|
||||
def turn_off(self):
|
||||
""" Turns the switch off. """
|
||||
"""Turns the device off."""
|
||||
self.wink.set_state(False)
|
||||
|
||||
def update(self):
|
||||
""" Update state of the light. """
|
||||
"""Update state of the device."""
|
||||
self.wink.update_state()
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.zigbee
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sets up and provides access to a ZigBee device and contains generic entity
|
||||
classes.
|
||||
Support for ZigBee devices.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/zigbee/
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.zone
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Allows defintion of zones in Home Assistant.
|
||||
Support for the definition of zones.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/zone/
|
||||
|
@ -32,7 +30,7 @@ ICON_HOME = 'mdi:home'
|
|||
|
||||
|
||||
def active_zone(hass, latitude, longitude, radius=0):
|
||||
""" Find the active zone for given latitude, longitude. """
|
||||
"""Find the active zone for given latitude, longitude."""
|
||||
# Sort entity IDs so that we are deterministic if equal distance to 2 zones
|
||||
zones = (hass.states.get(entity_id) for entity_id
|
||||
in sorted(hass.states.entity_ids(DOMAIN)))
|
||||
|
@ -62,7 +60,7 @@ def active_zone(hass, latitude, longitude, radius=0):
|
|||
|
||||
|
||||
def in_zone(zone, latitude, longitude, radius=0):
|
||||
""" Test if given latitude, longitude is in given zone. """
|
||||
"""Test if given latitude, longitude is in given zone."""
|
||||
zone_dist = distance(
|
||||
latitude, longitude,
|
||||
zone.attributes[ATTR_LATITUDE], zone.attributes[ATTR_LONGITUDE])
|
||||
|
@ -71,7 +69,7 @@ def in_zone(zone, latitude, longitude, radius=0):
|
|||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Setup zone. """
|
||||
"""Setup zone."""
|
||||
entities = set()
|
||||
|
||||
for key in extract_domain_configs(config, DOMAIN):
|
||||
|
@ -108,7 +106,7 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class Zone(Entity):
|
||||
""" Represents a Zone in Home Assistant. """
|
||||
"""Represents a Zone."""
|
||||
# pylint: disable=too-many-arguments, too-many-instance-attributes
|
||||
def __init__(self, hass, name, latitude, longitude, radius, icon, passive):
|
||||
self.hass = hass
|
||||
|
@ -121,19 +119,22 @@ class Zone(Entity):
|
|||
|
||||
@property
|
||||
def name(self):
|
||||
""" Return the name of the zone."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
""" The state property really does nothing for a zone. """
|
||||
"""Return the state property really does nothing for a zone."""
|
||||
return STATE
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon if any."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
""" Return the state attributes of the zone."""
|
||||
data = {
|
||||
ATTR_HIDDEN: True,
|
||||
ATTR_LATITUDE: self._latitude,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
homeassistant.components.zwave
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Connects Home Assistant to a Z-Wave network.
|
||||
Support for Z-Wave.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/zwave/
|
||||
|
@ -56,8 +54,8 @@ TYPE_BOOL = "Bool"
|
|||
TYPE_DECIMAL = "Decimal"
|
||||
|
||||
|
||||
# list of tuple (DOMAIN, discovered service, supported command
|
||||
# classes, value type)
|
||||
# List of tuple (DOMAIN, discovered service, supported command classes,
|
||||
# value type).
|
||||
DISCOVERY_COMPONENTS = [
|
||||
('sensor',
|
||||
DISCOVER_SENSORS,
|
||||
|
@ -93,28 +91,28 @@ NETWORK = None
|
|||
|
||||
|
||||
def _obj_to_dict(obj):
|
||||
""" Converts an obj into a hash for debug. """
|
||||
"""Converts an obj into a hash for debug."""
|
||||
return {key: getattr(obj, key) for key
|
||||
in dir(obj)
|
||||
if key[0] != '_' and not hasattr(getattr(obj, key), '__call__')}
|
||||
|
||||
|
||||
def _node_name(node):
|
||||
""" Returns the name of the node. """
|
||||
"""Returns the name of the node."""
|
||||
return node.name or "{} {}".format(
|
||||
node.manufacturer_name, node.product_name)
|
||||
|
||||
|
||||
def _value_name(value):
|
||||
""" Returns the name of the value. """
|
||||
"""Returns the name of the value."""
|
||||
return "{} {}".format(_node_name(value.node), value.label)
|
||||
|
||||
|
||||
def _object_id(value):
|
||||
""" Returns 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"""
|
||||
|
||||
to not collide with other entity_ids.
|
||||
"""
|
||||
object_id = "{}_{}".format(slugify(_value_name(value)),
|
||||
value.node.node_id)
|
||||
|
||||
|
@ -126,7 +124,7 @@ def _object_id(value):
|
|||
|
||||
|
||||
def nice_print_node(node):
|
||||
""" Prints a nice formatted node to the output (debug method). """
|
||||
"""Prints a nice formatted node to the output (debug method)."""
|
||||
node_dict = _obj_to_dict(node)
|
||||
node_dict['values'] = {value_id: _obj_to_dict(value)
|
||||
for value_id, value in node.values.items()}
|
||||
|
@ -138,8 +136,7 @@ def nice_print_node(node):
|
|||
|
||||
|
||||
def get_config_value(node, value_index):
|
||||
""" Returns the current config value for a specific index. """
|
||||
|
||||
"""Returns the current configuration value for a specific index."""
|
||||
try:
|
||||
for value in node.values.values():
|
||||
# 112 == config command class
|
||||
|
@ -193,8 +190,7 @@ def setup(hass, config):
|
|||
dispatcher.connect(log_all, weak=False)
|
||||
|
||||
def value_added(node, value):
|
||||
""" Called when a value is added to a node on the network. """
|
||||
|
||||
"""Called when a value is added to a node on the network."""
|
||||
for (component,
|
||||
discovery_service,
|
||||
command_ids,
|
||||
|
@ -230,7 +226,7 @@ def setup(hass, config):
|
|||
})
|
||||
|
||||
def scene_activated(node, scene_id):
|
||||
""" Called when a scene is activated on any node in the network. """
|
||||
"""Called when a scene is activated on any node in the network."""
|
||||
name = _node_name(node)
|
||||
object_id = "{}_{}".format(slugify(name), node.node_id)
|
||||
|
||||
|
@ -245,19 +241,19 @@ def setup(hass, config):
|
|||
scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
|
||||
|
||||
def add_node(event):
|
||||
""" Switch into inclusion mode """
|
||||
"""Switch into inclusion mode."""
|
||||
NETWORK.controller.begin_command_add_device()
|
||||
|
||||
def remove_node(event):
|
||||
""" Switch into exclusion mode"""
|
||||
"""Switch into exclusion mode."""
|
||||
NETWORK.controller.begin_command_remove_device()
|
||||
|
||||
def stop_zwave(event):
|
||||
""" Stop Z-wave. """
|
||||
"""Stop Z-wave."""
|
||||
NETWORK.stop()
|
||||
|
||||
def start_zwave(event):
|
||||
""" Called when Home Assistant starts up. """
|
||||
"""Startup """
|
||||
NETWORK.start()
|
||||
|
||||
polling_interval = convert(
|
||||
|
@ -267,7 +263,7 @@ def setup(hass, config):
|
|||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)
|
||||
|
||||
# register add / remove node services for zwave sticks without
|
||||
# Register add / remove node services for Z-Wave sticks without
|
||||
# hardware inclusion button
|
||||
hass.services.register(DOMAIN, SERVICE_ADD_NODE, add_node)
|
||||
hass.services.register(DOMAIN, SERVICE_REMOVE_NODE, remove_node)
|
||||
|
@ -278,37 +274,37 @@ def setup(hass, config):
|
|||
|
||||
|
||||
class ZWaveDeviceEntity:
|
||||
""" Represents a ZWave node entity within Home Assistant. """
|
||||
"""Represents a Z-Wave node entity."""
|
||||
def __init__(self, value, domain):
|
||||
self._value = value
|
||||
self.entity_id = "{}.{}".format(domain, self._object_id())
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
""" False because we will push our own state to HA when changed. """
|
||||
"""No polling needed."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
""" Returns a unique id. """
|
||||
"""Returns a unique id."""
|
||||
return "ZWAVE-{}-{}".format(self._value.node.node_id,
|
||||
self._value.object_id)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Returns the name of the device. """
|
||||
"""Returns the name of the device."""
|
||||
return _value_name(self._value)
|
||||
|
||||
def _object_id(self):
|
||||
""" 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"""
|
||||
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
return _object_id(self._value)
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
""" Returns device specific state attributes. """
|
||||
"""Return device specific state attributes."""
|
||||
attrs = {
|
||||
ATTR_NODE_ID: self._value.node.node_id,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue