diff --git a/homeassistant/components/zwave.py b/homeassistant/components/zwave.py index a46918353ec..1f22f21fa36 100644 --- a/homeassistant/components/zwave.py +++ b/homeassistant/components/zwave.py @@ -10,12 +10,12 @@ import sys import os.path from pprint import pprint -from homeassistant.util import slugify +from homeassistant.util import slugify, convert from homeassistant import bootstrap from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED, - ATTR_BATTERY_LEVEL, ATTR_LOCATION) + ATTR_BATTERY_LEVEL, ATTR_LOCATION, ATTR_ENTITY_ID, CONF_CUSTOMIZE) DOMAIN = "zwave" @@ -25,6 +25,7 @@ CONF_USB_STICK_PATH = "usb_path" DEFAULT_CONF_USB_STICK_PATH = "/zwaveusbstick" CONF_DEBUG = "debug" CONF_POLLING_INTERVAL = "polling_interval" +CONF_POLLING_INTENSITY = "polling_intensity" DEFAULT_ZWAVE_CONFIG_PATH = os.path.join(sys.prefix, 'share', 'python-openzwave', 'config') @@ -35,6 +36,8 @@ DISCOVER_SENSORS = "zwave.sensors" DISCOVER_SWITCHES = "zwave.switch" DISCOVER_LIGHTS = "zwave.light" +EVENT_SCENE_ACTIVATED = "zwave.scene_activated" + COMMAND_CLASS_SWITCH_MULTILEVEL = 38 COMMAND_CLASS_SWITCH_BINARY = 37 @@ -78,6 +81,8 @@ DISCOVERY_COMPONENTS = [ ATTR_NODE_ID = "node_id" ATTR_VALUE_ID = "value_id" +ATTR_SCENE_ID = "scene_id" + NETWORK = None @@ -88,6 +93,32 @@ def _obj_to_dict(obj): if key[0] != '_' and not hasattr(getattr(obj, key), '__call__')} +def _node_name(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. """ + return "{} {}".format(_node_name(value.node), value.label) + + +def _object_id(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""" + + object_id = "{}_{}".format(slugify(_value_name(value)), + value.node.node_id) + + # Add the instance id if there is more than one instance for the value + if value.instance > 1: + return "{}_{}".format(object_id, value.instance) + + return object_id + + def nice_print_node(node): """ Prints a nice formatted node to the output (debug method). """ node_dict = _obj_to_dict(node) @@ -126,7 +157,9 @@ def setup(hass, config): from openzwave.option import ZWaveOption from openzwave.network import ZWaveNetwork + # Load configuration use_debug = str(config[DOMAIN].get(CONF_DEBUG)) == '1' + customize = config[DOMAIN].get(CONF_CUSTOMIZE, {}) # Setup options options = ZWaveOption( @@ -148,6 +181,7 @@ def setup(hass, config): if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED, ZWaveNetwork.SIGNAL_VALUE_ADDED): pprint(_obj_to_dict(value)) + print("") dispatcher.connect(log_all, weak=False) @@ -171,6 +205,15 @@ def setup(hass, config): # Ensure component is loaded bootstrap.setup_component(hass, component, config) + # Configure node + name = "{}.{}".format(component, _object_id(value)) + + node_config = customize.get(name, {}) + polling_intensity = convert( + node_config.get(CONF_POLLING_INTENSITY), int) + if polling_intensity is not None: + value.enable_poll(polling_intensity) + # Fire discovery event hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { ATTR_SERVICE: discovery_service, @@ -180,8 +223,20 @@ def setup(hass, config): } }) + def scene_activated(node, scene_id): + """ Called when a scene is activated on any node in the network. """ + name = _node_name(node) + object_id = "{}_{}".format(slugify(name), node.node_id) + + hass.bus.fire(EVENT_SCENE_ACTIVATED, { + ATTR_ENTITY_ID: object_id, + ATTR_SCENE_ID: scene_id + }) + dispatcher.connect( value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False) + dispatcher.connect( + scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False) def add_node(event): """ Switch into inclusion mode """ @@ -199,9 +254,10 @@ def setup(hass, config): """ Called when Home Assistant starts up. """ NETWORK.start() - polling_interval = config[DOMAIN].get(CONF_POLLING_INTERVAL, None) + polling_interval = convert( + config[DOMAIN].get(CONF_POLLING_INTERVAL), int) if polling_interval is not None: - NETWORK.setPollInterval(polling_interval) + NETWORK.set_poll_interval(polling_interval, False) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave) @@ -235,24 +291,14 @@ class ZWaveDeviceEntity: @property def name(self): """ Returns the name of the device. """ - name = self._value.node.name or "{} {}".format( - self._value.node.manufacturer_name, self._value.node.product_name) - - return "{} {}".format(name, self._value.label) + 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""" - object_id = "{}_{}".format(slugify(self.name), - self._value.node.node_id) - - # Add the instance id if there is more than one instance for the value - if self._value.instance > 1: - return "{}_{}".format(object_id, self._value.instance) - - return object_id + return _object_id(self._value) @property def state_attributes(self):