Exemple #1
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up climate for a Nexia device."""
    coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][
        config_entry.entry_id]
    nexia_home: NexiaHome = coordinator.nexia_home

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_SET_HUMIDIFY_SETPOINT,
        SET_HUMIDITY_SCHEMA,
        f"async_{SERVICE_SET_HUMIDIFY_SETPOINT}",
    )
    platform.async_register_entity_service(
        SERVICE_SET_AIRCLEANER_MODE,
        SET_AIRCLEANER_SCHEMA,
        f"async_{SERVICE_SET_AIRCLEANER_MODE}",
    )
    platform.async_register_entity_service(
        SERVICE_SET_HVAC_RUN_MODE,
        SET_HVAC_RUN_MODE_SCHEMA,
        f"async_{SERVICE_SET_HVAC_RUN_MODE}",
    )

    entities: list[NexiaZone] = []
    for thermostat_id in nexia_home.get_thermostat_ids():
        thermostat: NexiaThermostat = nexia_home.get_thermostat_by_id(
            thermostat_id)
        for zone_id in thermostat.get_zone_ids():
            zone: NexiaThermostatZone = thermostat.get_zone_by_id(zone_id)
            entities.append(NexiaZone(coordinator, zone))

    async_add_entities(entities)
Exemple #2
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry,
                            async_add_entities: AddEntitiesCallback) -> None:
    """Set up sensor entities for the sensors in the tub."""

    controller = hass.data[DOMAIN][entry.entry_id][SMARTTUB_CONTROLLER]

    entities = []
    for spa in controller.spas:
        entities.extend([
            SmartTubSensor(controller.coordinator, spa, "State", "state"),
            SmartTubSensor(controller.coordinator, spa, "Flow Switch",
                           "flow_switch"),
            SmartTubSensor(controller.coordinator, spa, "Ozone", "ozone"),
            SmartTubSensor(controller.coordinator, spa, "UV", "uv"),
            SmartTubSensor(controller.coordinator, spa, "Blowout Cycle",
                           "blowout_cycle"),
            SmartTubSensor(controller.coordinator, spa, "Cleanup Cycle",
                           "cleanup_cycle"),
            SmartTubPrimaryFiltrationCycle(controller.coordinator, spa),
            SmartTubSecondaryFiltrationCycle(controller.coordinator, spa),
        ])

    async_add_entities(entities)

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        "set_primary_filtration",
        SET_PRIMARY_FILTRATION_SCHEMA,
        "async_set_primary_filtration",
    )

    platform.async_register_entity_service(
        "set_secondary_filtration",
        SET_SECONDARY_FILTRATION_SCHEMA,
        "async_set_secondary_filtration",
    )
Exemple #3
0
async def async_setup_entry(
    hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
    """Set up the Sensibo climate entry."""

    coordinator: SensiboDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]

    entities = [
        SensiboClimate(coordinator, device_id)
        for device_id, device_data in coordinator.data.items()
        # Remove none climate devices
        if device_data["hvac_modes"] and device_data["temp"]
    ]

    async_add_entities(entities)

    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_ASSUME_STATE,
        {
            vol.Required(ATTR_STATE): vol.In(["on", "off"]),
        },
        "async_assume_state",
    )
Exemple #4
0
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Litter-Robot cleaner using config entry."""
    hub: LitterRobotHub = hass.data[DOMAIN][entry.entry_id]

    entities = []
    for robot in hub.account.robots:
        entities.append(
            LitterRobotCleaner(robot=robot,
                               entity_type=TYPE_LITTER_BOX,
                               hub=hub))

    async_add_entities(entities, True)

    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_RESET_WASTE_DRAWER,
        {},
        "async_reset_waste_drawer",
    )
    platform.async_register_entity_service(
        SERVICE_SET_SLEEP_MODE,
        {
            vol.Required("enabled"): cv.boolean,
            vol.Optional("start_time"): cv.time,
        },
        "async_set_sleep_mode",
    )
    platform.async_register_entity_service(
        SERVICE_SET_WAIT_TIME,
        {vol.Required("minutes"): vol.In(VALID_WAIT_TIMES)},
        "async_set_wait_time",
    )
Exemple #5
0
async def async_setup_entry(
    hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
    """Set up TotalConnect alarm panels based on a config entry."""
    alarms = []

    coordinator = hass.data[DOMAIN][entry.entry_id]

    for location_id, location in coordinator.client.locations.items():
        location_name = location.location_name
        for partition_id in location.partitions:
            alarms.append(
                TotalConnectAlarm(
                    coordinator=coordinator,
                    name=location_name,
                    location_id=location_id,
                    partition_id=partition_id,
                )
            )

    async_add_entities(alarms, True)

    # Set up services
    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_ALARM_ARM_AWAY_INSTANT,
        {},
        "async_alarm_arm_away_instant",
    )

    platform.async_register_entity_service(
        SERVICE_ALARM_ARM_HOME_INSTANT,
        {},
        "async_alarm_arm_home_instant",
    )
Exemple #6
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up AdvantageAir climate platform."""

    instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id]

    entities: list[ClimateEntity] = []
    for ac_key, ac_device in instance["coordinator"].data["aircons"].items():
        entities.append(AdvantageAirAC(instance, ac_key))
        for zone_key, zone in ac_device["zones"].items():
            # Only add zone climate control when zone is in temperature control
            if zone["type"] != 0:
                entities.append(AdvantageAirZone(instance, ac_key, zone_key))
    async_add_entities(entities)

    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        ADVANTAGE_AIR_SERVICE_SET_MYZONE,
        {},
        "set_myzone",
    )
Exemple #7
0
async def async_setup_entry(hass, entry, async_add_entities):
    """Set up the Pi-hole switch."""
    name = entry.data[CONF_NAME]
    hole_data = hass.data[PIHOLE_DOMAIN][entry.entry_id]
    switches = [
        PiHoleSwitch(
            hole_data[DATA_KEY_API],
            hole_data[DATA_KEY_COORDINATOR],
            name,
            entry.entry_id,
        )
    ]
    async_add_entities(switches, True)

    # register service
    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_DISABLE,
        {
            vol.Required(SERVICE_DISABLE_ATTR_DURATION):
            vol.All(cv.time_period_str, cv.positive_timedelta),
        },
        "async_disable",
    )
Exemple #8
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up the Agent cameras."""
    filter_urllib3_logging()
    cameras = []

    server = hass.data[AGENT_DOMAIN][config_entry.entry_id][CONNECTION]
    if not server.devices:
        _LOGGER.warning("Could not fetch cameras from Agent server")
        return

    for device in server.devices:
        if device.typeID == 2:
            camera = AgentCamera(device)
            cameras.append(camera)

    async_add_entities(cameras)

    platform = async_get_current_platform()
    for service, method in CAMERA_SERVICES.items():
        platform.async_register_entity_service(service, {}, method)
Exemple #9
0
async def async_setup_entry(hass, config_entry, async_add_entities):
    """Create the Elk-M1 sensor platform."""
    elk_data = hass.data[DOMAIN][config_entry.entry_id]
    entities = []
    elk = elk_data["elk"]
    create_elk_entities(elk_data, elk.counters, "counter", ElkCounter,
                        entities)
    create_elk_entities(elk_data, elk.keypads, "keypad", ElkKeypad, entities)
    create_elk_entities(elk_data, [elk.panel], "panel", ElkPanel, entities)
    create_elk_entities(elk_data, elk.settings, "setting", ElkSetting,
                        entities)
    create_elk_entities(elk_data, elk.zones, "zone", ElkZone, entities)
    async_add_entities(entities, True)

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_SENSOR_COUNTER_REFRESH,
        {},
        "async_counter_refresh",
    )
    platform.async_register_entity_service(
        SERVICE_SENSOR_COUNTER_SET,
        ELK_SET_COUNTER_SERVICE_SCHEMA,
        "async_counter_set",
    )
    platform.async_register_entity_service(
        SERVICE_SENSOR_ZONE_BYPASS,
        ELK_USER_CODE_SERVICE_SCHEMA,
        "async_zone_bypass",
    )
    platform.async_register_entity_service(
        SERVICE_SENSOR_ZONE_TRIGGER,
        {},
        "async_zone_trigger",
    )
Exemple #10
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up the ONVIF camera video stream."""
    platform = entity_platform.async_get_current_platform()

    # Create PTZ service
    platform.async_register_entity_service(
        SERVICE_PTZ,
        {
            vol.Optional(ATTR_PAN): vol.In([DIR_LEFT, DIR_RIGHT]),
            vol.Optional(ATTR_TILT): vol.In([DIR_UP, DIR_DOWN]),
            vol.Optional(ATTR_ZOOM): vol.In([ZOOM_OUT, ZOOM_IN]),
            vol.Optional(ATTR_DISTANCE, default=0.1): cv.small_float,
            vol.Optional(ATTR_SPEED, default=0.5): cv.small_float,
            vol.Optional(ATTR_MOVE_MODE, default=RELATIVE_MOVE): vol.In(
                [
                    CONTINUOUS_MOVE,
                    RELATIVE_MOVE,
                    ABSOLUTE_MOVE,
                    GOTOPRESET_MOVE,
                    STOP_MOVE,
                ]
            ),
            vol.Optional(ATTR_CONTINUOUS_DURATION, default=0.5): cv.small_float,
            vol.Optional(ATTR_PRESET, default="0"): cv.string,
        },
        "async_perform_ptz",
    )

    device = hass.data[DOMAIN][config_entry.unique_id]
    async_add_entities(
        [ONVIFCameraEntity(device, profile) for profile in device.profiles]
    )
Exemple #11
0
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Bond fan devices."""
    data = hass.data[DOMAIN][entry.entry_id]
    hub: BondHub = data[HUB]
    bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
    platform = entity_platform.async_get_current_platform()

    fans: list[Entity] = [
        BondFan(hub, device, bpup_subs)
        for device in hub.devices
        if DeviceType.is_fan(device.type)
    ]

    platform.async_register_entity_service(
        SERVICE_SET_FAN_SPEED_TRACKED_STATE,
        {vol.Required("speed"): vol.All(vol.Number(scale=0), vol.Range(0, 100))},
        "async_set_speed_belief",
    )

    async_add_entities(fans, True)
Exemple #12
0
async def async_setup_entry(
    hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
    """Set up the Tado climate platform."""

    tado = hass.data[DOMAIN][entry.entry_id][DATA]
    entities = await hass.async_add_executor_job(_generate_entities, tado)

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_CLIMATE_TIMER,
        CLIMATE_TIMER_SCHEMA,
        "set_timer",
    )

    platform.async_register_entity_service(
        SERVICE_TEMP_OFFSET,
        CLIMATE_TEMP_OFFSET_SCHEMA,
        "set_temp_offset",
    )

    if entities:
        async_add_entities(entities, True)
Exemple #13
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up the Flo switches from config entry."""
    devices: list[FloDeviceDataUpdateCoordinator] = hass.data[FLO_DOMAIN][
        config_entry.entry_id
    ]["devices"]
    entities = []
    for device in devices:
        if device.device_type != "puck_oem":
            entities.append(FloSwitch(device))
    async_add_entities(entities)

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_SET_AWAY_MODE, {}, "async_set_mode_away"
    )
    platform.async_register_entity_service(
        SERVICE_SET_HOME_MODE, {}, "async_set_mode_home"
    )
    platform.async_register_entity_service(
        SERVICE_RUN_HEALTH_TEST, {}, "async_run_health_test"
    )
    platform.async_register_entity_service(
        SERVICE_SET_SLEEP_MODE,
        {
            vol.Required(ATTR_SLEEP_MINUTES, default=120): vol.In(SLEEP_MINUTE_OPTIONS),
            vol.Required(ATTR_REVERT_TO_MODE, default=SYSTEM_MODE_HOME): vol.In(
                SYSTEM_REVERT_MODES
            ),
        },
        "async_set_mode_sleep",
    )
Exemple #14
0
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Verisure alarm control panel from a config entry."""
    coordinator: VerisureDataUpdateCoordinator = hass.data[DOMAIN][
        entry.entry_id]

    platform = async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_DISABLE_AUTOLOCK,
        {},
        VerisureDoorlock.disable_autolock.__name__,
    )
    platform.async_register_entity_service(
        SERVICE_ENABLE_AUTOLOCK,
        {},
        VerisureDoorlock.enable_autolock.__name__,
    )

    async_add_entities(
        VerisureDoorlock(coordinator, serial_number)
        for serial_number in coordinator.data["locks"])
Exemple #15
0
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: entity_platform.AddEntitiesCallback,
) -> None:
    """Set up number entities for UniFi Protect integration."""
    data: ProtectData = hass.data[DOMAIN][entry.entry_id]
    entities: list[ProtectDeviceEntity] = async_all_device_entities(
        data,
        ProtectSelects,
        camera_descs=CAMERA_SELECTS,
        light_descs=LIGHT_SELECTS,
        sense_descs=SENSE_SELECTS,
        viewer_descs=VIEWER_SELECTS,
        lock_descs=DOORLOCK_SELECTS,
    )

    async_add_entities(entities)
    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_SET_DOORBELL_MESSAGE,
        SET_DOORBELL_LCD_MESSAGE_SCHEMA,
        "async_set_doorbell_message",
    )
Exemple #16
0
async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up WeMo binary sensors."""
    async def _discovered_wemo(device):
        """Handle a discovered Wemo device."""
        async_add_entities([WemoHumidifier(device)])

    async_dispatcher_connect(hass, f"{WEMO_DOMAIN}.fan", _discovered_wemo)

    await asyncio.gather(*[
        _discovered_wemo(device)
        for device in hass.data[WEMO_DOMAIN]["pending"].pop("fan")
    ])

    platform = entity_platform.async_get_current_platform()

    # This will call WemoHumidifier.set_humidity(target_humidity=VALUE)
    platform.async_register_entity_service(
        SERVICE_SET_HUMIDITY, SET_HUMIDITY_SCHEMA,
        WemoHumidifier.set_humidity.__name__)

    # This will call WemoHumidifier.reset_filter_life()
    platform.async_register_entity_service(
        SERVICE_RESET_FILTER_LIFE, {},
        WemoHumidifier.reset_filter_life.__name__)
Exemple #17
0
async def async_setup_entry(hass, entry, async_add_entities):
    """Set up the Nuki lock platform."""
    data = hass.data[NUKI_DOMAIN][entry.entry_id]
    coordinator = data[DATA_COORDINATOR]

    entities = [NukiLockEntity(coordinator, lock) for lock in data[DATA_LOCKS]]
    entities.extend(
        [NukiOpenerEntity(coordinator, opener) for opener in data[DATA_OPENERS]]
    )
    async_add_entities(entities)

    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        "lock_n_go",
        {
            vol.Optional(ATTR_UNLATCH, default=False): cv.boolean,
        },
        "lock_n_go",
        "set_continuous_mode",
        {
            vol.Required(ATTR_ENABLE): cv.boolean,
        },
        "set_continuous_mode",
    )
Exemple #18
0
async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up AdvantageAir sensor platform."""

    instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id]

    entities = []
    for ac_key, ac_device in instance["coordinator"].data["aircons"].items():
        entities.append(AdvantageAirTimeTo(instance, ac_key, "On"))
        entities.append(AdvantageAirTimeTo(instance, ac_key, "Off"))
        for zone_key, zone in ac_device["zones"].items():
            # Only show damper sensors when zone is in temperature control
            if zone["type"] != 0:
                entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key))
            # Only show wireless signal strength sensors when using wireless sensors
            if zone["rssi"] > 0:
                entities.append(AdvantageAirZoneSignal(instance, ac_key, zone_key))
    async_add_entities(entities)

    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        ADVANTAGE_AIR_SERVICE_SET_TIME_TO,
        {vol.Required("minutes"): cv.positive_int},
        "set_time_to",
    )
async def async_setup_platform(
    hass: HomeAssistant,
    config: ConfigType,
    async_add_entities: AddEntitiesCallback,
    discovery_info: DiscoveryInfoType | None = None,
) -> None:
    """Set up the Openhome platform."""

    if not discovery_info:
        return

    openhome_data = hass.data.setdefault(DATA_OPENHOME, set())

    name = discovery_info.get("name")
    description = discovery_info.get("ssdp_description")

    _LOGGER.info("Openhome device found: %s", name)
    device = await hass.async_add_executor_job(Device, description)
    await device.init()

    # if device has already been discovered
    if device.uuid() in openhome_data:
        return

    entity = OpenhomeDevice(hass, device)

    async_add_entities([entity])
    openhome_data.add(device.uuid())

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_INVOKE_PIN,
        {vol.Required(ATTR_PIN_INDEX): cv.positive_int},
        "async_invoke_pin",
    )
Exemple #20
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Sonos from a config entry."""
    platform = entity_platform.async_get_current_platform()

    @callback
    def async_create_entities(speaker: SonosSpeaker) -> None:
        """Handle device discovery and create entities."""
        async_add_entities([SonosMediaPlayerEntity(speaker)])

    @service.verify_domain_control(hass, SONOS_DOMAIN)
    async def async_service_handle(service_call: ServiceCall) -> None:
        """Handle dispatched services."""
        assert platform is not None
        entities = await platform.async_extract_from_service(service_call)

        if not entities:
            return

        speakers = []
        for entity in entities:
            assert isinstance(entity, SonosMediaPlayerEntity)
            speakers.append(entity.speaker)

        if service_call.service == SERVICE_JOIN:
            master = platform.entities.get(service_call.data[ATTR_MASTER])
            if master:
                await SonosSpeaker.join_multi(hass, master.speaker, speakers
                                              )  # type: ignore[arg-type]
            else:
                _LOGGER.error(
                    "Invalid master specified for join service: %s",
                    service_call.data[ATTR_MASTER],
                )
        elif service_call.service == SERVICE_UNJOIN:
            await SonosSpeaker.unjoin_multi(hass,
                                            speakers)  # type: ignore[arg-type]
        elif service_call.service == SERVICE_SNAPSHOT:
            await SonosSpeaker.snapshot_multi(
                hass,
                speakers,
                service_call.data[ATTR_WITH_GROUP]  # type: ignore[arg-type]
            )
        elif service_call.service == SERVICE_RESTORE:
            await SonosSpeaker.restore_multi(
                hass,
                speakers,
                service_call.data[ATTR_WITH_GROUP]  # type: ignore[arg-type]
            )

    config_entry.async_on_unload(
        async_dispatcher_connect(hass, SONOS_CREATE_MEDIA_PLAYER,
                                 async_create_entities))

    hass.services.async_register(
        SONOS_DOMAIN,
        SERVICE_JOIN,
        async_service_handle,
        cv.make_entity_service_schema(
            {vol.Required(ATTR_MASTER): cv.entity_id}),
    )

    hass.services.async_register(
        SONOS_DOMAIN,
        SERVICE_UNJOIN,
        async_service_handle,
        cv.make_entity_service_schema({}),
    )

    join_unjoin_schema = cv.make_entity_service_schema(
        {vol.Optional(ATTR_WITH_GROUP, default=True): cv.boolean})

    hass.services.async_register(SONOS_DOMAIN, SERVICE_SNAPSHOT,
                                 async_service_handle, join_unjoin_schema)

    hass.services.async_register(SONOS_DOMAIN, SERVICE_RESTORE,
                                 async_service_handle, join_unjoin_schema)

    platform.async_register_entity_service(  # type: ignore
        SERVICE_SET_TIMER,
        {
            vol.Required(ATTR_SLEEP_TIME): vol.All(
                vol.Coerce(int), vol.Range(min=0, max=86399)
            )
        },
        "set_sleep_timer",
    )

    platform.async_register_entity_service(SERVICE_CLEAR_TIMER, {},
                                           "clear_sleep_timer")  # type: ignore

    platform.async_register_entity_service(  # type: ignore
        SERVICE_UPDATE_ALARM,
        {
            vol.Required(ATTR_ALARM_ID): cv.positive_int,
            vol.Optional(ATTR_TIME): cv.time,
            vol.Optional(ATTR_VOLUME): cv.small_float,
            vol.Optional(ATTR_ENABLED): cv.boolean,
            vol.Optional(ATTR_INCLUDE_LINKED_ZONES): cv.boolean,
        },
        "set_alarm",
    )

    platform.async_register_entity_service(  # type: ignore
        SERVICE_SET_OPTION,
        {
            vol.Optional(ATTR_BUTTONS_ENABLED): cv.boolean,
            vol.Optional(ATTR_NIGHT_SOUND): cv.boolean,
            vol.Optional(ATTR_SPEECH_ENHANCE): cv.boolean,
            vol.Optional(ATTR_STATUS_LIGHT): cv.boolean,
        },
        "set_option",
    )

    platform.async_register_entity_service(  # type: ignore
        SERVICE_PLAY_QUEUE,
        {vol.Optional(ATTR_QUEUE_POSITION): cv.positive_int},
        "play_queue",
    )

    platform.async_register_entity_service(  # type: ignore
        SERVICE_REMOVE_FROM_QUEUE,
        {vol.Optional(ATTR_QUEUE_POSITION): cv.positive_int},
        "remove_from_queue",
    )
Exemple #21
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up the Motion Blind from a config entry."""
    entities = []
    motion_gateway = hass.data[DOMAIN][config_entry.entry_id][KEY_GATEWAY]
    coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR]
    sw_version = hass.data[DOMAIN][config_entry.entry_id][KEY_VERSION]

    for blind in motion_gateway.device_list.values():
        if blind.type in POSITION_DEVICE_MAP:
            entities.append(
                MotionPositionDevice(
                    coordinator,
                    blind,
                    POSITION_DEVICE_MAP[blind.type],
                    sw_version,
                ))

        elif blind.type in TILT_DEVICE_MAP:
            entities.append(
                MotionTiltDevice(
                    coordinator,
                    blind,
                    TILT_DEVICE_MAP[blind.type],
                    sw_version,
                ))

        elif blind.type in TDBU_DEVICE_MAP:
            entities.append(
                MotionTDBUDevice(
                    coordinator,
                    blind,
                    TDBU_DEVICE_MAP[blind.type],
                    sw_version,
                    "Top",
                ))
            entities.append(
                MotionTDBUDevice(
                    coordinator,
                    blind,
                    TDBU_DEVICE_MAP[blind.type],
                    sw_version,
                    "Bottom",
                ))
            entities.append(
                MotionTDBUDevice(
                    coordinator,
                    blind,
                    TDBU_DEVICE_MAP[blind.type],
                    sw_version,
                    "Combined",
                ))

        else:
            _LOGGER.warning(
                "Blind type '%s' not yet supported, assuming RollerBlind",
                blind.blind_type,
            )
            entities.append(
                MotionPositionDevice(
                    coordinator,
                    blind,
                    POSITION_DEVICE_MAP[BlindType.RollerBlind],
                    sw_version,
                ))

    async_add_entities(entities)

    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_SET_ABSOLUTE_POSITION,
        SET_ABSOLUTE_POSITION_SCHEMA,
        "async_set_absolute_position",
    )
Exemple #22
0
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up LIFX from a config entry."""
    # Priority 1: manual config
    if not (interfaces := hass.data[LIFX_DOMAIN].get(DOMAIN)):
        # Priority 2: Home Assistant enabled interfaces
        ip_addresses = (
            source_ip
            for source_ip in await network.async_get_enabled_source_ips(hass)
            if isinstance(source_ip, IPv4Address) and not source_ip.is_loopback
        )
        interfaces = [{CONF_SERVER: str(ip)} for ip in ip_addresses]

    platform = entity_platform.async_get_current_platform()
    lifx_manager = LIFXManager(hass, platform, config_entry,
                               async_add_entities)
    hass.data[DATA_LIFX_MANAGER] = lifx_manager

    for interface in interfaces:
        lifx_manager.start_discovery(interface)


def lifx_features(bulb):
    """Return a feature map for this bulb, or a default map if unknown."""
    return aiolifx().products.features_map.get(
        bulb.product) or aiolifx().products.features_map.get(1)


def find_hsbk(hass, **kwargs):
async def async_setup_platform(hass,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up the Yamaha platform."""

    # Keep track of configured receivers so that we don't end up
    # discovering a receiver dynamically that we have static config
    # for. Map each device from its zone_id .
    known_zones = hass.data.setdefault(DATA_YAMAHA, set())

    # Get the Infos for configuration from config (YAML) or Discovery
    config_info = YamahaConfigInfo(config=config,
                                   discovery_info=discovery_info)
    # Async check if the Receivers are there in the network
    receivers = await hass.async_add_executor_job(_discovery, config_info)

    entities = []
    for receiver in receivers:
        if receiver.zone in config_info.zone_ignore:
            continue

        entity = YamahaDevice(
            config_info.name,
            receiver,
            config_info.source_ignore,
            config_info.source_names,
            config_info.zone_names,
        )

        # Only add device if it's not already added
        if entity.zone_id not in known_zones:
            known_zones.add(entity.zone_id)
            entities.append(entity)
        else:
            _LOGGER.debug("Ignoring duplicate receiver: %s", config_info.name)

    async_add_entities(entities)

    # Register Service 'select_scene'
    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_SELECT_SCENE,
        {vol.Required(ATTR_SCENE): cv.string},
        "set_scene",
    )
    # Register Service 'enable_output'
    platform.async_register_entity_service(
        SERVICE_ENABLE_OUTPUT,
        {
            vol.Required(ATTR_ENABLED): cv.boolean,
            vol.Required(ATTR_PORT): cv.string
        },
        "enable_output",
    )
    # Register Service 'menu_cursor'
    platform.async_register_entity_service(
        SERVICE_MENU_CURSOR,
        {vol.Required(ATTR_CURSOR): vol.In(CURSOR_TYPE_MAP)},
        YamahaDevice.menu_cursor.__name__,
    )
Exemple #24
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up the Rachio switches."""
    zone_entities = []
    has_flex_sched = False
    entities = await hass.async_add_executor_job(_create_entities, hass,
                                                 config_entry)
    for entity in entities:
        if isinstance(entity, RachioZone):
            zone_entities.append(entity)
        if isinstance(entity,
                      RachioSchedule) and entity.type == SCHEDULE_TYPE_FLEX:
            has_flex_sched = True

    async_add_entities(entities)
    _LOGGER.info("%d Rachio switch(es) added", len(entities))

    def start_multiple(service: ServiceCall) -> None:
        """Service to start multiple zones in sequence."""
        zones_list = []
        person = hass.data[DOMAIN_RACHIO][config_entry.entry_id]
        entity_id = service.data[ATTR_ENTITY_ID]
        duration = iter(service.data[ATTR_DURATION])
        default_time = service.data[ATTR_DURATION][0]
        entity_to_zone_id = {
            entity.entity_id: entity.zone_id
            for entity in zone_entities
        }

        for (count, data) in enumerate(entity_id):
            if data in entity_to_zone_id:
                # Time can be passed as a list per zone,
                # or one time for all zones
                time = int(next(duration, default_time)) * 60
                zones_list.append({
                    ATTR_ID: entity_to_zone_id.get(data),
                    ATTR_DURATION: time,
                    ATTR_SORT_ORDER: count,
                })

        if len(zones_list) != 0:
            person.start_multiple_zones(zones_list)
            _LOGGER.debug("Starting zone(s) %s", entity_id)
        else:
            raise HomeAssistantError(
                "No matching zones found in given entity_ids")

    hass.services.async_register(
        DOMAIN_RACHIO,
        SERVICE_START_MULTIPLE_ZONES,
        start_multiple,
        schema=START_MULTIPLE_ZONES_SCHEMA,
    )

    if has_flex_sched:
        platform = entity_platform.async_get_current_platform()
        platform.async_register_entity_service(
            SERVICE_SET_ZONE_MOISTURE,
            {vol.Required(ATTR_PERCENT): cv.positive_int},
            "set_moisture_percent",
        )
Exemple #25
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Z-Wave sensor from config entry."""
    client: ZwaveClient = hass.data[DOMAIN][config_entry.entry_id][DATA_CLIENT]

    @callback
    def async_add_sensor(info: ZwaveDiscoveryInfo) -> None:
        """Add Z-Wave Sensor."""
        driver = client.driver
        assert driver is not None  # Driver is ready before platforms are loaded.
        entities: list[ZWaveBaseEntity] = []

        if info.platform_data:
            data: NumericSensorDataTemplateData = info.platform_data
        else:
            data = NumericSensorDataTemplateData()
        entity_description = ENTITY_DESCRIPTION_KEY_MAP.get(
            data.entity_description_key or "",
            SensorEntityDescription("base_sensor"))

        if info.platform_hint == "string_sensor":
            entities.append(
                ZWaveStringSensor(config_entry, driver, info,
                                  entity_description))
        elif info.platform_hint == "numeric_sensor":
            entities.append(
                ZWaveNumericSensor(
                    config_entry,
                    driver,
                    info,
                    entity_description,
                    data.unit_of_measurement,
                ))
        elif info.platform_hint == "list_sensor":
            entities.append(
                ZWaveListSensor(config_entry, driver, info,
                                entity_description))
        elif info.platform_hint == "config_parameter":
            entities.append(
                ZWaveConfigParameterSensor(config_entry, driver, info,
                                           entity_description))
        elif info.platform_hint == "meter":
            entities.append(
                ZWaveMeterSensor(config_entry, driver, info,
                                 entity_description))
        else:
            LOGGER.warning(
                "Sensor not implemented for %s/%s",
                info.platform_hint,
                info.primary_value.property_name,
            )
            return

        async_add_entities(entities)

    @callback
    def async_add_node_status_sensor(node: ZwaveNode) -> None:
        """Add node status sensor."""
        driver = client.driver
        assert driver is not None  # Driver is ready before platforms are loaded.
        async_add_entities([ZWaveNodeStatusSensor(config_entry, driver, node)])

    config_entry.async_on_unload(
        async_dispatcher_connect(
            hass,
            f"{DOMAIN}_{config_entry.entry_id}_add_{SENSOR_DOMAIN}",
            async_add_sensor,
        ))

    config_entry.async_on_unload(
        async_dispatcher_connect(
            hass,
            f"{DOMAIN}_{config_entry.entry_id}_add_node_status_sensor",
            async_add_node_status_sensor,
        ))

    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(
        SERVICE_RESET_METER,
        {
            vol.Optional(ATTR_METER_TYPE): vol.Coerce(int),
            vol.Optional(ATTR_VALUE): vol.Coerce(int),
        },
        "async_reset_meter",
    )
Exemple #26
0
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Bond light devices."""
    data = hass.data[DOMAIN][entry.entry_id]
    hub: BondHub = data[HUB]
    bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
    platform = entity_platform.async_get_current_platform()

    platform = entity_platform.async_get_current_platform()
    for service in ENTITY_SERVICES:
        platform.async_register_entity_service(
            service,
            {},
            f"async_{service}",
        )

    fan_lights: list[Entity] = [
        BondLight(hub, device, bpup_subs) for device in hub.devices
        if DeviceType.is_fan(device.type) and device.supports_light()
        and not (device.supports_up_light() and device.supports_down_light())
    ]

    fan_up_lights: list[Entity] = [
        BondUpLight(hub, device, bpup_subs, "up_light")
        for device in hub.devices
        if DeviceType.is_fan(device.type) and device.supports_up_light()
    ]

    fan_down_lights: list[Entity] = [
        BondDownLight(hub, device, bpup_subs, "down_light")
        for device in hub.devices
        if DeviceType.is_fan(device.type) and device.supports_down_light()
    ]

    fireplaces: list[Entity] = [
        BondFireplace(hub, device, bpup_subs) for device in hub.devices
        if DeviceType.is_fireplace(device.type)
    ]

    fp_lights: list[Entity] = [
        BondLight(hub, device, bpup_subs, "light") for device in hub.devices
        if DeviceType.is_fireplace(device.type) and device.supports_light()
    ]

    lights: list[Entity] = [
        BondLight(hub, device, bpup_subs) for device in hub.devices
        if DeviceType.is_light(device.type)
    ]

    platform.async_register_entity_service(
        SERVICE_SET_LIGHT_BRIGHTNESS_TRACKED_STATE,
        {
            vol.Required(ATTR_BRIGHTNESS):
            vol.All(vol.Number(scale=0), vol.Range(0, 255))
        },
        "async_set_brightness_belief",
    )

    platform.async_register_entity_service(
        SERVICE_SET_LIGHT_POWER_TRACKED_STATE,
        {vol.Required(ATTR_POWER_STATE): vol.All(cv.boolean)},
        "async_set_power_belief",
    )

    async_add_entities(
        fan_lights + fan_up_lights + fan_down_lights + fireplaces + fp_lights +
        lights,
        True,
    )
Exemple #27
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry,
                            async_add_entities: AddEntitiesCallback) -> None:
    """Set up RainMachine switches based on a config entry."""
    platform = entity_platform.async_get_current_platform()

    alter_program_schema = {vol.Required(CONF_PROGRAM_ID): cv.positive_int}
    alter_zone_schema = {vol.Required(CONF_ZONE_ID): cv.positive_int}

    for service_name, schema, method in (
        ("disable_program", alter_program_schema, "async_disable_program"),
        ("disable_zone", alter_zone_schema, "async_disable_zone"),
        ("enable_program", alter_program_schema, "async_enable_program"),
        ("enable_zone", alter_zone_schema, "async_enable_zone"),
        (
            "pause_watering",
            {
                vol.Required(CONF_SECONDS): cv.positive_int
            },
            "async_pause_watering",
        ),
        (
            "start_program",
            {
                vol.Required(CONF_PROGRAM_ID): cv.positive_int
            },
            "async_start_program",
        ),
        (
            "start_zone",
            {
                vol.Required(CONF_ZONE_ID):
                cv.positive_int,
                vol.Optional(CONF_ZONE_RUN_TIME, default=DEFAULT_ZONE_RUN):
                cv.positive_int,
            },
            "async_start_zone",
        ),
        ("stop_all", {}, "async_stop_all"),
        (
            "stop_program",
            {
                vol.Required(CONF_PROGRAM_ID): cv.positive_int
            },
            "async_stop_program",
        ),
        ("stop_zone", {
            vol.Required(CONF_ZONE_ID): cv.positive_int
        }, "async_stop_zone"),
        ("unpause_watering", {}, "async_unpause_watering"),
    ):
        platform.async_register_entity_service(service_name, schema, method)

    controller = hass.data[DOMAIN][DATA_CONTROLLER][entry.entry_id]
    programs_coordinator = hass.data[DOMAIN][DATA_COORDINATOR][
        entry.entry_id][DATA_PROGRAMS]
    zones_coordinator = hass.data[DOMAIN][DATA_COORDINATOR][
        entry.entry_id][DATA_ZONES]

    entities: list[RainMachineProgram | RainMachineZone] = [
        RainMachineProgram(
            programs_coordinator,
            controller,
            entry,
            RainMachineSwitchDescription(
                key=f"RainMachineProgram_{uid}",
                name=program["name"],
                uid=uid,
            ),
        ) for uid, program in programs_coordinator.data.items()
    ]
    entities.extend([
        RainMachineZone(
            zones_coordinator,
            controller,
            entry,
            RainMachineSwitchDescription(
                key=f"RainMachineZone_{uid}",
                name=zone["name"],
                uid=uid,
            ),
        ) for uid, zone in zones_coordinator.data.items()
    ])

    async_add_entities(entities)
async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up the Xiaomi vacuum cleaner robot from a config entry."""
    entities = []

    if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
        name = config_entry.title
        unique_id = config_entry.unique_id

        mirobo = MiroboVacuum(
            name,
            hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE],
            config_entry,
            unique_id,
            hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR],
        )
        entities.append(mirobo)

        platform = entity_platform.async_get_current_platform()

        platform.async_register_entity_service(
            SERVICE_START_REMOTE_CONTROL,
            {},
            MiroboVacuum.async_remote_control_start.__name__,
        )

        platform.async_register_entity_service(
            SERVICE_STOP_REMOTE_CONTROL,
            {},
            MiroboVacuum.async_remote_control_stop.__name__,
        )

        platform.async_register_entity_service(
            SERVICE_MOVE_REMOTE_CONTROL,
            {
                vol.Optional(ATTR_RC_VELOCITY):
                vol.All(vol.Coerce(float), vol.Clamp(min=-0.29, max=0.29)),
                vol.Optional(ATTR_RC_ROTATION):
                vol.All(vol.Coerce(int), vol.Clamp(min=-179, max=179)),
                vol.Optional(ATTR_RC_DURATION):
                cv.positive_int,
            },
            MiroboVacuum.async_remote_control_move.__name__,
        )

        platform.async_register_entity_service(
            SERVICE_MOVE_REMOTE_CONTROL_STEP,
            {
                vol.Optional(ATTR_RC_VELOCITY):
                vol.All(vol.Coerce(float), vol.Clamp(min=-0.29, max=0.29)),
                vol.Optional(ATTR_RC_ROTATION):
                vol.All(vol.Coerce(int), vol.Clamp(min=-179, max=179)),
                vol.Optional(ATTR_RC_DURATION):
                cv.positive_int,
            },
            MiroboVacuum.async_remote_control_move_step.__name__,
        )

        platform.async_register_entity_service(
            SERVICE_CLEAN_ZONE,
            {
                vol.Required(ATTR_ZONE_ARRAY):
                vol.All(
                    list,
                    [
                        vol.ExactSequence([
                            vol.Coerce(int),
                            vol.Coerce(int),
                            vol.Coerce(int),
                            vol.Coerce(int),
                        ])
                    ],
                ),
                vol.Required(ATTR_ZONE_REPEATER):
                vol.All(vol.Coerce(int), vol.Clamp(min=1, max=3)),
            },
            MiroboVacuum.async_clean_zone.__name__,
        )

        platform.async_register_entity_service(
            SERVICE_GOTO,
            {
                vol.Required("x_coord"): vol.Coerce(int),
                vol.Required("y_coord"): vol.Coerce(int),
            },
            MiroboVacuum.async_goto.__name__,
        )
        platform.async_register_entity_service(
            SERVICE_CLEAN_SEGMENT,
            {
                vol.Required("segments"):
                vol.Any(vol.Coerce(int), [vol.Coerce(int)])
            },
            MiroboVacuum.async_clean_segment.__name__,
        )

    async_add_entities(entities, update_before_add=True)
Exemple #29
0
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: entity_platform.AddEntitiesCallback,
) -> None:
    """Set up Ezviz cameras based on a config entry."""

    coordinator: EzvizDataUpdateCoordinator = hass.data[DOMAIN][
        entry.entry_id][DATA_COORDINATOR]

    camera_entities = []

    for camera, value in coordinator.data.items():

        camera_rtsp_entry = [
            item for item in hass.config_entries.async_entries(DOMAIN)
            if item.unique_id == camera and item.source != SOURCE_IGNORE
        ]

        # There seem to be a bug related to localRtspPort in Ezviz API.
        local_rtsp_port = (value["local_rtsp_port"]
                           if value["local_rtsp_port"] != 0 else
                           DEFAULT_RTSP_PORT)

        if camera_rtsp_entry:

            ffmpeg_arguments = camera_rtsp_entry[0].options[
                CONF_FFMPEG_ARGUMENTS]
            camera_username = camera_rtsp_entry[0].data[CONF_USERNAME]
            camera_password = camera_rtsp_entry[0].data[CONF_PASSWORD]

            camera_rtsp_stream = f"rtsp://{camera_username}:{camera_password}@{value['local_ip']}:{local_rtsp_port}{ffmpeg_arguments}"
            _LOGGER.debug(
                "Configuring Camera %s with ip: %s rtsp port: %s ffmpeg arguments: %s",
                camera,
                value["local_ip"],
                local_rtsp_port,
                ffmpeg_arguments,
            )

        else:

            hass.async_create_task(
                hass.config_entries.flow.async_init(
                    DOMAIN,
                    context={"source": SOURCE_DISCOVERY},
                    data={
                        ATTR_SERIAL: camera,
                        CONF_IP_ADDRESS: value["local_ip"],
                    },
                ))

            _LOGGER.warning(
                "Found camera with serial %s without configuration. Please go to integration to complete setup",
                camera,
            )

            ffmpeg_arguments = DEFAULT_FFMPEG_ARGUMENTS
            camera_username = DEFAULT_CAMERA_USERNAME
            camera_password = None
            camera_rtsp_stream = ""

        camera_entities.append(
            EzvizCamera(
                hass,
                coordinator,
                camera,
                camera_username,
                camera_password,
                camera_rtsp_stream,
                local_rtsp_port,
                ffmpeg_arguments,
            ))

    async_add_entities(camera_entities)

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_PTZ,
        {
            vol.Required(ATTR_DIRECTION):
            vol.In([DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT]),
            vol.Required(ATTR_SPEED):
            cv.positive_int,
        },
        "perform_ptz",
    )

    platform.async_register_entity_service(
        SERVICE_ALARM_TRIGER,
        {
            vol.Required(ATTR_ENABLE): cv.positive_int,
        },
        "perform_sound_alarm",
    )

    platform.async_register_entity_service(SERVICE_WAKE_DEVICE, {},
                                           "perform_wake_device")

    platform.async_register_entity_service(
        SERVICE_ALARM_SOUND,
        {vol.Required(ATTR_LEVEL): cv.positive_int},
        "perform_alarm_sound",
    )

    platform.async_register_entity_service(
        SERVICE_DETECTION_SENSITIVITY,
        {
            vol.Required(ATTR_LEVEL): cv.positive_int,
            vol.Required(ATTR_TYPE): cv.positive_int,
        },
        "perform_set_alarm_detection_sensibility",
    )
async def async_setup_platform(hass,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up the Xiaomi IR Remote (Chuangmi IR) platform."""
    host = config[CONF_HOST]
    token = config[CONF_TOKEN]

    # Create handler
    _LOGGER.info("Initializing with host %s (token %s...)", host, token[:5])

    # The Chuang Mi IR Remote Controller wants to be re-discovered every
    # 5 minutes. As long as polling is disabled the device should be
    # re-discovered (lazy_discover=False) in front of every command.
    device = ChuangmiIr(host, token, lazy_discover=False)

    # Check that we can communicate with device.
    try:
        device_info = await hass.async_add_executor_job(device.info)
        model = device_info.model
        unique_id = f"{model}-{device_info.mac_address}"
        _LOGGER.info(
            "%s %s %s detected",
            model,
            device_info.firmware_version,
            device_info.hardware_version,
        )
    except DeviceException as ex:
        _LOGGER.error("Device unavailable or token incorrect: %s", ex)
        raise PlatformNotReady from ex

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    friendly_name = config.get(CONF_NAME,
                               f"xiaomi_miio_{host.replace('.', '_')}")
    slot = config.get(CONF_SLOT)
    timeout = config.get(CONF_TIMEOUT)

    xiaomi_miio_remote = XiaomiMiioRemote(friendly_name, device, unique_id,
                                          slot, timeout,
                                          config.get(CONF_COMMANDS))

    hass.data[DATA_KEY][host] = xiaomi_miio_remote

    async_add_entities([xiaomi_miio_remote])

    async def async_service_led_off_handler(entity, service):
        """Handle set_led_off command."""
        await hass.async_add_executor_job(entity.device.set_indicator_led,
                                          False)

    async def async_service_led_on_handler(entity, service):
        """Handle set_led_on command."""
        await hass.async_add_executor_job(entity.device.set_indicator_led,
                                          True)

    async def async_service_learn_handler(entity, service):
        """Handle a learn command."""
        device = entity.device

        slot = service.data.get(CONF_SLOT, entity.slot)

        await hass.async_add_executor_job(device.learn, slot)

        timeout = service.data.get(CONF_TIMEOUT, entity.timeout)

        _LOGGER.info("Press the key you want Home Assistant to learn")
        start_time = utcnow()
        while (utcnow() - start_time) < timedelta(seconds=timeout):
            message = await hass.async_add_executor_job(device.read, slot)
            _LOGGER.debug("Message received from device: '%s'", message)

            if "code" in message and message["code"]:
                log_msg = "Received command is: {}".format(message["code"])
                _LOGGER.info(log_msg)
                hass.components.persistent_notification.async_create(
                    log_msg, title="Xiaomi Miio Remote")
                return

            if "error" in message and message["error"][
                    "message"] == "learn timeout":
                await hass.async_add_executor_job(device.learn, slot)

            await asyncio.sleep(1)

        _LOGGER.error("Timeout. No infrared command captured")
        hass.components.persistent_notification.async_create(
            "Timeout. No infrared command captured",
            title="Xiaomi Miio Remote")

    platform = entity_platform.async_get_current_platform()

    platform.async_register_entity_service(
        SERVICE_LEARN,
        {
            vol.Optional(CONF_TIMEOUT, default=10):
            cv.positive_int,
            vol.Optional(CONF_SLOT, default=1):
            vol.All(int, vol.Range(min=1, max=1000000)),
        },
        async_service_learn_handler,
    )
    platform.async_register_entity_service(
        SERVICE_SET_REMOTE_LED_ON,
        {},
        async_service_led_on_handler,
    )
    platform.async_register_entity_service(
        SERVICE_SET_REMOTE_LED_OFF,
        {},
        async_service_led_off_handler,
    )