def async_register(self): """Register all our services.""" self._hass.services.async_register( const.DOMAIN, const.SERVICE_ADD_NODE, self.async_add_node, schema=vol.Schema({ vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int), vol.Optional(const.ATTR_SECURE, default=False): vol.Coerce(bool), }), ) self._hass.services.async_register( const.DOMAIN, const.SERVICE_REMOVE_NODE, self.async_remove_node, schema=vol.Schema({ vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int) }), ) self._hass.services.async_register( const.DOMAIN, const.SERVICE_CANCEL_COMMAND, self.async_cancel_command, schema=vol.Schema({ vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int) }), ) self._hass.services.async_register( const.DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER, self.async_set_config_parameter, schema=vol.Schema({ vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int), vol.Required(const.ATTR_NODE_ID): vol.Coerce(int), vol.Required(const.ATTR_CONFIG_PARAMETER): vol.Coerce(int), vol.Required(const.ATTR_CONFIG_VALUE): vol.Any( vol.All( cv.ensure_list, [ vol.All( { vol.Exclusive(ATTR_LABEL, "bit"): cv.string, vol.Exclusive(ATTR_POSITION, "bit"): vol.Coerce(int), vol.Required(ATTR_VALUE): bool, }, cv.has_at_least_one_key( ATTR_LABEL, ATTR_POSITION), ) ], ), vol.Coerce(int), bool, cv.string, ), }), )
def Priority(v): try: return PriorityAliases[v].value except KeyError: return v MAX_PRIORITY: int = 10000 # NOTE(sileht): We use the max priority as an offset to order queue QUEUE_PRIORITY_OFFSET: int = MAX_PRIORITY PrioritySchema = voluptuous.All( voluptuous.Any("low", "medium", "high", int), voluptuous.Coerce(Priority), int, voluptuous.Range(min=1, max=MAX_PRIORITY), ) def strict_merge_parameter(v): if v == "smart": return StrictMergeParameter.ordered elif v == "smart+fastpath": return StrictMergeParameter.fasttrack else: for _, member in StrictMergeParameter.__members__.items(): if v == member.value: return member
{ vol.Required(CONF_NAME): cv.string, vol.Required(CONF_ADDRESS): is_address, vol.Required(CONF_SOURCE): vol.All( vol.Upper, vol.In(SETPOINTS + KEYS + BINSENSOR_PORTS) ), } ) CLIMATES_SCHEMA = vol.Schema( { vol.Required(CONF_NAME): cv.string, vol.Required(CONF_ADDRESS): is_address, vol.Required(CONF_SOURCE): vol.All(vol.Upper, vol.In(VARIABLES)), vol.Required(CONF_SETPOINT): vol.All(vol.Upper, vol.In(VARIABLES + SETPOINTS)), vol.Optional(CONF_MAX_TEMP, default=DEFAULT_MAX_TEMP): vol.Coerce(float), vol.Optional(CONF_MIN_TEMP, default=DEFAULT_MIN_TEMP): vol.Coerce(float), vol.Optional(CONF_LOCKABLE, default=False): vol.Coerce(bool), vol.Optional(CONF_UNIT_OF_MEASUREMENT, default=TEMP_CELSIUS): vol.In( TEMP_CELSIUS, TEMP_FAHRENHEIT ), } ) COVERS_SCHEMA = vol.Schema( { vol.Required(CONF_NAME): cv.string, vol.Required(CONF_ADDRESS): is_address, vol.Required(CONF_MOTOR): vol.All(vol.Upper, vol.In(MOTOR_PORTS)), vol.Optional(CONF_REVERSE_TIME): vol.All(vol.Upper, vol.In(MOTOR_REVERSE_TIME)), }
"name": "Temperature", "unit": TEMP_CELSIUS, "icon": "mdi:thermometer", "class": DEVICE_CLASS_TEMPERATURE, }, SENSOR_TYPE_WINDOWHANDLE: { "name": "WindowHandle", "unit": None, "icon": "mdi:window", "class": None, }, } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_ID): vol.All(cv.ensure_list, [vol.Coerce(int)]), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_DEVICE_CLASS, default=SENSOR_TYPE_POWER): cv.string, vol.Optional(CONF_MAX_TEMP, default=40): vol.Coerce(int), vol.Optional(CONF_MIN_TEMP, default=0): vol.Coerce(int), vol.Optional(CONF_RANGE_FROM, default=255): cv.positive_int, vol.Optional(CONF_RANGE_TO, default=0): cv.positive_int, } ) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up an EnOcean sensor device.""" dev_id = config.get(CONF_ID) dev_name = config.get(CONF_NAME) sensor_type = config.get(CONF_DEVICE_CLASS)
DEFAULT_HOST = "localhost" DEFAULT_PORT = 8125 DEFAULT_PREFIX = "hass" DEFAULT_RATE = 1 DOMAIN = "statsd" CONFIG_SCHEMA = vol.Schema( { DOMAIN: vol.Schema( { vol.Required(CONF_HOST, default=DEFAULT_HOST): cv.string, vol.Optional(CONF_ATTR, default=False): cv.boolean, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Optional(CONF_PREFIX, default=DEFAULT_PREFIX): cv.string, vol.Optional(CONF_RATE, default=DEFAULT_RATE): vol.All( vol.Coerce(int), vol.Range(min=1) ), vol.Optional(CONF_VALUE_MAP): dict, } ) }, extra=vol.ALLOW_EXTRA, ) def setup(hass, config): """Set up the StatsD component.""" conf = config[DOMAIN] host = conf.get(CONF_HOST) port = conf.get(CONF_PORT)
DEFAULT_NAME = 'default_name' DEFAULT_TIMERS = 4 DEFAULT_DEV = '/dev/ttyUSB0' DEFAULT_BAUDE = 115200 _LOGGER = logging.getLogger(__name__) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME,default=DEFAULT_NAME): cv.string, vol.Required(CONF_DATA):cv.string, vol.Optional(CONF_DEV,default=DEFAULT_DEV): cv.string, vol.Optional(CONF_BAUDE,default=DEFAULT_BAUDE): cv.string, vol.Optional(CONF_TIMERS,default = DEFAULT_TIMERS): vol.All(vol.Coerce(int),vol.Range(min=1, max=10)), }) def setup_platform(hass,config,add_devices,discovery_info=None): """setup the switch platform.""" Name = config.get(CONF_NAME) Data = config.get(CONF_DATA) Timers = config.get(CONF_TIMERS) Dev = config.get(CONF_DEV) Badue = int(config.get(CONF_BAUDE)) try: gateway = ZQGateway(Dev,Badue) # gateway = ZQGateway(CONF_DEV,CONF_BAUDE) except: _LOGGER.exception("Unable to open serial port for:" )
OrCondition = esphomelib_ns.class_('OrCondition', Condition) RangeCondition = esphomelib_ns.class_('RangeCondition', Condition) LambdaCondition = esphomelib_ns.class_('LambdaCondition', Condition) CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [ cv.templatable({ cv.GenerateID(CONF_CONDITION_ID): cv.declare_variable_id(Condition), vol.Optional(CONF_AND): validate_recursive_condition, vol.Optional(CONF_OR): validate_recursive_condition, vol.Optional(CONF_RANGE): vol.All( vol.Schema({ vol.Optional(CONF_ABOVE): vol.Coerce(float), vol.Optional(CONF_BELOW): vol.Coerce(float), }), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)), vol.Optional(CONF_LAMBDA): cv.lambda_, }) ]) def validate_automation(extra_schema=None, extra_validators=None, single=False): schema = AUTOMATION_SCHEMA.extend(extra_schema or {}) def validator_(value): if isinstance(value, list):
DEFAULT_TOLERANCE = 0.3 DEFAULT_NAME = 'Command Thermostat' CONF_OFF = 'command_off' CONF_HEATER = 'command_heater' CONF_COOLER = 'command_cooler' CONF_MIN_TEMP = 'min_temp' CONF_MAX_TEMP = 'max_temp' CONF_TARGET_TEMP = 'target_temp' SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_OFF): cv.string, vol.Optional(CONF_HEATER): cv.string, vol.Optional(CONF_COOLER): cv.string, vol.Optional(CONF_MAX_TEMP): vol.Coerce(float), vol.Optional(CONF_MIN_TEMP): vol.Coerce(float), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_TARGET_TEMP): vol.Coerce(float), }) @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up the generic thermostat platform.""" name = config.get(CONF_NAME) command_off = config.get(CONF_OFF) command_heater = config.get(CONF_HEATER) command_cooler = config.get(CONF_COOLER) min_temp = config.get(CONF_MIN_TEMP) max_temp = config.get(CONF_MAX_TEMP)
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Set up is called when Home Assistant is loading our component.""" hass.data.setdefault(DOMAIN, {}) _LOGGER.info( "Version %s is starting, if you have any issues please report" " them here: %s", VERSION, ISSUE_URL, ) should_generate_package = config_entry.data.get(CONF_GENERATE) updated_config = config_entry.data.copy() # pop CONF_GENERATE if it is in data updated_config.pop(CONF_GENERATE, None) # If CONF_PATH is absolute, make it relative. This can be removed in the future, # it is only needed for entries that are being migrated from using the old absolute # path config_path = hass.config.path() if config_entry.data[CONF_PATH].startswith(config_path): updated_config[CONF_PATH] = updated_config[CONF_PATH][len(config_path ):] # Remove leading slashes updated_config[CONF_PATH] = updated_config[CONF_PATH].lstrip( "/").lstrip("\\") if updated_config != config_entry.data: hass.config_entries.async_update_entry(config_entry, data=updated_config) config_entry.add_update_listener(update_listener) primary_lock, child_locks = await generate_keymaster_locks( hass, config_entry) hass.data[DOMAIN][config_entry.entry_id] = { PRIMARY_LOCK: primary_lock, CHILD_LOCKS: child_locks, UNSUB_LISTENERS: [], } coordinator = LockUsercodeUpdateCoordinator(hass, config_entry) hass.data[DOMAIN][config_entry.entry_id][COORDINATOR] = coordinator # Button Press async def _refresh_codes(service: ServiceCall) -> None: """Refresh lock codes.""" _LOGGER.debug("Refresh Codes service: %s", service) entity_id = service.data[ATTR_ENTITY_ID] instance_id = 1 await refresh_codes(hass, entity_id, instance_id) hass.services.async_register( DOMAIN, SERVICE_REFRESH_CODES, _refresh_codes, schema=vol.Schema({ vol.Required(ATTR_ENTITY_ID): vol.Coerce(str), }), ) # Add code async def _add_code(service: ServiceCall) -> None: """Set a user code.""" _LOGGER.debug("Add Code service: %s", service) entity_id = service.data[ATTR_ENTITY_ID] code_slot = service.data[ATTR_CODE_SLOT] usercode = service.data[ATTR_USER_CODE] await add_code(hass, entity_id, code_slot, usercode) hass.services.async_register( DOMAIN, SERVICE_ADD_CODE, _add_code, schema=vol.Schema({ vol.Required(ATTR_ENTITY_ID): vol.Coerce(str), vol.Required(ATTR_CODE_SLOT): vol.Coerce(int), vol.Required(ATTR_USER_CODE): vol.Coerce(str), }), ) # Clear code async def _clear_code(service: ServiceCall) -> None: """Clear a user code.""" _LOGGER.debug("Clear Code service: %s", service) entity_id = service.data[ATTR_ENTITY_ID] code_slot = service.data[ATTR_CODE_SLOT] await clear_code(hass, entity_id, code_slot) hass.services.async_register( DOMAIN, SERVICE_CLEAR_CODE, _clear_code, schema=vol.Schema({ vol.Required(ATTR_ENTITY_ID): vol.Coerce(str), vol.Required(ATTR_CODE_SLOT): vol.Coerce(int), }), ) # Generate package files def _generate_package(service: ServiceCall) -> None: """Generate the package files.""" _LOGGER.debug("DEBUG: %s", service) name = service.data[ATTR_NAME] generate_package_files(hass, name) hass.services.async_register( DOMAIN, SERVICE_GENERATE_PACKAGE, _generate_package, schema=vol.Schema({vol.Optional(ATTR_NAME): vol.Coerce(str)}), ) await async_reset_code_slot_if_pin_unknown( hass, primary_lock.lock_name, config_entry.data[CONF_SLOTS], config_entry.data[CONF_START], ) hass.async_create_task( hass.config_entries.async_forward_entry_setup(config_entry, PLATFORM)) # if the use turned on the bool generate the files if should_generate_package: servicedata = {"lockname": primary_lock.lock_name} await hass.services.async_call(DOMAIN, SERVICE_GENERATE_PACKAGE, servicedata) if using_zwave_js(hass): # Listen to Z-Wave JS events so we can fire our own events hass.data[DOMAIN][config_entry.entry_id][UNSUB_LISTENERS].append( hass.bus.async_listen( ZWAVE_JS_EVENT, functools.partial(handle_zwave_js_event, hass, config_entry), )) # Check if we need to check alarm type/alarm level sensors, in which case # we need to listen for lock state changes locks_to_watch = [] for lock in [primary_lock, *child_locks]: if (lock.alarm_level_or_user_code_entity_id not in ( None, "sensor.fake", ) and lock.alarm_type_or_access_control_entity_id not in (None, "sensor.fake")): locks_to_watch.append(lock) if locks_to_watch: if hass.state == CoreState.running: await homeassistant_started_listener(hass, config_entry, locks_to_watch) else: hass.bus.async_listen_once( EVENT_HOMEASSISTANT_STARTED, functools.partial(homeassistant_started_listener, hass, config_entry, locks_to_watch), ) return True
class Effect(BaseRegistry): """ Manages an effect """ NAME = "" _image = None _dirty = False _config = None _active = False _dimensions = (0, 0) # Basic effect properties that can be applied to all effects CONFIG_SCHEMA = vol.Schema({ vol.Optional('blur', description='Amount to blur the effect', default=0.0): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=10)), vol.Optional('flip', description='Flip the effect', default=False): bool, vol.Optional('mirror', description='Mirror the effect', default=False): bool, vol.Optional('brightness', description='Brightness of strip', default=1.0): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=10.0)), }) def __init__(self, ledfx, config): self._ledfx = ledfx self._dirty_callback = None self.update_config(config) def __del__(self): if self._active: self.deactivate() def activate(self, dimensions): """Attaches an output channel to the effect""" self._dimensions = dimensions self._image = Image.new("RGB", dimensions) self._active = True # Iterate all the base classes and check to see if there is a custom # implementation of config updates. If to notify the base class. valid_classes = list(type(self).__bases__) valid_classes.append(type(self)) for base in valid_classes: if base.activated != super(base, base).activated: base.activated(self) _LOGGER.info("Effect {} activated.".format(self.NAME)) def deactivate(self): """Detaches an output channel from the effect""" self._image = None self._active = False _LOGGER.info("Effect {} deactivated.".format(self.NAME)) def update_config(self, config): # TODO: Sync locks to ensure everything is thread safe validated_config = type(self).schema()(config) self._config = validated_config def inherited(cls, method): if hasattr(cls, method) and hasattr(super(cls, cls), method): return cls.foo == super(cls).foo return False # Iterate all the base classes and check to see if there is a custom # implementation of config updates. If to notify the base class. valid_classes = list(type(self).__bases__) valid_classes.append(type(self)) for base in valid_classes: if base.config_updated != super(base, base).config_updated: base.config_updated(self, self._config) _LOGGER.info("Effect {} config updated to {}.".format( self.NAME, validated_config)) def config_updated(self, config): """ Optional event for when an effect's config is updated. This should be used by the subclass only if they need to build up complex properties off the configuration, otherwise the config should just be referenced in the effect's loop directly """ pass def activated(self): """ Optional event if an effect was activated """ pass @property def is_active(self): """Return if the effect is currently active""" return self._active @property def is_2d(self): """Return if the effect is a matrix""" return self._dimensions[1] > 1 @property def outputimage(self): input = self.image # Apply some of the base output filters if necessary if self._config['brightness']: enhancer = ImageEnhance.Brightness(input) input = enhancer.enhance(self._config['brightness']) if self._config['blur'] != 0.0: input = input.filter( ImageFilter.GaussianBlur(radius=self._config['blur'])) # horizontal flip if self._config['flip']: input = ImageOps.mirror(input) # reflection effect if self._config['mirror']: # Scale image to half width hImage = input.resize( (int(self._dimensions[0] / 2), self._dimensions[1]), resample=3) input.paste(hImage, (0, 0)) input.paste(ImageOps.mirror(hImage), (int(self._dimensions[0] / 2), 0)) return input @property def image(self): """Returns the pixels for the channel""" if not self._active: raise Exception( 'Attempting to access image before effect is active') return self._image @image.setter def image(self, input): """Sets the pixels for the channel""" if not self._active: _LOGGER.warning( 'Attempting to set image before effect is active. Dropping.') return self._image = input self._dirty = True if self._dirty_callback: self._dirty_callback() def setDirtyCallback(self, callback): self._dirty_callback = callback @property def name(self): return self.NAME
} DEFAULT_MONITORED = [SENSOR_TEMP, SENSOR_HUMID, SENSOR_PRESS, SENSOR_AQ] OVERSAMPLING_VALUES = set([0, 1, 2, 4, 8, 16]) FILTER_VALUES = set([0, 1, 3, 7, 15, 31, 63, 127]) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_I2C_ADDRESS, default=DEFAULT_I2C_ADDRESS): cv.positive_int, vol.Optional(CONF_MONITORED_CONDITIONS, default=DEFAULT_MONITORED): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), vol.Optional(CONF_I2C_BUS, default=DEFAULT_I2C_BUS): cv.positive_int, vol.Optional(CONF_OVERSAMPLING_TEMP, default=DEFAULT_OVERSAMPLING_TEMP): vol.All(vol.Coerce(int), vol.In(OVERSAMPLING_VALUES)), vol.Optional(CONF_OVERSAMPLING_PRES, default=DEFAULT_OVERSAMPLING_PRES): vol.All(vol.Coerce(int), vol.In(OVERSAMPLING_VALUES)), vol.Optional(CONF_OVERSAMPLING_HUM, default=DEFAULT_OVERSAMPLING_HUM): vol.All(vol.Coerce(int), vol.In(OVERSAMPLING_VALUES)), vol.Optional(CONF_FILTER_SIZE, default=DEFAULT_FILTER_SIZE): vol.All(vol.Coerce(int), vol.In(FILTER_VALUES)), vol.Optional(CONF_GAS_HEATER_TEMP, default=DEFAULT_GAS_HEATER_TEMP): vol.All(vol.Coerce(int), vol.Range(200, 400)), vol.Optional(CONF_GAS_HEATER_DURATION, default=DEFAULT_GAS_HEATER_DURATION): vol.All(vol.Coerce(int), vol.Range(1, 4032)), vol.Optional(CONF_AQ_BURN_IN_TIME, default=DEFAULT_AQ_BURN_IN_TIME): cv.positive_int, vol.Optional(CONF_AQ_HUM_BASELINE, default=DEFAULT_AQ_HUM_BASELINE): vol.All(vol.Coerce(int), vol.Range(1, 100)), vol.Optional(CONF_AQ_HUM_WEIGHTING, default=DEFAULT_AQ_HUM_WEIGHTING):
PY_XIAOMI_GATEWAY = "xiaomi_gw" TIME_TILL_UNAVAILABLE = timedelta(minutes=150) SERVICE_PLAY_RINGTONE = 'play_ringtone' SERVICE_STOP_RINGTONE = 'stop_ringtone' SERVICE_ADD_DEVICE = 'add_device' SERVICE_REMOVE_DEVICE = 'remove_device' GW_MAC = vol.All(cv.string, lambda value: value.replace(':', '').lower(), vol.Length(min=12, max=12)) SERVICE_SCHEMA_PLAY_RINGTONE = vol.Schema({ vol.Required(ATTR_RINGTONE_ID): vol.All(vol.Coerce(int), vol.NotIn([9, 14, 15, 16, 17, 18, 19])), vol.Optional(ATTR_RINGTONE_VOL): vol.All(vol.Coerce(int), vol.Clamp(min=0, max=100)) }) SERVICE_SCHEMA_REMOVE_DEVICE = vol.Schema({ vol.Required(ATTR_DEVICE_ID): vol.All(cv.string, vol.Length(min=14, max=14)) }) GATEWAY_CONFIG = vol.Schema({ vol.Optional(CONF_MAC, default=None): vol.Any(GW_MAC, None), vol.Optional(CONF_KEY): vol.All(cv.string, vol.Length(min=16, max=16)), vol.Optional(CONF_HOST):
async def async_setup(hass, config: dict): """Expose fan control via statemachine and services.""" component = hass.data[DOMAIN] = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL) await component.async_setup(config) # After the transition to percentage and preset_modes concludes, # switch this back to async_turn_on and remove async_turn_on_compat component.async_register_entity_service( SERVICE_TURN_ON, { vol.Optional(ATTR_SPEED): cv.string, vol.Optional(ATTR_PERCENTAGE): vol.All(vol.Coerce(int), vol.Range(min=0, max=100)), vol.Optional(ATTR_PRESET_MODE): cv.string, }, "async_turn_on_compat", ) component.async_register_entity_service(SERVICE_TURN_OFF, {}, "async_turn_off") component.async_register_entity_service(SERVICE_TOGGLE, {}, "async_toggle") # After the transition to percentage and preset_modes concludes, # remove this service component.async_register_entity_service( SERVICE_SET_SPEED, {vol.Required(ATTR_SPEED): cv.string}, "async_set_speed_deprecated", [SUPPORT_SET_SPEED], ) component.async_register_entity_service( SERVICE_INCREASE_SPEED, { vol.Optional(ATTR_PERCENTAGE_STEP): vol.All(vol.Coerce(int), vol.Range(min=0, max=100)) }, "async_increase_speed", [SUPPORT_SET_SPEED], ) component.async_register_entity_service( SERVICE_DECREASE_SPEED, { vol.Optional(ATTR_PERCENTAGE_STEP): vol.All(vol.Coerce(int), vol.Range(min=0, max=100)) }, "async_decrease_speed", [SUPPORT_SET_SPEED], ) component.async_register_entity_service( SERVICE_OSCILLATE, {vol.Required(ATTR_OSCILLATING): cv.boolean}, "async_oscillate", [SUPPORT_OSCILLATE], ) component.async_register_entity_service( SERVICE_SET_DIRECTION, {vol.Optional(ATTR_DIRECTION): cv.string}, "async_set_direction", [SUPPORT_DIRECTION], ) component.async_register_entity_service( SERVICE_SET_PERCENTAGE, { vol.Required(ATTR_PERCENTAGE): vol.All(vol.Coerce(int), vol.Range(min=0, max=100)) }, "async_set_percentage", [SUPPORT_SET_SPEED], ) component.async_register_entity_service( SERVICE_SET_PRESET_MODE, {vol.Required(ATTR_PRESET_MODE): cv.string}, "async_set_preset_mode", [SUPPORT_SET_SPEED, SUPPORT_PRESET_MODE], ) return True
# List of possible effects ATTR_EFFECT_LIST = "effect_list" # Apply an effect to the light, can be EFFECT_COLORLOOP. ATTR_EFFECT = "effect" EFFECT_COLORLOOP = "colorloop" EFFECT_RANDOM = "random" EFFECT_WHITE = "white" COLOR_GROUP = "Color descriptors" LIGHT_PROFILES_FILE = "light_profiles.csv" # Service call validation schemas VALID_TRANSITION = vol.All(vol.Coerce(float), vol.Clamp(min=0, max=6553)) VALID_BRIGHTNESS = vol.All(vol.Coerce(int), vol.Clamp(min=0, max=255)) VALID_BRIGHTNESS_PCT = vol.All(vol.Coerce(float), vol.Range(min=0, max=100)) VALID_BRIGHTNESS_STEP = vol.All(vol.Coerce(int), vol.Clamp(min=-255, max=255)) VALID_BRIGHTNESS_STEP_PCT = vol.All(vol.Coerce(float), vol.Clamp(min=-100, max=100)) VALID_FLASH = vol.In([FLASH_SHORT, FLASH_LONG]) LIGHT_TURN_ON_SCHEMA = { vol.Exclusive(ATTR_PROFILE, COLOR_GROUP): cv.string, ATTR_TRANSITION: VALID_TRANSITION, vol.Exclusive(ATTR_BRIGHTNESS, ATTR_BRIGHTNESS): VALID_BRIGHTNESS, vol.Exclusive(ATTR_BRIGHTNESS_PCT, ATTR_BRIGHTNESS):
from homeassistant.core import HomeAssistant from .const import ( CONNECTION_TIMEOUT, DEFAULT_KEEP_ALIVE_INTERVAL, DEFAULT_PORT, DEFAULT_RECONNECT_INTERVAL, DOMAIN, ) from .errors import AlreadyConfigured, CannotConnect DATA_SCHEMA = vol.Schema({ vol.Required(CONF_HOST): str, vol.Optional(CONF_PORT, default=DEFAULT_PORT): vol.Coerce(int), }) async def connect_client(hass, user_input): """Connect the HLK-SW16 client.""" client_aw = create_hlk_sw16_connection( host=user_input[CONF_HOST], port=user_input[CONF_PORT], loop=hass.loop, timeout=CONNECTION_TIMEOUT, reconnect_interval=DEFAULT_RECONNECT_INTERVAL, keep_alive_interval=DEFAULT_KEEP_ALIVE_INTERVAL, ) return await asyncio.wait_for(client_aw, timeout=CONNECTION_TIMEOUT)
CONF_UPDATE_INTERVAL = 'update_interval' DEVICE_DEFAULT_NAME = 'Broadlink sensor' DEFAULT_TIMEOUT = 10 SENSOR_TYPES = { 'temperature': ['Temperature', TEMP_CELSIUS], 'air_quality': ['Air Quality', ' '], 'humidity': ['Humidity', '%'], 'light': ['Light', ' '], 'noise': ['Noise', ' '], } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEVICE_DEFAULT_NAME): vol.Coerce(str), vol.Optional(CONF_MONITORED_CONDITIONS, default=[]): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), vol.Optional(CONF_UPDATE_INTERVAL, default=timedelta(seconds=300)): (vol.All(cv.time_period, cv.positive_timedelta)), vol.Required(CONF_HOST): cv.string, vol.Required(CONF_MAC): cv.string, vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int }) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Broadlink device sensors."""
def _id(value: str) -> str: """Coerce id by removing '-'.""" return value.replace("-", "") WEBHOOK_SCHEMA = vol.Schema({ vol.Required(ATTR_ID): vol.All(cv.string, _id), vol.Required(ATTR_LATITUDE): cv.latitude, vol.Required(ATTR_LONGITUDE): cv.longitude, vol.Optional(ATTR_ACCURACY, default=DEFAULT_ACCURACY): vol.Coerce(float), vol.Optional(ATTR_ALTITUDE): vol.Coerce(float), vol.Optional(ATTR_BATTERY, default=DEFAULT_BATTERY): vol.Coerce(float), vol.Optional(ATTR_BEARING): vol.Coerce(float), vol.Optional(ATTR_SPEED): vol.Coerce(float), vol.Optional(ATTR_TIMESTAMP): vol.Coerce(int), }) async def async_setup(hass, hass_config): """Set up the Traccar component."""
"video3": "Video 3", "video4": "Video 4", "video5": "Video 5", "video6": "Video 6", "video7": "Video 7", "fm": "Radio", } DEFAULT_PLAYABLE_SOURCES = ("fm", "am", "tuner") PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Optional(CONF_HOST): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_MAX_VOLUME, default=SUPPORTED_MAX_VOLUME): vol.All( vol.Coerce(int), vol.Range(min=1, max=100) ), vol.Optional( CONF_RECEIVER_MAX_VOLUME, default=DEFAULT_RECEIVER_MAX_VOLUME ): cv.positive_int, vol.Optional(CONF_SOURCES, default=DEFAULT_SOURCES): {cv.string: cv.string}, } ) TIMEOUT_MESSAGE = "Timeout waiting for response." ATTR_HDMI_OUTPUT = "hdmi_output" ATTR_PRESET = "preset" ATTR_AUDIO_INFORMATION = "audio_information" ATTR_VIDEO_INFORMATION = "video_information"
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'},
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Establish connection with velbus.""" hass.data.setdefault(DOMAIN, {}) def callback(): modules = controller.get_modules() discovery_info = {"cntrl": controller} for platform in PLATFORMS: discovery_info[platform] = [] for module in modules: for channel in range(1, module.number_of_channels() + 1): for platform in PLATFORMS: if platform in module.get_categories(channel): discovery_info[platform].append( (module.get_module_address(), channel)) hass.data[DOMAIN][entry.entry_id] = discovery_info for platform in PLATFORMS: hass.add_job( hass.config_entries.async_forward_entry_setup(entry, platform)) try: controller = velbus.Controller(entry.data[CONF_PORT]) controller.scan(callback) except velbus.util.VelbusException as err: _LOGGER.error("An error occurred: %s", err) raise ConfigEntryNotReady from err def syn_clock(self, service=None): try: controller.sync_clock() except velbus.util.VelbusException as err: _LOGGER.error("An error occurred: %s", err) hass.services.async_register(DOMAIN, "sync_clock", syn_clock, schema=vol.Schema({})) def set_memo_text(service): """Handle Memo Text service call.""" module_address = service.data[CONF_ADDRESS] memo_text = service.data[CONF_MEMO_TEXT] memo_text.hass = hass try: controller.get_module(module_address).set_memo_text( memo_text.async_render()) except velbus.util.VelbusException as err: _LOGGER.error("An error occurred while setting memo text: %s", err) hass.services.async_register( DOMAIN, SERVICE_SET_MEMO_TEXT, set_memo_text, vol.Schema({ vol.Required(CONF_ADDRESS): vol.All(vol.Coerce(int), vol.Range(min=0, max=255)), vol.Optional(CONF_MEMO_TEXT, default=""): cv.template, }), ) return True
CONF_NOTIFIERS = 'notifiers' CONF_REPEAT = 'repeat' CONF_SKIP_FIRST = 'skip_first' DEFAULT_CAN_ACK = True DEFAULT_SKIP_FIRST = False ALERT_SCHEMA = vol.Schema({ vol.Required(CONF_NAME): cv.string, vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_STATE, default=STATE_ON): cv.string, vol.Required(CONF_REPEAT): vol.All(cv.ensure_list, [vol.Coerce(float)]), vol.Required(CONF_CAN_ACK, default=DEFAULT_CAN_ACK): cv.boolean, vol.Required(CONF_SKIP_FIRST, default=DEFAULT_SKIP_FIRST): cv.boolean, vol.Required(CONF_NOTIFIERS): cv.ensure_list }) CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ cv.slug: ALERT_SCHEMA, }), }, extra=vol.ALLOW_EXTRA)
CONF_RGB_VALUE_TEMPLATE, CONF_RGBW_VALUE_TEMPLATE, CONF_RGBWW_VALUE_TEMPLATE, CONF_STATE_VALUE_TEMPLATE, CONF_WHITE_VALUE_TEMPLATE, CONF_XY_VALUE_TEMPLATE, ] PLATFORM_SCHEMA_BASIC = vol.All( # CONF_VALUE_TEMPLATE is deprecated, support will be removed in 2021.10 cv.deprecated(CONF_VALUE_TEMPLATE, CONF_STATE_VALUE_TEMPLATE), mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({ vol.Optional(CONF_BRIGHTNESS_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_BRIGHTNESS_SCALE, default=DEFAULT_BRIGHTNESS_SCALE): vol.All(vol.Coerce(int), vol.Range(min=1)), vol.Optional(CONF_BRIGHTNESS_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_BRIGHTNESS_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_COLOR_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_COLOR_MODE_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_COLOR_TEMP_COMMAND_TEMPLATE): cv.template, vol.Optional(CONF_COLOR_TEMP_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_COLOR_TEMP_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_COLOR_TEMP_VALUE_TEMPLATE):
_LOGGER = logging.getLogger(__name__) # We want to fire remote commands right away PARALLEL_UPDATES = 0 ATTR_CHANNEL = "channel" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Optional(ATTR_ACTIVITY): cv.string, vol.Required(CONF_NAME): cv.string, vol.Optional(ATTR_DELAY_SECS, default=DEFAULT_DELAY_SECS): vol.Coerce(float), vol.Required(CONF_HOST): cv.string, # The client ignores port so lets not confuse the user by pretenting we do anything with this }, extra=vol.ALLOW_EXTRA, ) HARMONY_SYNC_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids}) HARMONY_CHANGE_CHANNEL_SCHEMA = vol.Schema({ vol.Required(ATTR_ENTITY_ID): cv.entity_ids, vol.Required(ATTR_CHANNEL): cv.positive_int, })
_CHANNELS_SCHEMA = vol.Schema( [ { vol.Required(CONF_INDEX): cv.positive_int, vol.Required(CONF_NAME): cv.string, vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean, vol.Optional(CONF_DEVICE_CLASS, default=DEFAULT_DEVICE_CLASS): cv.string, } ] ) _I2C_HATS_SCHEMA = vol.Schema( [ { vol.Required(CONF_BOARD): vol.In(I2C_HAT_NAMES), vol.Required(CONF_ADDRESS): vol.Coerce(int), vol.Required(CONF_CHANNELS): _CHANNELS_SCHEMA, } ] ) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( {vol.Optional(CONF_I2C_HATS): _I2C_HATS_SCHEMA} ) def setup_platform( hass: HomeAssistant, config: ConfigType, add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None,
SERVICE_DELETE_MESSAGE = 'delete_message' EVENT_TELEGRAM_CALLBACK = 'telegram_callback' EVENT_TELEGRAM_COMMAND = 'telegram_command' EVENT_TELEGRAM_TEXT = 'telegram_text' PARSER_HTML = 'html' PARSER_MD = 'markdown' PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ vol.Required(CONF_PLATFORM): cv.string, vol.Required(CONF_API_KEY): cv.string, vol.Required(CONF_ALLOWED_CHAT_IDS): vol.All(cv.ensure_list, [vol.Coerce(int)]), vol.Optional(ATTR_PARSER, default=PARSER_MD): cv.string, vol.Optional(CONF_PROXY_URL): cv.string, vol.Optional(CONF_PROXY_PARAMS): dict, }) BASE_SERVICE_SCHEMA = vol.Schema( { vol.Optional(ATTR_TARGET): vol.All(cv.ensure_list, [vol.Coerce(int)]), vol.Optional(ATTR_PARSER): cv.string, vol.Optional(ATTR_DISABLE_NOTIF): cv.boolean, vol.Optional(ATTR_DISABLE_WEB_PREV): cv.boolean, vol.Optional(ATTR_KEYBOARD): vol.All(cv.ensure_list, [cv.string]),
async def async_setup_entry(hass, config_entry, async_add_entities): kettler = hass.data[DOMAIN]["devices"][config_entry.entry_id] if kettler._type == 0 or kettler._type == 1 or kettler._type == 2: async_add_entities([RedmondWaterHeater(kettler)], True) if kettler._type == 5: async_add_entities([RedmondCooker(kettler)], True) platform = entity_platform.current_platform.get() platform.async_register_entity_service("set_timer",{vol.Required("hours"): vol.All(vol.Coerce(int), vol.Range(min=0, max=23)), vol.Required("minutes"): vol.All(vol.Coerce(int), vol.Range(min=0, max=59))},"async_set_timer",) platform.async_register_entity_service("set_manual_program",{vol.Required("prog"): vol.All(vol.Coerce(int), vol.Range(min=0, max=12)), vol.Required("subprog"): vol.All(vol.Coerce(int), vol.Range(min=0, max=3)),vol.Required("temp"): vol.All(vol.Coerce(int), vol.Range(min=30, max=180)), vol.Required("hours"): vol.All(vol.Coerce(int), vol.Range(min=0, max=23)),vol.Required("minutes"): vol.All(vol.Coerce(int), vol.Range(min=0, max=59)), vol.Required("dhours"): vol.All(vol.Coerce(int), vol.Range(min=0, max=23)),vol.Required("dminutes"): vol.All(vol.Coerce(int), vol.Range(min=0, max=59)), vol.Required("heat"): vol.All(vol.Coerce(int), vol.Range(min=0, max=1))},"async_set_manual_program",)
SERVICE_PERMIT = "permit" SERVICE_REMOVE = "remove" SERVICE_SET_ZIGBEE_CLUSTER_ATTRIBUTE = "set_zigbee_cluster_attribute" SERVICE_ISSUE_ZIGBEE_CLUSTER_COMMAND = "issue_zigbee_cluster_command" SERVICE_DIRECT_ZIGBEE_BIND = "issue_direct_zigbee_bind" SERVICE_DIRECT_ZIGBEE_UNBIND = "issue_direct_zigbee_unbind" SERVICE_ZIGBEE_BIND = "service_zigbee_bind" IEEE_SERVICE = "ieee_based_service" SERVICE_SCHEMAS = { SERVICE_PERMIT: vol.Schema({ vol.Optional(ATTR_IEEE_ADDRESS, default=None): convert_ieee, vol.Optional(ATTR_DURATION, default=60): vol.All(vol.Coerce(int), vol.Range(0, 254)), }), IEEE_SERVICE: vol.Schema({vol.Required(ATTR_IEEE_ADDRESS): convert_ieee}), SERVICE_SET_ZIGBEE_CLUSTER_ATTRIBUTE: vol.Schema({ vol.Required(ATTR_IEEE): convert_ieee, vol.Required(ATTR_ENDPOINT_ID): cv.positive_int, vol.Required(ATTR_CLUSTER_ID): cv.positive_int, vol.Optional(ATTR_CLUSTER_TYPE, default=CLUSTER_TYPE_IN): cv.string, vol.Required(ATTR_ATTRIBUTE): cv.positive_int, vol.Required(ATTR_VALUE): cv.string, vol.Optional(ATTR_MANUFACTURER): cv.positive_int, }), SERVICE_ISSUE_ZIGBEE_CLUSTER_COMMAND: vol.Schema({
CONF_NEW_ENTITY_IDS = 'new_entity_ids' ATTR_POWER = 'power_consumption' DEFAULT_CONF_AUTOHEAL = True DEFAULT_CONF_USB_STICK_PATH = '/zwaveusbstick' DEFAULT_POLLING_INTERVAL = 60000 DEFAULT_DEBUG = False DEFAULT_CONF_IGNORED = False DEFAULT_CONF_INVERT_OPENCLOSE_BUTTONS = False DEFAULT_CONF_REFRESH_VALUE = False DEFAULT_CONF_REFRESH_DELAY = 5 RENAME_NODE_SCHEMA = vol.Schema({ vol.Required(const.ATTR_NODE_ID): vol.Coerce(int), vol.Required(const.ATTR_NAME): cv.string, }) RENAME_VALUE_SCHEMA = vol.Schema({ vol.Required(const.ATTR_NODE_ID): vol.Coerce(int), vol.Required(const.ATTR_VALUE_ID): vol.Coerce(int), vol.Required(const.ATTR_NAME): cv.string, }) SET_CONFIG_PARAMETER_SCHEMA = vol.Schema({ vol.Required(const.ATTR_NODE_ID):
"""Metadata for services.""" validator: Any example: str selector: dict[str, Any] description: str | None = None ARG_TYPE_METADATA = { UserServiceArgType.BOOL: ServiceMetadata( validator=cv.boolean, example="False", selector={"boolean": None}, ), UserServiceArgType.INT: ServiceMetadata( validator=vol.Coerce(int), example="42", selector={"number": {CONF_MODE: "box"}}, ), UserServiceArgType.FLOAT: ServiceMetadata( validator=vol.Coerce(float), example="12.3", selector={"number": {CONF_MODE: "box", "step": 1e-3}}, ), UserServiceArgType.STRING: ServiceMetadata( validator=cv.string, example="Example text", selector={"text": None}, ), UserServiceArgType.BOOL_ARRAY: ServiceMetadata( validator=[cv.boolean],
False ] CONF_LOCAL_IP = 'local_ip' CONF_LOCAL_PORT = 'local_port' CONF_REMOTE_IP = 'remote_ip' CONF_REMOTE_PORT = 'remote_port' CONF_RESOLVENAMES = 'resolvenames' CONF_DELAY = 'delay' DEVICE_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): "homematic", vol.Required(ATTR_NAME): cv.string, vol.Required(ATTR_ADDRESS): cv.string, vol.Optional(ATTR_CHANNEL, default=1): vol.Coerce(int), vol.Optional(ATTR_PARAM): cv.string, }) CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Required(CONF_LOCAL_IP): cv.string, vol.Optional(CONF_LOCAL_PORT, default=8943): cv.port, vol.Required(CONF_REMOTE_IP): cv.string, vol.Optional(CONF_REMOTE_PORT, default=2001): cv.port, vol.Optional(CONF_RESOLVENAMES, default=False): vol.In(CONF_RESOLVENAMES_OPTIONS), vol.Optional(CONF_USERNAME, default="Admin"): cv.string, vol.Optional(CONF_PASSWORD, default=""): cv.string, vol.Optional(CONF_DELAY, default=0.5): vol.Coerce(float), }),