ESPHome Nuki Bridge

Hi,

Based on Nuki BLE API implementation for ESP32, I’ve built an ESPHome lock component for Nuki smart door lock.
The component acts as a bridge for the Nuki, and creates lock (and other) entities in HA. Notice that once paired to ESPHome, the existing Nuki bridge (if you have any) will be disconnected.

The configuration is quite simple:

esphome:

  libraries:
  - Preferences
  - https://github.com/nkolban/ESP32_BLE_Arduino/
  - https://github.com/I-Connect/NukiBleEsp32#v0.0.4

external_components:
  - source: github://uriyacovy/ESPHome_nuki_lock

lock:
  - platform: nuki_lock
    name: Nuki Lock
    is_paired: 
      name: "Nuki Paired"
    battery_critical:
      name: "Nuki Battery Critical"
    battery_level:
      name: "Nuki Battery Level"

Upon first run, the ESPHome will wait until it is paired to the Nuki. To pair, press the Nuki for about 5 seconds until the led turns constantly on.

See further details here: GitHub - uriyacovy/ESPHome_nuki_lock: ESPHome lock platform for Nuki Smartlock

Disclaimer: I’m not related to Nuki in anyway, and I created this as a quick learning project. I’ll be able to offer very little support, but PRs are always welcomed.

11 Likes

This is great! Thanks for your contribution :slight_smile: :hugs:

1 Like

Holy moly. That’s exactly what I needed. Thank you so much!

1 Like

Thanks so much for this component! It works very fast. However, it is a bit unstable for me for my 2 doors. Both esp32’s have excellent wifi but somehow, in HA it mentions it goes unavailable every x minutes. Someone recognize this? I will add a syslogger to it to be able to debug it a better.

Thanks giejay.
Please try the dev repository as explained here, and let me know if this works for you:

1 Like

Thanks! Tried it but I got a compile error:

Compiling .pioenvs/sheddoor/libc13/NukiBleEsp/NukiLock.cpp.o
In file included from .piolibdeps/sheddoor/NukiBleEsp/src/NukiBle.cpp:13:0:
.piolibdeps/sheddoor/NukiBleEsp/src/NukiBle.h: In constructor 'Nuki::NukiBle::NukiBle(const string&, uint32_t, NimBLEUUID, NimBLEUUID, NimBLEUUID, NimBLEUUID, std::__cxx11::string)':
.piolibdeps/sheddoor/NukiBleEsp/src/NukiBle.h:323:14: error: 'Nuki::NukiBle::deviceId' will be initialized after [-Werror=reorder]
     uint32_t deviceId;            //The ID of the Nuki App, Nuki Bridge or Nuki Fob to be authorized.
              ^
.piolibdeps/sheddoor/NukiBleEsp/src/NukiBle.h:281:22: error:   'const NimBLEUUID Nuki::NukiBle::pairingServiceUUID' [-Werror=reorder]
     const NimBLEUUID pairingServiceUUID;
                      ^
.piolibdeps/sheddoor/NukiBleEsp/src/NukiBle.cpp:30:1: error:   when initialized here [-Werror=reorder]
 NukiBle::NukiBle(const std::string& deviceName,
 ^
Archiving .pioenvs/sheddoor/libc9d/libBleScanner.a
Compiling .pioenvs/sheddoor/libc13/NukiBleEsp/NukiLockUtils.cpp.o
Indexing .pioenvs/sheddoor/libc9d/libBleScanner.a
.piolibdeps/sheddoor/NukiBleEsp/src/NukiBle.cpp: In member function 'Nuki::PairingState Nuki::NukiBle::pairStateMachine(Nuki::PairingState)':
.piolibdeps/sheddoor/NukiBleEsp/src/NukiBle.cpp:677:78: warning: ignoring return value of 'int crypto_scalarmult_curve25519(unsigned char*, const unsigned char*, const unsigned char*)', declared with attribute warn_unused_result [-Wunused-result]
       crypto_scalarmult_curve25519(sharedKeyS, myPrivateKey, remotePublicKey);
                                                                              ^
Compiling .pioenvs/sheddoor/libc13/NukiBleEsp/NukiOpener.cpp.o
cc1plus: some warnings being treated as errors
*** [.pioenvs/sheddoor/libc13/NukiBleEsp/NukiBle.cpp.o] Error 1
===================================================================== [FAILED] Took 170.79 seconds 

This is my yaml:

esphome:
  name: sheddoor
  libraries:
  - Preferences
  # - https://github.com/nkolban/ESP32_BLE_Arduino/
  - https://github.com/uriyacovy/NukiBleEsp32#dev

external_components:
  - source: github://uriyacovy/ESPHome_nuki_lock@dev

lock:
  # Required:
  - platform: nuki_lock
    name: Shed Door Lock
    is_connected: 
      name: "Shed Door Connected"
    is_paired: 
      name: "Shed Door Paired"
  # Optional:
    battery_critical:
      name: "Shed Door Battery Critical"
    battery_level:
      name: "Shed Door Battery Level"
    # door_sensor:
    #   name: "Shed Door Sensor"
    # door_sensor_state:
    #   name: "Shed Door Sensor State"

# esp32:
#   board: az-delivery-devkit-v4
#   framework:
#     type: arduino

esp32:
  board: az-delivery-devkit-v4
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: ""

ota:
  password: ""

I did a esphome clean command and removed the temp folders but still no luck. Any idea?

Edit: After also changing the esp32 block to the one you posted, it works. I thought that should just remain as is and point to my az-delivery-devkit-d4 but I guess I was wrong:)

esp32:
  board: esp32dev
  framework:
    type: arduino
    version: 2.0.3
    platform_version: 4.4.0

@uriyacovy

After running the dev branch for a day, this is the result:

I see a similar behavior in the logs:

Oct 19 14:12:08 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:12:08 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:20:00 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:20:00 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:20:07 sheddoor api.connection: [W][api.connection:078]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connection reset
Oct 19 14:24:30 sheddoor api.connection: [W][api.connection:080]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connection closed
Oct 19 14:24:31 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:24:31 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:33:30 sheddoor api.connection: [W][api.connection:078]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connection reset
Oct 19 14:33:30 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:33:30 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:35:45 sheddoor api.connection: [W][api.connection:080]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connection closed
Oct 19 14:35:45 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:35:45 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:41:23 sheddoor api.connection: [W][api.connection:080]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connection closed
Oct 19 14:41:24 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:41:25 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:45:53 sheddoor api.connection: [W][api.connection:080]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connection closed
Oct 19 14:45:54 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:45:54 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:57:10 sheddoor api: [D][api:102]: Accepted ::FFFF:192.168.2.15
Oct 19 14:57:10 sheddoor api.connection: [D][api.connection:861]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connected successfully
Oct 19 14:57:20 sheddoor api.connection: [W][api.connection:080]: Home Assistant 2022.8.6 (::FFFF:192.168.2.15): Connection closed

The wifi should be pretty stable and I’m also seeing the same behavior for my other lock which is just next to the router. Can’t seem to figure out why there might be a reset or disconnect happening every hour for x seconds.

Edit:
Tried to add the power_save_mode: none option after reading through some GitHub issues. Unfortunately that prevents the API port from being accessible, “not able to connect” messages. The device is pingable so wifi works fine.

Hello,
Thank you for the dev, I have a question is it possible to have the “open door” command, because the behavior I have is just to lock/unlock ?

thanks

Hi,
This is already implemented, see here: Option to unlatch the door · Issue #1 · uriyacovy/ESPHome_nuki_lock · GitHub

1 Like

Great, thank you.
I added an ‘Open’ button to the Yaml and did a reinstall.
it works very well :slight_smile:

button:
  - platform: template
    name: "Nuki Open"
    on_press:
      - lock.open: nuki

I have another question, is it normal that the “bridge” refuses to connect if the wifi is hidden?
thanks

I’m not sure it is related to the this bridge implementation, since it does not change the default wifi behavior. Does it work for you in general?

Thank you for your reply.
This is the only device that cannot connect to the hotspot when it is hidden. Prior to installing your firmware (with the base firmware installed via the web tool), it was able to connect to the same access point (hidden). I may be wrong, but I think it is related to a version of library that handles WiFi or something like that.

Edit:
Ok, I solved the problem by adding the variable hidden set to true, based on the documentation found at WiFi Component — ESPHome.

Here’s wifi part in my yaml:

wifi:
  networks:
  - ssid: !secret wifi_2g_ssid
    bssid: !secret wifi_2g_bssid
    password: !secret wifi_2g_password
    hidden: true
  - ssid: !secret wifi_5g_ssid
    bssid: !secret wifi_5g_bssid
    password: !secret wifi_5g_password
    hidden: true

does this support the jammed status for us European cousin who have lift to lock handles?

I use the following code but recieve an error message.

esphome:
  name: $device_name
  libraries:
  - Preferences
  - https://github.com/uriyacovy/NukiBleEsp32#dev
  comment: "ciPIR with NUKI"

external_components:
  - source: github://uriyacovy/ESPHome_nuki_lock@dev

esp32:
  board: esp32dev
  framework:
    type: arduino
    version: 2.0.3
    platform_version: 4.4.0

Where is the crc16.h file

Compiling .pioenvs/bwm-korridor-ug-eingang/lib0e3/NukiBleEsp/NukiLockUtils.cpp.o
.piolibdeps/bwm-korridor-ug-eingang/NukiBleEsp/src/NukiBle.cpp: In member function 'Nuki::PairingState Nuki::NukiBle::pairStateMachine(Nuki::PairingState)':
.piolibdeps/bwm-korridor-ug-eingang/NukiBleEsp/src/NukiBle.cpp:698:35: warning: ignoring return value of 'int crypto_scalarmult_curve25519(unsigned char*, const unsigned char*, const unsigned char*)', declared with attribute warn_unused_result [-Wunused-result]
       crypto_scalarmult_curve25519(sharedKeyS, myPrivateKey, remotePublicKey);
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compiling .pioenvs/bwm-korridor-ug-eingang/lib0e3/NukiBleEsp/NukiOpener.cpp.o
Compiling .pioenvs/bwm-korridor-ug-eingang/lib0e3/NukiBleEsp/NukiOpenerUtils.cpp.o
Compiling .pioenvs/bwm-korridor-ug-eingang/lib0e3/NukiBleEsp/NukiUtils.cpp.o
.piolibdeps/bwm-korridor-ug-eingang/NukiBleEsp/src/NukiUtils.cpp:4:10: fatal error: Crc16.h: No such file or directory

***************************************************************
* Looking for Crc16.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:Crc16.h"
* Web  > https://registry.platformio.org/search?q=header:Crc16.h
*
***************************************************************

 #include "Crc16.h"
          ^~~~~~~~~
compilation terminated.
*** [.pioenvs/bwm-korridor-ug-eingang/lib0e3/NukiBleEsp/NukiUtils.cpp.o] Error 1

Is it possible to use another door sensor status like aqara to update the nuki “door_sensor_state:” inside the card?

The Aqara FP2 sensor has an esp32 and espHome should by pssoible to flash.

I mean the aqara door sensors

hello,

just include Crc16 in the libs part:

libraries:

many thanks, this was the solution.