Create entity for each sensor variable.

Refactors to create a separate entity for each variable associated with
a child sensor.
This commit is contained in:
Andrew Thigpen 2015-04-25 20:07:44 -05:00
parent dfbeddf1f7
commit 3cff05ef91
2 changed files with 66 additions and 36 deletions

View File

@ -17,10 +17,15 @@ import homeassistant.external.pymysensors.mysensors.const as const
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.const import ( from homeassistant.const import (
ATTR_BATTERY_LEVEL, EVENT_HOMEASSISTANT_STOP, TEMP_CELCIUS) ATTR_BATTERY_LEVEL, EVENT_HOMEASSISTANT_STOP,
TEMP_CELCIUS, TEMP_FAHRENHEIT,
STATE_ON, STATE_OFF)
CONF_PORT = "port" CONF_PORT = "port"
ATTR_NODE_ID = "node_id"
ATTR_CHILD_ID = "child_id"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -28,21 +33,38 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
""" Setup the mysensors platform. """ """ Setup the mysensors platform. """
devices = {} # keep track of devices added to HA devices = {} # keep track of devices added to HA
# Just assume celcius means that the user wants metric for now.
# It may make more sense to make this a global config option in the future.
is_metric = (hass.config.temperature_unit == TEMP_CELCIUS)
def sensor_update(update_type, nid): def sensor_update(update_type, nid):
""" Callback for sensor updates from the MySensors gateway. """ """ Callback for sensor updates from the MySensors gateway. """
_LOGGER.info("sensor_update %s: node %s", update_type, nid)
sensor = gateway.sensors[nid] sensor = gateway.sensors[nid]
if sensor.sketch_name is None: if sensor.sketch_name is None:
return return
if nid not in devices: if nid not in devices:
devices[nid] = MySensorsNode(sensor.sketch_name) devices[nid] = {}
add_devices([devices[nid]])
node = devices[nid] node = devices[nid]
node.battery_level = sensor.battery_level new_devices = []
for child_id, child in sensor.children.items(): for child_id, child in sensor.children.items():
node.update_child(child_id, child) if child_id not in node:
node.update_ha_state() node[child_id] = {}
for value_type, value in child.values.items():
if value_type not in node[child_id]:
name = '{} {}.{}'.format(sensor.sketch_name, nid, child.id)
node[child_id][value_type] = \
MySensorsNodeValue(
nid, child_id, name, value_type, is_metric)
new_devices.append(node[child_id][value_type])
else:
node[child_id][value_type].update_sensor(
value, sensor.battery_level)
if new_devices:
_LOGGER.info("adding new devices: %s", new_devices)
add_devices(new_devices)
port = config.get(CONF_PORT) port = config.get(CONF_PORT)
if port is None: if port is None:
@ -51,21 +73,23 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
gateway = mysensors.SerialGateway(port, sensor_update) gateway = mysensors.SerialGateway(port, sensor_update)
gateway.start() gateway.start()
gateway.metric = is_metric
# Just assume celcius means that the user wants metric for now.
# It may make more sense to make this a global config option in the future.
gateway.metric = (hass.config.temperature_unit == TEMP_CELCIUS)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP,
lambda event: gateway.stop()) lambda event: gateway.stop())
class MySensorsNode(Entity): class MySensorsNodeValue(Entity):
""" Represents a MySensors node. """ """ Represents the value of a MySensors child node. """
def __init__(self, name): # pylint: disable=too-many-arguments
def __init__(self, node_id, child_id, name, value_type, metric):
self._name = name self._name = name
self.node_id = node_id
self.child_id = child_id
self.battery_level = 0 self.battery_level = 0
self.children = {} self.value_type = value_type
self.metric = metric
self._value = ''
@property @property
def should_poll(self): def should_poll(self):
@ -80,29 +104,35 @@ class MySensorsNode(Entity):
@property @property
def state(self): def state(self):
""" Returns the state of the device. """ """ Returns the state of the device. """
return '' return self._value
@property
def unit_of_measurement(self):
""" Unit of measurement of this entity. """
if self.value_type == const.SetReq.V_TEMP:
return TEMP_CELCIUS if self.metric else TEMP_FAHRENHEIT
elif self.value_type == const.SetReq.V_HUM or \
self.value_type == const.SetReq.V_DIMMER or \
self.value_type == const.SetReq.V_LIGHT_LEVEL:
return '%'
return None
@property @property
def state_attributes(self): def state_attributes(self):
""" Returns the state attributes. """ """ Returns the state attributes. """
attrs = {} return {
attrs[ATTR_BATTERY_LEVEL] = self.battery_level ATTR_NODE_ID: self.node_id,
ATTR_CHILD_ID: self.child_id,
ATTR_BATTERY_LEVEL: self.battery_level,
}
for child in self.children.values(): def update_sensor(self, value, battery_level):
for value_type, value in child.values.items(): """ Update a sensor with the latest value from the controller. """
attrs[value_type] = value _LOGGER.info("%s value = %s", self._name, value)
return attrs if self.value_type == const.SetReq.V_TRIPPED or \
self.value_type == const.SetReq.V_ARMED:
def update_child(self, child_id, child): self._value = STATE_ON if int(value) == 1 else STATE_OFF
""" Sets the values of a child sensor. """ else:
self.children[child_id] = MySensorsChildSensor( self._value = value
const.Presentation(child.type).name, self.battery_level = battery_level
{const.SetReq(t).name: v for t, v in child.values.items()}) self.update_ha_state()
class MySensorsChildSensor():
""" Represents a MySensors child sensor. """
# pylint: disable=too-few-public-methods
def __init__(self, child_type, values):
self.type = child_type
self.values = values

@ -1 +1 @@
Subproject commit b3937f3ac15f47f57ed0cfb95709a77b7b7bed06 Subproject commit 75e0f505715b0cbf5a38e63749ea1d6ccf90773a