def data_packet(value): """Decode a data packet given for a Broadlink remote.""" value = cv.string(value) extra = len(value) % 4 if extra > 0: value = value + ("=" * (4 - extra)) return b64decode(value)
def _bytearray_string(data): val = cv.string(data) try: return bytearray.fromhex(val) except ValueError as err: raise vol.Invalid( "Data must be a hex string with multiple of two characters" ) from err
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)
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 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 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, error_value=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, error_value=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, error_value=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, error_value=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, 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: 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, error_value=None) if fan_speed: self._fan_speed = fan_speed self.async_write_op_state()