async def async_play_media(self, media_type, media_id, **kwargs): """Support changing a channel.""" # Type channel if media_type == MEDIA_TYPE_CHANNEL: try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error("Media ID must be positive integer") return for digit in media_id: await self.hass.async_add_job(self.send_command, "KEY_" + digit) await self.hass.async_add_job(self.send_command, "KEY_ENTER") # Launch an app elif media_type == MEDIA_TYPE_APP: await self.hass.async_add_job(self.send_command, media_id, "run_app") # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return await self.hass.async_add_job(self.send_command, media_id) else: _LOGGER.error("Unsupported media type") return
async def async_play_media(self, media_type, media_id, **kwargs): """Support changing a channel.""" # Type channel if media_type == MEDIA_TYPE_CHANNEL: try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error("Media ID must be positive integer") return def send_digit(): for digit in media_id: self.send_command("KEY_" + digit) sleep(KEYPRESS_DEFAULT_DELAY) self.send_command("KEY_ENTER") await self.hass.async_add_executor_job(send_digit) # Launch an app elif media_type == MEDIA_TYPE_APP: await self.async_send_command(media_id, "run_app") # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return source_key = media_id await self._async_send_keys(source_key) # Play media elif media_type == MEDIA_TYPE_URL: try: cv.url(media_id) except vol.Invalid: _LOGGER.error('Media ID must be an url (ex: "http://"') return await self._upnp.async_set_current_media(media_id) self._playing = True # Trying to make stream component work on TV elif media_type == "application/vnd.apple.mpegurl": await self._upnp.async_set_current_media(media_id) self._playing = True elif media_type == MEDIA_TYPE_BROWSER: await self.hass.async_add_executor_job( self._ws.open_browser, media_id ) else: _LOGGER.error("Unsupported media type") return
async def async_play_media(self, media_type, media_id, **kwargs): """Support changing a channel.""" # Type channel if media_type == MEDIA_TYPE_CHANNEL: try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error("Media ID must be positive integer") return for digit in media_id: await self.hass.async_add_job(self.send_command, "KEY_" + digit) await self.hass.async_add_job(self.send_command, "KEY_ENTER") # Launch an app elif media_type == MEDIA_TYPE_APP: await self.hass.async_add_job(self.send_command, media_id, "run_app") # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return await self.hass.async_add_job(self.send_command, media_id) # Play media elif media_type == MEDIA_TYPE_URL: try: cv.url(media_id) except vol.Invalid: _LOGGER.error('Media ID must be an url (ex: "http://"') return await self.hass.async_add_job(self._upnp.set_current_media, media_id) self._playing = True # Trying to make stream component work on TV elif media_type == "application/vnd.apple.mpegurl": await self.hass.async_add_job(self._upnp.set_current_media, media_id) self._playing = True else: _LOGGER.error("Unsupported media type: " + media_type) return
async def async_play_media(self, media_type, media_id, **kwargs): # Type channel if media_type == MEDIA_TYPE_CHANNEL: # media_id should only be a channel number try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error('Media ID must be positive integer') return for digit in media_id: await self.hass.async_add_job(self.send_key, 'KEY_' + digit) await asyncio.sleep(KEY_PRESS_TIMEOUT, self.hass.loop) # Launch an app elif media_type == MEDIA_TYPE_APP: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "Youtube"') return await self.hass.async_add_job(self.launch_app, media_id) # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return await self.hass.async_add_job(self.send_key, media_id) # Launch stream elif (media_type == MEDIA_TYPE_URL or media_type == MEDIA_TYPE_MUSIC): _LOGGER.error("Playing on TV " + str(media_id)) self._upnp = self.get_upnp() self._upnp.set_current_media(media_id) self._upnp.play() # Launch stream elif (media_type == "application/vnd.apple.mpegurl"): _LOGGER.error("Playing Stream on TV " + str(media_id)) self._upnp = self.get_upnp() self._upnp.set_current_media(str(media_id)) self._upnp.play() else: _LOGGER.error('Unsupported media type: {type} - {id}'.format( type=media_type, id=media_id))
async def async_play_media(self, media_type, media_id, **kwargs): """Support running different media type command.""" media_type = media_type.lower() # Type channel if media_type == MEDIA_TYPE_CHANNEL: await self._async_set_channel(media_id) # Launch an app elif media_type == MEDIA_TYPE_APP: await self._async_launch_app(media_id) # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return source_key = media_id await self._async_send_keys(source_key) # Play media elif media_type == MEDIA_TYPE_URL: try: cv.url(media_id) except vol.Invalid: _LOGGER.error('Media ID must be an url (ex: "http://"') return await self._upnp.async_set_current_media(media_id) self._playing = True # Trying to make stream component work on TV elif media_type == "application/vnd.apple.mpegurl": await self._upnp.async_set_current_media(media_id) self._playing = True elif media_type == MEDIA_TYPE_BROWSER: await self.async_send_command(media_id, CMD_OPEN_BROWSER) elif media_type == MEDIA_TYPE_TEXT: await self.async_send_command(media_id, CMD_SEND_TEXT) else: _LOGGER.error("Unsupported media type: %s", media_type) return
def valid_topic(value: Any) -> str: """Validate that this is a valid topic name/filter.""" value = cv.string(value) try: raw_value = value.encode("utf-8") except UnicodeError as err: raise vol.Invalid( "MQTT topic name/filter must be valid UTF-8 string.") from err if not raw_value: raise vol.Invalid("MQTT topic name/filter must not be empty.") if len(raw_value) > 65535: raise vol.Invalid( "MQTT topic name/filter must not be longer than 65535 encoded bytes." ) if "\0" in value: raise vol.Invalid( "MQTT topic name/filter must not contain null character.") if any(char <= "\u001F" for char in value): raise vol.Invalid( "MQTT topic name/filter must not contain control characters.") if any("\u007f" <= char <= "\u009F" for char in value): raise vol.Invalid( "MQTT topic name/filter must not contain control characters.") if any("\ufdd0" <= char <= "\ufdef" for char in value): raise vol.Invalid( "MQTT topic name/filter must not contain non-characters.") if any((ord(char) & 0xFFFF) in (0xFFFE, 0xFFFF) for char in value): raise vol.Invalid( "MQTT topic name/filter must not contain noncharacters.") return value
def _bytearray_string(data): val = cv.string(data) try: return bytearray.fromhex(val) except ValueError: raise vol.Invalid( "Data must be a hex string with multiple of two characters")
def data_packet(value): """Decode a data packet given for clas.""" value = cv.string(value) extra = len(value) % 4 if extra > 0: value = value + ("=" * (4 - extra)) return b64decode(value)
def data_packet(value): """Decode a data packet given for broadlink.""" value = cv.string(value) extra = len(value) % 4 if extra > 0: value = value + ('=' * (4 - extra)) return b64decode(value)
def data_packet(value): """Decode a data packet given for broadlink.""" value = cv.string(value) extra = len(value) % 4 if extra > 0: value = value + ('=' * (4 - extra)) return b64decode(value)
def message_received(topic, payload, qos): """Handle new MQTT message.""" if topic == self._battery_level_topic and \ self._battery_level_template: battery_level = self._battery_level_template\ .async_render_with_possible_json_value( payload, error_value=None) if battery_level is not None: self._battery_level = int(battery_level) if topic == self._charging_topic and self._charging_template: charging = self._charging_template\ .async_render_with_possible_json_value( payload, error_value=None) if charging is not None: self._charging = cv.boolean(charging) if topic == self._cleaning_topic and self._cleaning_template: cleaning = self._cleaning_template \ .async_render_with_possible_json_value( payload, error_value=None) if cleaning is not None: self._cleaning = cv.boolean(cleaning) if topic == self._docked_topic and self._docked_template: docked = self._docked_template \ .async_render_with_possible_json_value( payload, error_value=None) if docked is not None: self._docked = cv.boolean(docked) if topic == self._error_topic and self._error_template: error = self._error_template \ .async_render_with_possible_json_value( payload, error_value=None) if error is not None: self._error = cv.string(error) if self._docked: if self._charging: self._status = "Docked & Charging" else: self._status = "Docked" elif self._cleaning: self._status = "Cleaning" elif self._error is not None and not self._error: self._status = "Error: {}".format(self._error) else: self._status = "Stopped" if topic == self._fan_speed_topic and self._fan_speed_template: fan_speed = self._fan_speed_template\ .async_render_with_possible_json_value( payload, error_value=None) if fan_speed is not None: self._fan_speed = fan_speed self.async_schedule_update_ha_state()
def mac_address(mac): """Validate and convert a MAC address to bytes.""" mac = cv.string(mac) if len(mac) == 17: mac = "".join(mac[i:i + 2] for i in range(0, 17, 3)) elif len(mac) == 14: mac = "".join(mac[i:i + 4] for i in range(0, 14, 5)) elif len(mac) != 12: raise ValueError("Invalid MAC address") return bytes.fromhex(mac)
async def async_play_media(self, media_type, media_id, **kwargs): if media_type == MEDIA_TYPE_CHANNEL: try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error("Media ID must be positive integer") return for digit in media_id: await self._tizenws.send_key("KEY_" + digit, KEYPRESS_DEFAULT_DELAY) await self._tizenws.send_ke("KEY_ENTER") if media_type == MEDIA_TYPE_APP: await self._tizenws.run_app(media_id) elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return # source_key = media_id await self._tizenws.send_key(media_id) elif media_type == MEDIA_TYPE_URL: try: cv.url(media_id) except vol.Invalid: _LOGGER.error('Media ID must be an url (ex: "http://"') return await self._upnp.async_set_current_media(media_id) elif media_type == "application/vnd.apple.mpegurl": await self._upnp.async_set_current_media(media_id) # elif media_type == MEDIA_TYPE_BROWSER: # self._tizenws.open_browser(media_id) else: _LOGGER.error("Unsupported media type") return self.async_schedule_update_ha_state(True)
async def async_play_media(self, media_type, media_id, **kwargs): """Support changing a channel.""" # Type channel if media_type == MEDIA_TYPE_CHANNEL: try: cv.positive_int(media_id.replace("-", "", 1)) # Hyphen must be between numbers if media_id.startswith("-") or media_id.endswith("-"): raise vol.Invalid("") except vol.Invalid: _LOGGER.error( "Media ID must be channel with optional sub-channel, separated by a hyphen (ex. 20-2)" ) return for digit in media_id: await self.hass.async_add_job( self.send_command, "KEY_PLUS100" if digit == "-" else "KEY_" + digit) await self.hass.async_add_job(self.send_command, "KEY_ENTER") # Launch an app elif media_type == MEDIA_TYPE_APP: await self.hass.async_add_job(self.send_command, media_id, "run_app") # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return await self.hass.async_add_job(self.send_command, media_id) else: _LOGGER.error("Unsupported media type") return
def validate_entity_config(values): """Validate config entry for CONF_ENTITY.""" entities = {} for entity_id, config in values.items(): entity = cv.entity_id(entity_id) params = {} if not isinstance(config, dict): raise vol.Invalid('The configuration for "{}" must be ' ' a dictionary.'.format(entity)) for key in (CONF_NAME, ): value = config.get(key, -1) if value != -1: params[key] = cv.string(value) domain, _ = split_entity_id(entity) if domain in ('alarm_control_panel', 'lock'): code = config.get(ATTR_CODE) params[ATTR_CODE] = cv.string(code) if code else None entities[entity] = params return entities
def indications_validator(indications: Any): if isinstance(indications, Mapping): temp_indications = {**indications} dict_indications = {} for key in indications.keys(): key_str = str(key) match = RE_INDICATIONS_KEY.search(key_str) if match: value = cv.positive_float(indications[key]) idx = cv.positive_int(match.group(3)) if idx in dict_indications and dict_indications[idx] != value: raise vol.Invalid( 'altering indication value for same index: %s' % (idx, ), path=[key_str]) dict_indications[idx] = value del temp_indications[key] if temp_indications: errors = [ vol.Invalid('extra keys not allowed', path=[key]) for key in temp_indications.keys() ] if len(errors) == 1: raise errors[0] raise vol.MultipleInvalid(errors) list_indications = [] for key in sorted(dict_indications.keys()): if len(list_indications) < key - 1: raise vol.Invalid('missing indication index: %d' % (key - 1, )) list_indications.append(dict_indications[key]) else: try: indications = map(str.strip, cv.string(indications).split(',')) except (vol.Invalid, vol.MultipleInvalid): indications = cv.ensure_list(indications) list_indications = list(map(cv.positive_float, indications)) if len(list_indications) < 1: raise vol.Invalid('empty set of indications provided') return list_indications
def valid_topic(value: Any) -> str: """Validate that this is a valid topic name/filter.""" value = cv.string(value) try: raw_value = value.encode('utf-8') except UnicodeError: raise vol.Invalid("MQTT topic name/filter must be valid UTF-8 string.") if not raw_value: raise vol.Invalid("MQTT topic name/filter must not be empty.") if len(raw_value) > 65535: raise vol.Invalid("MQTT topic name/filter must not be longer than " "65535 encoded bytes.") if '\0' in value: raise vol.Invalid("MQTT topic name/filter must not contain null " "character.") return value
def valid_topic(value: Any) -> str: """Validate that this is a valid topic name/filter.""" value = cv.string(value) try: raw_value = value.encode('utf-8') except UnicodeError: raise vol.Invalid("MQTT topic name/filter must be valid UTF-8 string.") if not raw_value: raise vol.Invalid("MQTT topic name/filter must not be empty.") if len(raw_value) > 65535: raise vol.Invalid("MQTT topic name/filter must not be longer than " "65535 encoded bytes.") if '\0' in value: raise vol.Invalid("MQTT topic name/filter must not contain null " "character.") return value
def valid_country(value: Any) -> str: """Validate that the given country is supported.""" value = cv.string(value) all_supported_countries = holidays.list_supported_countries() try: raw_value = value.encode("utf-8") except UnicodeError as err: raise vol.Invalid( "The country name or the abbreviation must be a valid UTF-8 string." ) from err if not raw_value: raise vol.Invalid("Country name or the abbreviation must not be empty.") if value not in all_supported_countries: raise vol.Invalid("Country is not supported.") return value
def validate_entity_config(values): """Validate config entry for CONF_ENTITY.""" entities = {} for key, config in values.items(): entity = cv.entity_id(key) params = {} if not isinstance(config, dict): raise vol.Invalid('The configuration for "{}" must be ' ' an dictionary.'.format(entity)) domain, _ = split_entity_id(entity) if domain == 'alarm_control_panel': code = config.get(ATTR_CODE) params[ATTR_CODE] = cv.string(code) if code else None entities[entity] = params return entities
SCAN_INTERVAL = timedelta(seconds=30) BATTERY_SCAN_INTERVAL = timedelta(hours=12) DEFAULT_TOPIC = "/SensorService/SensorValue" DEFAULT_SET_SUFFIX = "/Set" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_NAME): cv.string, vol.Required(CONF_MAC): cv.string, vol.Optional(CONF_TOPIC): cv.string, vol.Optional(CONF_SET_SUFFIX): cv.string, vol.Required(CONF_DEVICE_CLASS): cv.string('meizu_remote'), }) ATTR_TEMPERATURE = 'Temperature' ATTR_HUMIDITY = 'Humidity' ATTR_BATTERY = 'Battery' def setup_platform(hass, config, add_devices, discovery_info=None): # get config name = config.get(CONF_NAME) mac_address = config.get(CONF_MAC) topic = config.get(CONF_TOPIC, DEFAULT_TOPIC) set_suffix = config.get(CONF_SET_SUFFIX, DEFAULT_SET_SUFFIX) update_interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL) # init meizu remote
def message_received(msg): """Handle new MQTT message.""" if (msg.topic == self._state_topics[CONF_BATTERY_LEVEL_TOPIC] and self._templates[CONF_BATTERY_LEVEL_TEMPLATE]): battery_level = self._templates[ CONF_BATTERY_LEVEL_TEMPLATE].async_render_with_possible_json_value( msg.payload, None) if battery_level: self._battery_level = int(battery_level) if (msg.topic == self._state_topics[CONF_CHARGING_TOPIC] and self._templates[CONF_CHARGING_TEMPLATE]): charging = self._templates[ CONF_CHARGING_TEMPLATE].async_render_with_possible_json_value( msg.payload, None) if charging: self._charging = cv.boolean(charging) if (msg.topic == self._state_topics[CONF_CLEANING_TOPIC] and self._templates[CONF_CLEANING_TEMPLATE]): cleaning = self._templates[ CONF_CLEANING_TEMPLATE].async_render_with_possible_json_value( msg.payload, None) if cleaning: self._cleaning = cv.boolean(cleaning) if (msg.topic == self._state_topics[CONF_DOCKED_TOPIC] and self._templates[CONF_DOCKED_TEMPLATE]): docked = self._templates[ CONF_DOCKED_TEMPLATE].async_render_with_possible_json_value( msg.payload, None) if docked: self._docked = cv.boolean(docked) if (msg.topic == self._state_topics[CONF_ERROR_TOPIC] and self._templates[CONF_ERROR_TEMPLATE]): error = self._templates[ CONF_ERROR_TEMPLATE].async_render_with_possible_json_value( msg.payload, None) if error is not None: self._error = cv.string(error) if self._docked: if self._charging: self._status = "Docked & Charging" else: self._status = "Docked" elif self._cleaning: self._status = "Cleaning" elif self._error: self._status = f"Error: {self._error}" else: self._status = "Stopped" if (msg.topic == self._state_topics[CONF_FAN_SPEED_TOPIC] and self._templates[CONF_FAN_SPEED_TEMPLATE]): fan_speed = self._templates[ CONF_FAN_SPEED_TEMPLATE].async_render_with_possible_json_value( msg.payload, None) if fan_speed: self._fan_speed = fan_speed self.async_write_ha_state()
async def async_play_media(self, media_type, media_id, **kwargs): # Type channel if media_type == MEDIA_TYPE_CHANNEL: """Support changing a channel.""" _LOGGER.debug("Trying to change %s to %s",media_type,media_id) try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error("Media ID must be positive integer") return if self._api_key and self._device_id: if self._running_app == 'TV/HDMI' and self._cloud_source in ["DigitalTv", "digitalTv", "TV"]: #In TV mode, change channel if self._cloud_channel != media_id: await self.hass.async_add_job(self._smartthings_keys, f"ST_CH{media_id}") else: #Change to TV source before changing channel self.hass.async_add_job(self._smartthings_keys, "ST_TV") time.sleep(5) smartthings.device_update(self) if self._cloud_channel != media_id: await self.hass.async_add_job(self._smartthings_keys, f"ST_CH{media_id}") else: keychain = "" for digit in media_id: keychain += "KEY_{}+".format(digit) keychain += "KEY_ENTER" if self._running_app == 'TV/HDMI': self.hass.async_add_job(self.async_play_media, MEDIA_TYPE_KEY, keychain) else: found_source = False for source in self._source_list: if source.lower() in ["tv", "live tv", "livetv"]: found_source = True await self.hass.async_add_job(self.async_select_source, source) time.sleep(2) break if found_source == False: keychain = "KEY_EXIT+KEY_EXIT+{}".format(keychain) self.hass.async_add_job(self.async_play_media, MEDIA_TYPE_KEY, keychain) # Launch an app elif media_type == MEDIA_TYPE_APP: await self.hass.async_add_job(self.send_command, media_id, "run_app") # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return source_key = media_id if "+" in source_key: all_source_keys = source_key.split("+") last_was_delay = True for this_key in all_source_keys: if this_key.isdigit(): last_was_delay = True time.sleep(int(this_key)/1000) else: if this_key.startswith("ST_"): await self.hass.async_add_job(self._smartthings_keys, this_key) else: if last_was_delay == False: time.sleep(DEFAULT_KEY_CHAIN_DELAY) last_was_delay = False self.hass.async_add_job(self.send_command, this_key) elif source_key.startswith("ST_"): await self.hass.async_add_job(self._smartthings_keys, source_key) else: await self.hass.async_add_job(self.send_command, source_key) # Play media elif media_type == MEDIA_TYPE_URL: try: cv.url(media_id) except vol.Invalid: _LOGGER.error('Media ID must be an url (ex: "http://"') return await self.hass.async_add_job(self._upnp.set_current_media, media_id) self._playing = True # Trying to make stream component work on TV elif media_type == "application/vnd.apple.mpegurl": await self.hass.async_add_job(self._upnp.set_current_media, media_id) self._playing = True elif media_type == MEDIA_TYPE_BROWSER: try: await self.hass.async_add_job(self._ws.open_browser, media_id) except (ConnectionResetError, AttributeError, BrokenPipeError,websocket._exceptions.WebSocketTimeoutException): self._ws.close() else: _LOGGER.error("Unsupported media type") return
def valid_subscribe_topic(value: Any, invalid_chars='\0') -> str: """Validate that we can subscribe using this MQTT topic.""" value = cv.string(value) if all(c not in value for c in invalid_chars): return vol.Length(min=1, max=65535)(value) raise vol.Invalid('Invalid MQTT topic name')
def message_received(topic, payload, qos): """Handle new MQTT message.""" if topic == self._state_topics[CONF_BATTERY_LEVEL_TOPIC] and \ self._templates[CONF_BATTERY_LEVEL_TEMPLATE]: battery_level = self._templates[CONF_BATTERY_LEVEL_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if battery_level is not None: self._battery_level = int(battery_level) if topic == self._state_topics[CONF_CHARGING_TOPIC] and \ self._templates[CONF_CHARGING_TEMPLATE]: charging = self._templates[CONF_CHARGING_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if charging is not None: self._charging = cv.boolean(charging) if topic == self._state_topics[CONF_CLEANING_TOPIC] and \ self._templates[CONF_CLEANING_TEMPLATE]: cleaning = self._templates[CONF_CLEANING_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if cleaning is not None: self._cleaning = cv.boolean(cleaning) if topic == self._state_topics[CONF_DOCKED_TOPIC] and \ self._templates[CONF_DOCKED_TEMPLATE]: docked = self._templates[CONF_DOCKED_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if docked is not None: self._docked = cv.boolean(docked) if topic == self._state_topics[CONF_ERROR_TOPIC] and \ self._templates[CONF_ERROR_TEMPLATE]: error = self._templates[CONF_ERROR_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if error is not None: self._error = cv.string(error) if self._docked: if self._charging: self._status = "Docked & Charging" else: self._status = "Docked" elif self._cleaning: self._status = "Cleaning" elif self._error is not None and not self._error: self._status = "Error: {}".format(self._error) else: self._status = "Stopped" if topic == self._state_topics[CONF_FAN_SPEED_TOPIC] and \ self._templates[CONF_FAN_SPEED_TEMPLATE]: fan_speed = self._templates[CONF_FAN_SPEED_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if fan_speed is not None: self._fan_speed = fan_speed self.async_schedule_update_ha_state()
def message_received(topic, payload, qos): """Handle new MQTT message.""" if topic == self._state_topics[CONF_BATTERY_LEVEL_TOPIC] and \ self._templates[CONF_BATTERY_LEVEL_TEMPLATE]: battery_level = self._templates[CONF_BATTERY_LEVEL_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if battery_level is not None: self._battery_level = int(battery_level) if topic == self._state_topics[CONF_CHARGING_TOPIC] and \ self._templates[CONF_CHARGING_TEMPLATE]: charging = self._templates[CONF_CHARGING_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if charging is not None: self._charging = cv.boolean(charging) if topic == self._state_topics[CONF_CLEANING_TOPIC] and \ self._templates[CONF_CLEANING_TEMPLATE]: cleaning = self._templates[CONF_CLEANING_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if cleaning is not None: self._cleaning = cv.boolean(cleaning) if topic == self._state_topics[CONF_DOCKED_TOPIC] and \ self._templates[CONF_DOCKED_TEMPLATE]: docked = self._templates[CONF_DOCKED_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if docked is not None: self._docked = cv.boolean(docked) if topic == self._state_topics[CONF_ERROR_TOPIC] and \ self._templates[CONF_ERROR_TEMPLATE]: error = self._templates[CONF_ERROR_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if error is not None: self._error = cv.string(error) if self._docked: if self._charging: self._status = "Docked & Charging" else: self._status = "Docked" elif self._cleaning: self._status = "Cleaning" elif self._error is not None and not self._error: self._status = "Error: {}".format(self._error) else: self._status = "Stopped" if topic == self._state_topics[CONF_FAN_SPEED_TOPIC] and \ self._templates[CONF_FAN_SPEED_TEMPLATE]: fan_speed = self._templates[CONF_FAN_SPEED_TEMPLATE]\ .async_render_with_possible_json_value( payload, error_value=None) if fan_speed is not None: self._fan_speed = fan_speed self.async_schedule_update_ha_state()
async def async_play_media(self, media_type, media_id, **kwargs): """Support changing a channel.""" # Type channel if media_type == MEDIA_TYPE_CHANNEL: try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error("Media ID must be positive integer") return for digit in media_id: await self.hass.async_add_job(self.send_command, "KEY_" + digit) await self.hass.async_add_job(self.send_command, "KEY_ENTER") # Launch an app elif media_type == MEDIA_TYPE_APP: await self.hass.async_add_job(self.send_command, media_id, "run_app") # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return source_key = media_id if "+" in source_key: all_source_keys = source_key.split("+") for this_key in all_source_keys: if this_key.isdigit(): time.sleep(int(this_key) / 1000) else: if this_key.startswith("ST_"): await self.hass.async_add_job( self._smartthings_keys, this_key) else: await self.hass.async_add_job( self.send_command, this_key) elif source_key.startswith("ST_"): await self.hass.async_add_job(self._smartthings_keys, source_key) else: await self.hass.async_add_job(self.send_command, source_key) # Play media elif media_type == MEDIA_TYPE_URL: try: cv.url(media_id) except vol.Invalid: _LOGGER.error('Media ID must be an url (ex: "http://"') return self._upnp.set_current_media(media_id) self._playing = True # Trying to make stream component work on TV elif media_type == "application/vnd.apple.mpegurl": self._upnp.set_current_media(media_id) self._playing = True elif media_type == MEDIA_TYPE_BROWSER: try: self._ws.open_browser(media_id) except (ConnectionResetError, AttributeError, BrokenPipeError, websocket._exceptions.WebSocketTimeoutException): self._ws.close() else: _LOGGER.error("Unsupported media type") return
async def async_play_media(self, media_type, media_id, **kwargs): """Support changing a channel.""" # Type channel if media_type == MEDIA_TYPE_CHANNEL: try: cv.positive_int(media_id) except vol.Invalid: _LOGGER.error("Media ID must be positive integer") return for digit in media_id: await self.hass.async_add_job(self.send_command, "KEY_" + digit) await self.hass.async_add_job(self.send_command, "KEY_ENTER") # Launch an app elif media_type == MEDIA_TYPE_APP: await self.hass.async_add_job(self.send_command, media_id, "run_app") # Send custom key elif media_type == MEDIA_TYPE_KEY: try: cv.string(media_id) except vol.Invalid: _LOGGER.error('Media ID must be a string (ex: "KEY_HOME"') return source_key = media_id if source_key.startswith("ST_"): if source_key.startswith("ST_HDMI"): smartthings.send_command(self, source_key.replace("ST_", ""), "selectsource") elif source_key == "ST_TV": smartthings.send_command(self, "digitalTv", "selectsource") elif "+" in source_key: all_source_keys = source_key.split("+") for this_key in all_source_keys: if this_key.isdigit(): time.sleep(int(this_key) / 1000) else: await self.hass.async_add_job(self.send_command, this_key) else: await self.hass.async_add_job(self.send_command, source_key) # Play media elif media_type == MEDIA_TYPE_URL: try: cv.url(media_id) except vol.Invalid: _LOGGER.error('Media ID must be an url (ex: "http://"') return self._upnp.set_current_media(media_id) self._playing = True # Trying to make stream component work on TV elif media_type == "application/vnd.apple.mpegurl": self._upnp.set_current_media(media_id) self._playing = True else: _LOGGER.error("Unsupported media type") return
from homeassistant.components.sensor import (PLATFORM_SCHEMA) from homeassistant.helpers.event import track_time_interval _LOGGER = logging.getLogger(__name__) CONF_TOPIC = "topic" CONF_SET_SUFFIX = "set_suffix" SCAN_INTERVAL = timedelta(seconds=30) BATTERY_SCAN_INTERVAL = timedelta(hours=12) DEFAULT_TOPIC = "/SensorService/SensorValue" DEFAULT_SET_SUFFIX = "/Set" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_NAME): cv.string, vol.Required(CONF_MAC): cv.string, vol.Required(CONF_DEVICE_CLASS): cv.string('meizu_remote'), }) ATTR_TEMPERATURE = 'Temperature' ATTR_HUMIDITY = 'Humidity' ATTR_BATTERY = 'Battery' def setup_platform(hass, config, add_devices, discovery_info=None): # get config name = config.get(CONF_NAME) mac_address = config.get(CONF_MAC) topic = config.get(CONF_TOPIC, DEFAULT_TOPIC) set_suffix = config.get(CONF_SET_SUFFIX, DEFAULT_SET_SUFFIX) update_interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL) # init meizu remote
def data_packet(value): """Decode a data packet given for broadlink.""" return b64decode(cv.string(value))