Ejemplo n.º 1
0
def setup(hass, config):
    """Setup the history hooks."""
    hass.wsgi.register_view(Last5StatesView)
    hass.wsgi.register_view(HistoryPeriodView)
    register_built_in_panel(hass, 'history', 'History', 'mdi:poll-box')

    return True
Ejemplo n.º 2
0
def setup(hass, config):
    """Setup the history hooks."""
    hass.wsgi.register_view(Last5StatesView)
    hass.wsgi.register_view(HistoryPeriodView)
    register_built_in_panel(hass, "history", "History", "mdi:poll-box")

    return True
Ejemplo n.º 3
0
def setup(hass, config):
    """Set up the iFrame frontend panels."""
    for url_path, info in config[DOMAIN].items():
        register_built_in_panel(
            hass, 'iframe', info.get(CONF_TITLE), info.get(CONF_ICON),
            url_path, {'url': info[CONF_URL]})

    return True
Ejemplo n.º 4
0
def setup(hass, config):
    """Set up the iFrame frontend panels."""
    for url_path, info in config[DOMAIN].items():
        register_built_in_panel(hass, 'iframe', info.get(CONF_TITLE),
                                info.get(CONF_ICON), url_path,
                                {'url': info[CONF_URL]})

    return True
def test_get_panels(hass, websocket_client):
    """Test get_panels command."""
    frontend.register_built_in_panel(hass, 'map', 'Map',
                                     'mdi:account-location')

    websocket_client.send_json({
        'id': 5,
        'type': wapi.TYPE_GET_PANELS,
    })

    msg = yield from websocket_client.receive_json()
    assert msg['id'] == 5
    assert msg['type'] == wapi.TYPE_RESULT
    assert msg['success']
    assert msg['result'] == hass.data[frontend.DATA_PANELS]
Ejemplo n.º 6
0
def test_get_panels(hass, websocket_client):
    """Test get_panels command."""
    frontend.register_built_in_panel(hass, 'map', 'Map',
                                     'mdi:account-location')

    websocket_client.send_json({
        'id': 5,
        'type': wapi.TYPE_GET_PANELS,
    })

    msg = yield from websocket_client.receive_json()
    assert msg['id'] == 5
    assert msg['type'] == wapi.TYPE_RESULT
    assert msg['success']
    assert msg['result'] == hass.data[frontend.DATA_PANELS]
Ejemplo n.º 7
0
def setup(hass, config):
    """Setup the history hooks."""
    filters = Filters()
    exclude = config[DOMAIN].get(CONF_EXCLUDE)
    if exclude:
        filters.excluded_entities = exclude[CONF_ENTITIES]
        filters.excluded_domains = exclude[CONF_DOMAINS]
    include = config[DOMAIN].get(CONF_INCLUDE)
    if include:
        filters.included_entities = include[CONF_ENTITIES]
        filters.included_domains = include[CONF_DOMAINS]

    hass.http.register_view(HistoryPeriodView(filters))
    register_built_in_panel(hass, 'history', 'History', 'mdi:poll-box')

    return True
Ejemplo n.º 8
0
def setup(hass, config):
    """Set up the history hooks."""
    filters = Filters()
    exclude = config[DOMAIN].get(CONF_EXCLUDE)
    if exclude:
        filters.excluded_entities = exclude[CONF_ENTITIES]
        filters.excluded_domains = exclude[CONF_DOMAINS]
    include = config[DOMAIN].get(CONF_INCLUDE)
    if include:
        filters.included_entities = include[CONF_ENTITIES]
        filters.included_domains = include[CONF_DOMAINS]

    hass.http.register_view(HistoryPeriodView(filters))
    register_built_in_panel(hass, 'history', 'History', 'mdi:poll-box')

    return True
Ejemplo n.º 9
0
def async_setup(hass, config):
    """Set up the HASSio component."""
    try:
        host = os.environ['HASSIO']
    except KeyError:
        _LOGGER.error("No HassIO supervisor detect!")
        return False

    websession = async_get_clientsession(hass)
    hassio = HassIO(hass.loop, websession, host)

    if not (yield from hassio.is_connected()):
        _LOGGER.error("Not connected with HassIO!")
        return False

    hass.http.register_view(HassIOView(hassio))

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'hassio', 'Hass.io',
                                'mdi:access-point-network')

    if 'http' in config:
        yield from hassio.update_hass_api(config.get('http'))

    @asyncio.coroutine
    def async_service_handler(service):
        """Handle service calls for HassIO."""
        api_command = MAP_SERVICE_API[service.service][0]
        addon = service.data[ATTR_ADDON]
        data = service.data[ATTR_INPUT] if ATTR_INPUT in service.data else None

        yield from hassio.send_command(api_command.format(addon=addon),
                                       payload=data,
                                       timeout=60)

    for service, settings in MAP_SERVICE_API.items():
        hass.services.async_register(DOMAIN,
                                     service,
                                     async_service_handler,
                                     schema=settings[1])

    return True
Ejemplo n.º 10
0
def async_setup(hass, config):
    """Set up the HASSio component."""
    try:
        host = os.environ['HASSIO']
    except KeyError:
        _LOGGER.error("No HassIO supervisor detect!")
        return False

    websession = async_get_clientsession(hass)
    hassio = HassIO(hass.loop, websession, host)

    if not (yield from hassio.is_connected()):
        _LOGGER.error("Not connected with HassIO!")
        return False

    hass.http.register_view(HassIOView(hassio))

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'hassio', 'Hass.io',
                                'mdi:access-point-network')

    if 'http' in config:
        yield from hassio.update_hass_api(config['http'])

    if 'homeassistant' in config:
        yield from hassio.update_hass_timezone(config['homeassistant'])

    @asyncio.coroutine
    def async_service_handler(service):
        """Handle service calls for HassIO."""
        api_command = MAP_SERVICE_API[service.service][0]
        addon = service.data.get(ATTR_ADDON)
        data = service.data[ATTR_INPUT] if ATTR_INPUT in service.data else None

        yield from hassio.send_command(
            api_command.format(addon=addon), payload=data, timeout=60)

    for service, settings in MAP_SERVICE_API.items():
        hass.services.async_register(
            DOMAIN, service, async_service_handler, schema=settings[1])

    return True
Ejemplo n.º 11
0
def setup(hass, config):
    """Listen for download events to download files."""
    def log_message(service):
        """Handle sending notification message service calls."""
        message = service.data[ATTR_MESSAGE]
        name = service.data[ATTR_NAME]
        domain = service.data.get(ATTR_DOMAIN)
        entity_id = service.data.get(ATTR_ENTITY_ID)

        message = template.render(hass, message)
        log_entry(hass, name, message, domain, entity_id)

    hass.wsgi.register_view(LogbookView)

    register_built_in_panel(hass, 'logbook', 'Logbook',
                            'mdi:format-list-bulleted-type')

    hass.services.register(DOMAIN, 'log', log_message,
                           schema=LOG_MESSAGE_SCHEMA)
    return True
Ejemplo n.º 12
0
def setup(hass, config):
    """Listen for download events to download files."""
    def log_message(service):
        """Handle sending notification message service calls."""
        message = service.data[ATTR_MESSAGE]
        name = service.data[ATTR_NAME]
        domain = service.data.get(ATTR_DOMAIN)
        entity_id = service.data.get(ATTR_ENTITY_ID)

        message = template.render(hass, message)
        log_entry(hass, name, message, domain, entity_id)

    hass.wsgi.register_view(LogbookView)

    register_built_in_panel(hass, 'logbook', 'Logbook',
                            'mdi:format-list-bulleted-type')

    hass.services.register(DOMAIN, 'log', log_message,
                           schema=LOG_MESSAGE_SCHEMA)
    return True
Ejemplo n.º 13
0
def async_setup(hass, config):
    """Setup the config component."""
    register_built_in_panel(hass, 'config', 'Configuration', 'mdi:settings')

    @asyncio.coroutine
    def setup_panel(panel_name):
        """Setup a panel."""
        panel = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, panel_name)

        if not panel:
            return

        success = yield from panel.async_setup(hass)

        if success:
            key = '{}.{}'.format(DOMAIN, panel_name)
            hass.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: key})
            hass.config.components.add(key)

    tasks = [setup_panel(panel_name) for panel_name in SECTIONS]

    for panel_name in ON_DEMAND:
        if panel_name in hass.config.components:
            tasks.append(setup_panel(panel_name))

    if tasks:
        yield from asyncio.wait(tasks, loop=hass.loop)

    @callback
    def component_loaded(event):
        """Respond to components being loaded."""
        panel_name = event.data.get(ATTR_COMPONENT)
        if panel_name in ON_DEMAND:
            hass.async_add_job(setup_panel(panel_name))

    hass.bus.async_listen(EVENT_COMPONENT_LOADED, component_loaded)

    return True
Ejemplo n.º 14
0
def async_setup(hass, config):
    """Setup the config component."""
    register_built_in_panel(hass, 'config', 'Configuration', 'mdi:settings')

    @asyncio.coroutine
    def setup_panel(panel_name):
        """Setup a panel."""
        panel = yield from async_prepare_setup_platform(hass, config, DOMAIN,
                                                        panel_name)

        if not panel:
            return

        success = yield from panel.async_setup(hass)

        if success:
            key = '{}.{}'.format(DOMAIN, panel_name)
            hass.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: key})
            hass.config.components.add(key)

    tasks = [setup_panel(panel_name) for panel_name in SECTIONS]

    for panel_name in ON_DEMAND:
        if panel_name in hass.config.components:
            tasks.append(setup_panel(panel_name))

    if tasks:
        yield from asyncio.wait(tasks, loop=hass.loop)

    @callback
    def component_loaded(event):
        """Respond to components being loaded."""
        panel_name = event.data.get(ATTR_COMPONENT)
        if panel_name in ON_DEMAND:
            hass.async_add_job(setup_panel(panel_name))

    hass.bus.async_listen(EVENT_COMPONENT_LOADED, component_loaded)

    return True
Ejemplo n.º 15
0
def async_setup(hass, config):
    """Set up the HASSio component."""
    try:
        host = os.environ['HASSIO']
    except KeyError:
        _LOGGER.error("No HassIO supervisor detect!")
        return False

    websession = async_get_clientsession(hass)
    hassio = HassIO(hass.loop, websession, host)

    api_ok = yield from hassio.is_connected()
    if not api_ok:
        _LOGGER.error("Not connected with HassIO!")
        return False

    hass.http.register_view(HassIOView(hassio))

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'hassio', 'Hass.io',
                                'mdi:access-point-network')

    return True
Ejemplo n.º 16
0
def async_setup(hass, config):
    """Setup the hassio component."""
    try:
        host = os.environ['HASSIO']
    except KeyError:
        _LOGGER.error("No HassIO supervisor detect!")
        return False

    websession = async_get_clientsession(hass)
    hassio = HassIO(hass.loop, websession, host)

    api_ok = yield from hassio.is_connected()
    if not api_ok:
        _LOGGER.error("Not connected with HassIO!")
        return False

    hass.http.register_view(HassIOView(hassio))

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'hassio', 'Hass.io',
                                'mdi:access-point-network')

    return True
Ejemplo n.º 17
0
def setup(hass, config):
    """Set up Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    descriptions = conf_util.load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    from pydispatch import dispatcher
    # pylint: disable=import-error
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    # Load configuration
    use_debug = config[DOMAIN].get(CONF_DEBUG)
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL)
    device_config = EntityValues(
        config[DOMAIN][CONF_DEVICE_CONFIG],
        config[DOMAIN][CONF_DEVICE_CONFIG_DOMAIN],
        config[DOMAIN][CONF_DEVICE_CONFIG_GLOB])

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get(CONF_CONFIG_PATH))

    options.set_console_output(use_debug)

    if CONF_NETWORK_KEY in config[DOMAIN]:
        options.addOption("NetworkKey", config[DOMAIN][CONF_NETWORK_KEY])

    options.lock()

    network = hass.data[DATA_NETWORK] = ZWaveNetwork(options, autostart=False)
    hass.data[DATA_DEVICES] = {}
    hass.data[DATA_ENTITY_VALUES] = []

    if use_debug:  # pragma: no cover
        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Handle new added value to a node on the network."""
        # Check if this value should be tracked by an existing entity
        for values in hass.data[DATA_ENTITY_VALUES]:
            values.check_value(value)

        for schema in DISCOVERY_SCHEMAS:
            if not check_node_schema(node, schema):
                continue
            if not check_value_schema(
                    value,
                    schema[const.DISC_VALUES][const.DISC_PRIMARY]):
                continue

            values = ZWaveDeviceEntityValues(
                hass, schema, value, config, device_config)

            # We create a new list and update the reference here so that
            # the list can be safely iterated over in the main thread
            new_values = hass.data[DATA_ENTITY_VALUES] + [values]
            hass.data[DATA_ENTITY_VALUES] = new_values

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    def node_added(node):
        """Handle a new node on the network."""
        entity = ZWaveNodeEntity(node, network)
        node_config = device_config.get(entity.entity_id)
        if node_config.get(CONF_IGNORED):
            _LOGGER.info(
                "Ignoring node entity %s due to device settings",
                entity.entity_id)
            return
        component.add_entities([entity])

    def scene_activated(node, scene_id):
        """Handle an activated scene on any node in the network."""
        hass.bus.fire(const.EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: _node_object_id(node),
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_SCENE_ID: scene_id
        })

    def node_event_activated(node, value):
        """Handle a nodeevent on any node in the network."""
        hass.bus.fire(const.EVENT_NODE_EVENT, {
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_BASIC_LEVEL: value
        })

    def network_ready():
        """Handle the query of all awake nodes."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes "
                     "have been queried. Sleeping nodes will be "
                     "queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Handle the querying of all nodes on network."""
        _LOGGER.info("Z-Wave network is complete. All nodes on the network "
                     "have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
    dispatcher.connect(
        scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
    dispatcher.connect(
        node_event_activated, ZWaveNetwork.SIGNAL_NODE_EVENT, weak=False)
    dispatcher.connect(
        network_ready, ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED, weak=False)
    dispatcher.connect(
        network_complete, ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED, weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Z-Wave add_node have been initialized")
        network.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Z-Wave add_node_secure have been initialized")
        network.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Z-Wwave remove_node have been initialized")
        network.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running Z-Wave command")
        network.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("Z-Wave heal running")
        network.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Z-Wave soft_reset have been initialized")
        network.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Z-Wave test_network have been initialized")
        network.test()

    def stop_network(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping Z-Wave network")
        network.stop()
        if hass.state == CoreState.running:
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info(
            "Renamed Z-Wave node %d to %s", node_id, name)

    def rename_value(service):
        """Rename a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        name = service.data.get(const.ATTR_NAME)
        value.label = name
        _LOGGER.info(
            "Renamed Z-Wave value (Node %d Value %d) to %s",
            node_id, value_id, name)

    def remove_failed_node(service):
        """Remove failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to remove zwave node %d", node_id)
        network.controller.remove_failed_node(node_id)

    def replace_failed_node(service):
        """Replace failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to replace zwave node %d", node_id)
        network.controller.replace_failed_node(node_id)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE)
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION)
                .values()):
            if value.index != param:
                continue
            if value.type in [const.TYPE_LIST, const.TYPE_BOOL]:
                value.data = selection
                _LOGGER.info("Setting config list parameter %s on Node %s "
                             "with selection %s", param, node_id,
                             selection)
                return
            else:
                value.data = int(selection)
                _LOGGER.info("Setting config parameter %s on Node %s "
                             "with selection %s", param, node_id,
                             selection)
                return
        node.set_config_param(param, selection, size)
        _LOGGER.info("Setting unknown config parameter %s on Node %s "
                     "with selection %s", param, node_id,
                     selection)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info("Config parameter %s on Node %s: %s",
                     param, node_id, get_config_value(node, param))

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, network, node_id)
        if association_type == 'add':
            node.add_association(target_node_id, instance)
            _LOGGER.info("Adding association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)
        if association_type == 'remove':
            node.remove_association(target_node_id, instance)
            _LOGGER.info("Removing association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)

    @asyncio.coroutine
    def async_refresh_entity(service):
        """Refresh values that specific entity depends on."""
        entity_id = service.data.get(ATTR_ENTITY_ID)
        async_dispatcher_send(
            hass, SIGNAL_REFRESH_ENTITY_FORMAT.format(entity_id))

    def refresh_node(service):
        """Refresh all node info."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        node.refresh_info()

    def reset_node_meters(service):
        """Reset meter counters of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        instance = service.data.get(const.ATTR_INSTANCE)
        node = network.nodes[node_id]
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_METER)
                .values()):
            if value.index != const.METER_RESET_INDEX:
                continue
            if value.instance != instance:
                continue
            network.manager.pressButton(value.value_id)
            network.manager.releaseButton(value.value_id)
            _LOGGER.info("Resetting meters on node %s instance %s....",
                         node_id, instance)
            return
        _LOGGER.info("Node %s on instance %s does not have resettable "
                     "meters.", node_id, instance)

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting Z-Wave network...")
        network.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(const.NETWORK_READY_WAIT_SECS):
            _LOGGER.debug(
                "network state: %d %s", network.state,
                network.state_str)
            if network.state >= network.STATE_AWAKED:
                _LOGGER.info("Z-Wave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                const.NETWORK_READY_WAIT_SECS)
            _LOGGER.info(
                "final network state: %d %s", network.state,
                network.state_str)

        polling_interval = convert(
            config[DOMAIN].get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            network.set_poll_interval(polling_interval, False)

        poll_interval = network.get_poll_interval()
        _LOGGER.info("Z-Wave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
                               descriptions[const.SERVICE_ADD_NODE])
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure,
                               descriptions[const.SERVICE_ADD_NODE_SECURE])
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
                               descriptions[const.SERVICE_REMOVE_NODE])
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command,
                               descriptions[const.SERVICE_CANCEL_COMMAND])
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network,
                               descriptions[const.SERVICE_HEAL_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
                               descriptions[const.SERVICE_SOFT_RESET])
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network,
                               descriptions[const.SERVICE_TEST_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
                               stop_network,
                               descriptions[const.SERVICE_STOP_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
                               start_zwave,
                               descriptions[const.SERVICE_START_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node,
                               descriptions[const.SERVICE_RENAME_NODE],
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_RENAME_VALUE,
                               rename_value,
                               descriptions[const.SERVICE_RENAME_VALUE],
                               schema=RENAME_VALUE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
                               set_config_parameter,
                               descriptions[
                                   const.SERVICE_SET_CONFIG_PARAMETER],
                               schema=SET_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_CONFIG_PARAMETER,
                               print_config_parameter,
                               descriptions[
                                   const.SERVICE_PRINT_CONFIG_PARAMETER],
                               schema=PRINT_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_FAILED_NODE,
                               remove_failed_node,
                               descriptions[const.SERVICE_REMOVE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REPLACE_FAILED_NODE,
                               replace_failed_node,
                               descriptions[const.SERVICE_REPLACE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)

        hass.services.register(DOMAIN, const.SERVICE_CHANGE_ASSOCIATION,
                               change_association,
                               descriptions[
                                   const.SERVICE_CHANGE_ASSOCIATION],
                               schema=CHANGE_ASSOCIATION_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               descriptions[
                                   const.SERVICE_SET_WAKEUP],
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_NODE,
                               print_node,
                               descriptions[
                                   const.SERVICE_PRINT_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_ENTITY,
                               async_refresh_entity,
                               descriptions[
                                   const.SERVICE_REFRESH_ENTITY],
                               schema=REFRESH_ENTITY_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_NODE,
                               refresh_node,
                               descriptions[
                                   const.SERVICE_REFRESH_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_RESET_NODE_METERS,
                               reset_node_meters,
                               descriptions[
                                   const.SERVICE_RESET_NODE_METERS],
                               schema=RESET_NODE_METERS_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("Z-Wave network autoheal is enabled")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc')
        hass.http.register_view(api.ZWaveNodeValueView)
        hass.http.register_view(api.ZWaveNodeGroupView)
        hass.http.register_view(api.ZWaveNodeConfigView)
        hass.http.register_view(api.ZWaveUserCodeView)
        hass.http.register_static_path(
            URL_API_OZW_LOG, hass.config.path(OZW_LOG_FILENAME), False)

    return True
Ejemplo n.º 18
0
def setup(hass, config):
    """Setup Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    descriptions = conf_util.load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    try:
        import libopenzwave
    except ImportError:
        _LOGGER.error("You are missing required dependency Python Open "
                      "Z-Wave. Please follow instructions at: "
                      "https://home-assistant.io/components/zwave/")
        return False
    from pydispatch import dispatcher
    # pylint: disable=import-error
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    default_zwave_config_path = os.path.join(os.path.dirname(
        libopenzwave.__file__), 'config')

    # Load configuration
    use_debug = config[DOMAIN].get(CONF_DEBUG)
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL)
    device_config = EntityValues(
        config[DOMAIN][CONF_DEVICE_CONFIG],
        config[DOMAIN][CONF_DEVICE_CONFIG_DOMAIN],
        config[DOMAIN][CONF_DEVICE_CONFIG_GLOB])

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get(
            CONF_CONFIG_PATH, default_zwave_config_path))

    options.set_console_output(use_debug)
    options.lock()

    network = hass.data[ZWAVE_NETWORK] = ZWaveNetwork(options, autostart=False)
    hass.data[DATA_ZWAVE_DICT] = {}

    if use_debug:  # pragma: no cover
        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    discovered_values = []

    def value_added(node, value):
        """Called when a value is added to a node on the network."""
        # Check if this value should be tracked by an existing entity
        for values in discovered_values:
            values.check_value(value)

        for schema in DISCOVERY_SCHEMAS:
            if not check_node_schema(node, schema):
                continue
            if not check_value_schema(
                    value,
                    schema[const.DISC_VALUES][const.DISC_PRIMARY]):
                continue

            values = ZWaveDeviceEntityValues(
                hass, schema, value, config, device_config)
            discovered_values.append(values)

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    def node_added(node):
        """Called when a node is added on the network."""
        entity = ZWaveNodeEntity(node, network)
        node_config = device_config.get(entity.entity_id)
        if node_config.get(CONF_IGNORED):
            _LOGGER.info(
                "Ignoring node entity %s due to device settings.",
                entity.entity_id)
            return
        component.add_entities([entity])

    def scene_activated(node, scene_id):
        """Called when a scene is activated on any node in the network."""
        hass.bus.fire(const.EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: _node_object_id(node),
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_SCENE_ID: scene_id
        })

    def node_event_activated(node, value):
        """Called when a nodeevent is activated on any node in the network."""
        hass.bus.fire(const.EVENT_NODE_EVENT, {
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_BASIC_LEVEL: value
        })

    def network_ready():
        """Called when all awake nodes have been queried."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes"
                     " have been queried. Sleeping nodes will be"
                     " queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Called when all nodes on network have been queried."""
        _LOGGER.info("Zwave network is complete. All nodes on the network"
                     " have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
    dispatcher.connect(
        scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
    dispatcher.connect(
        node_event_activated, ZWaveNetwork.SIGNAL_NODE_EVENT, weak=False)
    dispatcher.connect(
        network_ready, ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED, weak=False)
    dispatcher.connect(
        network_complete, ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED, weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Zwave add_node have been initialized.")
        network.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Zwave add_node_secure have been initialized.")
        network.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Zwave remove_node have been initialized.")
        network.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running ZWave command.")
        network.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("ZWave heal running.")
        network.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Zwave soft_reset have been initialized.")
        network.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Zwave test_network have been initialized.")
        network.test()

    def stop_network(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping ZWave network.")
        network.stop()
        if hass.state == CoreState.running:
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = hass.data[ZWAVE_NETWORK].nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info(
            "Renamed ZWave node %d to %s", node_id, name)

    def remove_failed_node(service):
        """Remove failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info('Trying to remove zwave node %d', node_id)
        network.controller.remove_failed_node(node_id)

    def replace_failed_node(service):
        """Replace failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info('Trying to replace zwave node %d', node_id)
        network.controller.replace_failed_node(node_id)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE, 2)
        i = 0
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION)
                .values()):
            if value.index == param and value.type == const.TYPE_LIST:
                _LOGGER.debug('Values for parameter %s: %s', param,
                              value.data_items)
                i = len(value.data_items) - 1
        if i == 0:
            node.set_config_param(param, selection, size)
        else:
            if selection > i:
                _LOGGER.info('Config parameter selection does not exist!'
                             ' Please check zwcfg_[home_id].xml in'
                             ' your homeassistant config directory. '
                             ' Available selections are 0 to %s', i)
                return
            node.set_config_param(param, selection, size)
            _LOGGER.info('Setting config parameter %s on Node %s '
                         'with selection %s and size=%s', param, node_id,
                         selection, size)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info("Config parameter %s on Node %s : %s",
                     param, node_id, get_config_value(node, param))

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, network, node_id)
        if association_type == 'add':
            node.add_association(target_node_id, instance)
            _LOGGER.info("Adding association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)
        if association_type == 'remove':
            node.remove_association(target_node_id, instance)
            _LOGGER.info("Removing association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)

    @asyncio.coroutine
    def async_refresh_entity(service):
        """Refresh values that specific entity depends on."""
        entity_id = service.data.get(ATTR_ENTITY_ID)
        async_dispatcher_send(
            hass, SIGNAL_REFRESH_ENTITY_FORMAT.format(entity_id))

    def refresh_node(service):
        """Refresh all node info."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        node.refresh_info()

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting ZWave network.")
        network.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(const.NETWORK_READY_WAIT_SECS):
            _LOGGER.debug(
                "network state: %d %s", hass.data[ZWAVE_NETWORK].state,
                network.state_str)
            if network.state >= network.STATE_AWAKED:
                _LOGGER.info("zwave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                const.NETWORK_READY_WAIT_SECS)
            _LOGGER.info(
                "final network state: %d %s", network.state,
                network.state_str)

        polling_interval = convert(
            config[DOMAIN].get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            network.set_poll_interval(polling_interval, False)

        poll_interval = network.get_poll_interval()
        _LOGGER.info("zwave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
                               descriptions[const.SERVICE_ADD_NODE])
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure,
                               descriptions[const.SERVICE_ADD_NODE_SECURE])
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
                               descriptions[const.SERVICE_REMOVE_NODE])
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command,
                               descriptions[const.SERVICE_CANCEL_COMMAND])
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network,
                               descriptions[const.SERVICE_HEAL_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
                               descriptions[const.SERVICE_SOFT_RESET])
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network,
                               descriptions[const.SERVICE_TEST_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
                               stop_network,
                               descriptions[const.SERVICE_STOP_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
                               start_zwave,
                               descriptions[const.SERVICE_START_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node,
                               descriptions[const.SERVICE_RENAME_NODE],
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
                               set_config_parameter,
                               descriptions[
                                   const.SERVICE_SET_CONFIG_PARAMETER],
                               schema=SET_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_CONFIG_PARAMETER,
                               print_config_parameter,
                               descriptions[
                                   const.SERVICE_PRINT_CONFIG_PARAMETER],
                               schema=PRINT_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_FAILED_NODE,
                               remove_failed_node,
                               descriptions[const.SERVICE_REMOVE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REPLACE_FAILED_NODE,
                               replace_failed_node,
                               descriptions[const.SERVICE_REPLACE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)

        hass.services.register(DOMAIN, const.SERVICE_CHANGE_ASSOCIATION,
                               change_association,
                               descriptions[
                                   const.SERVICE_CHANGE_ASSOCIATION],
                               schema=CHANGE_ASSOCIATION_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               descriptions[
                                   const.SERVICE_SET_WAKEUP],
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_NODE,
                               print_node,
                               descriptions[
                                   const.SERVICE_PRINT_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_ENTITY,
                               async_refresh_entity,
                               descriptions[
                                   const.SERVICE_REFRESH_ENTITY],
                               schema=REFRESH_ENTITY_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_NODE,
                               refresh_node,
                               descriptions[
                                   const.SERVICE_REFRESH_NODE],
                               schema=NODE_SERVICE_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("ZWave network autoheal is enabled.")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc')

    return True
Ejemplo n.º 19
0
def setup(hass, config):
    """Setup Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    descriptions = conf_util.load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    try:
        import libopenzwave
    except ImportError:
        _LOGGER.error("You are missing required dependency Python Open "
                      "Z-Wave. Please follow instructions at: "
                      "https://home-assistant.io/components/zwave/")
        return False
    from pydispatch import dispatcher
    # pylint: disable=import-error
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    default_zwave_config_path = os.path.join(
        os.path.dirname(libopenzwave.__file__), 'config')

    # Load configuration
    use_debug = config[DOMAIN].get(CONF_DEBUG)
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL)
    device_config = EntityValues(config[DOMAIN][CONF_DEVICE_CONFIG],
                                 config[DOMAIN][CONF_DEVICE_CONFIG_DOMAIN],
                                 config[DOMAIN][CONF_DEVICE_CONFIG_GLOB])

    # Setup options
    options = ZWaveOption(config[DOMAIN].get(CONF_USB_STICK_PATH),
                          user_path=hass.config.config_dir,
                          config_path=config[DOMAIN].get(
                              CONF_CONFIG_PATH, default_zwave_config_path))

    options.set_console_output(use_debug)
    options.lock()

    network = hass.data[ZWAVE_NETWORK] = ZWaveNetwork(options, autostart=False)
    hass.data[DATA_ZWAVE_DICT] = {}

    if use_debug:  # pragma: no cover

        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    discovered_values = []

    def value_added(node, value):
        """Called when a value is added to a node on the network."""
        # Check if this value should be tracked by an existing entity
        for values in discovered_values:
            values.check_value(value)

        for schema in DISCOVERY_SCHEMAS:
            if not check_node_schema(node, schema):
                continue
            if not check_value_schema(
                    value, schema[const.DISC_VALUES][const.DISC_PRIMARY]):
                continue

            values = ZWaveDeviceEntityValues(hass, schema, value, config,
                                             device_config)
            discovered_values.append(values)

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    def node_added(node):
        """Called when a node is added on the network."""
        entity = ZWaveNodeEntity(node, network)
        node_config = device_config.get(entity.entity_id)
        if node_config.get(CONF_IGNORED):
            _LOGGER.info("Ignoring node entity %s due to device settings.",
                         entity.entity_id)
            return
        component.add_entities([entity])

    def scene_activated(node, scene_id):
        """Called when a scene is activated on any node in the network."""
        hass.bus.fire(
            const.EVENT_SCENE_ACTIVATED, {
                ATTR_ENTITY_ID: _node_object_id(node),
                const.ATTR_OBJECT_ID: _node_object_id(node),
                const.ATTR_SCENE_ID: scene_id
            })

    def node_event_activated(node, value):
        """Called when a nodeevent is activated on any node in the network."""
        hass.bus.fire(
            const.EVENT_NODE_EVENT, {
                const.ATTR_OBJECT_ID: _node_object_id(node),
                const.ATTR_BASIC_LEVEL: value
            })

    def network_ready():
        """Called when all awake nodes have been queried."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes"
                     " have been queried. Sleeping nodes will be"
                     " queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Called when all nodes on network have been queried."""
        _LOGGER.info("Zwave network is complete. All nodes on the network"
                     " have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    dispatcher.connect(value_added,
                       ZWaveNetwork.SIGNAL_VALUE_ADDED,
                       weak=False)
    dispatcher.connect(node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
    dispatcher.connect(scene_activated,
                       ZWaveNetwork.SIGNAL_SCENE_EVENT,
                       weak=False)
    dispatcher.connect(node_event_activated,
                       ZWaveNetwork.SIGNAL_NODE_EVENT,
                       weak=False)
    dispatcher.connect(network_ready,
                       ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                       weak=False)
    dispatcher.connect(network_complete,
                       ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED,
                       weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Zwave add_node have been initialized.")
        network.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Zwave add_node_secure have been initialized.")
        network.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Zwave remove_node have been initialized.")
        network.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running ZWave command.")
        network.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("ZWave heal running.")
        network.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Zwave soft_reset have been initialized.")
        network.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Zwave test_network have been initialized.")
        network.test()

    def stop_network(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping ZWave network.")
        network.stop()
        if hass.state == CoreState.running:
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = hass.data[ZWAVE_NETWORK].nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info("Renamed ZWave node %d to %s", node_id, name)

    def remove_failed_node(service):
        """Remove failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info('Trying to remove zwave node %d', node_id)
        network.controller.remove_failed_node(node_id)

    def replace_failed_node(service):
        """Replace failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info('Trying to replace zwave node %d', node_id)
        network.controller.replace_failed_node(node_id)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE, 2)
        i = 0
        for value in (node.get_values(
                class_id=const.COMMAND_CLASS_CONFIGURATION).values()):
            if value.index == param and value.type == const.TYPE_LIST:
                _LOGGER.debug('Values for parameter %s: %s', param,
                              value.data_items)
                i = len(value.data_items) - 1
        if i == 0:
            node.set_config_param(param, selection, size)
        else:
            if selection > i:
                _LOGGER.info(
                    'Config parameter selection does not exist!'
                    ' Please check zwcfg_[home_id].xml in'
                    ' your homeassistant config directory. '
                    ' Available selections are 0 to %s', i)
                return
            node.set_config_param(param, selection, size)
            _LOGGER.info(
                'Setting config parameter %s on Node %s '
                'with selection %s and size=%s', param, node_id, selection,
                size)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info("Config parameter %s on Node %s : %s", param, node_id,
                     get_config_value(node, param))

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, network, node_id)
        if association_type == 'add':
            node.add_association(target_node_id, instance)
            _LOGGER.info(
                "Adding association for node:%s in group:%s "
                "target node:%s, instance=%s", node_id, group, target_node_id,
                instance)
        if association_type == 'remove':
            node.remove_association(target_node_id, instance)
            _LOGGER.info(
                "Removing association for node:%s in group:%s "
                "target node:%s, instance=%s", node_id, group, target_node_id,
                instance)

    @asyncio.coroutine
    def async_refresh_entity(service):
        """Refresh values that specific entity depends on."""
        entity_id = service.data.get(ATTR_ENTITY_ID)
        async_dispatcher_send(hass,
                              SIGNAL_REFRESH_ENTITY_FORMAT.format(entity_id))

    def refresh_node(service):
        """Refresh all node info."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        node.refresh_info()

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting ZWave network.")
        network.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(const.NETWORK_READY_WAIT_SECS):
            _LOGGER.debug("network state: %d %s",
                          hass.data[ZWAVE_NETWORK].state, network.state_str)
            if network.state >= network.STATE_AWAKED:
                _LOGGER.info("zwave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                const.NETWORK_READY_WAIT_SECS)
            _LOGGER.info("final network state: %d %s", network.state,
                         network.state_str)

        polling_interval = convert(config[DOMAIN].get(CONF_POLLING_INTERVAL),
                                   int)
        if polling_interval is not None:
            network.set_poll_interval(polling_interval, False)

        poll_interval = network.get_poll_interval()
        _LOGGER.info("zwave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
                               descriptions[const.SERVICE_ADD_NODE])
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure,
                               descriptions[const.SERVICE_ADD_NODE_SECURE])
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
                               descriptions[const.SERVICE_REMOVE_NODE])
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command,
                               descriptions[const.SERVICE_CANCEL_COMMAND])
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network,
                               descriptions[const.SERVICE_HEAL_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
                               descriptions[const.SERVICE_SOFT_RESET])
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network,
                               descriptions[const.SERVICE_TEST_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
                               stop_network,
                               descriptions[const.SERVICE_STOP_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
                               start_zwave,
                               descriptions[const.SERVICE_START_NETWORK])
        hass.services.register(DOMAIN,
                               const.SERVICE_RENAME_NODE,
                               rename_node,
                               descriptions[const.SERVICE_RENAME_NODE],
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(
            DOMAIN,
            const.SERVICE_SET_CONFIG_PARAMETER,
            set_config_parameter,
            descriptions[const.SERVICE_SET_CONFIG_PARAMETER],
            schema=SET_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(
            DOMAIN,
            const.SERVICE_PRINT_CONFIG_PARAMETER,
            print_config_parameter,
            descriptions[const.SERVICE_PRINT_CONFIG_PARAMETER],
            schema=PRINT_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REMOVE_FAILED_NODE,
                               remove_failed_node,
                               descriptions[const.SERVICE_REMOVE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REPLACE_FAILED_NODE,
                               replace_failed_node,
                               descriptions[const.SERVICE_REPLACE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)

        hass.services.register(DOMAIN,
                               const.SERVICE_CHANGE_ASSOCIATION,
                               change_association,
                               descriptions[const.SERVICE_CHANGE_ASSOCIATION],
                               schema=CHANGE_ASSOCIATION_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               descriptions[const.SERVICE_SET_WAKEUP],
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_PRINT_NODE,
                               print_node,
                               descriptions[const.SERVICE_PRINT_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REFRESH_ENTITY,
                               async_refresh_entity,
                               descriptions[const.SERVICE_REFRESH_ENTITY],
                               schema=REFRESH_ENTITY_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REFRESH_NODE,
                               refresh_node,
                               descriptions[const.SERVICE_REFRESH_NODE],
                               schema=NODE_SERVICE_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("ZWave network autoheal is enabled.")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc')

    return True
Ejemplo n.º 20
0
def async_setup(hass, config):
    """Register the built-in map panel."""
    register_built_in_panel(hass, 'map', 'Map', 'mdi:account-location')
    return True
Ejemplo n.º 21
0
def async_setup(hass, config):
    """Set up the automation."""
    component = EntityComponent(_LOGGER,
                                DOMAIN,
                                hass,
                                group_name=GROUP_NAME_ALL_AUTOMATIONS)

    yield from _async_process_config(hass, config, component)

    descriptions = yield from hass.async_add_job(
        conf_util.load_yaml_config_file,
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    @asyncio.coroutine
    def trigger_service_handler(service_call):
        """Handle automation triggers."""
        tasks = []
        for entity in component.async_extract_from_service(service_call):
            tasks.append(
                entity.async_trigger(service_call.data.get(ATTR_VARIABLES),
                                     True))

        if tasks:
            yield from asyncio.wait(tasks, loop=hass.loop)

    @asyncio.coroutine
    def turn_onoff_service_handler(service_call):
        """Handle automation turn on/off service calls."""
        tasks = []
        method = 'async_{}'.format(service_call.service)
        for entity in component.async_extract_from_service(service_call):
            tasks.append(getattr(entity, method)())

        if tasks:
            yield from asyncio.wait(tasks, loop=hass.loop)

    @asyncio.coroutine
    def toggle_service_handler(service_call):
        """Handle automation toggle service calls."""
        tasks = []
        for entity in component.async_extract_from_service(service_call):
            if entity.is_on:
                tasks.append(entity.async_turn_off())
            else:
                tasks.append(entity.async_turn_on())

        if tasks:
            yield from asyncio.wait(tasks, loop=hass.loop)

    @asyncio.coroutine
    def reload_service_handler(service_call):
        """Remove all automations and load new ones from config."""
        conf = yield from component.async_prepare_reload()
        if conf is None:
            return
        yield from _async_process_config(hass, conf, component)

    hass.services.async_register(DOMAIN,
                                 SERVICE_TRIGGER,
                                 trigger_service_handler,
                                 descriptions.get(SERVICE_TRIGGER),
                                 schema=TRIGGER_SERVICE_SCHEMA)

    hass.services.async_register(DOMAIN,
                                 SERVICE_RELOAD,
                                 reload_service_handler,
                                 descriptions.get(SERVICE_RELOAD),
                                 schema=RELOAD_SERVICE_SCHEMA)

    hass.services.async_register(DOMAIN,
                                 SERVICE_TOGGLE,
                                 toggle_service_handler,
                                 descriptions.get(SERVICE_TOGGLE),
                                 schema=SERVICE_SCHEMA)

    for service in (SERVICE_TURN_ON, SERVICE_TURN_OFF):
        hass.services.async_register(DOMAIN,
                                     service,
                                     turn_onoff_service_handler,
                                     descriptions.get(service),
                                     schema=SERVICE_SCHEMA)

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'automation', 'Automations',
                                'mdi:playlist-play')

    return True
Ejemplo n.º 22
0
def async_setup(hass, config):
    """Set up the automation."""
    component = EntityComponent(_LOGGER, DOMAIN, hass,
                                group_name=GROUP_NAME_ALL_AUTOMATIONS)

    yield from _async_process_config(hass, config, component)

    descriptions = yield from hass.async_add_job(
        conf_util.load_yaml_config_file, os.path.join(
            os.path.dirname(__file__), 'services.yaml')
    )

    @asyncio.coroutine
    def trigger_service_handler(service_call):
        """Handle automation triggers."""
        tasks = []
        for entity in component.async_extract_from_service(service_call):
            tasks.append(entity.async_trigger(
                service_call.data.get(ATTR_VARIABLES), True))

        if tasks:
            yield from asyncio.wait(tasks, loop=hass.loop)

    @asyncio.coroutine
    def turn_onoff_service_handler(service_call):
        """Handle automation turn on/off service calls."""
        tasks = []
        method = 'async_{}'.format(service_call.service)
        for entity in component.async_extract_from_service(service_call):
            tasks.append(getattr(entity, method)())

        if tasks:
            yield from asyncio.wait(tasks, loop=hass.loop)

    @asyncio.coroutine
    def toggle_service_handler(service_call):
        """Handle automation toggle service calls."""
        tasks = []
        for entity in component.async_extract_from_service(service_call):
            if entity.is_on:
                tasks.append(entity.async_turn_off())
            else:
                tasks.append(entity.async_turn_on())

        if tasks:
            yield from asyncio.wait(tasks, loop=hass.loop)

    @asyncio.coroutine
    def reload_service_handler(service_call):
        """Remove all automations and load new ones from config."""
        conf = yield from component.async_prepare_reload()
        if conf is None:
            return
        yield from _async_process_config(hass, conf, component)

    hass.services.async_register(
        DOMAIN, SERVICE_TRIGGER, trigger_service_handler,
        descriptions.get(SERVICE_TRIGGER), schema=TRIGGER_SERVICE_SCHEMA)

    hass.services.async_register(
        DOMAIN, SERVICE_RELOAD, reload_service_handler,
        descriptions.get(SERVICE_RELOAD), schema=RELOAD_SERVICE_SCHEMA)

    hass.services.async_register(
        DOMAIN, SERVICE_TOGGLE, toggle_service_handler,
        descriptions.get(SERVICE_TOGGLE), schema=SERVICE_SCHEMA)

    for service in (SERVICE_TURN_ON, SERVICE_TURN_OFF):
        hass.services.async_register(
            DOMAIN, service, turn_onoff_service_handler,
            descriptions.get(service), schema=SERVICE_SCHEMA)

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'automation', 'Automations',
                                'mdi:playlist-play')

    return True