MQTT API & Homebridge / HomeKit

In case anyone wants to add a SL3P to Homebridge and thus HomeKit via IP (MQTT) instead of BLE, here is a ready made config that works for me:

  1. Connect the Smart Lock to your MQTT Server (seep API instructions)
  2. Go to Homebridge Admin > Plugins, search for and install the Homebridge Mqttthing plugin
  3. Go to Homebridge Admin > Configuration and add the Smart Lock as new accessory:

This configuration is for a Smart Lock with handle on the outside and a door sensor:

  "accessories": [
        {
            "accessory": "mqttthing",
            "type": "custom",
            "name": "Eingang",
            "url": "mqtt://YOUR_MQTT_SERVER",
            "username": "nuki",
            "password": "YOUR_MQTT_PASSWORD",
            "mqttOptions": {
                "keepalive": 60
            },
            "mqttPubOptions": {
                "qos": 2
            },
            "services": [
                {
                    "type": "lockMechanism",
                    "name": "Nuki Smart Lock",
                    "topics": {
                        "getOnline": "nuki/YOUR_NUKI_ID/connected",
                        "setLockTargetState": {
                            "topic": "nuki/YOUR_NUKI_ID/lockAction",
                            "apply": "if (message == 'S') { return 2 } else { return 1 }"
                        },
                        "getLockTargetState": {
                            "topic": "nuki/YOUR_NUKI_ID/state",
                            "apply": "if (message == 1 || message == 4) { return 'S'} else if (message == 0 || message == 255) { return '?'} else if (message == 254) { return 'J' } else { return 'U' }"
                        },
                        "getLockCurrentState": {
                            "topic": "nuki/YOUR_NUKI_ID/state",
                            "apply": "if (message == 1 || message == 2) { return 'S'} else if (message == 0 || message == 255) { return '?'} else if (message == 254) { return 'J' } else { return 'U' }"
                        },
                        "getBatteryLevel": "nuki/NUKI_ID/batteryChargeState",
                        "getChargingState": {
                            "topic": "nuki/YOUR_NUKI_ID/batteryCharging",
                            "apply": "if (message == 'true') { return 'CHARGING' } else { return 'NOT_CHARGING' }"
                        },
                        "getStatusLowBattery": "nuki/YOUR_NUKI_ID/batteryCritical"
                    }
                },
                {
                    "type": "contactSensor",
                    "name": "Nuki Doorsensor",
                    "topics": {
                        "getContactSensorState": {
                            "topic": "nuki/YOUR_NUKI_ID/doorsensorState",
                            "apply": "if (message == 3) { return true } else { return false }"
                        },
                        "getStatusActive": {
                            "topic": "nuki/YOUR_NUKI_ID/doorsensorState",
                            "apply": "if (message < 16) { return true } else { return false }"
                        },
                        "getStatusTampered": {
                            "topic": "nuki/YOUR_NUKI_ID/doorsensorState",
                            "apply": "if (message == 240) { return true } else { return false }"
                        },
                        "getStatusLowBattery": "nuki/YOUR_NUKI_ID/doorsensorBatteryCritical"
                    }
                }
            ]
        }
    ],

If you have a knob at the outside it should be sufficient to change this:

                       "setLockTargetState": {
                            "topic": "nuki/YOUR_NUKI_ID/lockAction",
                            "apply": "if (message == 'S') { return 2 } else { return 1 }"
                        },

to this:

                       "setLockTargetState": {
                            "topic": "nuki/YOUR_NUKI_ID/lockAction",
                            "apply": "if (message == 'S') { return 2 } else { return 3 }"
                        },

The configs work, but are not fully tested.

Just to let you know that your example has the wrong value:

In the lower code blocks regarding door knobs (replace … by …) is “(message == ‘Secured’)”. It should be “(message == ‘S’)” instead

Skjall

1 Like

Thank you. Is fixed now.

1 Like

Thanks for posting the example, is my first time using MQTT, works fine for me in homebridge.
Having only one problem, that the config for the chargingState is creating warnings:

Warning: chargingState received [false] which is not in configured values {“NOT_CHARGING”:0,“CHARGING”:1,“NOT_CHARGEABLE”:2}

Have changed the config to match the warning, wondering as the state is a binary tag, how this should work?

Thanks dueso

Charging state was previously untested. I tested it now and fixed the config in the original posting.

The Smart Lock supports only the two states “charging” and “not charging”. “Not chargeable” is not supported.

1 Like

Hey Jürgen,

love your example. Helped me a lot using MQTT for the first time.

I try to find a way to identify user / fingerprint to use it as a trigger to open our garage. E.g. Right finger opens door, left finger only our garage. Any ideas? Is there a way to use lockActionEvent?

Thanks a lot.
Ben

1 Like

That should work if you create a stateless programmable switch which is pressed whenever the /lockActionEvent with the right parameters is triggered (see Nuki MQTT documentation for the proper parameters). You will have to set up a different keypad codes and associate fingers to it in order to get different trigger values.

One important thing to note is that lockActionEvents are only triggered when the lockAction is also executed by the lock. i.e. you can only unlock your garage door together with the Smart Lock and not alone.

1 Like

Thanks a lot. I really appreciate it! You made me trying hard to find to get it done by myself. It’s really fun, I am a total beginner though.

I managed to find out the individual lockActionEvent parameters I need to trigger the stateless programmable switch (e.g. 3,0,1451693983,6,). I set up different keypad codes / fingers. I can also see the switch in homebridge. I unfortunately didn’t solve the challenge to find the right code. The error message I get in the log is:

[Smart lock] Warning: switch received 3,0,1451693983,6,2 which is not in configured values {"1": 0, "2":1, „L“:2}.

Here is one of my wrecked attempts:

{
    "accessory": "mqttthing",
    "type": "statelessProgrammableSwitch",
    "name": "Smart lock",
    "url": "mqtt://XXX.XXX.XXX.XX",
    "username": "XXXX",
    "password": "XXXXXXXX",
    "topics": {
        “getSwitch”: {
            “topic”: “nuki/NUKI_LOCK_ID/lockActionEvent”,
            “apply”: “if (message == ‘3,0,1451693983,6,2’) { return 1 }”
        }
    }
},

Could you please help me out?

Just had a quick look at it and it seems to be quite right.

2 things you could try:

  • Make sure to use the right quotation marks. Single quote should be this: ’
    “if (message == ‘3,0,1451693983,6,2’) { return 1 }”
  • You could try something very generic that always matches. e.g. “apply”: “return 1 ”. This should trigger a single press on every lockAction Event. If this works you at least know that everything so far is correct.
1 Like