Skip to content

Commit

Permalink
fix: add http2 push to replace websocket
Browse files Browse the repository at this point in the history
This should restore push updates.

Also includes dependency updates.

closes #1953
closes #1976
closes #1967
  • Loading branch information
alandtse committed Sep 29, 2023
1 parent 823e952 commit a3dde7f
Show file tree
Hide file tree
Showing 10 changed files with 1,424 additions and 1,315 deletions.
531 changes: 268 additions & 263 deletions custom_components/alexa_media/__init__.py

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions custom_components/alexa_media/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ async def async_step_start_proxy(self, user_input=None):
{"config_flow_id": self.flow_id, "callback_url": str(callback_url)}
)
self.login._session.cookie_jar.clear() # pylint: disable=protected-access
self.login.proxy_url = proxy_url
return self.async_external_step(step_id="check_proxy", url=str(proxy_url))

async def async_step_check_proxy(self, user_input=None):
Expand Down Expand Up @@ -576,6 +577,8 @@ async def _test_login(self):
"refresh_token": login.refresh_token,
"expires_in": login.expires_in,
"mac_dms": login.mac_dms,
"code_verifier": login.code_verifier,
"authorization_code": login.authorization_code,
}
self.hass.data.setdefault(
DATA_ALEXAMEDIA,
Expand Down
2 changes: 1 addition & 1 deletion custom_components/alexa_media/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/custom-components/alexa_media_player/issues",
"loggers": ["alexapy", "authcaptureproxy"],
"requirements": ["alexapy==1.26.8", "packaging>=20.3", "wrapt>=1.12.1"],
"requirements": ["alexapy==1.27.0", "packaging>=20.3", "wrapt>=1.12.1"],
"version": "4.6.5"
}
32 changes: 16 additions & 16 deletions custom_components/alexa_media/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ async def _refresh_if_no_audiopush(already_refreshed=False):
if self.hass and self.async_schedule_update_ha_state:
email = self._login.email
force_refresh = not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][email]["http2"]
)
self.async_schedule_update_ha_state(force_refresh=force_refresh)
elif "bluetooth_change" in event:
Expand Down Expand Up @@ -781,7 +781,7 @@ async def async_select_source(self, source):
await self.alexa_api.set_bluetooth(devices["address"])
self._source = source
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand Down Expand Up @@ -948,15 +948,15 @@ async def async_update(self):
await self.refresh( # pylint: disable=unexpected-keyword-arg
device, no_throttle=True
)
websocket_enabled = (
self.hass.data[DATA_ALEXAMEDIA]["accounts"].get(email, {}).get("websocket")
push_enabled = (
self.hass.data[DATA_ALEXAMEDIA]["accounts"].get(email, {}).get("http2")
)
if (
self.state in [STATE_PLAYING]
and
# only enable polling if websocket not connected
(
not websocket_enabled
not push_enabled
or not seen_commands
or not (
"PUSH_AUDIO_PLAYER_STATE" in seen_commands
Expand All @@ -981,11 +981,11 @@ async def async_update(self):
async_call_later(
self.hass,
PLAY_SCAN_INTERVAL,
lambda _: self.async_schedule_update_ha_state(force_refresh=True),
self.async_schedule_update_ha_state,
)
elif self._should_poll: # Not playing, one last poll
self._should_poll = False
if not websocket_enabled:
if not push_enabled:
_LOGGER.debug(
"%s: Disabling polling and scheduling last update in"
" 300 seconds for %s",
Expand All @@ -995,7 +995,7 @@ async def async_update(self):
async_call_later(
self.hass,
300,
lambda _: self.async_schedule_update_ha_state(force_refresh=True),
self.async_schedule_update_ha_state,
)
else:
_LOGGER.debug(
Expand Down Expand Up @@ -1118,7 +1118,7 @@ async def async_set_volume_level(self, volume):
await self.alexa_api.set_volume(volume)
self._media_vol_level = volume
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand Down Expand Up @@ -1166,7 +1166,7 @@ async def async_mute_volume(self, mute):
else:
await self.alexa_api.set_volume(50)
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand All @@ -1183,7 +1183,7 @@ async def async_media_play(self):
else:
await self.alexa_api.play()
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand All @@ -1200,7 +1200,7 @@ async def async_media_pause(self):
else:
await self.alexa_api.pause()
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand Down Expand Up @@ -1229,7 +1229,7 @@ async def async_media_stop(self):
][CONF_QUEUE_DELAY],
)
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand Down Expand Up @@ -1267,7 +1267,7 @@ async def async_media_next_track(self):
else:
await self.alexa_api.next()
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand All @@ -1284,7 +1284,7 @@ async def async_media_previous_track(self):
else:
await self.alexa_api.previous()
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand Down Expand Up @@ -1585,7 +1585,7 @@ async def async_play_media(self, media_type, media_id, enqueue=None, **kwargs):
**kwargs,
)
if not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["websocket"]
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._login.email]["http2"]
):
await self.async_update()

Expand Down
6 changes: 3 additions & 3 deletions custom_components/alexa_media/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ def _handle_coordinator_update(self) -> None:
class AlexaMediaNotificationSensor(SensorEntity):
"""Representation of Alexa Media sensors."""

_unrecorded_attributes = frozenset({"sorted_active", "sorted_all"})

def __init__(
self,
client,
Expand Down Expand Up @@ -579,9 +581,7 @@ def hidden(self):
@property
def should_poll(self):
"""Return the polling state."""
return not (
self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._account]["websocket"]
)
return not (self.hass.data[DATA_ALEXAMEDIA]["accounts"][self._account]["http2"])

def _process_state(self, value) -> Optional[datetime.datetime]:
return dt.as_local(value[self._sensor_property]) if value else None
Expand Down
2 changes: 1 addition & 1 deletion custom_components/alexa_media/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ update_last_called:

clear_history:
# Description of the service
description: Clear last entries from Alexa history for each Alexa account.
description: Clear last entries from Alexa Voice history for each Alexa account.
# Different fields that your service accepts
fields:
# Key of the field
Expand Down
36 changes: 36 additions & 0 deletions custom_components/alexa_media/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,41 @@
}
}
}
},
"services": {
"clear_history": {
"name": "Clear Amazon Voice History",
"description": "Clear last entries from Alexa Voice history for each Alexa account.",
"fields": {
"email": {
"name": "Email address",
"description": "Accounts to clear. Empty will clear all."
},
"entries": {
"name": "Number of Entries",
"description": "Number of entries to clear from 1 to 50. If empty, clear 50."
}
}
},
"force_logout": {
"name": "Force Logout",
"description": "Force account to logout. Used mainly for debugging.",
"fields": {
"email": {
"name": "Email address",
"description": "Accounts to clear. Empty will clear all."
}
}
},
"update_last_called": {
"name": "Update Last Called Sensor",
"description": "Forces update of last_called echo device for each Alexa account.",
"fields": {
"email": {
"name": "Email address",
"description": "List of Alexa accounts to update. If empty, will update all known accounts."
}
}
}
}
}
83 changes: 60 additions & 23 deletions custom_components/alexa_media/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
{
"config": {
"abort": {
"forgot_password": "The Forgot Password page was detected. This normally is the result of too may failed logins. Amazon may require action before a relogin can be attempted.",
"login_failed": "Alexa Media Player failed to login.",
"reauth_successful": "Alexa Media Player successfully reauthenticated. Please ignore the \"Aborted\" message from HA."
},
"error": {
"2fa_key_invalid": "Invalid Built-In 2FA key",
"connection_error": "Error connecting; check network and retry",
"identifier_exists": "Email for Alexa URL already registered",
"invalid_credentials": "Invalid credentials",
"invalid_url": "URL is invalid: {message}",
"unable_to_connect_hass_url": "Unable to connect to Home Assistant url. Please check the External Url under Configuration -> General",
"2fa_key_invalid": "Invalid Built-In 2FA key",
"unable_to_connect_hass_url": "Unable to connect to Home Assistant url. Please check the Internal Url under Configuration -> General",
"unknown_error": "Unknown error: {message}"
},
"step": {
"user": {
"data": {
"password": "Password",
"email": "Email Address",
"url": "Amazon region domain (e.g., amazon.co.uk)",
"hass_url": "Url to access Home Assistant",
"otp_secret": "Built-in 2FA App Key (automatically generate 2FA Codes). This is not six digits long.",
"include_devices": "Included device (comma separated)",
"exclude_devices": "Excluded device (comma separated)",
"debug": "Advanced debugging",
"scan_interval": "Seconds between scans",
"proxy": "Use Login Proxy method (2FA not required)",
"oauth_login": "Enable oauth-token app method"
},
"description": "Please confirm the information below. For legacy configuration, disable `Use Login Proxy method` option.",
"title": "Alexa Media Player - Configuration"
},
"proxy_warning": {
"data": {
"proxy_warning": "Ignore and Continue - I understand that no support for login issues are provided for bypassing this warning."
Expand All @@ -28,23 +40,12 @@
},
"description": "**{email} - alexa.{url}** \nHave you successfully confirmed an OTP from the Built-in 2FA App Key with Amazon? \n >OTP Code {message}",
"title": "Alexa Media Player - OTP Confirmation"
},
"user": {
"data": {
"debug": "Advanced debugging",
"email": "Email Address",
"exclude_devices": "Excluded device (comma separated)",
"hass_url": "Url to access Home Assistant",
"include_devices": "Included device (comma separated)",
"otp_secret": "Built-in 2FA App Key (automatically generate 2FA Codes). This is not six digits long.",
"password": "Password",
"scan_interval": "Seconds between scans",
"securitycode": "[%key_id:55616596%]",
"url": "Amazon region domain (e.g., amazon.co.uk)"
},
"description": "Please confirm the information below. For legacy configuration, disable `Use Login Proxy method` option.",
"title": "Alexa Media Player - Configuration"
}
},
"abort": {
"forgot_password": "The Forgot Password page was detected. This normally is the result of too may failed logins. Amazon may require action before a relogin can be attempted.",
"login_failed": "Alexa Media Player failed to login.",
"reauth_successful": "Alexa Media Player successfully reauthenticated. Please ignore the \"Aborted\" message from HA."
}
},
"options": {
Expand All @@ -57,5 +58,41 @@
}
}
}
},
"services": {
"clear_history": {
"name": "Clear Amazon Voice History",
"description": "Clear voice history. Note: This will reset last_called",
"fields": {
"email": {
"name": "Email address",
"description": "Accounts to clear. Empty will clear all."
},
"entries": {
"name": "Number of Entries",
"description": "Number of entries to clear from 1 to 50. If empty, clear 50."
}
}
},
"force_logout": {
"name": "Force Logout",
"description": "Force account to logout. Used mainly for debugging.",
"fields": {
"email": {
"name": "Email address",
"description": "Accounts to clear. Empty will clear all."
}
}
},
"update_last_called": {
"name": "Update Last Called Sensor",
"description": "Manually update the last called sensor status.",
"fields": {
"email": {
"name": "Email address",
"description": "List of Alexa accounts to update. If empty, will update all known accounts."
}
}
}
}
}
Loading

0 comments on commit a3dde7f

Please sign in to comment.