82 lines
2.9 KiB
Python
82 lines
2.9 KiB
Python
"""Helper functions for mysensors package."""
|
|
from collections import defaultdict
|
|
import logging
|
|
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.const import CONF_NAME
|
|
from homeassistant.core import callback
|
|
from homeassistant.helpers import discovery
|
|
import homeassistant.helpers.config_validation as cv
|
|
|
|
from .const import (
|
|
ATTR_DEVICES, DOMAIN, MYSENSORS_CONST_SCHEMA, PLATFORM, SCHEMA, TYPE)
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
@callback
|
|
def discover_mysensors_platform(hass, hass_config, platform, new_devices):
|
|
"""Discover a MySensors platform."""
|
|
task = hass.async_create_task(discovery.async_load_platform(
|
|
hass, platform, DOMAIN,
|
|
{ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN}, hass_config))
|
|
return task
|
|
|
|
|
|
def validate_child(gateway, node_id, child):
|
|
"""Validate that a child has the correct values according to schema.
|
|
|
|
Return a dict of platform with a list of device ids for validated devices.
|
|
"""
|
|
validated = defaultdict(list)
|
|
|
|
if not child.values:
|
|
_LOGGER.debug(
|
|
"No child values for node %s child %s", node_id, child.id)
|
|
return validated
|
|
if gateway.sensors[node_id].sketch_name is None:
|
|
_LOGGER.debug("Node %s is missing sketch name", node_id)
|
|
return validated
|
|
pres = gateway.const.Presentation
|
|
set_req = gateway.const.SetReq
|
|
s_name = next(
|
|
(member.name for member in pres if member.value == child.type), None)
|
|
if s_name not in MYSENSORS_CONST_SCHEMA:
|
|
_LOGGER.warning("Child type %s is not supported", s_name)
|
|
return validated
|
|
child_schemas = MYSENSORS_CONST_SCHEMA[s_name]
|
|
|
|
def msg(name):
|
|
"""Return a message for an invalid schema."""
|
|
return "{} requires value_type {}".format(
|
|
pres(child.type).name, set_req[name].name)
|
|
|
|
for schema in child_schemas:
|
|
platform = schema[PLATFORM]
|
|
v_name = schema[TYPE]
|
|
value_type = next(
|
|
(member.value for member in set_req if member.name == v_name),
|
|
None)
|
|
if value_type is None:
|
|
continue
|
|
_child_schema = child.get_schema(gateway.protocol_version)
|
|
vol_schema = _child_schema.extend(
|
|
{vol.Required(set_req[key].value, msg=msg(key)):
|
|
_child_schema.schema.get(set_req[key].value, val)
|
|
for key, val in schema.get(SCHEMA, {v_name: cv.string}).items()},
|
|
extra=vol.ALLOW_EXTRA)
|
|
try:
|
|
vol_schema(child.values)
|
|
except vol.Invalid as exc:
|
|
level = (logging.WARNING if value_type in child.values
|
|
else logging.DEBUG)
|
|
_LOGGER.log(
|
|
level,
|
|
"Invalid values: %s: %s platform: node %s child %s: %s",
|
|
child.values, platform, node_id, child.id, exc)
|
|
continue
|
|
dev_id = id(gateway), node_id, child.id, value_type
|
|
validated[platform].append(dev_id)
|
|
return validated
|