Nuki Card with Callback support (supports both Lock & Opener, it replaces the official integration)

Not right now, but I put in the to-do list a configurable set of actions (like you now select the language), so each user can decide which action to send to the lock.

image

1 Like

Sounds good,
It will be great to have a possibly to make different buttons for the two actions.
Do you think it will be possible?

It’s a lock template sensor, I can customize the actions, not the button itself. So you will always see lock/unlock, for obvious reasons. If a lock is already locked, why would you want to see the lock button? And viceversa… :slight_smile:

The lock/unlock now works perfect now, including the state indication.
What I meant was to have a different button just for the lock&go action.
But I figured it’s quite simple to make a custom button using rest command service to do that…

it’s simple, you can do it yourself on lovelace: Button Card - Home Assistant (home-assistant.io)

Something like this (haven’t tested it):

type: button
name: Lock 'n' Go
show_state: false
icon: mdi:lock
tap_action:
  action: call-service
  service: rest_command.nuki_lock_action
  service_data:
    action: 4

Nuki Card v9.0 released: eliminated localization support in code, leveraging HA device_class so translation of status strings is automatically managed by HA (please delete the json file). Introduced two new input_select to configure the lock and unlock actions: you can decide what actions are executed when you press the lock/unlock button. Sensor names have changed, please update the lovecard code.

Don’t forget to:

  • eliminate the .json file
  • update the lovelace code
1 Like

@spokin: Jeroen, I think I had a good idea for the serialization of the calls to the bridge, that is the main issue still unresolved: instead of configuring the REST sensors to poll automatically, we can use a global variable (input_text) to trigger when they should start, a sort of timer but driven by the automation, so it can leverage the queue mechanism. Even if two timers expire at the same moment they will be in the automation queue. It’s the only serialization mechanism we have in pure template/yaml code. I found no other “clean” way to do it.

Let me know your thoughts on this…:slight_smile:

First, really nice work you did.

I’m +1 on searching for an opener integration, especially i am in need for the ringactionTimestamp value as a sensor. With the List Command my Output is like this:

[{"deviceType": 0, "nukiId": 1234567, "name": "Zuhause", "firmwareVersion": "2.10.8", 
"lastKnownState": {"mode": 2, "state": 3, "stateName": "unlocked", "batteryCritical": false, "batteryCharging": false, "batteryChargeState": 82, "doorsensorState": 2, "doorsensorStateName":
 "door closed", "timestamp": "2021-08-01T14:41:27+00:00"}}, {"deviceType": 2, "nukiId": 1234567,
 "name": "Opener", "firmwareVersion": "1.6.4", "lastKnownState": {"mode": 2, "state": 1, "stateName":
 "online", "batteryCritical": false, "ringactionTimestamp": "2021-08-01T14:41:09+00:00",
 "ringactionState": false, "timestamp": "2021-08-01T14:50:00+00:00"}}]

The ringactiontimestamp shows the time when somebody pushed the doorbell. With a Sensor of the timestamp i could easy create an automation to open the door when the doorbell rings.
Is there a chance this could be integrated without much work for you?

Btw, if you need testers for an opener integration i would do the best i can :wink:

Thanks Mike

Mike, the opener is on the to-do list, but since I know nothing about it, I will surely need the help of someone like you. In order to automate these things, I need to fully understand how they work, etc.

Right now the integration is mature in terms of functionality, but it has one big issue, due to the bridge: it needs to serialize http/rest calls, unfortunately the bridge only supports 1 at a time.

Once I solve this issue, and I feel it’s solid, we can add more functionality. I hope you can wait…then we can start collaborating on the opener. :slight_smile:

Mike, please go in Dev Tools, and show me the state of your sensor.nuki_bridge_endpoint_list, like in this screenshot.

Thanks.

Good morning…:slight_smile:

I worked all night to serialize the calls to the bridge, and I found a simple and effective approach, it’s working good, and finally no more issues with the bridge.

Let me explain what I did: I had 3 REST sensors in the code, each with its polling time, plus, in certain part of the code, I was manually updating the sensors (refresh) because I modified the status of the bridge. So it could often happen that two calls could overlap and the bridge is poorly designed, so when it receives two calles at a time it doesn’t queue them but it behaves strangely, sometimes it rebooted.

So what I decided to do is disable the polling on two of the sensors, and leave only one as the main “clock” for the communication to the bridge. Unfortunately I found out you can’t explicitly disable the polling, I tried with scan_interval: 0, but had the opposite effect: it polled every microsecond. So I tried with scan_interval: -1 but it acted even more weirdly. In the end I simply used the opposite: a very high number: scan_interval: 31536000 (1 year polling time). :slight_smile:

Having solved the polling period problem, I coded a new trigger for the main clock rest sensor, so when its timer expires and it updates, I run the usual callback script, but on top of the script I refresh the two “manual” REST sensors with the polling timer effectively disabled. Since the automation trigger is configured in queue mode, and the script is a single sequence of commands, there’s no possibility for the REST calls to the bridge to overlap because I have a single point of control, in the sequence, with the appropriate delays between the first and second call (5 secs.). It works very well. I monitored the Bridge log, and I don’t see List/Info commands overlapping in the same second. No reboots. :slight_smile:

Now, the only problem that I couldn’t solve is that when you restart HA, all the sensors are refreshed, even those with the high polling time, so at boot-time, it can happen that two commands overlap and you see some errors in the log, but it causes no big issues, at the next cycle of the “clock” sensor (180 secs.) everything goes back in place and all info is refreshed. If someone has an idea on how to stop HA from refreshing two specific REST sensors, please let me know, I’d greatly appreciate it.

Before releasing v10.0, I wanted someone else to test it besides me, so I published the code in a separate gist: it would greatly help me if at least 3-4 people would test this version and report back.

Note: the callback updates when I open the door or lock/unlock the Nuki are EXTREMELY fast now, I tested 20-30 times, and the average time is 1-2 seconds for the door sensor, and 3-4 seconds for the lock. :slight_smile:

Thanks a lot for your help and support,

Alessandro

2 Likes

No Problem, Screenshots of info and list:

endpoint_list

In the info sensor i can already see the opener (device: 2). As far as i understand it it’s the same as a lock for home assistant. Unlocking it starts ring to open, unlatching starts the open process of the door of the house. Locking disables ring to open.

Greetz Mike

Hi Alessandro,

Good work, as always, thank you.
Everything works and I can confirm the times you experienced. So far I also don’t have entries in the log.
What else can I test / report?

1 Like

Fantastic Joerg. If you have no entries in the log and the response times of the callback are fast like mine, I’m super-happy. :slight_smile:

In reality, 50% of the times when you restart HA, the activation of the 2 sensors should create an error, you will probably see it in the future until I find a solution for that.

Thanks a lot for testing and reporting. I hope a couple of more friends can report so I can release it.

I think this is the best version 'til now. :slight_smile:

You’re welcome.

:+1:

1 Like

The way I prepared the list sensor excludes the second device of the list you have.

We’ll have to add proper support for the opener. A little bit of patience…probably last night I solved the serialization of the calls to the bridge, so next step could also be the opener. We’ll see. :slight_smile:

Take all the time you need, a day more or less doesn’t even matter. If i can do anything you’re welcome, else i am waiting patiently.

Many thanks in advance

Mike

1 Like

Alessandro, installed v10rc1, no error on startup following errors about 1 hour later:
2021-08-02 12:46:30 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.1.47:8080/callback/list?&token=ucqbkj failed with

2021-08-02 12:46:30 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data

2021-08-02 12:46:35 ERROR (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Choose at step 1: choice 3: Error executing script. Error for call_service at pos 1: Error rendering data template: JSONDecodeError: Expecting value: line 1 column 1 (char 0)

2021-08-02 12:46:35 ERROR (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Error executing script. Error for choose at pos 1: Error rendering data template: JSONDecodeError: Expecting value: line 1 column 1 (char 0)

2021-08-02 12:46:35 ERROR (MainThread) [homeassistant.components.automation.nuki_card_callback] Error while executing automation automation.nuki_card_callback: Error rendering data template: JSONDecodeError: Expecting value: line 1 column 1 (char 0)
corresponding Nuki log:
{“timestamp”: “2021-08-02T10:52:50+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:52:45+00:00”, “type”: “HTTP-List”},
{“timestamp”: “2021-08-02T10:49:49+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:49:44+00:00”, “type”: “HTTP-List”},
{“timestamp”: “2021-08-02T10:48:36+00:00”, “type”: “SSE-PushNukisResponse”},
{“timestamp”: “2021-08-02T10:48:36+00:00”, “type”: “SSE-PushNukisRequest”, “count”: 1},
{“timestamp”: “2021-08-02T10:47:07+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Disconnected”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:47:07+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Disconnect”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:47:07+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-ConnectionTimeout”},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-CommandComplete”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerResponse”, “pairIndex”: 0, “bytes”: 205},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerResponse”, “pairIndex”: 0, “bytes”: 273},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerResponse”, “pairIndex”: 0, “bytes”: 273},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-AlreadyConnected”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerRequest”, “pairIndex”: 0, “bytes”: 96},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-CommandComplete”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerResponse”, “pairIndex”: 0, “bytes”: 245},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-AlreadyConnected”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:02+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerRequest”, “pairIndex”: 0, “bytes”: 56},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-CommandComplete”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerResponse”, “pairIndex”: 0, “bytes”: 229},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-AlreadyConnected”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerRequest”, “pairIndex”: 0, “bytes”: 56},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-CommandComplete”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerResponse”, “pairIndex”: 0, “bytes”: 245},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-SendingSSE”, “pairIndex”: 0, “bytes”: 56},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “type”: “SSE-KeyturnerEventResp”},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-TurnOnNotific”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:01+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Connected”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:47:00+00:00”, “type”: “BLE-Connect”, “macAddr”: “54D2722ABBDD”},
{“timestamp”: “2021-08-02T10:47:00+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Connect”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:47:00+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerRequest”, “pairIndex”: 0, “bytes”: 56},
{“timestamp”: “2021-08-02T10:46:52+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Disconnected”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:46:52+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Disconnect”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:46:52+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-ConnectionTimeout”},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “type”: “HTTP-Post”, “nukiId”: “192ABBDD”},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerEventReq”},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-ReadStates”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-TurnOnNotific”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Connected”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “type”: “BLE-Connect”, “macAddr”: “54D2722ABBDD”},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Connect”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:47+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-StateChanged”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:34+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Disconnected”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:46:34+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Disconnect”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:46:34+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-ConnectionTimeout”},
{“timestamp”: “2021-08-02T10:46:29+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-CommandComplete”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:29+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerResponse”, “pairIndex”: 0, “bytes”: 229},
{“timestamp”: “2021-08-02T10:46:29+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-AlreadyConnected”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:29+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerRequest”, “pairIndex”: 0, “bytes”: 56},
{“timestamp”: “2021-08-02T10:46:28+00:00”, “type”: “SSE-KeyturnerEventResp”},
{“timestamp”: “2021-08-02T10:46:28+00:00”, “type”: “HTTP-Post”, “nukiId”: “192ABBDD”},
{“timestamp”: “2021-08-02T10:46:28+00:00”, “nukiId”: “192ABBDD”, “type”: “SSE-KeyturnerEventReq”},
{“timestamp”: “2021-08-02T10:46:28+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-ReadStates”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:27+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-TurnOnNotific”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:27+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Connected”, “pairIndex”: 0, “bleHandle”: “0001”},
{“timestamp”: “2021-08-02T10:46:27+00:00”, “type”: “BLE-Connect”, “macAddr”: “54D2722ABBDD”},
{“timestamp”: “2021-08-02T10:46:27+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-Connect”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:46:27+00:00”, “nukiId”: “192ABBDD”, “type”: “BLE-StateChanged”, “pairIndex”: 0},
{“timestamp”: “2021-08-02T10:43:47+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:43:42+00:00”, “type”: “HTTP-List”},
{“timestamp”: “2021-08-02T10:40:46+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:40:40+00:00”, “type”: “HTTP-List”},

My canary in the coalmine always brings me backto the raw and naked reality. :slight_smile:

As far as I can see from the logs, I don’t see double commands in the same second, the sequence looks correct…info command is 5 secons from the list, then the sequence repeats every 3 minutes (but it could also be 10mins, that’s not important).

{“timestamp”: “2021-08-02T10:52:50+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:52:45+00:00”, “type”: “HTTP-List”},
{“timestamp”: “2021-08-02T10:49:49+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:49:44+00:00”, “type”: “HTTP-List”},
{“timestamp”: “2021-08-02T10:43:47+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:43:42+00:00”, “type”: “HTTP-List”},
{“timestamp”: “2021-08-02T10:40:46+00:00”, “type”: “HTTP-Info”},
{“timestamp”: “2021-08-02T10:40:40+00:00”, “type”: “HTTP-List”},

The problem is that the callback/list command is not logged in the bridge, so I don’t know when it happened. But from HA logs you reported, that is the command that was rejected.

Were you doing tests for the callback? Deleting/adding one?
DId you notice problems on the card or was it still working ok?

This evening I will check the callback/list command, and see if there’s some point in which it’s not serialized.

Thanks for the help.

Here I see something happening on the bridge: a BLE disconnect. Did something happen in the period 12.46.29 - 12.46.47? That’s probably why the command failed, the bridge was busy doing something for the BT/BLE connection with the lock…