giejay / nukiPyBridge

30 stars 9 forks source link

Support for Nuki Opener #3

Closed Unkn0wn-MDCLXIV closed 4 years ago

Unkn0wn-MDCLXIV commented 4 years ago

@PingBo 's repo seems to be maintained as well.

Pingbo commented 4 years ago

Partially... I only added/adjusted the Script to my needs. So i won't maintain the code actively. But i already submitted a pull request with my changes, that @giejay can add it to his code.

I don't have an opener, so i can't look into it :( But i can imagine that it will be a little bit harder to add it here. As the opener usually connects to the bridge and the bridge will than send the open command to the smartlock. I think the bluetooth traffic there is also encrypted like the communictation between smartlock and bridge. So i don't know if you can use the code here to decrypt the messages from the opener or if you have to develop a whole new script for it...

giejay commented 4 years ago

I don't have a door opener myself but what would be the use case?

oxc commented 4 years ago

The use cases would be opening the (front) door, and getting door bell notifications.

giejay commented 4 years ago

So next to unlocking the door, also opening it? And what do you mean with doorbell notifications? Which doorbell?

oxc commented 4 years ago

The opener is connected to the in-house bus of the house door bell system. It can "press" the front door buzzer, and it sends events when the front door bell to my apartment is rang. It's not in any way connected to the nuki lock, I don't even have one (yet).

giejay commented 4 years ago

Ok, clear, I dont have an opener so Im not able to add support for it, sorry.

oxc commented 4 years ago

I'm installing mine right now. I'll see what I can do...

baquilla commented 4 years ago

Ok, clear, I dont have an opener so Im not able to add support for it, sorry.

I've been using pyBridge and it works like a charm. You have done a great job. Eventhough I don't use Nuki Opener, I know that the Android App Nuki Bridge does not and will not support Nuki Opener (see support team comments on Nuki's forum), users are annoyed as the Nuki web site does not show clear info about this lack and they discover it after purchase. In the end, including this feature in your project will be useful for a lot of people and they will be really grateful.

I can support it in a few ways if you'd like to continue the development, like finding a Nuki Opener for you, sharing tips about using the Opener to simulate door bell so you don't need to make a real installation, and so on. I don't have too much time to spend coding and reverse engineering on it but I can also help testing.

Ping me if you like.

oxc commented 4 years ago

I don't think reverse engineering will be needed, the documentation of the Bluetooth protocol is publicly available: https://developer.nuki.io/page/nuki-opener-api-110/7

baquilla commented 4 years ago

I don't think reverse engineering will be needed, the documentation of the Bluetooth protocol is publicly available: https://developer.nuki.io/page/nuki-opener-api-110/7

My fault. I didn't find find it a few years ago when I installed my first Nuki. Therefore, easier to integrate the Opener into pyBridge. Thanks for pointing that @oxc

giejay commented 4 years ago

I'm having some spare time on my hands so I updated the repo with better retry logic to improve stability, and now I'm looking into this issue.

I checked the API documentation and the authentication part seems to be exactly the same as the SmartLock. Someone with an Opener can already try to pair it with this nukiPyBridge, it should just work! Hold the opener for 5 seconds and use the connect endpoint as described in the README.

Next to that, activating the Ring to Open function seems to work exactly like the unlock command. The only small difference is the response:

OP sends Opener States command with status RTO active on USDIO
CL receives decrypted: 020300E007030708182C3C00000007

vs

SL sends Keyturner States command with status unlocking on USDIO
CL receives decrypted: 020200E00703070818203C00000007
SL sends Keyturner States command with status unlocked on USDIO
CL receives decrypted: 020300E007030708182C3C00000007

But that should be an easy fix.

The only thing which is not that straight forward, is getting doorbell notifications. I guess that will have to use a polling mechanism to check for the latest state: https://developer.nuki.io/page/nuki-opener-api-110/7/#heading--opener-states. I want to have the same mechanism for the SmartLock, polling the Log Entries, but Im afraid it will drain the battery quickly....

oxc commented 4 years ago

You'll have to use the passive scanning for the beacon and watch for the 59 rssi. IIRC the library does that already?

oxc commented 4 years ago

Please note that the documentation is mentioning the wrong service Uuids, see https://developer.nuki.io/t/wrong-bluetooth-service-uuids-in-opener-api-documentation/7436

giejay commented 4 years ago

Im not that familiar with the Bluetooth protocol, is there some documentation available regarding passive scanning using gatttool?

oxc commented 4 years ago

Ah, I'm sorry, I mixed that up with nubli, which uses passive scan, but uses HCI directly, not the dbus protocol. For usage with dbus, you will have to use the mgmt-api "AddDevice" command to add the device to the kernel's/driver's whitelist, then the kernel will automatically do background scans for this device. This way, you can get the Nuki's beacon information without drawing any additional power by requesting scan replies (aka. active scan).

AFAICT from a quick glance, the GATTToolBackend does not support passive scans (it would have to pass the --passive flag to the hcitool command)

giejay commented 4 years ago

Thanks for the explanation, that project looks quite promising, I will try to get that one working for one of my nukis, especially the part around status updates.

Are you also using nubli?

oxc commented 4 years ago

Actually, I've started writing my own library in Rust, as a pet project to try the language. A number of Bluetooth and Nuki projects have been a great help though.

With the white edition coming out, I'll probably buy a bridge, so I'm not sure I'll stick with a custom solution in the long run.

giejay commented 4 years ago

Ah ok. My language of choice is Scala and I'm also developing in Typescript so nubli might be easier to extend for me. Python is still a bit rusty;)

I'm especially interested in speeding up the unlocking process, after my lastest commits, it went down from 20 seconds to 12, so already a lot better. Don't think nubli will have better speeds perse but Im gonna check that out in the coming days.

giejay commented 4 years ago

@oxc I have checked out nubli, made a fork, used the forked nuble repo from abandonware and added an express webserver: https://github.com/giejay/nubli.

It now works exactly the same as this nukiPyBridge, only a lot (!) faster, like 2 seconds instead of 10-20. So, I'm probably gonna move to Nubli, the only thing I still need to implement is listening to changes so I don't need to poll it everytime.

That should be as straight forward as the example right?

nubli.onReadyToScan()
    .then(() => {
        console.log("Ready to scan :)");
        nubli.startScanning();
    })
    .catch((err) => {
        console.log(err);
    });

nubli.on("smartLockDiscovered", async (smartlock) => {
    if (smartlock.configExists()) {
        await smartlock.readConfig();
    }

    console.log("Listening for activity log changes");

    smartlock.on("activityLogChanged", () => {
        console.log("changed - retrieving state now");
        smartlock.connect()
        .then(async () => {
            let lockState = await smartlock.readLockState();
            console.log(lockState);
            await smartlock.disconnect();
        }).catch((err) => {
            console.log("connection failed:", err);
        });
    });
});

This will not drain the battery as I understand?

oxc commented 4 years ago

Looks good to me, but I have never used nubli before. You should probably check out the author's homebridge-nubli project, I think it's safe to assume it uses the library correctly :)

giejay commented 4 years ago

I will close this one since the opener should be supported already.

State changes won't be supported for now.

oxc commented 4 years ago

As I said, I don't think it's supported, because it uses different UUIDs.

Please note that the documentation is mentioning the wrong service Uuids, see https://developer.nuki.io/t/wrong-bluetooth-service-uuids-in-opener-api-documentation/7436