-
Notifications
You must be signed in to change notification settings - Fork 58
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
Port infos on Control+ hub not always available #63
Comments
The reason for this is that you aren’t waiting to query for attached devices after connecting. Attached devices aren’t available immediately after connection - there is a handshake process, and then the hub discovers and advertises attached devices. You can wait for the “attach”/“detach” events to be emitted from the hub for the ports you want. At that point you’ll know it’s available and ready. You can also use this to update your UI as you remove and plug in new devices. |
I added an event listener for the "attach" events like this:
But only events for certain ports are received:
sometimes...
Port A again is never "attached". Any ideas? |
I have the same problem with the port A of my boost move hub, which was not detected most of the time. I did not find the circonstances that make it be found or not. I thought it was low battery, it happens less since I changed them but still. I note we both use the Web Bluetooth version of this lib. It may be a thing to look at, I wonder if it drops some messages. |
Interesting. Are you both using the Web Bluetooth version, or Node.js? If you are able, can you enable |
I also use web bluetooth, yes.
I also was wondering if the browser version has some different behaviour, but then I realized that the setup also was wrong. I now changed the way how I set up the event listeners and handle the connected hubs. I realized that the event listeners need to be registered before calling poweredUP.on("discover", async (hub: Hub) => { // Wait to discover hubs
// Puts this hub into the list of "known hubs" with the connected flag set to false
dispatch({type: ActionType.DISCOVER, payload: {hub}});
// Add event listeneres....
hub.on("attach", (port, device) => {
dispatch({type: ActionType.ATTACH_PORT, payload: {hub, port}});
});
await hub.connect();
// Sets the connected state of this hub to true
dispatch({type: ActionType.CONNECT, payload: {hub}});
}); This seems to improve the situation so that
I can provide you some debug output later on, yes. It also should easy to enable debug output by adding the "debug" key to the localStorage for https://brick-remote.ractive.ch 😉 |
I made some tests on chrome 78.0.3904.108 on windows 10 and could not reproduce on my own project, the web bluethooth example and https://brick-remote.ractive.ch/ (which is very nice). I tried without any device on C and D ports at startup, with boost devices, with other devices... nothing wrong. Only once on the web bluetooth example, I got the port A about 2s late. It could also be a firmware problem, I don't remember if I had an update since or not. |
Interesting: I tested it yesterday on three computers and the results were completely different (all tests using the latest Chrome 78):
And all seems fine on your system as well. So the question is - why do different systems behave differently... 🤔 I'll collect some logs of the different system so that we can compare them... |
I saved some logs. I have a control+ hub with two x-large motors connected to the ports A and B and a large motor connected to D. This log here from the MacBook air is the happy case, where all ports on the control+ hub get "attached" (and are properly shown): On the Surface pro, no port is attached at all: On the lenovo x1 extreme, only ports B and D are attached: @nathankellenicki: Do you see anything suspicious? |
I think I do actually! I notice that a) Messages seem to be correct, and b) You do get port advertisement messages. I also notice that they tend to appear in order - starting at 0 and ending . at 99/100. In the last two examples I see that it's always the first couple that are missed. There is a weird hacky flow in this library to figure out the hub type before connecting by actually connecting but caching received messages that don't apply to the discovery in a mailbox, to be redelivered after actually connecting. I wonder if a those two port messages come through before the connect but are for some reason not redelivered. I'll keep digging! |
Why not get the hub type from the advertising data before connecting? |
@dlech Advertising and Manufacturer Data is not currently implemented in Web Bluetooth on Chrome (or any browser for that matter). The only way to do it currently is to connect to the hub and ask it. https://developer.mozilla.org/en-US/docs/Web/API/BluetoothAdvertisingData |
@ractive I've published a new version ( You'll need to expand the debug namespaces a bit: Thanks! |
Here we go: Happy case on MacBook Air with all ports detected: Ports B and D detected on the lenovo: Worst case scenario on the surface pro with no ports detected at all: I hope this gives you some more insights @nathankellenicki. To produce logfiles yourself , you can open https://brick-remote.ractive.ch/?debug=* and reload the page again (repace * with |
I want to play the log game too, so I grabbed my lenovo X380 and my control+ with two basic motors on A & B and two XL motors on C & D.
Then I unplug the A port.
And I replug it, then the magic happens
From my understanding, I miss the port A attachement message at first but I get one if I unplug/replug the device. This tends to confirm @nathankellenicki theory. |
That's a good finding. The brick-remote app now handles both So if you now unplug a motor that was shown as "not attached" and then plug it in again, it will be correctly recognized. So really just the initial |
@ractive It does. So I see from the logs for your Lenovo that the first message that gets stashed is for port 1, and on your Surface the first one is port 50. So you're potentially missing a whole bunch of messages. I'm not sure yet, but it could be a couple of things. The first, that my stashing code is wrong and is missing a whole bunch of messages. I'll put some more debug code in and ask you to help me again. The second, that the Web Bluetooth stack is a half-baked implementation (which we know to be true!) that seems to get notified on characteristics before the client has subscribed to notifications, which would be a bigger problem. More than likely the first. :)
I checked out the project and would love to debug myself, but unfortunately a) On my MacBook Pro I can't reproduce, and b) I'm still on a work trip and only have a Powered UP hub with me, and there seems to be a bug causing React to fail to render when it tries to see what devices are on C and D (PUP hub only has A and B). I plan to raise an issue against your repo with some more info if that's ok. :) |
Yes of course. It's easy to generate these logs.
I was looking for a way to determine what ports a hub actually has, but there's no way to do that at the moment, so I just blindly try A-D. So it could well be that it blows up when it tries to get infos about non existing ports. 🙈
Of course! :-) |
I tried to understand the mailbox: The device mailbox is emptied in
I am not sure how it works:
I am lost at the
If there can be more than one message in |
I also noticed |
@ractive I've just published a new version ( @aileo That's a good catch within If this is indeed the case, the debug I added in |
Also a good catch. I suspect as the add/remove happen in the same thread tick, you're right, no messages would be lost. But I could solve this by keeping a reference and removing after the new one is added. |
Here some logs with version 5.0.3: |
So it seems in the case of the Surface, it was successful? I see it discovering all attached devices. Do you have a log from an unsuccessful case? Lenovo I can see the issue clearly. :) |
Oh. I didn't even check what devices have been attached on the surface. Here's another log, where only port D is attached, but port A & B are still missing. But yeah, there's some improvement here because for the first time at least one port has been attached on the surface. I tried several times and always just port D was attached... Another thing that I noticed on the surface was that now sometimes the hub is not discovered properly anymore. A log of such an attempt is here: |
Well, I haven't actually changed any code, just added logging. :) So if there's an improvement, it has to be a coincidence! Thanks for that. I think the problem is deeper than I thought - even when logging all data, the first message that comes in is for portId Perhaps there's some difference between Bluetooth stacks on Windows vs macOS/Linux whereby it doesn't wait for I'll need to try getting my hands on a Windows machine to debug this any further myself I think. |
Closing as no further activity, and I'm unable to repro this. If this is still an issue, feel free to reopen. :) |
I'm implementing a react based remote control app using node-poweredup:
https://brick-remote.ractive.ch
I'm testing and developing this with the Control+ hubs.
The issue is that when a hub is connected, its port infos are not always available.
In this example ports A, B and D are connected, but port A never shows any info, port B most of the time and port D almost always:
I'm getting the port info with
hub.getPortDeviceType(port)
(see here) after a call toawait hub.connect()
(see here).The ports that are identified as "unkown" also don't get sensor messages. While e..g port B gets "rotate" events, port A does not.
Steering the motors on those ports although works and e.g. a motor on port A that is recognized as "unknown" can be successfully controlled by calling
hub.setMotorSpeed("A", 50)
(see here).Any ideas what is wrong here so that the port infos are not correctly set after the hub is connected?
The source code of the app can be found here and started locally with
yarn start dev
. Debug logging is currently enabled (see here).The text was updated successfully, but these errors were encountered: