-
Notifications
You must be signed in to change notification settings - Fork 381
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
Attempting to fix 738 #886
Attempting to fix 738 #886
Conversation
I would appreciate some feedback on this. Is there a better approach I could try? Any tips would be appreciated, I'll give it a serious try. |
pychromecast/socket_client.py
Outdated
# When a new cast status is received, give Audible time to load | ||
if status.app_id == "25456794": | ||
self.logger.debug("Detected Audible connection. Sleeping for 1s") | ||
time.sleep(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not really OK way to fix a race. Is there another message we can wait for instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not sure. any ideas you have, or example code you can point me to? i'll try whatever i can.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue #738 talks about the Sirius XM app misbehaving, but your comment in the PR talks about Audible. Could you clarify the relationship between the two apps? Or are they the same?
Also, after going through the comments in #738, it's not fully clear to me what pychromecast does which offends the app so much that it terminates, only that adding a delay fixes the problem.
Have you been able to determine how the delay fixes it?
If you run pychromecast with debug enabled, it will dump out all messages sent to and received from the pychromecast, have you done that?
Also, I'm not sure how you've been debugging. But if you want a simple isolated test case, maybe this example script is enough to trigger (and debug) the problem:
python3 -m examples.simple_listener_example --cast 'Living room' --show-debug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, there's already a comment in #738 about using the simple listener example to trigger the problem: #738 (comment)
If you could do that, but with the updated syntax as in my previous comment, both with and without your workaround, that would be really useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
git switch master
python3 -m examples.simple_listener_example --cast 'Garage speakers' --show-debug > workspace/master.std.txt 2> workspace/master.err.txt
git switch geoffoxholm:users/geoff/audible_debug
python3 -m examples.simple_listener_example --cast 'Garage speakers' --show-debug > workspace/patch.std.txt 2> workspace/patch.err.txt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a jump in requestId
in messages sent by pychromecast to the device which I can't explain. We only increment the requestId
when calculating it here:
pychromecast/pychromecast/socket_client.py
Lines 855 to 856 in 449c0b5
request_id = self._gen_request_id() | |
data[REQUEST_ID] = request_id |
Have you removed any lines from the logs?
Edit: Maybe it's ping messages being omitted from the log
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be sure, could you change here to log also the pings, both on master and your patch branch, and collect new logs:
pychromecast/pychromecast/socket_client.py
Lines 873 to 882 in 449c0b5
# Log all messages except heartbeat | |
if msg.namespace != NS_HEARTBEAT: | |
self.logger.debug( | |
"[%s(%s):%s] Sending: %s", | |
self.fn or "", | |
self.host, | |
self.port, | |
_message_to_string(msg, data), | |
) | |
pychromecast/pychromecast/socket_client.py
Lines 689 to 697 in 449c0b5
# debug messages | |
if message.namespace != NS_HEARTBEAT: | |
self.logger.debug( | |
"[%s(%s):%s] Received: %s", | |
self.fn or "", | |
self.host, | |
self.port, | |
_message_to_string(message, data), | |
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
git switch master
git pull
# make edits
git diff > workspace/master.diff.txt
python3 -m examples.simple_listener_example --cast 'Garage speakers' --show-debug > workspace/master.std.txt 2> workspace/master.err.txt
master.diff.txt
master.err.txt
master.std.txt
git stash # stash edits
git switch users/geoff/audible_debug
git stash pop # pop edits
git diff master > workspace/branch.diff.txt
python3 -m examples.simple_listener_example --cast 'Garage speakers' --show-debug > workspace/branch.std.txt 2> workspace/branch.err.txt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue #738 talks about the Sirius XM app misbehaving, but your comment in the PR talks about Audible. Could you clarify the relationship between the two apps? Or are they the same?
They are different apps. In the end the issue with Sirius XM was "fixed" (avoided) when the app was redesigned. It seems the Audible app has a similar pathology to the one that was present in the Sirius XM app, but no longer is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @emontnemery,
Any insight from the last logs you requested from @geoffoxholm?
I also have similar problem and setup and would like to contribute so that Audible works when pychromecast is active on the same network.
I can test the changes and try to fix some logic.
As of now the sleep tricks works, but I understand in your judgement it wont ever be merged since it's an ugly trick to fix race condition.
What is the better way to handle this? To me this behaves like an app quirk,and should be handled as so.
What Chat GPT is suggesting is what I had in mind too; the delay prevents some kind of overlap between outstanding requests. |
Since the logs don't point to the delay preventing an overlap in requests or any other out-of-order issue, I think a delay is the best we can do in pychromecast. Could you try this change instead of what's in the PR: diff --git a/pychromecast/socket_client.py b/pychromecast/socket_client.py
index 1d8eac1..c3d911e 100644
--- a/pychromecast/socket_client.py
+++ b/pychromecast/socket_client.py
@@ -490,6 +490,14 @@ class SocketClient(threading.Thread, CastStatusListener):
self.session_id = status.session_id
if new_channel and self.destination_id is not None:
+ if (
+ any(namespace in self._handlers for namespace in self.app_namespaces)
+ and self.destination_id not in self._open_channels
+ and status.app_id == "25456794"
+ ):
+ self.logger.debug("Detected Audible app. Sleeping for 1s")
+ time.sleep(1)
+
# If any of the namespaces of the new app are supported
# we will automatically connect to it to receive updates
for namespace in self.app_namespaces: |
@aryasenna @geoffoxholm could you try the version I suggest in #886 (comment) ? |
@emontnemery - yes, sorry, i will try it as soon as i can. thank you for the suggestion. |
Thanks a lot for the response. I've tested your proposed code on my HA install.
Audible plays fine on the target cast device (tested with Nest Hub and Chromecast Audio) After checking the patch, I get your hesitancy, it's quite "ugly" to make sleep based on an app ID like this, but it works, and Audible is not so obscure if you see home-assistant/core#87387 (comment) 🤷🏾♂️ |
@aryasenna - thank you for checking. i have added you to my fork, so if you wish to push to the PR branch, please go ahead. |
@emontnemery I integrated your code to the PR d418837 |
@aryasenna You didn't try my exact suggestion, I meant for the delay to be moved inside the check for new channel. def new_cast_status(self, status: CastStatus) -> None:
"""Called when a new cast status has been received."""
new_channel = self.destination_id != status.transport_id
if new_channel and self.destination_id is not None:
self.disconnect_channel(self.destination_id)
self.app_namespaces = status.namespaces
self.destination_id = status.transport_id
self.session_id = status.session_id
if new_channel and self.destination_id is not None:
# App quirk: If the Audible app is running, wait 1s after receiving cast status
# before connecting to the media player channel. This is a workaround for
# https://github.com/home-assistant-libs/pychromecast/issues/738
if (
any(namespace in self._handlers for namespace in self.app_namespaces)
and self.destination_id not in self._open_channels
and status.app_id == "25456794"
):
self.logger.debug("Detected Audible connection. Sleeping for 1s")
time.sleep(1)
# If any of the namespaces of the new app are supported
# we will automatically connect to it to receive updates
for namespace in self.app_namespaces:
if namespace in self._handlers:
self._ensure_channel_connected(self.destination_id)
for handler in set(self._handlers[namespace]):
handler.channel_connected() |
Also, instead of the magic number, please add the app constant: diff --git a/pychromecast/config.py b/pychromecast/config.py
index 9c9864e..ac5a6ac 100644
--- a/pychromecast/config.py
+++ b/pychromecast/config.py
@@ -22,6 +22,7 @@ APP_BBCIPLAYER = "5E81F6DB"
APP_SHAKA = "07AEE832"
APP_NRKTV = "3AEDF8D1"
APP_NRKRADIO = "A49874B1"
+APP_AUDIBLE = "25456794" |
@emontnemery Sorry for the confusion. I basically updated the PR branch with the wrong code in d418837, but when I did the test, the sleep() was definitely under Just double-checked the current code running on my VM: I can confirm with the current code Audible is working fine. I fixed it on e05baea, and it includes the use of app constant, as you requested. |
Thanks @aryasenna for following through on this. I have reviewed your changes locally, and have tested in my own environment and everything looks good to me. as an extremely minor nit, the blank line after the conditional is unusual for this codebase. |
OK @geoffoxholm, I've also removed the extra line break. I hope @emontnemery finds this PR acceptable now, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @geoffoxholm and @aryasenna 👍
Home assistant core PR: home-assistant/core#129251 |
I'm trying to fix #738.
It looks like some apps (maybe just "Audible" at the moment) have a very rigid interpretation of the connection handshake, and abandon it if messages come out-of-order.
I'd love any feedback to help move this forward. I can step into the debugger, do whatever is needed to figure out how to fix the issue, though I'm new to the
pychromecast
repo.