Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: release 2024-09-15 #2528

Merged
merged 5 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions custom_components/alexa_media/alexa_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,11 @@ def parse_temperature_from_coordinator(
coordinator: DataUpdateCoordinator, entity_id: str
) -> Optional[str]:
"""Get the temperature of an entity from the coordinator data."""
value = parse_value_from_coordinator(
temperature = parse_value_from_coordinator(
coordinator, entity_id, "Alexa.TemperatureSensor", "temperature"
)
return value.get("value") if value and "value" in value else None
_LOGGER.debug("parse_temperature_from_coordinator: %s", temperature)
return temperature


def parse_air_quality_from_coordinator(
Expand Down
174 changes: 174 additions & 0 deletions custom_components/alexa_media/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,177 @@
ALEXA_ICON_DEFAULT = "mdi:molecule"

UPLOAD_PATH = "www/alexa_tts"

# Note: Some of these are likely wrong
MODEL_IDS = {
"A10A33FOX2NUBK": "Echo Spot",
"A10L5JEZTKKCZ8": "Vobot Bunny",
"A11QM4H9HGV71H": "Echo Show 5 (Gen3)",
"A12GXV8XMS007S": "Fire TV (Gen1)",
"A12IZU8NMHSY5U": "Generic Device",
"A132LT22WVG6X5": "Samsung Soundbar Q700A",
"A13B2WB920IZ7X": "Samsung HW-Q70T Soundbar",
"A13W6HQIHKEN3Z": "Echo Auto",
"A14ZH95E6SE9Z1": "Bose Home Speaker 300",
"A15996VY63BQ2D": "Echo Show 8 (Gen2)",
"A15ERDAKK5HQQG": "Sonos",
"A15QWUTQ6FSMYX": "Echo Buds (Gen2)",
"A16MZVIFVHX6P6": "Generic Echo",
"A17LGWINFBUTZZ": "Anker Roav Viva",
"A18BI6KPKDOEI4": "Ecobee4",
"A18O6U1UQFJ0XK": "Echo Plus (Gen2)",
"A18TCD9FP10WJ9": "Orbi Voice",
"A18X8OBWBCSLD8": "Samsung Soundbar",
"A195TXHV1M5D4A": "Echo Auto",
"A1C66CX2XD756O": "Fire Tablet HD",
"A1EIANJ7PNB0Q7": "Echo Show 15 (Gen1)",
"A1ENT81UXFMNNO": "Unknown",
"A1ETW4IXK2PYBP": "Talk to Alexa",
"A1F1F76XIW4DHQ": "Unknown TV",
"A1F8D55J0FWDTN": "Fire TV (Toshiba)",
"A1H0CMF1XM0ZP4": "Bose SoundTouch 30",
"A1J16TEDOYCZTN": "Fire Tablet",
"A1JJ0KFC4ZPNJ3": "Echo Input",
"A1L4KDRIILU6N9": "Sony Speaker",
"A1LOQ8ZHF4G510": "Samsung Soundbar Q990B",
"A1M0A9L9HDBID3": "One-Link Safe and Sound",
"A1MUORL8FP149X": "Unknown",
"A1N9SW0I0LUX5Y": "Ford/Lincoln Alexa App",
"A1NL4BVLQ4L3N3": "Echo Show (Gen1)",
"A1NQ0LXWBGVQS9": "2021 Samsung QLED TV",
"A1P31Q3MOWSHOD": "Zolo Halo Speaker",
"A1P7E7V3FCZKU6": "Fire TV (Gen3)",
"A1Q69AKRWLJC0F": "TV",
"A1Q7QCGNMXAKYW": "Generic Tablet",
"A1QKZ9D0IJY332": "Samsung TV 2020-U",
"A1RABVCI4QCIKC": "Echo Dot (Gen3)",
"A1RTAM01W29CUP": "Windows App",
"A1SCI5MODUBAT1": "Pioneer DMH-W466NEX",
"A1TD5Z1R8IWBHA": "Tablet",
"A1VGB7MHSIEYFK": "Fire TV Cube Gen3",
"A1W2YILXTG9HA7": "Nextbase 522GW Dashcam",
"A1W46V57KES4B5": "Cable TV box Brazil",
"A1WZKXFLI43K86": "Fire TV Stick MAX",
"A1XWJRHALS1REP": "Echo Show 5 (Gen2)",
"A1Z88NGR2BK6A2": "Echo Show 8 (Gen1)",
"A25EC4GIHFOCSG": "Unrecognized Media Player",
"A25OJWHZA1MWNB": "2021 Samsung QLED TV",
"A265XOI9586NML": "Fire TV Stick",
"A27VEYGQBW3YR5": "Echo Link",
"A2A3XFQ1AVYLHZ": "SONY WF-1000XM5",
"A2BRQDVMSZD13S": "SURE Universal Remote",
"A2C8J6UHV0KFCV": "Alexa Gear",
"A2DS1Q2TPDJ48U": "Echo Dot Clock (Gen5)",
"A2E0SNTXJVT7WK": "Fire TV (Gen2)",
"A2E5N6DMWCW8MZ": "Brilliant Smart Switch",
"A2EZ3TS0L1S2KV": "Sonos Beam",
"A2GFL5ZMWNE0PX": "Fire TV (Gen3)",
"A2H4LV5GIZ1JFT": "Echo Dot Clock (Gen4)",
"A2HZENIFNYTXZD": "Facebook Portal",
"A2I0SCCU3561Y8": "Samsung Soundbar Q800A",
"A2IS7199CJBT71": "TV",
"A2IVLV5VM2W81": "Alexa Mobile Voice iOS",
"A2J0R2SD7G9LPA": "Lenovo SmartTab M10",
"A2JKHJ0PX4J3L3": "Fire TV Cube (Gen2)",
"A2LH725P8DQR2A": "Fabriq Riff",
"A2LWARUGJLBYEW": "Fire TV Stick (Gen2)",
"A2M35JJZWCQOMZ": "Echo Plus (Gen1)",
"A2M4YX06LWP8WI": "Fire Tablet",
"A2N49KXGVA18AR": "Fire Tablet HD 10 Plus",
"A2OSP3UA4VC85F": "Sonos",
"A2R2GLZH1DFYQO": "Zolo Halo Speaker",
"A2RU4B77X9R9NZ": "Echo Link Amp",
"A2TF17PFR55MTB": "Alexa Mobile Voice Android",
"A2TTLILJHVNI9X": "LG TV",
"A2U21SRK4QGSE1": "Echo Dot Clock (Gen4)",
"A2UONLFQW0PADH": "Echo Show 8 (Gen3)",
"A2V9UEGZ82H4KZ": "Fire Tablet HD 10",
"A2VAXZ7UNGY4ZH": "Wyze Headphones",
"A2WFDCBDEXOXR8": "Bose Soundbar 700",
"A2WN1FJ2HG09UN": "Ultimate Alexa App",
"A2X8WT9JELC577": "Ecobee5",
"A2XPGY5LRKB9BE": "Fitbit Versa 2",
"A2Y04QPFCANLPQ": "Bose QuietComfort 35 II",
"A303PJF6ISQ7IC": "Echo Auto",
"A30YDR2MK8HMRV": "Echo (Gen3)",
"A31DTMEEVDDOIV": "Fire TV Stick Lite",
"A324YMIUSWQDGE": "Samsung 8K TV",
"A32DDESGESSHZA": "Echo Dot (Gen3)",
"A32DOYMUN6DTXA": "Echo Dot (Gen3)",
"A339L426Y220I4": "Teufel Radio",
"A347G2JC8I4HC7": "Roav Car Charger Pro",
"A37CFAHI1O0CXT": "Logitech Blast",
"A37M7RU8Z6ZFB": "Garmin Speak",
"A37SHHQ3NUL7B5": "Bose Home Speaker 500",
"A38949IHXHRQ5P": "Echo Tap",
"A38BPK7OW001EX": "Raspberry Alexa",
"A38EHHIB10L47V": "Fire Tablet HD 8",
"A39BU42XNMN516": "Generic Device",
"A3B50IC5QPZPWP": "Polk Command Bar",
"A3B5K1G3EITBIF": "Facebook Portal",
"A3BRT6REMPQWA8": "Bose Home Speaker 450",
"A3BW5ZVFHRCQPO": "BMW Alexa Integration",
"A3C9PE6TNYLTCH": "Speaker Group",
"A3CY98NH016S5F": "Facebook Portal Mini",
"A3D4YURNTARP5K": "Facebook Portal TV",
"A3EVMLQTU6WL1W": "Fire TV (GenX)",
"A3F1S88NTZZXS9": "Dash Wand",
"A3FX4UWTP28V1P": "Echo (Gen3)",
"A3GFRGUNIGG1I5": "Samsung TV QN50Q60CAGXZD",
"A3HF4YRA2L7XGC": "Fire TV Cube",
"A3IYPH06PH1HRA": "Echo Frames",
"A3K69RS3EIMXPI": "Hisense Smart TV",
"A3KULB3NQN7Z1F": "Unknown TV",
"A3L0T0VL9A921N": "Fire Tablet HD 8",
"A3NPD82ABCPIDP": "Sonos Beam",
"A3QPPX1R9W5RJV": "Fabriq Chorus",
"A3QS1XP2U6UJX9": "SONY WF-1000XM4",
"A3R9S4ZZECZ6YL": "Fire Tablet HD 10",
"A3RBAYBE7VM004": "Echo Studio",
"A3RCTOK2V0A4ZG": "LG TV",
"A3RMGO6LYLH7YN": "Echo Dot (Gen4)",
"A3S5BH2HU6VAYF": "Echo Dot (Gen2)",
"A3SSG6GR8UU7SN": "Echo Sub",
"A3SSWQ04XYPXBH": "Generic Tablet",
"A3TCJ8RTT3NVI7": "Alexa Listens",
"A3VRME03NAXFUB": "Echo Flex",
"A4ZP7ZC4PI6TO": "Echo Show 5 (Gen1)",
"A4ZXE0RM7LQ7A": "Echo Dot (Gen5)",
"A52ARKF0HM2T4": "Facebook Portal+",
"A6SIQKETF3L2E": "Unknown Device",
"A7WXQPH584YP": "Echo (Gen2)",
"A81PNL0A63P93": "Home Remote",
"A8DM4FYR6D3HT": "TV",
"AA1IN44SS3X6O": "Ecobee Thermostat Premium",
"AB72C64C86AW2": "Echo (Gen1)",
"ABJ2EHL7HQT4L": "Unknown Amplifier",
"ADVBD696BHNV5": "Fire TV Stick (Gen1)",
"AE7X7Z227NFNS": "HiMirror Mini",
"AF473ZSOIRKFJ": "Onkyo VC-PX30",
"AFF50AL5E3DIU": "Fire TV (Insignia)",
"AFF5OAL5E3DIU": "Fire TV",
"AGHZIK8D6X7QR": "Fire TV",
"AHJYKVA63YCAQ": "Sonos",
"AIPK7MM90V7TB": "Echo Show 10 (Gen3)",
"AKKLQD9FZWWQS": "Jabra Elite",
"AKNO1N0KSFN8L": "Echo Dot (Gen1)",
"AKO51L5QAQKL2": "Alexa Jams",
"AKPGW064GI9HE": "Fire TV Stick 4K (Gen3)",
"ALT9P69K6LORD": "Echo Auto",
"AMCZ48H33RCDF": "Samsung HW-Q910B 9.1.2 ch Soundbar",
"AN630UQPG2CA4": "Fire TV (Toshiba)",
"AO6HHP9UE6EOF": "Unknown Media Device",
"AP1F6KUH00XPV": "Stereo/Subwoofer Pair",
"AP4RS91ZQ0OOI": "Fire TV (Toshiba)",
"APHEAY6LX7T13": "Samsung Smart Refrigerator",
"AQCGW9PSYWRF": "TV",
"AR6X0XNIME80V": "Unknown TV",
"ASQZWP4GPYUT7": "Echo Pop",
"ATNLRCEBX3W4P": "Generic Tablet",
"AUPUQSVCVHXP0": "Ecobee Switch+",
"AVD3HM0HOJAAL": "Sonos",
"AVE5HX13UR5NO": "Logitech Zero Touch",
"AVN2TMX8MU2YM": "Bose Home Speaker 500",
"AVU7CPPF2ZRAS": "Fire Tablet HD 8",
"AWZZ5CVHX2CD": "Echo Show (Gen2)",
}
25 changes: 21 additions & 4 deletions custom_components/alexa_media/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
DEPENDENT_ALEXA_COMPONENTS,
MIN_TIME_BETWEEN_FORCED_SCANS,
MIN_TIME_BETWEEN_SCANS,
MODEL_IDS,
PLAY_SCAN_INTERVAL,
UPLOAD_PATH,
)
Expand Down Expand Up @@ -180,9 +181,14 @@ async def async_setup_entry(hass, config_entry, async_add_devices):
_LOGGER.debug(
"%s: Loading config entry for %s", hide_email(account), component
)
await hass.config_entries.async_forward_entry_setups(
config_entry, [component]
)
try:
await hass.config_entries.async_forward_entry_setups(
config_entry, [component]
)
except (asyncio.TimeoutError, TimeoutException) as ex:
raise ConfigEntryNotReady(
f"Timeout while loading config entry for {component}"
) from ex
return True
raise ConfigEntryNotReady

Expand Down Expand Up @@ -412,6 +418,15 @@ async def _refresh_if_no_audiopush(already_refreshed=False):
self.hass.data[DATA_ALEXAMEDIA]["accounts"][email]["http2"]
)
self.async_schedule_update_ha_state(force_refresh=force_refresh)
if self._last_called:
self.hass.bus.async_fire(
"alexa_media_last_called_event",
{
"last_called": self.device_serial_number,
"timestamp": self._last_called_timestamp,
"summary": self._last_called_summary,
},
)
elif "bluetooth_change" in event:
if event_serial == self.device_serial_number:
_LOGGER.debug(
Expand Down Expand Up @@ -1607,7 +1622,9 @@ def device_info(self):
"identifiers": {(ALEXA_DOMAIN, self.unique_id)},
"name": self.name,
"manufacturer": "Amazon",
"model": f"{self._device_family} {self._device_type}",
"model": MODEL_IDS.get(
self._device_type, f"{self._device_family} {self._device_type}"
),
"sw_version": self._software_version,
}

Expand Down
51 changes: 44 additions & 7 deletions custom_components/alexa_media/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,10 @@ async def create_temperature_sensors(account_dict, temperature_entities):
coordinator = account_dict["coordinator"]
for temp in temperature_entities:
_LOGGER.debug(
"Creating entity %s for a temperature sensor with name %s",
"Creating entity %s for a temperature sensor with name %s (%s)",
temp["id"],
temp["name"],
temp,
)
serial = temp["device_serial"]
device_info = lookup_device_info(account_dict, serial)
Expand Down Expand Up @@ -254,16 +255,25 @@ def __init__(self, coordinator, entity_id, name, media_player_device_id):
"""Initialize temperature sensor."""
super().__init__(coordinator)
self.alexa_entity_id = entity_id
# Need to append "+temperature" because the Alexa entityId is for a physical device
# and a single physical device can have multiple HA entities
self._attr_unique_id = entity_id + "_temperature"
self._attr_name = name + " Temperature"
self._attr_device_class = SensorDeviceClass.TEMPERATURE
self._attr_state_class = SensorStateClass.MEASUREMENT
self._attr_native_value: Optional[datetime.datetime] = (
value_and_scale: Optional[datetime.datetime] = (
parse_temperature_from_coordinator(coordinator, entity_id)
)
self._attr_native_unit_of_measurement: Optional[str] = UnitOfTemperature.CELSIUS
# This includes "_temperature" because the Alexa entityId is for a physical device
# A single physical device could have multiple HA entities
self._attr_unique_id = entity_id + "_temperature"
self._attr_native_value = self._get_temperature_value(value_and_scale)
self._attr_native_unit_of_measurement = self._get_temperature_scale(
value_and_scale
)
_LOGGER.debug(
"Coordinator init: %s: %s %s",
self._attr_name,
self._attr_native_value,
self._attr_native_unit_of_measurement,
)
self._attr_device_info = (
{
"identifiers": {media_player_device_id},
Expand All @@ -276,11 +286,38 @@ def __init__(self, coordinator, entity_id, name, media_player_device_id):
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._attr_native_value = parse_temperature_from_coordinator(
value_and_scale = parse_temperature_from_coordinator(
self.coordinator, self.alexa_entity_id
)
self._attr_native_value = self._get_temperature_value(value_and_scale)
self._attr_native_unit_of_measurement = self._get_temperature_scale(
value_and_scale
)
_LOGGER.debug(
"Coordinator update: %s: %s %s",
self._attr_name,
self._attr_native_value,
self._attr_native_unit_of_measurement,
)
super()._handle_coordinator_update()

def _get_temperature_value(self, value):
if value and "value" in value:
_LOGGER.debug("TemperatureSensor value: %s", value.get("value"))
return value.get("value")
return None

def _get_temperature_scale(self, value):
if value and "scale" in value:
_LOGGER.debug("TemperatureSensor scale: %s", value.get("scale"))
if value.get("scale") == "CELSIUS":
return UnitOfTemperature.CELSIUS
if value.get("scale") == "FAHRENHEIT":
return UnitOfTemperature.FAHRENHEIT
if value.get("scale") == "KELVIN":
return UnitOfTemperature.KELVIN
return None


class AirQualitySensor(SensorEntity, CoordinatorEntity):
"""A air quality sensor reported by an Amazon indoor air quality monitor."""
Expand Down
Loading
Loading