<commit_before>"""
Support for Xiaomi Philips Lights (LED Ball & Ceiling Lamp, Eyecare Lamp 2).

For more details about this platform, please refer to the documentation
https://home-assistant.io/components/light.xiaomi_miio/
"""
import asyncio
import datetime
from datetime import timedelta
from functools import partial
import logging
from math import ceil

import voluptuous as vol

from homeassistant.components.light import (
    ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_ENTITY_ID, DOMAIN, PLATFORM_SCHEMA,
    SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, Light)
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_TOKEN
from homeassistant.exceptions import PlatformNotReady
import homeassistant.helpers.config_validation as cv
from homeassistant.util import dt

REQUIREMENTS = ['python-miio==0.4.3', 'construct==2.9.45']

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = 'Xiaomi Philips Light'
DATA_KEY = 'light.xiaomi_miio'

CONF_MODEL = 'model'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_HOST): cv.string,
    vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)),
    vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
    vol.Optional(CONF_MODEL): vol.In(
        ['philips.light.sread1',
         'philips.light.ceiling',
         'philips.light.zyceiling',
         'philips.light.bulb',
         'philips.light.candle',
         'philips.light.candle2',
         'philips.light.mono1',
         ]),
})

# The light does not accept cct values < 1
CCT_MIN = 1
CCT_MAX = 100

DELAYED_TURN_OFF_MAX_DEVIATION_SECONDS = 4
DELAYED_TURN_OFF_MAX_DEVIATION_MINUTES = 1

SUCCESS = ['ok']
ATTR_MODEL = 'model'
ATTR_SCENE = 'scene'
ATTR_DELAYED_TURN_OFF = 'delayed_turn_off'
ATTR_TIME_PERIOD = 'time_period'
ATTR_NIGHT_LIGHT_MODE = 'night_light_mode'
ATTR_AUTOMATIC_COLOR_TEMPERATURE = 'automatic_color_temperature'
ATTR_REMINDER = 'reminder'
ATTR_EYECARE_MODE = 'eyecare_mode'

SERVICE_SET_SCENE = 'xiaomi_miio_set_scene'
SERVICE_SET_DELAYED_TURN_OFF = 'xiaomi_miio_set_delayed_turn_off'
SERVICE_REMINDER_ON = 'xiaomi_miio_reminder_on'
SERVICE_REMINDER_OFF = 'xiaomi_miio_reminder_off'
SERVICE_NIGHT_LIGHT_MODE_ON = 'xiaomi_miio_night_light_mode_on'
SERVICE_NIGHT_LIGHT_MODE_OFF = 'xiaomi_miio_night_light_mode_off'
SERVICE_EYECARE_MODE_ON = 'xiaomi_miio_eyecare_mode_on'
SERVICE_EYECARE_MODE_OFF = 'xiaomi_miio_eyecare_mode_off'

XIAOMI_MIIO_SERVICE_SCHEMA = vol.Schema({
    vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
})

SERVICE_SCHEMA_SET_SCENE = XIAOMI_MIIO_SERVICE_SCHEMA.extend({
    vol.Required(ATTR_SCENE):
        vol.All(vol.Coerce(int), vol.Clamp(min=1, max=4))
})

SERVICE_SCHEMA_SET_DELAYED_TURN_OFF = XIAOMI_MIIO_SERVICE_SCHEMA.extend({
    vol.Required(ATTR_TIME_PERIOD):
        vol.All(cv.time_period, cv.positive_timedelta)
})

SERVICE_TO_METHOD = {
    SERVICE_SET_DELAYED_TURN_OFF: {
        'method': 'async_set_delayed_turn_off',
        'schema': SERVICE_SCHEMA_SET_DELAYED_TURN_OFF},
    SERVICE_SET_SCENE: {
        'method': 'async_set_scene',
        'schema': SERVICE_SCHEMA_SET_SCENE},
    SERVICE_REMINDER_ON: {'method': 'async_reminder_on'},
    SERVICE_REMINDER_OFF: {'method': 'async_reminder_off'},
    SERVICE_NIGHT_LIGHT_MODE_ON: {'method': 'async_night_light_mode_on'},
    SERVICE_NIGHT_LIGHT_MODE_OFF: {'method': 'async_night_light_mode_off'},
    SERVICE_EYECARE_MODE_ON: {'method': 'async_eyecare_mode_on'},
    SERVICE_EYECARE_MODE_OFF: {'method': 'async_eyecare_mode_off'},
}


async def async_setup_platform(hass, config, async_add_entities,
                               discovery_info=None):
    """Set up the light from config."""
    from miio import Device, DeviceException
    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    name = config.get(CONF_NAME)
    token = config.get(CONF_TOKEN)
    model = config.get(CONF_MODEL)

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

    devices = []
    unique_id = None

    if model is None:
        try:
            miio_device = Device(host, token)
            device_info = miio_device.info()
            model = device_info.model
            unique_id = "{}-{}".format(model, device_info.mac_address)
            _LOGGER.info("%s %s %s detected",
                         model,
                         device_info.firmware_version,
                         device_info.hardware_version)
        except DeviceException:
            raise PlatformNotReady

    if model == 'philips.light.sread1':
        from miio import PhilipsEyecare
        light = PhilipsEyecare(host, token)
        primary_device = XiaomiPhilipsEyecareLamp(
            name, light, model, unique_id)
        devices.append(primary_device)
        hass.data[DATA_KEY][host] = primary_device

        secondary_device = XiaomiPhilipsEyecareLampAmbientLight(
            name, light, model, unique_id)
        devices.append(secondary_device)
        # The ambient light doesn't expose additional services.
        # A hass.data[DATA_KEY] entry isn't needed.
    elif model in ['philips.light.ceiling', 'philips.light.zyceiling']:
        from miio import Ceil
        light = Ceil(host, token)
        device = XiaomiPhilipsCeilingLamp(name, light, model, unique_id)
        devices.append(device)
        hass.data[DATA_KEY][host] = device
    elif model in ['philips.light.bulb',
                   'philips.light.candle',
                   'philips.light.candle2']:
        from miio import PhilipsBulb
        light = PhilipsBulb(host, token)
        device = XiaomiPhilipsBulb(name, light, model, unique_id)
        devices.append(device)
        hass.data[DATA_KEY][host] = device
    elif model == 'philips.light.mono1':
        from miio import PhilipsBulb
        light = PhilipsBulb(host, token)
        device = XiaomiPhilipsGenericLight(name, light, model, unique_id)
        devices.append(device)
        hass.data[DATA_KEY][host] = device
    else:
        _LOGGER.error(
            'Unsupported device found! Please create an issue at '
            'https://github.com/syssi/philipslight/issues '
            'and provide the following data: %s', model)
        return False

    async_add_entities(devices, update_before_add=True)

    async def async_service_handler(service):<commit_msg>Add Philips Zhirui Downlight support (#18455)<commit_after>"""
Support for Xiaomi Philips Lights (LED Ball & Ceiling Lamp, Eyecare Lamp 2).

For more details about this platform, please refer to the documentation
https://home-assistant.io/components/light.xiaomi_miio/
"""
import asyncio
import datetime
from datetime import timedelta
from functools import partial
import logging
from math import ceil

import voluptuous as vol

from homeassistant.components.light import (
    ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_ENTITY_ID, DOMAIN, PLATFORM_SCHEMA,
    SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, Light)
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_TOKEN
from homeassistant.exceptions import PlatformNotReady
import homeassistant.helpers.config_validation as cv
from homeassistant.util import dt

REQUIREMENTS = ['python-miio==0.4.3', 'construct==2.9.45']

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = 'Xiaomi Philips Light'
DATA_KEY = 'light.xiaomi_miio'

CONF_MODEL = 'model'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_HOST): cv.string,
    vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)),
    vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
    vol.Optional(CONF_MODEL): vol.In(
        ['philips.light.sread1',
         'philips.light.ceiling',
         'philips.light.zyceiling',
         'philips.light.bulb',
         'philips.light.candle',
         'philips.light.candle2',
         'philips.light.mono1',
         'philips.light.downlight',
         ]),
})

# The light does not accept cct values < 1
CCT_MIN = 1
CCT_MAX = 100

DELAYED_TURN_OFF_MAX_DEVIATION_SECONDS = 4
DELAYED_TURN_OFF_MAX_DEVIATION_MINUTES = 1

SUCCESS = ['ok']
ATTR_MODEL = 'model'
ATTR_SCENE = 'scene'
ATTR_DELAYED_TURN_OFF = 'delayed_turn_off'
ATTR_TIME_PERIOD = 'time_period'
ATTR_NIGHT_LIGHT_MODE = 'night_light_mode'
ATTR_AUTOMATIC_COLOR_TEMPERATURE = 'automatic_color_temperature'
ATTR_REMINDER = 'reminder'
ATTR_EYECARE_MODE = 'eyecare_mode'

SERVICE_SET_SCENE = 'xiaomi_miio_set_scene'
SERVICE_SET_DELAYED_TURN_OFF = 'xiaomi_miio_set_delayed_turn_off'
SERVICE_REMINDER_ON = 'xiaomi_miio_reminder_on'
SERVICE_REMINDER_OFF = 'xiaomi_miio_reminder_off'
SERVICE_NIGHT_LIGHT_MODE_ON = 'xiaomi_miio_night_light_mode_on'
SERVICE_NIGHT_LIGHT_MODE_OFF = 'xiaomi_miio_night_light_mode_off'
SERVICE_EYECARE_MODE_ON = 'xiaomi_miio_eyecare_mode_on'
SERVICE_EYECARE_MODE_OFF = 'xiaomi_miio_eyecare_mode_off'

XIAOMI_MIIO_SERVICE_SCHEMA = vol.Schema({
    vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
})

SERVICE_SCHEMA_SET_SCENE = XIAOMI_MIIO_SERVICE_SCHEMA.extend({
    vol.Required(ATTR_SCENE):
        vol.All(vol.Coerce(int), vol.Clamp(min=1, max=4))
})

SERVICE_SCHEMA_SET_DELAYED_TURN_OFF = XIAOMI_MIIO_SERVICE_SCHEMA.extend({
    vol.Required(ATTR_TIME_PERIOD):
        vol.All(cv.time_period, cv.positive_timedelta)
})

SERVICE_TO_METHOD = {
    SERVICE_SET_DELAYED_TURN_OFF: {
        'method': 'async_set_delayed_turn_off',
        'schema': SERVICE_SCHEMA_SET_DELAYED_TURN_OFF},
    SERVICE_SET_SCENE: {
        'method': 'async_set_scene',
        'schema': SERVICE_SCHEMA_SET_SCENE},
    SERVICE_REMINDER_ON: {'method': 'async_reminder_on'},
    SERVICE_REMINDER_OFF: {'method': 'async_reminder_off'},
    SERVICE_NIGHT_LIGHT_MODE_ON: {'method': 'async_night_light_mode_on'},
    SERVICE_NIGHT_LIGHT_MODE_OFF: {'method': 'async_night_light_mode_off'},
    SERVICE_EYECARE_MODE_ON: {'method': 'async_eyecare_mode_on'},
    SERVICE_EYECARE_MODE_OFF: {'method': 'async_eyecare_mode_off'},
}


async def async_setup_platform(hass, config, async_add_entities,
                               discovery_info=None):
    """Set up the light from config."""
    from miio import Device, DeviceException
    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    name = config.get(CONF_NAME)
    token = config.get(CONF_TOKEN)
    model = config.get(CONF_MODEL)

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

    devices = []
    unique_id = None

    if model is None:
        try:
            miio_device = Device(host, token)
            device_info = miio_device.info()
            model = device_info.model
            unique_id = "{}-{}".format(model, device_info.mac_address)
            _LOGGER.info("%s %s %s detected",
                         model,
                         device_info.firmware_version,
                         device_info.hardware_version)
        except DeviceException:
            raise PlatformNotReady

    if model == 'philips.light.sread1':
        from miio import PhilipsEyecare
        light = PhilipsEyecare(host, token)
        primary_device = XiaomiPhilipsEyecareLamp(
            name, light, model, unique_id)
        devices.append(primary_device)
        hass.data[DATA_KEY][host] = primary_device

        secondary_device = XiaomiPhilipsEyecareLampAmbientLight(
            name, light, model, unique_id)
        devices.append(secondary_device)
        # The ambient light doesn't expose additional services.
        # A hass.data[DATA_KEY] entry isn't needed.
    elif model in ['philips.light.ceiling', 'philips.light.zyceiling']:
        from miio import Ceil
        light = Ceil(host, token)
        device = XiaomiPhilipsCeilingLamp(name, light, model, unique_id)
        devices.append(device)
        hass.data[DATA_KEY][host] = device
    elif model in ['philips.light.bulb',
                   'philips.light.candle',
                   'philips.light.candle2',
                   'philips.light.downlight']:
        from miio import PhilipsBulb
        light = PhilipsBulb(host, token)
        device = XiaomiPhilipsBulb(name, light, model, unique_id)
        devices.append(device)
        hass.data[DATA_KEY][host] = device
    elif model == 'philips.light.mono1':
        from miio import PhilipsBulb
        light = PhilipsBulb(host, token)
        device = XiaomiPhilipsGenericLight(name, light, model, unique_id)
        devices.append(device)
        hass.data[DATA_KEY][host] = device
    else:
        _LOGGER.error(
            'Unsupported device found! Please create an issue at '
            'https://github.com/syssi/philipslight/issues '
            'and provide the following data: %s', model)
        return False

    async_add_entities(devices, update_before_add=True)

    async def async_service_handler(service):
{'fraction_non_alphanumeric': 0.09684755332496864, 'fraction_numerical': 0.004783563362609787, 'mean_word_length': 3.5709677419354837, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1681699', 'n_tokens_mistral': 4530, 'n_tokens_neox': 4449, 'n_words': 792}