urish/muse-js

Handle bootloader connection issue

jdpigeon opened this issue · 5 comments

Just noticed that muse-js is running into a similar issue that Muse LSL did before this PR: alexandrebarachant/muse-lsl#37

When a headband is charged from empty all the way to full, it will often go into a different preset mode ('bootloader') and require a 'reset to headset mode' command (0x03 2a 31 0a) before it's BLE characteristics are made available for connection.

Attempting to connect to the headset in this mode leads to the following error:
No Characteristics matching UUID 273e000b-4c4d-454d-96be-f03bac821358 found in Service with UUID 0000fe8d-0000-1000-8000-00805f9b34fb.

I suggest that we add a getDeviceInfo check to the connect function and handle a 'bootloader' device state by sending a reset command with the sendCommand function

urish commented

Thanks! PR?

Can confirm that client.sendCommand("*1") kicks the headband out of bootloader and into headset mode.

Will make a PR sometime this week. Do you agree with the addition of a deviceInfo check to the connect function?

urish commented

Awesome. Yes, sound good - this should be transparent for the user.

deviceInfo is using async/await, which is a new feature in JavaScript which add syntactic sugar on top of promises:

    async deviceInfo() {
        const resultListener = this.controlResponses.pipe(filter((r) => !!r.fw), take(1)).toPromise();
        await this.sendCommand('v1');
        return resultListener as Promise<MuseDeviceInfo>;
    }

This is equivalent to writing:

    deviceInfo() {
        const resultListener = this.controlResponses.pipe(filter((r) => !!r.fw), take(1)).toPromise();
        return this.sendCommand('v1').then(() => {
            return resultListener as Promise<MuseDeviceInfo>;
        });
    }

Ah thanks man, I'll get on it.

Turned out I just forgot to execute it. deviceInfo sounds like a property to me, not a function. Maybe I should rename it to getDeviceInfo?

urish commented

Perhaps it'd make more sense, but that would also break the API. I'd rather keep it this way...