Example #1
0
def merge_packages_config(config, packages):
    """Merge packages into the top-level configuration. Mutate config."""
    # pylint: disable=too-many-nested-blocks
    PACKAGES_CONFIG_SCHEMA(packages)
    for pack_name, pack_conf in packages.items():
        for comp_name, comp_conf in pack_conf.items():
            if comp_name == CONF_CORE:
                continue
            component = get_component(comp_name)

            if component is None:
                _log_pkg_error(pack_name, comp_name, config, "does not exist")
                continue

            if hasattr(component, 'PLATFORM_SCHEMA'):
                config[comp_name] = cv.ensure_list(config.get(comp_name))
                config[comp_name].extend(cv.ensure_list(comp_conf))
                continue

            if hasattr(component, 'CONFIG_SCHEMA'):
                merge_type, _ = _identify_config_schema(component)

                if merge_type == 'list':
                    config[comp_name] = cv.ensure_list(config.get(comp_name))
                    config[comp_name].extend(cv.ensure_list(comp_conf))
                    continue

                if merge_type == 'dict':
                    if not isinstance(comp_conf, dict):
                        _log_pkg_error(
                            pack_name, comp_name, config,
                            "cannot be merged. Expected a dict.")
                        continue

                    if comp_name not in config:
                        config[comp_name] = OrderedDict()

                    if not isinstance(config[comp_name], dict):
                        _log_pkg_error(
                            pack_name, comp_name, config,
                            "cannot be merged. Dict expected in main config.")
                        continue

                    for key, val in comp_conf.items():
                        if key in config[comp_name]:
                            _log_pkg_error(pack_name, comp_name, config,
                                           "duplicate key '{}'".format(key))
                            continue
                        config[comp_name][key] = val
                    continue

            # The last merge type are sections that may occur only once
            if comp_name in config:
                _log_pkg_error(
                    pack_name, comp_name, config, "may occur only once"
                    " and it already exist in your main configuration")
                continue
            config[comp_name] = comp_conf

    return config
Example #2
0
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
    """Setup the pilight platform."""
    # Find and return switches controlled by pilight
    switches = config.get("switches", {})
    devices = []

    for dev_name, properties in switches.items():
        devices.append(
            PilightSwitch(
                hass,
                properties.get("name", dev_name),
                properties.get("on_code"),
                properties.get("off_code"),
                ensure_list(properties.get("on_code_receive", False)),
                ensure_list(properties.get("off_code_receive", False)),
            )
        )

    add_devices_callback(devices)
Example #3
0
def _recursive_merge(
        conf: Dict[str, Any], package: Dict[str, Any]) -> Union[bool, str]:
    """Merge package into conf, recursively."""
    error = False  # type: Union[bool, str]
    for key, pack_conf in package.items():
        if isinstance(pack_conf, dict):
            if not pack_conf:
                continue
            conf[key] = conf.get(key, OrderedDict())
            error = _recursive_merge(conf=conf[key], package=pack_conf)

        elif isinstance(pack_conf, list):
            if not pack_conf:
                continue
            conf[key] = cv.ensure_list(conf.get(key))
            conf[key].extend(cv.ensure_list(pack_conf))

        else:
            if conf.get(key) is not None:
                return key
            conf[key] = pack_conf
    return error
Example #4
0
    def send_code(call):
        """Send RF code to the pilight-daemon."""
        message_data = call.data

        # Patch data because of bug:
        # https://github.com/pilight/pilight/issues/296
        # Protocol has to be in a list otherwise segfault in pilight-daemon
        message_data['protocol'] = ensure_list(message_data['protocol'])

        try:
            pilight_client.send_code(message_data)
        except IOError:
            _LOGGER.error('Pilight send failed for %s', str(message_data))
Example #5
0
DOMAIN = 'hue'
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=5)

# Device icon / attrs
MODELS = ['SML', 'RWL', 'ZGP', 'GEO']
MODELS_ATTRS = {
    'SML': {'icon': 'mdi:run-fast',
            'attrs': ['light_level', 'battery', 'last_updated',
                      'lux', 'dark', 'daylight', 'temperature']},
    'RWL': {'icon': 'mdi:remote', 'attrs': ['battery', 'last_updated']},
    'ZGP': {'icon': 'mdi:remote', 'attrs': ['battery', 'last_updated']},
    'GEO': {'icon': 'mdi:cellphone', 'attrs': []}}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Optional(CONF_DEVICES): cv.ensure_list(MODELS),
})


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the Hue sensors."""
    import hue_sensors as hs
    url = hass.data[DOMAIN] + '/sensors'
    data = HueSensorData(url, hs.parse_hue_api_response)
    data.update()
    sensors = []
    models = config.get(CONF_DEVICES)
    for key in data.data.keys():
        if not models or data.data[key]['model'] in models:
            sensors.append(HueSensor(key, data))
    add_devices(sensors, True)
Example #6
0
OFF_STATES = [STATE_IDLE, STATE_OFF, STATE_UNAVAILABLE]

ATTRS_SCHEMA = cv.schema_with_slug_keys(cv.string)
CMD_SCHEMA = cv.schema_with_slug_keys(cv.SERVICE_SCHEMA)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_NAME):
        cv.string,
        vol.Optional(CONF_CHILDREN, default=[]):
        cv.entity_ids,
        vol.Optional(CONF_COMMANDS, default={}):
        CMD_SCHEMA,
        vol.Optional(CONF_ATTRS, default={}):
        vol.Or(cv.ensure_list(ATTRS_SCHEMA), ATTRS_SCHEMA),
        vol.Optional(CONF_STATE_TEMPLATE):
        cv.template,
    },
    extra=vol.REMOVE_EXTRA,
)


async def async_setup_platform(hass,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up the universal media players."""
    player = UniversalMediaPlayer(
        hass,
        config.get(CONF_NAME),
Example #7
0
CONF_STREET = "street"
CONF_REFRESH_RATE = 'refreshRate'
CONF_MAX_COUNT = 'maxCount'

MANIFEST = json.load(
    open("%s/manifest.json" % os.path.dirname(os.path.realpath(__file__))))
DOMAIN = MANIFEST["domain"]
VERSION = MANIFEST["version"]
DEFAULT_NAME = MANIFEST["name"]
PLATFORM = "binary_sensor"
DEFAULT_METHOD = 'GET'
DEFAULT_VERIFY_SSL = True
ISSUE_URL = "https://github.com/konikvranik/hacs_cez/issues"
SCHEMA = {
    vol.Required(CONF_NAME, default=DEFAULT_NAME): cv.string,
    vol.Required(CONF_STREET): cv.ensure_list(vol.Any(list, cv.string)),
    vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
    vol.Optional(CONF_FORCE_UPDATE, default=True): cv.boolean,
    vol.Optional(CONF_REFRESH_RATE, default=86400): vol.All(vol.Coerce(int)),
    vol.Optional(CONF_MAX_COUNT, default=5): vol.All(vol.Coerce(int)),
}
SERVICE = 'refresh'

CONFIG_SCHEMA = vol.Schema({vol.Optional(DOMAIN): vol.Schema(SCHEMA)},
                           extra=ALLOW_EXTRA)

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(hass, entry):
    """Set up ESPHome binary sensors based on a config entry."""
Example #8
0
async def merge_packages_config(
    hass: HomeAssistant,
    config: Dict,
    packages: Dict[str, Any],
    _log_pkg_error: Callable = _log_pkg_error,
) -> Dict:
    """Merge packages into the top-level configuration. Mutate config."""
    PACKAGES_CONFIG_SCHEMA(packages)
    for pack_name, pack_conf in packages.items():
        for comp_name, comp_conf in pack_conf.items():
            if comp_name == CONF_CORE:
                continue
            # If component name is given with a trailing description, remove it
            # when looking for component
            domain = comp_name.split(" ")[0]

            try:
                integration = await async_get_integration_with_requirements(
                    hass, domain
                )
                component = integration.get_component()
            except (IntegrationNotFound, RequirementsNotFound, ImportError) as ex:
                _log_pkg_error(pack_name, comp_name, config, str(ex))
                continue

            merge_list = hasattr(component, "PLATFORM_SCHEMA")

            if not merge_list and hasattr(component, "CONFIG_SCHEMA"):
                merge_type, _ = _identify_config_schema(component)
                merge_list = merge_type == "list"

            if merge_list:
                config[comp_name] = cv.remove_falsy(
                    cv.ensure_list(config.get(comp_name)) + cv.ensure_list(comp_conf)
                )
                continue

            if comp_conf is None:
                comp_conf = OrderedDict()

            if not isinstance(comp_conf, dict):
                _log_pkg_error(
                    pack_name, comp_name, config, "cannot be merged. Expected a dict."
                )
                continue

            if comp_name not in config or config[comp_name] is None:
                config[comp_name] = OrderedDict()

            if not isinstance(config[comp_name], dict):
                _log_pkg_error(
                    pack_name,
                    comp_name,
                    config,
                    "cannot be merged. Dict expected in main config.",
                )
                continue

            error = _recursive_merge(conf=config[comp_name], package=comp_conf)
            if error:
                _log_pkg_error(
                    pack_name, comp_name, config, f"has duplicate key '{error}'"
                )

    return config
Example #9
0
DIAL_CONFIG_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
    vol.Optional(ATTR_MIN_VALUE): vol.Coerce(int),
    vol.Optional(ATTR_MAX_VALUE): vol.Coerce(int),
    vol.Optional(ATTR_MIN_POSITION): cv.positive_int,
    vol.Optional(ATTR_MAX_POSITION): cv.positive_int,
    vol.Optional(ATTR_ROTATION): vol.In(ROTATIONS),
    vol.Optional(ATTR_SCALE): vol.In(SCALES),
    vol.Optional(ATTR_TICKS): cv.positive_int
})

DIAL_STATE_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
    vol.Required(ATTR_VALUE): vol.Coerce(int),
    vol.Optional(ATTR_LABELS): cv.ensure_list(cv.string)
})

WINK_COMPONENTS = [
    'binary_sensor', 'sensor', 'light', 'switch', 'lock', 'cover', 'climate',
    'fan', 'alarm_control_panel', 'scene', 'water_heater'
]

WINK_HUBS = []


def _request_app_setup(hass, config):
    """Assist user with configuring the Wink dev application."""
    hass.data[DOMAIN]['configurator'] = True
    configurator = hass.components.configurator
Example #10
0
async def merge_packages_config(
    hass: HomeAssistant,
    config: dict,
    packages: dict[str, Any],
    _log_pkg_error: Callable = _log_pkg_error,
) -> dict:
    """Merge packages into the top-level configuration. Mutate config."""
    PACKAGES_CONFIG_SCHEMA(packages)
    for pack_name, pack_conf in packages.items():
        for comp_name, comp_conf in pack_conf.items():
            if comp_name == CONF_CORE:
                continue
            # If component name is given with a trailing description, remove it
            # when looking for component
            domain = comp_name.split(" ")[0]

            try:
                integration = await async_get_integration_with_requirements(
                    hass, domain)
                component = integration.get_component()
            except INTEGRATION_LOAD_EXCEPTIONS as ex:
                _log_pkg_error(pack_name, comp_name, config, str(ex))
                continue

            try:
                config_platform: ModuleType | None = integration.get_platform(
                    "config")
                # Test if config platform has a config validator
                if not hasattr(config_platform, "async_validate_config"):
                    config_platform = None
            except ImportError:
                config_platform = None

            merge_list = False

            # If integration has a custom config validator, it needs to provide a hint.
            if config_platform is not None:
                merge_list = config_platform.PACKAGE_MERGE_HINT == "list"  # type: ignore[attr-defined]

            if not merge_list:
                merge_list = hasattr(component, "PLATFORM_SCHEMA")

            if not merge_list and hasattr(component, "CONFIG_SCHEMA"):
                merge_list = _identify_config_schema(component) == "list"

            if merge_list:
                config[comp_name] = cv.remove_falsy(
                    cv.ensure_list(config.get(comp_name)) +
                    cv.ensure_list(comp_conf))
                continue

            if comp_conf is None:
                comp_conf = OrderedDict()

            if not isinstance(comp_conf, dict):
                _log_pkg_error(pack_name, comp_name, config,
                               "cannot be merged. Expected a dict.")
                continue

            if comp_name not in config or config[comp_name] is None:
                config[comp_name] = OrderedDict()

            if not isinstance(config[comp_name], dict):
                _log_pkg_error(
                    pack_name,
                    comp_name,
                    config,
                    "cannot be merged. Dict expected in main config.",
                )
                continue

            error = _recursive_merge(conf=config[comp_name], package=comp_conf)
            if error:
                _log_pkg_error(pack_name, comp_name, config,
                               f"has duplicate key '{error}'")

    return config
Example #11
0
    name: Name to identify appliance/device eg. Living Room Lamp (required)
    key:  Auth key, if different from platform key (optional)
'''
SWITCH_SCHEMA = vol.Schema({
    vol.Required(CONF_UUID): cv.string,
    vol.Required(CONF_NAME): cv.string,
    vol.Optional(CONF_KEY): cv.string,
})
'''
    switches: [] one or more SWITCH_SCHEMA (required)
    key:  Auth key to use for all appliances/devices (optional)
    validate: validate key for incomming requests (default: True)
'''
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_SWITCHES):
    cv.ensure_list(SWITCH_SCHEMA),
    vol.Optional(CONF_KEY):
    cv.string,
    vol.Optional(CONF_VALIDATE, default=True):
    cv.boolean,
})


def setup_platform(hass, config, add_entities, discovery_info=None):
    switches = []
    for swConfig in config[CONF_SWITCHES]:
        switches.append(
            MerossSwitch(
                hass.components.mqtt,
                swConfig[CONF_UUID],
                next(
Example #12
0
DIAL_CONFIG_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
    vol.Optional(ATTR_MIN_VALUE): vol.Coerce(int),
    vol.Optional(ATTR_MAX_VALUE): vol.Coerce(int),
    vol.Optional(ATTR_MIN_POSITION): cv.positive_int,
    vol.Optional(ATTR_MAX_POSITION): cv.positive_int,
    vol.Optional(ATTR_ROTATION): vol.In(ROTATIONS),
    vol.Optional(ATTR_SCALE): vol.In(SCALES),
    vol.Optional(ATTR_TICKS): cv.positive_int,
})

DIAL_STATE_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
    vol.Required(ATTR_VALUE): vol.Coerce(int),
    vol.Optional(ATTR_LABELS): cv.ensure_list(cv.string),
})

WINK_COMPONENTS = [
    'binary_sensor', 'sensor', 'light', 'switch', 'lock', 'cover', 'climate',
    'fan', 'alarm_control_panel', 'scene', 'water_heater'
]

WINK_HUBS = []


def _request_app_setup(hass, config):
    """Assist user with configuring the Wink dev application."""
    hass.data[DOMAIN]['configurator'] = True
    configurator = hass.components.configurator
Example #13
0
from homeassistant import config_entries
from homeassistant.const import CONF_NAME, CONF_TIMEOUT
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv

from .const import ATTR_TARIFF, DEFAULT_NAME, DEFAULT_TIMEOUT, DOMAIN, PLATFORM, TARIFFS

UI_CONFIG_SCHEMA = vol.Schema({
    vol.Required(CONF_NAME, default=DEFAULT_NAME):
    str,
    vol.Required(ATTR_TARIFF, default=TARIFFS[1]):
    vol.In(TARIFFS),
})
SENSOR_SCHEMA = UI_CONFIG_SCHEMA.extend(
    {vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int})
CONFIG_SCHEMA = vol.Schema({DOMAIN: cv.ensure_list(SENSOR_SCHEMA)},
                           extra=vol.ALLOW_EXTRA)


async def async_setup(hass: HomeAssistant, config: dict):
    """
    Set up the electricity price sensor from configuration.yaml.

    ```yaml
    pvpc_hourly_pricing:
      - name: PVPC manual ve
        tariff: electric_car
      - name: PVPC manual nocturna
        tariff: discrimination
        timeout: 3
    ```
Example #14
0
SHOW_SCHEMA = vol.Schema({
    vol.Optional(CONF_CONFIG, False): cv.boolean,
    vol.Optional(CONF_TIMELINE, False): cv.boolean,
})

SUN_SCHEMA = vol.Schema({
    vol.Required(CONF_SUN): cv.sun_event,
    vol.Optional(CONF_BEFORE): cv.positive_time_period,
    vol.Optional(CONF_AFTER): cv.positive_time_period,
})

time_event = vol.Any(cv.time, SUN_SCHEMA)
month_event = vol.All(cv.ensure_list, [vol.In(MONTHS)])

day_number = vol.All(vol.Coerce(int), vol.Range(min=0, max=31))
day_event = vol.Any(CONF_ODD, CONF_EVEN, cv.ensure_list(day_number))

SCHEDULE_SCHEMA = vol.Schema({
    vol.Required(CONF_TIME): time_event,
    vol.Required(CONF_DURATION): cv.positive_time_period,
    vol.Optional(CONF_NAME): cv.string,
    vol.Optional(CONF_WEEKDAY): cv.weekdays,
    vol.Optional(CONF_MONTH): month_event,
    vol.Optional(CONF_DAY): day_event,
})

ZONE_SCHEMA = vol.Schema({
    vol.Optional(CONF_SCHEDULES):
    vol.All(cv.ensure_list, [SCHEDULE_SCHEMA]),
    vol.Optional(CONF_ZONE_ID):
    cv.string,
Example #15
0
CONF_INDEX = "index"
CONF_RUN_SECONDS = "run_seconds"
CONF_CONTINUE_RUNNING_STATIONS = "continue_running_stations"

DOMAIN = "opensprinkler"

DEFAULT_NAME = "OpenSprinkler"

DEFAULT_SCAN_INTERVAL = 5

SCHEMA_SERVICE_RUN_SECONDS = {
    vol.Required(CONF_INDEX): cv.positive_int,
    vol.Required(CONF_RUN_SECONDS): cv.positive_int,
}
SCHEMA_SERVICE_RUN = {
    vol.Optional(CONF_RUN_SECONDS):
    vol.Or(
        cv.ensure_list(cv.positive_int),
        cv.ensure_list(SCHEMA_SERVICE_RUN_SECONDS),
        cv.positive_int,
        vol.Schema({}, extra=vol.ALLOW_EXTRA),
    ),
    vol.Optional(CONF_CONTINUE_RUNNING_STATIONS):
    cv.boolean,
}
SCHEMA_SERVICE_STOP = {}

SERVICE_RUN = "run"
SERVICE_STOP = "stop"
Example #16
0
CONF_EVOLUTION_ARROWS_MIN = 'evolution_arrows_minutes'
CONF_REMOTE_API = 'remote_api'
CONF_WEATHER = 'weather'

DEFAULT_NAME = "Psychrometric chart"
DEFAULT_SCAN_INTERVAL_SEC = 60

DEFAULT_DEAD_BAND = 0.5  # ĀŗC
DEFAULT_DELTA_EVOLUTION = 5400  # 1.5h
DEFAULT_FREQ_SAMPLING_SEC = 300  # 300 (5min)

BINARY_SENSOR_NAME = 'close_house'
SENSOR_NAME = 'house_delta_temperature'

POINT_SCHEMA = vol.Schema(cv.entity_ids)
POINTS_SCHEMA = vol.Schema(vol.Any(POINT_SCHEMA, cv.ensure_list(POINT_SCHEMA)))
ROOM_SCHEMA = vol.Schema({cv.string: POINTS_SCHEMA})

CONFIG_SCHEMA = vol.Schema(
    {
        DOMAIN:
        vol.Schema(
            {
                vol.Required(CONF_INTERIOR):
                ROOM_SCHEMA,
                vol.Optional(CONF_EXTERIOR):
                POINTS_SCHEMA,
                vol.Optional(CONF_WEATHER):
                POINTS_SCHEMA,
                vol.Optional(CONF_NAME, default=DEFAULT_NAME):
                cv.string,
Example #17
0
        },
        "time": datetime.timedelta(seconds=3)
    },
    "light_on": {
        "name": "{} Light On",
        "icon": {
            True: "lightbulb-on",
            False: "lightbulb"
        },
        "time": datetime.timedelta(minutes=5)
    }
}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_SWITCHES, default=[]):
        vol.All(cv.ensure_list([vol.In(SWITCHES)]))
})


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the DoorBird switch platform."""
    switches = []

    for doorstation in hass.data[DOORBIRD_DOMAIN]:

        device = doorstation.device

        for switch in SWITCHES:

            _LOGGER.debug("Adding DoorBird switch %s",
                          SWITCHES[switch]["name"].format(doorstation.name))
Example #18
0
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv

from .const import ATTR_TARIFF, DEFAULT_NAME, DEFAULT_TARIFF, DOMAIN, PLATFORM, TARIFFS

UI_CONFIG_SCHEMA = vol.Schema({
    vol.Required(CONF_NAME, default=DEFAULT_NAME):
    str,
    vol.Required(ATTR_TARIFF, default=DEFAULT_TARIFF):
    vol.In(TARIFFS),
})
CONFIG_SCHEMA = vol.Schema({DOMAIN: cv.ensure_list(UI_CONFIG_SCHEMA)},
                           extra=vol.ALLOW_EXTRA)


async def async_setup(hass: HomeAssistant, config: dict):
    """
    Set up the electricity price sensor from configuration.yaml.

    ```yaml
    pvpc_hourly_pricing:
      - name: PVPC manual ve
        tariff: electric_car
      - name: PVPC manual nocturna
        tariff: discrimination
        timeout: 3
    ```
Example #19
0
from homeassistant import config_entries
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv

from .const import ATTR_TARIFF, DEFAULT_NAME, DEFAULT_TARIFF, DOMAIN, PLATFORMS, TARIFFS

UI_CONFIG_SCHEMA = vol.Schema(
    {
        vol.Required(CONF_NAME, default=DEFAULT_NAME): str,
        vol.Required(ATTR_TARIFF, default=DEFAULT_TARIFF): vol.In(TARIFFS),
    }
)
CONFIG_SCHEMA = vol.Schema(
    vol.All(cv.deprecated(DOMAIN), {DOMAIN: cv.ensure_list(UI_CONFIG_SCHEMA)}),
    extra=vol.ALLOW_EXTRA,
)


async def async_setup(hass: HomeAssistant, config: dict):
    """
    Set up the electricity price sensor from configuration.yaml.

    ```yaml
    pvpc_hourly_pricing:
      - name: PVPC manual ve
        tariff: electric_car
      - name: PVPC manual nocturna
        tariff: discrimination
        timeout: 3
Example #20
0
 def _update_sub_entities(self, properties, services=None, domain=None):
     from .binary_sensor import MiotBinarySensorSubEntity
     from .switch import MiotSwitchSubEntity
     from .light import MiotLightSubEntity
     if isinstance(services, MiotService):
         sls = [services]
     elif services:
         sls = self._miot_service.spec.get_services(
             *cv.ensure_list(services))
     else:
         sls = [self._miot_service]
     add_sensors = self._add_entities.get('sensor')
     add_binary_sensors = self._add_entities.get('binary_sensor')
     add_switches = self._add_entities.get('switch')
     add_lights = self._add_entities.get('light')
     for s in sls:
         if not properties:
             fnm = s.unique_name
             tms = self._check_same_sub_entity(fnm, domain)
             new = True
             if fnm in self._subs:
                 new = False
                 self._subs[fnm].update()
             elif tms > 0:
                 if tms <= 1:
                     _LOGGER.info(
                         'Device %s sub entity %s: %s already exists.',
                         self.name, domain, fnm)
             elif add_lights and domain == 'light' and s.get_property('on'):
                 self._subs[fnm] = MiotLightSubEntity(self, s)
                 add_lights([self._subs[fnm]])
             if new and fnm in self._subs:
                 self._check_same_sub_entity(fnm, domain, add=1)
                 _LOGGER.debug('Added sub entity %s: %s for %s.', domain,
                               fnm, self.name)
             continue
         pls = s.get_properties(*cv.ensure_list(properties))
         for p in pls:
             if p.full_name not in self._state_attrs:
                 continue
             fnm = p.unique_name
             tms = self._check_same_sub_entity(fnm, domain)
             new = True
             if fnm in self._subs:
                 new = False
                 self._subs[fnm].update()
             elif tms > 0:
                 if tms <= 1:
                     _LOGGER.info(
                         'Device %s sub entity %s: %s already exists.',
                         self.name, domain, fnm)
             elif add_switches and p.format == 'bool' and p.writeable:
                 self._subs[fnm] = MiotSwitchSubEntity(self, p)
                 add_switches([self._subs[fnm]])
             elif add_binary_sensors and p.format == 'bool':
                 self._subs[fnm] = MiotBinarySensorSubEntity(self, p)
                 add_binary_sensors([self._subs[fnm]])
             elif add_sensors and domain == 'sensor':
                 self._subs[fnm] = MiotSensorSubEntity(self, p)
                 add_sensors([self._subs[fnm]])
             if new and fnm in self._subs:
                 self._check_same_sub_entity(fnm, domain, add=1)
                 _LOGGER.debug('Added sub entity %s: %s for %s.', domain,
                               fnm, self.name)
Example #21
0
def merge_packages_config(hass: HomeAssistant,
                          config: Dict,
                          packages: Dict,
                          _log_pkg_error: Callable = _log_pkg_error) -> Dict:
    """Merge packages into the top-level configuration. Mutate config."""
    # pylint: disable=too-many-nested-blocks
    PACKAGES_CONFIG_SCHEMA(packages)
    for pack_name, pack_conf in packages.items():
        for comp_name, comp_conf in pack_conf.items():
            if comp_name == CONF_CORE:
                continue
            component = get_component(hass, comp_name)

            if component is None:
                _log_pkg_error(pack_name, comp_name, config, "does not exist")
                continue

            if hasattr(component, 'PLATFORM_SCHEMA'):
                if not comp_conf:
                    continue  # Ensure we dont add Falsy items to list
                config[comp_name] = cv.ensure_list(config.get(comp_name))
                config[comp_name].extend(cv.ensure_list(comp_conf))
                continue

            if hasattr(component, 'CONFIG_SCHEMA'):
                merge_type, _ = _identify_config_schema(component)

                if merge_type == 'list':
                    if not comp_conf:
                        continue  # Ensure we dont add Falsy items to list
                    config[comp_name] = cv.ensure_list(config.get(comp_name))
                    config[comp_name].extend(cv.ensure_list(comp_conf))
                    continue

            if comp_conf is None:
                comp_conf = OrderedDict()

            if not isinstance(comp_conf, dict):
                _log_pkg_error(pack_name, comp_name, config,
                               "cannot be merged. Expected a dict.")
                continue

            if comp_name not in config or config[comp_name] is None:
                config[comp_name] = OrderedDict()

            if not isinstance(config[comp_name], dict):
                _log_pkg_error(
                    pack_name, comp_name, config,
                    "cannot be merged. Dict expected in main config.")
                continue
            if not isinstance(comp_conf, dict):
                _log_pkg_error(pack_name, comp_name, config,
                               "cannot be merged. Dict expected in package.")
                continue

            error = _recursive_merge(conf=config[comp_name], package=comp_conf)
            if error:
                _log_pkg_error(pack_name, comp_name, config,
                               "has duplicate key '{}'".format(error))

    return config
Example #22
0
        },
        "time": datetime.timedelta(seconds=3)
    },
    "light_on": {
        "name": "Light On",
        "icon": {
            True: "lightbulb-on",
            False: "lightbulb"
        },
        "time": datetime.timedelta(minutes=5)
    }
}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_SWITCHES, default=[]):
        vol.All(cv.ensure_list([vol.In(SWITCHES)]))
})


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the DoorBird switch platform."""
    device = hass.data.get(DOORBIRD_DOMAIN)

    switches = []
    for switch in SWITCHES:
        _LOGGER.debug("Adding DoorBird switch %s", SWITCHES[switch]["name"])
        switches.append(DoorBirdSwitch(device, switch))

    add_devices(switches)
    _LOGGER.info("Added DoorBird switches")
Example #23
0
ATTR_ACCOUNT = CONF_ACCOUNT
ATTR_BANK = 'bank'
ATTR_ACCOUNT_TYPE = 'account_type'

SCHEMA_ACCOUNTS = vol.Schema({
    vol.Required(CONF_ACCOUNT): cv.string,
    vol.Optional(CONF_NAME, default=None): vol.Any(None, cv.string),
})

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_BIN): cv.string,
    vol.Required(CONF_USERNAME): cv.string,
    vol.Required(CONF_PIN): cv.string,
    vol.Required(CONF_URL): cv.string,
    vol.Optional(CONF_NAME): cv.string,
    vol.Optional(CONF_ACCOUNTS, default=[]): cv.ensure_list(SCHEMA_ACCOUNTS),
    vol.Optional(CONF_HOLDINGS, default=[]): cv.ensure_list(SCHEMA_ACCOUNTS),
})


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the sensors.

    Login to the bank and get a list of existing accounts. Create a
    sensor for each account.
    """
    credentials = BankCredentials(config[CONF_BIN], config[CONF_USERNAME],
                                  config[CONF_PIN], config[CONF_URL])
    fints_name = config.get(CONF_NAME, config[CONF_BIN])

    account_config = {acc[CONF_ACCOUNT]: acc[CONF_NAME]
Example #24
0
def merge_packages_config(config, packages, _log_pkg_error=_log_pkg_error):
    """Merge packages into the top-level configuration. Mutate config."""
    # pylint: disable=too-many-nested-blocks
    PACKAGES_CONFIG_SCHEMA(packages)
    for pack_name, pack_conf in packages.items():
        for comp_name, comp_conf in pack_conf.items():
            if comp_name == CONF_CORE:
                continue
            component = get_component(comp_name)

            if component is None:
                _log_pkg_error(pack_name, comp_name, config, "does not exist")
                continue

            if hasattr(component, 'PLATFORM_SCHEMA'):
                if not comp_conf:
                    continue  # Ensure we dont add Falsy items to list
                config[comp_name] = cv.ensure_list(config.get(comp_name))
                config[comp_name].extend(cv.ensure_list(comp_conf))
                continue

            if hasattr(component, 'CONFIG_SCHEMA'):
                merge_type, _ = _identify_config_schema(component)

                if merge_type == 'list':
                    if not comp_conf:
                        continue  # Ensure we dont add Falsy items to list
                    config[comp_name] = cv.ensure_list(config.get(comp_name))
                    config[comp_name].extend(cv.ensure_list(comp_conf))
                    continue

                if merge_type == 'dict':
                    if comp_conf is None:
                        comp_conf = OrderedDict()

                    if not isinstance(comp_conf, dict):
                        _log_pkg_error(pack_name, comp_name, config,
                                       "cannot be merged. Expected a dict.")
                        continue

                    if comp_name not in config:
                        config[comp_name] = OrderedDict()

                    if not isinstance(config[comp_name], dict):
                        _log_pkg_error(
                            pack_name, comp_name, config,
                            "cannot be merged. Dict expected in main config.")
                        continue

                    for key, val in comp_conf.items():
                        if key in config[comp_name]:
                            _log_pkg_error(pack_name, comp_name, config,
                                           "duplicate key '{}'".format(key))
                            continue
                        config[comp_name][key] = val
                    continue

            # The last merge type are sections that may occur only once
            if comp_name in config:
                _log_pkg_error(
                    pack_name, comp_name, config, "may occur only once"
                    " and it already exist in your main configuration")
                continue
            config[comp_name] = comp_conf

    return config
Example #25
0
    cv.positive_int,
    vol.Optional(ATTR_MAX_POSITION):
    cv.positive_int,
    vol.Optional(ATTR_ROTATION):
    vol.In(ROTATIONS),
    vol.Optional(ATTR_SCALE):
    vol.In(SCALES),
    vol.Optional(ATTR_TICKS):
    cv.positive_int,
})

DIAL_STATE_SCHEMA = ENTITY_SERVICE_SCHEMA.extend({
    vol.Required(ATTR_VALUE):
    vol.Coerce(int),
    vol.Optional(ATTR_LABELS):
    cv.ensure_list(cv.string),
})

WINK_COMPONENTS = [
    "binary_sensor",
    "sensor",
    "light",
    "switch",
    "lock",
    "cover",
    "climate",
    "fan",
    "alarm_control_panel",
    "scene",
    "water_heater",
]
Example #26
0
async def async_start(  # noqa: C901
        hass: HomeAssistant, discovery_topic, config_entry=None) -> None:
    """Start MQTT Discovery."""
    mqtt_integrations = {}

    async def async_discovery_message_received(msg):
        """Process the received message."""
        hass.data[LAST_DISCOVERY] = time.time()
        payload = msg.payload
        topic = msg.topic
        topic_trimmed = topic.replace(f"{discovery_topic}/", "", 1)

        if not (match := TOPIC_MATCHER.match(topic_trimmed)):
            if topic_trimmed.endswith("config"):
                _LOGGER.warning(
                    "Received message on illegal discovery topic '%s'. The topic contains "
                    "not allowed characters. For more information see "
                    "https://www.home-assistant.io/docs/mqtt/discovery/#discovery-topic",
                    topic,
                )
            return

        component, node_id, object_id = match.groups()

        if component not in SUPPORTED_COMPONENTS:
            _LOGGER.warning("Integration %s is not supported", component)
            return

        if payload:
            try:
                payload = json_loads(payload)
            except ValueError:
                _LOGGER.warning("Unable to parse JSON %s: '%s'", object_id,
                                payload)
                return

        payload = MQTTConfig(payload)

        for key in list(payload):
            abbreviated_key = key
            key = ABBREVIATIONS.get(key, key)
            payload[key] = payload.pop(abbreviated_key)

        if CONF_DEVICE in payload:
            device = payload[CONF_DEVICE]
            for key in list(device):
                abbreviated_key = key
                key = DEVICE_ABBREVIATIONS.get(key, key)
                device[key] = device.pop(abbreviated_key)

        if TOPIC_BASE in payload:
            base = payload.pop(TOPIC_BASE)
            for key, value in payload.items():
                if isinstance(value, str) and value:
                    if value[0] == TOPIC_BASE and key.endswith("topic"):
                        payload[key] = f"{base}{value[1:]}"
                    if value[-1] == TOPIC_BASE and key.endswith("topic"):
                        payload[key] = f"{value[:-1]}{base}"
            if payload.get(CONF_AVAILABILITY):
                for availability_conf in cv.ensure_list(
                        payload[CONF_AVAILABILITY]):
                    if not isinstance(availability_conf, dict):
                        continue
                    if topic := availability_conf.get(CONF_TOPIC):
                        if topic[0] == TOPIC_BASE:
                            availability_conf[
                                CONF_TOPIC] = f"{base}{topic[1:]}"
                        if topic[-1] == TOPIC_BASE:
                            availability_conf[
                                CONF_TOPIC] = f"{topic[:-1]}{base}"
Example #27
0
    vol.Any(None, cv.string),
})

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_BIN):
    cv.string,
    vol.Required(CONF_USERNAME):
    cv.string,
    vol.Required(CONF_PIN):
    cv.string,
    vol.Required(CONF_URL):
    cv.string,
    vol.Optional(CONF_NAME):
    cv.string,
    vol.Optional(CONF_ACCOUNTS, default=[]):
    cv.ensure_list(SCHEMA_ACCOUNTS),
    vol.Optional(CONF_HOLDINGS, default=[]):
    cv.ensure_list(SCHEMA_ACCOUNTS),
})


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the sensors.

    Login to the bank and get a list of existing accounts. Create a
    sensor for each account.
    """
    credentials = BankCredentials(config[CONF_BIN], config[CONF_USERNAME],
                                  config[CONF_PIN], config[CONF_URL])
    fints_name = config.get(CONF_NAME, config[CONF_BIN])
Example #28
0
def merge_packages_config(hass: HomeAssistant, config: Dict, packages: Dict,
                          _log_pkg_error: Callable = _log_pkg_error) -> Dict:
    """Merge packages into the top-level configuration. Mutate config."""
    # pylint: disable=too-many-nested-blocks
    PACKAGES_CONFIG_SCHEMA(packages)
    for pack_name, pack_conf in packages.items():
        for comp_name, comp_conf in pack_conf.items():
            if comp_name == CONF_CORE:
                continue
            component = get_component(hass, comp_name)

            if component is None:
                _log_pkg_error(pack_name, comp_name, config, "does not exist")
                continue

            if hasattr(component, 'PLATFORM_SCHEMA'):
                if not comp_conf:
                    continue  # Ensure we dont add Falsy items to list
                config[comp_name] = cv.ensure_list(config.get(comp_name))
                config[comp_name].extend(cv.ensure_list(comp_conf))
                continue

            if hasattr(component, 'CONFIG_SCHEMA'):
                merge_type, _ = _identify_config_schema(component)

                if merge_type == 'list':
                    if not comp_conf:
                        continue  # Ensure we dont add Falsy items to list
                    config[comp_name] = cv.ensure_list(config.get(comp_name))
                    config[comp_name].extend(cv.ensure_list(comp_conf))
                    continue

            if comp_conf is None:
                comp_conf = OrderedDict()

            if not isinstance(comp_conf, dict):
                _log_pkg_error(
                    pack_name, comp_name, config,
                    "cannot be merged. Expected a dict.")
                continue

            if comp_name not in config or config[comp_name] is None:
                config[comp_name] = OrderedDict()

            if not isinstance(config[comp_name], dict):
                _log_pkg_error(
                    pack_name, comp_name, config,
                    "cannot be merged. Dict expected in main config.")
                continue
            if not isinstance(comp_conf, dict):
                _log_pkg_error(
                    pack_name, comp_name, config,
                    "cannot be merged. Dict expected in package.")
                continue

            error = _recursive_merge(conf=config[comp_name],
                                     package=comp_conf)
            if error:
                _log_pkg_error(pack_name, comp_name, config,
                               "has duplicate key '{}'".format(error))

    return config
Example #29
0
async def merge_packages_config(hass: HomeAssistant, config: Dict,
                                packages: Dict,
                                _log_pkg_error: Callable = _log_pkg_error) \
        -> Dict:
    """Merge packages into the top-level configuration. Mutate config."""
    # pylint: disable=too-many-nested-blocks
    PACKAGES_CONFIG_SCHEMA(packages)
    for pack_name, pack_conf in packages.items():
        for comp_name, comp_conf in pack_conf.items():
            if comp_name == CONF_CORE:
                continue
            # If component name is given with a trailing description, remove it
            # when looking for component
            domain = comp_name.split(' ')[0]

            try:
                integration = await async_get_integration(hass, domain)
            except IntegrationNotFound:
                _log_pkg_error(pack_name, comp_name, config, "does not exist")
                continue

            try:
                component = integration.get_component()
            except ImportError:
                _log_pkg_error(pack_name, comp_name, config,
                               "unable to import")
                continue

            if hasattr(component, 'PLATFORM_SCHEMA'):
                if not comp_conf:
                    continue  # Ensure we dont add Falsy items to list
                config[comp_name] = cv.ensure_list(config.get(comp_name))
                config[comp_name].extend(cv.ensure_list(comp_conf))
                continue

            if hasattr(component, 'CONFIG_SCHEMA'):
                merge_type, _ = _identify_config_schema(component)

                if merge_type == 'list':
                    if not comp_conf:
                        continue  # Ensure we dont add Falsy items to list
                    config[comp_name] = cv.ensure_list(config.get(comp_name))
                    config[comp_name].extend(cv.ensure_list(comp_conf))
                    continue

            if comp_conf is None:
                comp_conf = OrderedDict()

            if not isinstance(comp_conf, dict):
                _log_pkg_error(pack_name, comp_name, config,
                               "cannot be merged. Expected a dict.")
                continue

            if comp_name not in config or config[comp_name] is None:
                config[comp_name] = OrderedDict()

            if not isinstance(config[comp_name], dict):
                _log_pkg_error(
                    pack_name, comp_name, config,
                    "cannot be merged. Dict expected in main config.")
                continue
            if not isinstance(comp_conf, dict):
                _log_pkg_error(pack_name, comp_name, config,
                               "cannot be merged. Dict expected in package.")
                continue

            error = _recursive_merge(conf=config[comp_name], package=comp_conf)
            if error:
                _log_pkg_error(pack_name, comp_name, config,
                               "has duplicate key '{}'".format(error))

    return config
Example #30
0
from homeassistant import config_entries
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv

from .const import ATTR_TARIFF, DEFAULT_NAME, DEFAULT_TARIFF, DOMAIN, PLATFORMS, TARIFFS

UI_CONFIG_SCHEMA = vol.Schema(
    {
        vol.Required(CONF_NAME, default=DEFAULT_NAME): str,
        vol.Required(ATTR_TARIFF, default=DEFAULT_TARIFF): vol.In(TARIFFS),
    }
)
CONFIG_SCHEMA = vol.Schema(
    {DOMAIN: cv.ensure_list(UI_CONFIG_SCHEMA)}, extra=vol.ALLOW_EXTRA
)


async def async_setup(hass: HomeAssistant, config: dict):
    """
    Set up the electricity price sensor from configuration.yaml.

    ```yaml
    pvpc_hourly_pricing:
      - name: PVPC manual ve
        tariff: electric_car
      - name: PVPC manual nocturna
        tariff: discrimination
        timeout: 3
    ```
Example #31
0
def datapoints_greater_than_degree(value: dict) -> dict:
    """Validate data point list is greater than polynomial degrees."""
    if not len(value[CONF_DATAPOINTS]) > value[CONF_DEGREE]:
        raise vol.Invalid(
            f"{CONF_DATAPOINTS} must have at least {value[CONF_DEGREE]+1} {CONF_DATAPOINTS}"
        )

    return value


COMPENSATION_SCHEMA = vol.Schema(
    {
        vol.Required(CONF_TRACKED_ENTITY_ID): cv.entity_id,
        vol.Optional(CONF_DATAPOINTS): vol.All(
            cv.ensure_list(cv.matches_regex(MATCH_DATAPOINT)),
        ),
        vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
        vol.Optional(CONF_ATTRIBUTE): cv.string,
        vol.Optional(CONF_PRECISION, default=DEFAULT_PRECISION): cv.positive_int,
        vol.Optional(CONF_DEGREE, default=DEFAULT_DEGREE): vol.All(
            vol.Coerce(int),
            vol.Range(min=1, max=7),
        ),
        vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
    }
)

CONFIG_SCHEMA = vol.Schema(
    {
        DOMAIN: vol.Schema(
'''
WeatherChina怀Developer by Charley
'''
import logging
import voluptuous as vol

from homeassistant.const import TEMP_CELSIUS
from homeassistant.helpers.entity import Entity
from homeassistant.components.sensor import PLATFORM_SCHEMA
import homeassistant.helpers.config_validation as cv

import requests
import json

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {vol.Required('CityCode', default=[]): vol.All(cv.ensure_list(cv.string))})

_Logger = logging.getLogger(__name__)


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the sensor platform."""

    # global _CityCodes
    cityCodes = config.get('CityCode')
    dev = []
    for code in cityCodes:
        # _Logger.info('[WeatherChina] init CityCode======>'+ code)
        dev.append(WeatherChina(code))

    add_devices(dev)
Example #33
0
ATTR_DATA = 'data'
CONF_STATE = 'state'

OFF_STATES = [STATE_IDLE, STATE_OFF]
REQUIREMENTS = []
_LOGGER = logging.getLogger(__name__)

ATTRS_SCHEMA = vol.Schema({cv.slug: cv.string})
CMD_SCHEMA = vol.Schema({cv.slug: cv.SERVICE_SCHEMA})

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_NAME): cv.string,
    vol.Optional(CONF_CHILDREN, default=[]): cv.entity_ids,
    vol.Optional(CONF_COMMANDS, default={}): CMD_SCHEMA,
    vol.Optional(CONF_ATTRS, default={}):
        vol.Or(cv.ensure_list(ATTRS_SCHEMA), ATTRS_SCHEMA),
    vol.Optional(CONF_STATE_TEMPLATE): cv.template
}, extra=vol.REMOVE_EXTRA)


@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the universal media players."""
    player = UniversalMediaPlayer(
        hass,
        config.get(CONF_NAME),
        config.get(CONF_CHILDREN),
        config.get(CONF_COMMANDS),
        config.get(CONF_ATTRS),
        config.get(CONF_STATE_TEMPLATE)
    )
Example #34
0
             'step':
             prop.range_step(),
             'description':
             prop.list_description(value) if prop.value_list else None,
         }) or []
         if isinstance(pms, dict) and 'method' in pms:
             setter = pms.get('method', setter)
             pms = pms.get('params', [])
     elif fmt and hasattr(mph, fmt):
         pms = [getattr(mph, fmt)(value)]
     elif d := cfg.get('dict', {}):
         for dk, dv in d.items():
             if dv == value:
                 pms = [dk]
                 break
 pms = cv.ensure_list(pms)
 if not setter:
     _LOGGER.warning('%s: Set miio prop via miot failed: %s',
                     self.model, [key, setter, cfg])
     return None
 _LOGGER.info('%s: Set miio prop via miot: %s', self.model,
              [key, setter, pms])
 ret = device.send(setter, pms) or ['']
 iok = ret == ['ok']
 if self.config.get('ignore_result'):
     iok = ret or isinstance(ret, list)
 cbk = cfg.get('set_callback')
 if iok and cbk:
     cbk(prop=cfg.get('prop'),
         config=cfg,
         setter=setter,