mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
1) Performed many pylint and flake8 fixes to clean up isy994 integration and hidden entities addition. 2) Added necessary code to allow groups to also be hidden. 3) Made most of the weather data from the isy994 component be hidden by default.
This commit is contained in:
parent
caed69d5ea
commit
b20424261c
@ -625,8 +625,8 @@ class StateMachine(object):
|
||||
# components that don't use the Entity base class for their entities.
|
||||
# The sun component is an example of this. The Entity class cannot be
|
||||
# imported cleanly, so assume the state is shown. This means that for
|
||||
# visibility to be supported, the state must originate from a class that
|
||||
# uses the base class Entity or it must manually put the hidden
|
||||
# visibility to be supported, the state must originate from a class
|
||||
# that uses the base class Entity or it must manually put the hidden
|
||||
# attribute in its attributes dictionary.
|
||||
if ATTR_HIDDEN not in attributes:
|
||||
attributes[ATTR_HIDDEN] = False
|
||||
|
@ -208,7 +208,7 @@ def process_ha_core_config(hass, config):
|
||||
if key in config:
|
||||
setattr(hass.config, attr, config[key])
|
||||
|
||||
Entity._visibility.update(config.get('visibility', [{}])[0])
|
||||
Entity.visibility.update(config.get('visibility', [{}])[0])
|
||||
|
||||
if CONF_TEMPERATURE_UNIT in config:
|
||||
unit = config[CONF_TEMPERATURE_UNIT]
|
||||
|
@ -7,10 +7,11 @@ Provides functionality to group devices that can be turned on or off.
|
||||
|
||||
import homeassistant as ha
|
||||
from homeassistant.helpers import generate_entity_id
|
||||
from homeassistant.helpers.entity import Entity
|
||||
import homeassistant.util as util
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, STATE_ON, STATE_OFF,
|
||||
STATE_HOME, STATE_NOT_HOME, STATE_UNKNOWN)
|
||||
STATE_HOME, STATE_NOT_HOME, STATE_UNKNOWN, ATTR_HIDDEN)
|
||||
|
||||
DOMAIN = "group"
|
||||
DEPENDENCIES = []
|
||||
@ -112,6 +113,10 @@ def setup(hass, config):
|
||||
|
||||
class Group(object):
|
||||
""" Tracks a group of entity ids. """
|
||||
|
||||
visibility = Entity.visibility
|
||||
_hidden = False
|
||||
|
||||
def __init__(self, hass, name, entity_ids=None, user_defined=True):
|
||||
self.hass = hass
|
||||
self.name = name
|
||||
@ -138,7 +143,8 @@ class Group(object):
|
||||
return {
|
||||
ATTR_ENTITY_ID: self.tracking,
|
||||
ATTR_AUTO: not self.user_defined,
|
||||
ATTR_FRIENDLY_NAME: self.name
|
||||
ATTR_FRIENDLY_NAME: self.name,
|
||||
ATTR_HIDDEN: self.hidden
|
||||
}
|
||||
|
||||
def update_tracked_entity_ids(self, entity_ids):
|
||||
@ -213,6 +219,24 @@ class Group(object):
|
||||
self.hass.states.set(
|
||||
self.entity_id, group_off, self.state_attr)
|
||||
|
||||
@property
|
||||
def hidden(self):
|
||||
"""
|
||||
Returns the official decision of whether the entity should be hidden.
|
||||
Any value set by the user in the configuration file will overwrite
|
||||
whatever the component sets for visibility.
|
||||
"""
|
||||
if self.entity_id is not None and \
|
||||
self.entity_id.lower() in self.visibility:
|
||||
return self.visibility[self.entity_id.lower()] == 'hide'
|
||||
else:
|
||||
return self._hidden
|
||||
|
||||
@hidden.setter
|
||||
def hidden(self, val):
|
||||
""" Sets the suggestion for visibility. """
|
||||
self._hidden = bool(val)
|
||||
|
||||
|
||||
def setup_group(hass, name, entity_ids, user_defined=True):
|
||||
""" Sets up a group state that is the combined state of
|
||||
|
@ -29,15 +29,19 @@ SENSOR_STRING = 'Sensor'
|
||||
HIDDEN_STRING = '{HIDE ME}'
|
||||
|
||||
# setup logger
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""
|
||||
Setup isy994 component.
|
||||
This will automatically import associated lights, switches, and sensors.
|
||||
"""
|
||||
# pylint: disable=global-statement
|
||||
# check for required values in configuration file
|
||||
if not validate_config(config,
|
||||
{DOMAIN: [CONF_HOST, CONF_USERNAME, CONF_PASSWORD]},
|
||||
logger):
|
||||
_LOGGER):
|
||||
return False
|
||||
|
||||
# pull and parse standard configuration
|
||||
@ -52,7 +56,7 @@ def setup(hass, config):
|
||||
addr = addr.replace('https://', '')
|
||||
https = True
|
||||
else:
|
||||
logger.error('isy994 host value in configuration file is invalid.')
|
||||
_LOGGER.error('isy994 host value in configuration file is invalid.')
|
||||
return False
|
||||
port = host.port
|
||||
addr = addr.replace(':{}'.format(port), '')
|
||||
@ -65,7 +69,7 @@ def setup(hass, config):
|
||||
|
||||
# connect to ISY controller
|
||||
global ISY
|
||||
ISY = PyISY.ISY(addr, port, user, password, use_https=https, log=logger)
|
||||
ISY = PyISY.ISY(addr, port, user, password, use_https=https, log=_LOGGER)
|
||||
if not ISY.connected:
|
||||
return False
|
||||
|
||||
@ -91,6 +95,7 @@ class ISYDeviceABC(ToggleEntity):
|
||||
_states = []
|
||||
_dtype = None
|
||||
_domain = None
|
||||
_name = None
|
||||
|
||||
def __init__(self, node):
|
||||
# setup properties
|
||||
@ -98,34 +103,39 @@ class ISYDeviceABC(ToggleEntity):
|
||||
self.hidden = HIDDEN_STRING in self.raw_name
|
||||
|
||||
# track changes
|
||||
self._changeHandler = self.node.status. \
|
||||
subscribe('changed', self.onUpdate)
|
||||
self._change_handler = self.node.status. \
|
||||
subscribe('changed', self.on_update)
|
||||
|
||||
def __del__(self):
|
||||
""" cleanup subscriptions because it is the right thing to do. """
|
||||
self._changeHandler.unsubscribe()
|
||||
self._change_handler.unsubscribe()
|
||||
|
||||
@property
|
||||
def domain(self):
|
||||
""" Returns the domain of the entity. """
|
||||
return self._domain
|
||||
|
||||
@property
|
||||
def dtype(self):
|
||||
""" Returns the data type of the entity (binary or analog). """
|
||||
if self._dtype in ['analog', 'binary']:
|
||||
return self._dtype
|
||||
return 'binary' if self._units is None else 'analog'
|
||||
return 'binary' if self.unit_of_measurement is None else 'analog'
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
""" Tells Home Assistant not to poll this entity. """
|
||||
return False
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
""" returns 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. """
|
||||
attr = {ATTR_FRIENDLY_NAME: self.name}
|
||||
for name, prop in self._attrs.items():
|
||||
attr[name] = getattr(self, prop)
|
||||
@ -134,18 +144,18 @@ class ISYDeviceABC(ToggleEntity):
|
||||
@property
|
||||
def unique_id(self):
|
||||
""" Returns the id of this isy sensor """
|
||||
# pylint: disable=protected-access
|
||||
return self.node._id
|
||||
|
||||
@property
|
||||
def raw_name(self):
|
||||
try:
|
||||
return str(self._name)
|
||||
except AttributeError:
|
||||
return str(self.node.name)
|
||||
""" Returns 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 name of the node if any. """
|
||||
""" Returns the cleaned name of the node. """
|
||||
return self.raw_name.replace(HIDDEN_STRING, '').strip()
|
||||
|
||||
def update(self):
|
||||
@ -153,16 +163,18 @@ class ISYDeviceABC(ToggleEntity):
|
||||
# ISY objects are automatically updated by the ISY's event stream
|
||||
pass
|
||||
|
||||
def onUpdate(self, e):
|
||||
def on_update(self, event):
|
||||
""" Handles the update received event. """
|
||||
self.update_ha_state()
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
""" Returns 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 self.is_on
|
||||
|
||||
@property
|
||||
@ -178,17 +190,18 @@ class ISYDeviceABC(ToggleEntity):
|
||||
attrs = [kwargs.get(name) for name in self._onattrs]
|
||||
self.node.on(*attrs)
|
||||
else:
|
||||
logger.error('ISY cannot turn on sensors.')
|
||||
_LOGGER.error('ISY cannot turn on sensors.')
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
""" turns the device off """
|
||||
if self.domain is not 'sensor':
|
||||
self.node.off()
|
||||
else:
|
||||
logger.error('ISY cannot turn off sensors.')
|
||||
_LOGGER.error('ISY cannot turn off sensors.')
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
""" Returns the defined units of measurement or None. """
|
||||
try:
|
||||
return self.node.units
|
||||
except AttributeError:
|
||||
|
@ -3,13 +3,29 @@
|
||||
import logging
|
||||
|
||||
# homeassistant imports
|
||||
from homeassistant.components.isy994 import ISY, ISYDeviceABC, SENSOR_STRING
|
||||
from homeassistant.components.isy994 import (ISY, ISYDeviceABC, SENSOR_STRING,
|
||||
HIDDEN_STRING)
|
||||
from homeassistant.const import (STATE_OPEN, STATE_CLOSED, STATE_HOME,
|
||||
STATE_NOT_HOME, STATE_ON, STATE_OFF)
|
||||
|
||||
DEFAULT_HIDDEN_WEATHER = ['Temperature_High', 'Temperature_Low', 'Feels_Like',
|
||||
'Temperature_Average', 'Pressure', 'Dew_Point',
|
||||
'Gust_Speed', 'Evapotranspiration',
|
||||
'Irrigation_Requirement', 'Water_Deficit_Yesterday',
|
||||
'Elevation', 'Average_Temperature_Tomorrow',
|
||||
'High_Temperature_Tomorrow',
|
||||
'Low_Temperature_Tomorrow', 'Humidity_Tomorrow',
|
||||
'Wind_Speed_Tomorrow', 'Gust_Speed_Tomorrow',
|
||||
'Rain_Tomorrow', 'Snow_Tomorrow',
|
||||
'Forecast_Average_Temperature',
|
||||
'Forecast_High_Temperature',
|
||||
'Forecast_Low_Temperature', 'Forecast_Humidity',
|
||||
'Forecast_Rain', 'Forecast_Snow']
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
""" Sets up the isy994 platform. """
|
||||
# pylint: disable=protected-access
|
||||
logger = logging.getLogger(__name__)
|
||||
devs = []
|
||||
# verify connection
|
||||
@ -21,7 +37,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
if ISY.climate is not None:
|
||||
for prop in ISY.climate._id2name:
|
||||
if prop is not None:
|
||||
node = WeatherPseudoNode('ISY.weather.' + prop, prop,
|
||||
prefix = HIDDEN_STRING if prop in DEFAULT_HIDDEN_WEATHER else ''
|
||||
node = WeatherPseudoNode('ISY.weather.' + prop, prefix + prop,
|
||||
getattr(ISY.climate, prop),
|
||||
getattr(ISY.climate, prop + '_units'))
|
||||
devs.append(ISYSensorDevice(node))
|
||||
@ -42,7 +59,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
# folder does not exist
|
||||
pass
|
||||
else:
|
||||
for dtype, name, node_id in folder.children:
|
||||
for _, _, node_id in folder.children:
|
||||
node = folder[node_id].leaf
|
||||
devs.append(ISYSensorDevice(node, states))
|
||||
|
||||
@ -51,6 +68,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
|
||||
class WeatherPseudoNode(object):
|
||||
""" This class allows weather variable to act as regular nodes. """
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self, device_id, name, status, units=None):
|
||||
self._id = device_id
|
||||
@ -64,6 +82,6 @@ class ISYSensorDevice(ISYDeviceABC):
|
||||
|
||||
_domain = 'sensor'
|
||||
|
||||
def __init__(self, node, states=[]):
|
||||
def __init__(self, node, states=None):
|
||||
super().__init__(node)
|
||||
self._states = states
|
||||
self._states = states or []
|
||||
|
@ -83,7 +83,7 @@ class Entity(object):
|
||||
|
||||
hass = None
|
||||
entity_id = None
|
||||
_visibility = {}
|
||||
visibility = {}
|
||||
|
||||
def update_ha_state(self, force_refresh=False):
|
||||
"""
|
||||
@ -138,8 +138,8 @@ class Entity(object):
|
||||
whatever the component sets for visibility.
|
||||
"""
|
||||
if self.entity_id is not None and \
|
||||
self.entity_id.lower() in self._visibility:
|
||||
return self._visibility[self.entity_id.lower()] == 'hide'
|
||||
self.entity_id.lower() in self.visibility:
|
||||
return self.visibility[self.entity_id.lower()] == 'hide'
|
||||
else:
|
||||
return self._hidden
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user