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

It’s not important to discuss further, since only one user in this thread had this issue and asked for help, I think majority of HA users already faced the http/https issue and solved it, through NGINX, Nabu Casa, or other way, because it’s not related to one integration like Nuki Card, but all integrations. :slight_smile:

Good night.

No, this http/https issue is not related to all integrations, only to Nuki Card ! You can configure HA to allow only https user access - so without to have to solve any http/https issue before - whatever integrations you are using. You don’t even need to know NGINX exists. Except if you want to use Nuki Card.

This is the reason why to point out NGINX in this topic make sense for users using that configuration. It is not mandatory, of course (they can find the solution by themselves) but it make sense.

I saw you removed the mention to NGINX from the description (except if I missed it). But don’t worry, I wrote this post only to refute your (quoted) assertion, not to convince you to mention NGINX again, do as you like :sunglasses:

You really don’t understand the central point of all this, and let me explain why: any device integrated with HA that doesn’t support https needs to communicate with HA through HTTP only. I bet you know EVERY integration available for HA, judging from the tone of your post, right? It has nothing to do with the code or the integrations, but with the DEVICES. The Nuki Bridge sends the callback to HA without involvement of the Nuki Card, and unfortunately it can’t call an https:// URL. Nothing to do with Nuki Card. :slight_smile:

Go and check HACS repository, personally use integrations that need HTTP access way before I started to think about the Nuki Card. The code of Nuki Card doesn’t care about HTTP/HTTPS, it only needs URLs, it’s a limitation of the Nuki Bridge, not of the Nuki Card. Once the official Nuki integration will support callbacks, it will have the same requirement: HTTP only, you understand why it doesn’t depend on the code now? Hope you do, because it’s boring repeating same things over and over.

No, it doesn’t. If a device that you want to integrate only supports HTTP, you need to modify HA config accordingly, it has NOTHING to do with Nuki Card, but with a limitation of the device. Many IoT devices don’t support https, did you think about the reason they don’t? Because these devices have a small cpu/chipset, not powerful, so they don’t support cpu intensive protocols like https. It is very common for these devices to support http only.

The original post hit the 32000 max character, so when I released v7 I had to cut anything not mandatory, and guess what I thought was not important? :slight_smile:

Now I revised the post, reworded some paragraphs and reintroduced your beloved NGINX note. :slight_smile:

Hi @alexdelprete
Last night I noticed that the lock became unavailable and stayed that way all night.
I guess it’s related to my Nuki app setting to enter “Battery saving” mode 22:00-06:00
One of the saving method is probably to shut down the lock updates to the bridge…
As a result I get the lock and door sensor grayed out and become unavailable for the night.
Is there a way to have the Nuki Card to be updated with the saving time frame (even manually) so it won’t check or disregard “unavailability” of the lock and just keep the last update as the current state?

The two first chapters of your answer are fully irrelevant : I never said that is the fault of Nuki Card, I say it is a consequence of using Nuki Card when HA is configured with https. I know it is a limitation of Nuki bridge which doesn’t allow to request HA using https.

So my post becomes, I hope, less boring now and your answer comes down to:

If a device that you want to integrate only supports HTTP, you need to modify HA config accordingly.

No.

Before to have a Nuki lock, I was running HA configured with a ssl_certificate so only https connection was possible. This didn’t prevent HA to use any of my integrations/devices, without NGINX or Nabu Casa while I have many http-only devices, such as Shelly 1 devices for example. So, it worked but according to you it should not !

The explanaition is that an http/https connection is not symmetric. To have HA configured as an https server prevent HA to serve http requests but not prevent HA to send http request to http compliant devices. In the first case it acts as a server, in the second case it acts as the client of a device acting as a server. There is no need for an http device to be https compliant in a HA configuration with ssl_certificate as long as the device acts only as a server (which is true in many/most cases AFAIK).

When I bought a Nuki lock, I began using the official integration with no need to change my config (polling = requests from HA to Nuki bridge, so no problem) even with a ssl_certificate configuration). Later I installed Nuki Card to get a responsive solution (thank you again for the nice work). But it was not running because callbacks are http request from Nuki bridge to HA configured as an https server.

There is nothing we can do to solve that that so I made some some searches and finally I found the NGINX addon. My HA server continue to accept only https requests (I did not change its configuration) but thanks to NGINX, all local http requests to HA (in my case, only the callbacks from Nuki bridge) are converted by NGINX (acting in front of HA) into https requests to my HA server which is happy since it is https.

PS. I am not aware of any one but may be some types of device need to send http requests to HA (instead of only serving http requests from HA). In this case only, I agree that you need to have already solved the http/https issue before even to think about Nuki Card. Anyway, even if such devices exist, it is wrong/inexact to say:

it’s not related to one integration like Nuki Card, but all integrations

I hope we raise the point where each of us have the same understanding of this matter so the discussion could be closed serenely.

Thank you so much, you solved it. The indents are ok, just lost while copying to the reply, but I really overlocked the exclamation mark.

If a device needs to call HA via http and you secured it to https only, it won’t work. Do you understand that or you still deny it? Shellies (I have 30 of them) don’t rely on http to communicate with HA, probably you don’t know how the Shelly integration works (it uses CoIoT protocol), that’s why you choose such a bad example.

A device that webhooks with HA uses http or https, many devices only use http, my solar inverter card for example can be integrated only via http, so it doesn’t work if I secured HA to https only also on local network.

Why do you think NGINX HA addon has been published? Did you read the notes of the addon? I’ll help you:

So according to you, NGINX HA addon is only needed because of the Nuki Card. Do you really believe this is the case? Come on…:slight_smile:

From this, I can understand you never configured a web server, you don’t know how it works. A web server can listen BOTH on http and https, at the same time. It’s up to you to configure it to accept or not connections via http or https. And you don’t even understand how a callback works, it’s not HA that does the http request, it’s the bridge that calls the webhook url passing data, HA is the server in that case and the bridge is the client. Let alone your statements about certificates, it’s too complex to explain you how an SSL handshake/connection works, and trust me: from what you wrote, you don’t understand how it works. You need to study things a little bit more before making up an opinion and strongly comment on it, while not understanding the basics of how it works.

You are not aware because you only know the integrations that YOU need, not ALL the integrations/devices that all other users need. Do you think NGINX HA addon exists because I was developing the Nuki Card? :rofl:

I repeat: " it’s not related to one integration like Nuki Card, but all integrations", adding for your comprehension: "all integrations that require http connection TO HA. Clear now? :slight_smile:

No, we don’t have the same understanding and view of things, probably because we have a different background, I do these things since almost 25 years as a professional job, and if you insist telling me that HTTP access for HA is needed only because of the Nuki Card, I’ll keep telling you that you didn’t understand.

Anyway, this is my last reply in the thread to you regarding this issue. If you want to continue, please write me in private, this is getting boring for other people to read. And don’t worry, I’m not angry or nervous, I love discussing, no problem at all, and nothing personal. :slight_smile:

Ciao,

Alessandro

No problem, and glad that it’s now working for you. :slight_smile:

It could technically be done, but it would require the bridge to provide information about that setting, otherwise the Nuki Card would never know when the device is in battery save mode. In the Bridge API documentation, I don’t see any indication about that setting.

So the solution for you is simple: you need to setup an automation in HA that disables the Nuki Card automation at 22:00 and it re-enables it at 06:00. :slight_smile:

Hi Allessandro,

Again a big thank you for your work. I have extended it by inserting a possibility to translate some of the sensors. To achieve the possibility for translation, I made these changes:

  • Sensor states are now based on numerical values instead of alpha numerical values where needed
  • Added a input_select variable for selecting the language. There are now 3 possibilities, English, German and Dutch. Unfortunately not Italian because I don’t know that language, but it can be added. Please leave “en” as the first option in the selection list, because if this input select isn’t known, it will default to the first option in the list. Languages can be added bij searching for “{% elif states(‘input_select.nuki_language’) ==”. Just adding another “{% elif states(‘input_select.nuki_language’) == ‘’ %}” followed by a string in the new language will do the job. After a restart of HA, the (new) language can be set from “Configuration → Helpers → Nuki language for HA UI”.

So here is the code:

########################
# Nuki Card v8.0       #
########################

#######################################################################################################################
###                                                                                                                 ###
### Automations                                                                                                     ###
###                                                                                                                 ###
#######################################################################################################################

automation:
  - id: "nuki_card_callback"
    alias: Nuki Card Callback
    description: Automation for the Nuki doorlock
    trigger:
      - platform: webhook
        webhook_id: !secret nuki_bridge_webhook
      - platform: event
        event_type:
          - automation_reloaded
          - event_template_reloaded
      - platform: state
        entity_id: sensor.nuki_door_sensor_state
      - platform: state
        entity_id: sensor.nuki_lock_sensor_state
      - platform: state
        entity_id: binary_sensor.nuki_bridge_callback
        to: "off"
    condition: []
    mode: single
    action:
      - choose:
          - conditions: >
              {{ trigger.platform == 'webhook' }}
            sequence:
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_door_sensor_state
                data:
                  value: >
                    {{ trigger.json.doorsensorState }}
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_lock_sensor_state
                data:
                  value: >
                    {{ trigger.json.state }}
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_last_activity
                data:
                  value: >
                    {{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }}
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_trigger_platform
                data:
                  value: >
                    {{ trigger.platform }}
          - conditions: >
              {{ trigger.platform == 'state' or trigger.platform == 'event' }}
            sequence:
              - service: script.nuki_bridge_check_callback
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_door_sensor
                data:
                  value: >
                    {{ states('sensor.nuki_door_sensor_state') }}
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_lock_sensor
                data:
                  value: >
                    {{ states('sensor.nuki_lock_sensor_state') }}
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_last_activity
                data:
                  value: >
                    {{ states('sensor.nuki_last_activity') }}
              - service: input_text.set_value
                target:
                  entity_id: input_text.nuki_bridge_trigger_platform
                data:
                  value: >
                    {{ trigger.platform }}
        default: []
#######################################################################################################################
###                                                                                                                 ###
### Input Selects                                                                                                   ###
###                                                                                                                 ###
#######################################################################################################################

input_select:
  nuki_language:
    name: "Nuki language for HA UI"
    options:
      - en
      - de
      - nl
    icon: mdi:blur-radial

#######################################################################################################################
###                                                                                                                 ###
### Input Texts & Numbers                                                                                           ###
###                                                                                                                 ###
#######################################################################################################################
input_text:
  nuki_bridge_url:
    name: "Nuki Card (bridge url)"
    initial: !secret nuki_bridge_url
  nuki_bridge_token:
    name: "Nuki Card (bridge token)"
    initial: !secret nuki_bridge_token
  nuki_bridge_webhook:
    name: "Nuki Card (bridge webhook)"
    initial: !secret nuki_bridge_webhook
    max: 255
  nuki_ha_internal_url:
    name: "Nuki Card (HA internal URL)"
    initial: !secret nuki_ha_internal_url
  nuki_bridge_door_sensor:
    name: "Nuki Card (door sensor)"
  nuki_bridge_door_sensor_state:
    name: "Nuki Card (door sensor state)"
  nuki_bridge_lock_sensor:
    name: "Nuki Card (lock sensor)"
  nuki_bridge_lock_sensor_state:
    name: "Nuki Card (lock sensor state)"
  nuki_bridge_last_activity:
    name: "Nuki Card (last activity)"
  nuki_bridge_trigger_platform:
    name: "Nuki Card (trigger platform)"

#######################################################################################################################
###                                                                                                                 ###
### Binary sensors                                                                                                  ###
###                                                                                                                 ###
#######################################################################################################################

binary_sensor:
  - platform: template
    sensors:
      nuki_door_state:
        unique_id: nuki_door_state
        friendly_name: "Nuki Door State"
        device_class: door
        value_template: >
          {{ is_state_attr('sensor.nuki_door_sensor_state','numeric_state', 3) }}
        availability_template: >
          {{ is_state_attr('sensor.nuki_door_sensor_state','numeric_state', 3) or is_state_attr('sensor.nuki_door_sensor_state','numeric_state', 2) }}
        icon_template: >
          {% if is_state_attr('sensor.nuki_door_sensor_state','numeric_state', 3) %}
            mdi:door-open
          {% elif is_state_attr('sensor.nuki_door_sensor_state','numeric_state', 2) and is_state_attr('sensor.nuki_lock_sensor_state','numeric_state', 1) %}
            mdi:door-closed-lock
          {% elif is_state_attr('sensor.nuki_door_sensor_state','numeric_state', 2) and is_state_attr('sensor.nuki_lock_sensor_state','numeric_state', 3) %}
            mdi:door-closed
          {% else %}
            mdi:alert-box-outline
          {% endif %}
        attribute_templates:
          trigger_platform: >
            {{ states('input_text.nuki_bridge_trigger_platform') }}
          bridge_callback: >
            {% if state_attr('binary_sensor.nuki_bridge_callback','callback_id')|int > -1 %}
              Configured (ID: {{ state_attr('binary_sensor.nuki_bridge_callback','callback_id') }})
            {% else %}
              Not configured (ID: {{ state_attr('binary_sensor.nuki_bridge_callback','callback_id') }})
            {% endif %}
          nuki_id: >
            {{ states('sensor.nuki_id') }}
          door_state: >
            {{ states('input_text.nuki_bridge_door_sensor') }}
          lock_state: >
            {{ states('input_text.nuki_bridge_lock_sensor') }}
          lock_battery: >
            {{ states('sensor.nuki_lock_battery_level') }}
          lock_battery_critical: >
            {{ states('sensor.nuki_lock_battery_critical_state') }}
          keypad_battery_critical: >
            {% if states('sensor.nuki_keypad_battery_critical_state') != 'unknown' %}
              {{ states('sensor.nuki_keypad_battery_critical_state') }}
            {% else %}
              not installed 
            {% endif %}
          last_update_callback: >
            {{ states('input_text.nuki_bridge_last_activity') }}
          last_update_polled: >
            {{ states('sensor.nuki_last_activity') }}
          door_sensor_polled: >
            {{ states('sensor.nuki_door_sensor_state') }}
          lock_sensor_polled: >
            {{ states('sensor.nuki_lock_sensor_state') }}

      nuki_bridge_callback:
        unique_id: nuki_bridge_callback
        friendly_name: "Nuki Bridge Callback"
        icon_template: mdi:arrow-vertical-lock
        value_template: >
          {% if states('sensor.nuki_bridge_callback_list') == 'OK' %}
            {% for callback in state_attr('sensor.nuki_bridge_callback_list','callbacks') %}
              {% if states('input_text.nuki_bridge_webhook') in callback.url %}
                on
              {% else %}
                off
              {% endif %}
            {% endfor %}
          {% else %}
            off
          {% endif %}
        attribute_templates:
          callback_id: >
            {% if states('sensor.nuki_bridge_callback_list') == 'OK' %}
              {% for callback in state_attr('sensor.nuki_bridge_callback_list','callbacks') %}
                {% if states('input_text.nuki_bridge_webhook') in callback.url %}
                  {{ callback.id }}
                {% else %}
                  {{ -1 }}
                {% endif %}
              {% endfor %}
            {% else %}
              {{ -1 }}
            {% endif %}


#######################################################################################################################
###                                                                                                                 ###
### Locks                                                                                                           ###
###                                                                                                                 ###
#######################################################################################################################

lock:
  - platform: template
    name: "Nuki Lock Action"
    unique_id: nuki_lock_action
    value_template: >
      {{ is_state_attr('sensor.nuki_lock_sensor_state', 'numeric_state', 1) }}
    availability_template: >
      {{ is_state_attr('sensor.nuki_lock_sensor_state','numeric_state', 1) or is_state_attr('sensor.nuki_lock_sensor_state','numeric_state', 3) }}
    lock:
      service: rest_command.nuki_lock_action
      data:
        action: 2
    unlock:
      service: rest_command.nuki_lock_action
      data:
        action: 1


#######################################################################################################################
###                                                                                                                 ###
### rest commands                                                                                                   ###
###                                                                                                                 ###
#######################################################################################################################

rest_command:
  nuki_lock_action:
    url: "{{ states('input_text.nuki_bridge_url') }}/lockAction?nukiId={{ states('sensor.nuki_id') }}&action={{ action }}&token={{ states('input_text.nuki_bridge_token') | urlencode }}"
  nuki_bridge_add_callback:
    url: "{{ states('input_text.nuki_bridge_url') }}/callback/add?url={{ states('input_text.nuki_ha_internal_url') | urlencode }}/api/webhook/{{ states('input_text.nuki_bridge_webhook') | urlencode }}&token={{ states('input_text.nuki_bridge_token') | urlencode }}"
  nuki_bridge_del_callback:
    url: "{{ states('input_text.nuki_bridge_url') }}/callback/remove?id={{ state_attr('sensor.nuki_bridge_callback','callback_id') }}&token={{ states('input_text.nuki_bridge_token') | urlencode }}"


#######################################################################################################################
###                                                                                                                 ###
### scripts                                                                                                         ###
###                                                                                                                 ###
#######################################################################################################################

script:
  nuki_bridge_check_callback:
    sequence:
      - service: homeassistant.update_entity
        target:
          entity_id: sensor.nuki_bridge_callback_list
      - service: homeassistant.update_entity
        target:
          entity_id: binary_sensor.nuki_bridge_callback
      - alias: "Repeat the sequence UNTIL the conditions are true"
        repeat:
          while: "{{ states('binary_sensor.nuki_bridge_callback') == 'off' and repeat.index < 5 }}"
          sequence:
            - service: rest_command.nuki_bridge_add_callback
            - service: homeassistant.update_entity
              target:
                entity_id: sensor.nuki_bridge_callback_list
            - service: homeassistant.update_entity
              target:
                entity_id: binary_sensor.nuki_bridge_callback
            - delay:
                seconds: 5
            - service: persistent_notification.create
              data:
                notification_id: "nuki_card_persistent"
                title: Nuki Card (bridge configuration)
                message: >
                  * [**Script nuki_bridge_check_callback**] ran at {{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }}

                  * [**Bridge Callback ID:**] "{{ state_attr('binary_sensor.nuki_bridge_callback','callback_id') }}"
                  
                  * [**Callback List:**] {{ state_attr('sensor.nuki_bridge_callback_list','callbacks') }}


#######################################################################################################################
###                                                                                                                 ###
### sensors                                                                                                         ###
###                                                                                                                 ###
#######################################################################################################################

sensor:
  - platform: rest
    scan_interval: 120
    resource_template: "{{ states('input_text.nuki_bridge_url') }}/callback/list?&token={{ states('input_text.nuki_bridge_token') | urlencode }}"
    name: "Nuki Bridge Callback List"
    value_template: >
      {% if (state_attr('sensor.nuki_bridge_callback_list','callbacks') | trim | length) >= 2 %}
        OK
      {% else %}
        {% if states('input_select.nuki_language') == 'de' %}
          Nicht konfiguriert
        {% elif states('input_select.nuki_language') == 'nl' %}
          Niet gecofigureerd
        {% else %}
          Not configured
        {% endif%}
      {% endif %}
    json_attributes:
      - callbacks

  - platform: rest
    scan_interval: 120
    resource_template: "{{ states('input_text.nuki_bridge_url') }}/list?&token={{ states('input_text.nuki_bridge_token') | urlencode }}"
    name: "Nuki Bridge Endpoint List"
    value_template: "OK"
    json_attributes:
      - lastKnownState
      - firmwareVersion
      - nukiId
      - name

  - platform: rest
    scan_interval: 120
    resource_template: "{{ states('input_text.nuki_bridge_url') }}/info?&token={{ states('input_text.nuki_bridge_token') | urlencode }}"
    name: "Nuki Bridge Endpoint Info"
    value_template: "OK"
    json_attributes:
      - versions
      - scanResults
      - wlanConnected
      - serverConnected

  - platform: template
    sensors:
      nuki_device_name:
        unique_id: nuki_device_name
        friendly_name: "Nuki Device Name"
        icon_template: mdi:alphabetical-variant
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_info','scanResults')[0]['name'] }}
          {% endif %}

      nuki_bridge_fw_version:
        unique_id: nuki_bridge_fw_version
        friendly_name: "Nuki Bridge FW Version"
        icon_template: mdi:numeric
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_info','versions')['firmwareVersion'] }}
          {% endif %}

      nuki_bridge_lock_bt_rssi:
        unique_id: nuki_bridge_lock_bt_rssi
        friendly_name: "Nuki Bridge<->Lock BT RSSI"
        icon_template: mdi:signal-distance-variant
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_info','scanResults')[0]['rssi'] }}
          {% endif %}

      nuki_bridge_wifi_connected:
        unique_id: nuki_bridge_wifi_connected
        friendly_name: "Nuki Bridge WiFi Connected"
        icon_template: mdi:wifi-cog
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_info','wlanConnected') }}
          {% endif %}

      nuki_bridge_wifi_fw_version:
        unique_id: nuki_bridge_wifi_fw_version
        friendly_name: "Nuki Bridge WiFi FW Version"
        icon_template: mdi:numeric
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_info','versions')['wifiFirmwareVersion'] }}
          {% endif %}

      nuki_bridge_cloud_connected:
        unique_id: nuki_bridge_cloud_connected
        friendly_name: "Nuki Bridge Cloud Connected"
        icon_template: mdi:server-network
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_info','serverConnected') }}
          {% endif %}

      nuki_bridge_lock_bt_state:
        unique_id: nuki_bridge_lock_bt_state
        friendly_name: "Nuki Bridge<->Lock BT State"
        icon_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {% if state_attr('sensor.nuki_bridge_endpoint_info','scanResults')[0]['paired'] %}
              mdi:bluetooth-connect
            {% elif not state_attr('sensor.nuki_bridge_endpoint_info','scanResults')[0]['paired'] %}
              mdi:bluetooth-off
            {% else %}
              mdi:bluetooth-audio
            {% endif %}
          {% endif %}
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_info') == "OK" %}
            {% if state_attr('sensor.nuki_bridge_endpoint_info','scanResults')[0]['paired'] %}
              {% if states('input_select.nuki_language') == 'de' %}
                angebunden
              {% elif states('input_select.nuki_language') == 'nl' %}
                verbonden
              {% else %}
                connected
              {% endif%}
            {% elif not state_attr('sensor.nuki_bridge_endpoint_info','scanResults')[0]['paired'] %}
              {% if states('input_select.nuki_language') == 'de' %}
                getrennt
              {% elif states('input_select.nuki_language') == 'nl' %}
                verbroken
              {% else %}
                disconnected
              {% endif%}
            {% else %}
              {% if states('input_select.nuki_language') == 'de' %}
                unbekannt
              {% elif states('input_select.nuki_language') == 'nl' %}
                onbekend
              {% else %}
                unknown
              {% endif%}
            {% endif %}
          {% endif %}

      nuki_id:
        unique_id: nuki_id
        friendly_name: "Nuki ID"
        icon_template: mdi:numeric
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_list','nukiId') }}
          {% endif %}

      nuki_lock_fw_version:
        unique_id: nuki_lock_fw_version
        friendly_name: "Nuki Lock FW Version"
        icon_template: mdi:numeric
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_list','firmwareVersion') }}
          {% endif %}

      nuki_lock_battery_critical_state:
        unique_id: nuki_lock_battery_critical_state
        friendly_name: "Nuki Lock Battery Critical State"
        icon_template: mdi:battery-alert-variant-outline
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_list','lastKnownState')['batteryCritical'] }}
          {% endif %}

      nuki_friendly_name:
        unique_id: nuki_friendly_name
        friendly_name: "Nuki Friendly Name"
        icon_template: mdi:numeric
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {{ state_attr('sensor.nuki_bridge_endpoint_list','name') }}
          {% endif %}

      nuki_last_activity:
        unique_id: nuki_last_activity
        friendly_name: "Nuki Last Activity"
        icon_template: mdi:clock-check-outline
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {{ (as_timestamp(state_attr('sensor.nuki_bridge_endpoint_list','lastKnownState')['timestamp'])) | timestamp_custom("%H:%M:%S (%b %d)") }}
          {% endif %}

      nuki_lock_battery_level:
        unique_id: nuki_lock_battery_level
        friendly_name: "Nuki Lock Battery Level"
        device_class: "battery"
        unit_of_measurement: "%"
        icon_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {% set battery_level = state_attr('sensor.nuki_bridge_endpoint_list', 'lastKnownState')['batteryChargeState'] | default(0) | int %}
            {% set battery_charging = state_attr('sensor.nuki_bridge_endpoint_list', 'lastKnownState')['batteryCharging'] %}
            {% set battery_round = (battery_level / 10) | int * 10 %}
            {% if battery_round >= 100 and not battery_charging %}
              mdi:battery
            {% elif battery_round >= 100 and battery_charging %}
              mdi:battery-charging
            {% elif battery_round > 0 and not battery_charging %}
              mdi:battery-{{ battery_round }}
            {% elif battery_round > 0 and battery_charging %}
              mdi:battery-charging-{{ battery_round }}
            {% else %}
              mdi:battery-alert-variant-outline
            {% endif %}
          {% endif %}
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {% set battery_level = state_attr('sensor.nuki_bridge_endpoint_list', 'lastKnownState')['batteryChargeState'] | default(0) | int %}
            {% if state_attr('sensor.nuki_bridge_endpoint_list', 'lastKnownState')['batteryCharging'] %}
              {{ battery_level }}
            {% else %}
              {{ battery_level }}
            {% endif %}
          {% endif %}

      nuki_door_sensor_state:
        unique_id: nuki_door_sensor_state
        friendly_name: "Nuki Door Sensor State"
        icon_template: >
          {% if is_state('input_text.nuki_bridge_door_sensor_state', '2') and is_state('input_text.nuki_bridge_lock_sensor_state', '3') %}
            mdi:door-closed
          {% elif is_state('input_text.nuki_bridge_door_sensor_state', '2') and is_state('input_text.nuki_bridge_lock_sensor_state', '1') %}
            mdi:door-closed-lock
          {% elif is_state('input_text.nuki_bridge_door_sensor_state', '3') %}
            mdi:door-open
          {% endif %}
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {% if states('input_select.nuki_language') == 'de' %}
              {% set my_state = {1: 'deactiviert', 2: 'gesperrt', 3: 'geöffnet', 4: 'unbekannt', 5: 'kalibrierend'} %}
            {% elif states('input_select.nuki_language') == 'nl' %}
              {% set my_state = {1: 'gedeactiveerd', 2: 'gesloten', 3: 'open', 4: 'onbekend', 5: 'aan het calibreren'} %}
            {% else %}
              {% set my_state = {1: 'deactivated', 2: 'closed', 3: 'open', 4: 'unknown', 5: 'calibrating'} %}
            {% endif%}
            {{ my_state[states('input_text.nuki_bridge_door_sensor_state') | int] }}
          {% endif %}
        attribute_templates:
          numeric_state: >
            {{ states('input_text.nuki_bridge_door_sensor_state') | int }}

      nuki_lock_sensor_state:
        unique_id: nuki_lock_sensor_state
        friendly_name: "Nuki Lock Sensor State"
        icon_template: >
          {% if is_state('input_text.nuki_bridge_lock_sensor_state', '1') %}
            mdi:lock-outline
          {% elif is_state('input_text.nuki_bridge_lock_sensor_state', '3') %}
            mdi:lock-open-outline
          {% endif %}
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {% if states('input_select.nuki_language') == 'de' %}
              {% set my_state = {0: 'nict kalibriert', 1: 'gesperrt', 2:'aufmachen', 3: 'geöffnet', 4: 'sperren', 5: 'aufgeklinkt', 6: "geöffnet (lock ‘n’ go)", 7: 'aufklinkend', 254: 'Antrieb blockiert', 255: 'undefiniert'} %}
            {% elif states('input_select.nuki_language') == 'nl' %}
              {% set my_state = {0: 'niet gecalibreerd', 1: 'gesloten', 2:'openen', 3: 'open', 4: 'sluiten', 5: 'ontgrendeld', 6: "open (lock ‘n’ go)", 7: 'ontgrendelen', 254: 'moter geblokkeerd', 255: 'onbekend'} %}
            {% else %}
              {% set my_state = {0: 'uncalibrated', 1: 'locked', 2:'unlocking', 3: 'unlocked', 4: 'locking', 5: 'unlatched', 6: "unlocked (lock ‘n’ go)", 7: 'unlatching', 254: 'motor blocked', 255: 'undefined'} %}
            {% endif%}
            {{ my_state[states('input_text.nuki_bridge_lock_sensor_state') | int] }}
          {% endif %}
        attribute_templates:
          numeric_state: >
            {{ states('input_text.nuki_bridge_lock_sensor_state') | int }}

      nuki_keypad_battery_critical_state:
        unique_id: nuki_keypad_battery_critical_state
        friendly_name: "Nuki Keypad Battery Critical State"
        icon_template: mdi:battery-alert-variant-outline
        value_template: >
          {% if states('sensor.nuki_bridge_endpoint_list') == "OK" %}
            {% if state_attr('sensor.nuki_bridge_endpoint_list', 'lastKnownState')['keypadBatteryCritical'] != null %}
              {{ state_attr('sensor.nuki_bridge_endpoint_list', 'lastKnownState')['keypadBatteryCritical'] }}
            {% else %}
              {% if states('input_select.nuki_language') == 'de' %}
                nicht installiert
              {% elif states('input_select.nuki_language') == 'nl' %}
                niet geïnstalleerd
              {% else %}
                not installed 
              {% endif%}
            {% endif %}
          {% endif %}

Spokin,

thanks a lot for this, but I’m not convinced it’s the best way to solve the language problem, too many IFs to do a translation. The code will become bloated and probably slower.

I will think about it and let you know…I think we can come out with a more efficient and flexible solution, that abstracts the code of the automation from the strings of the labels/messages to be translated…we need a file, or something that users can themselves edit and the code references labels, whose contents can be translated.

Will let you know…thanks a lot for trying to improve this integration with new ideas, I greatly appreciate it. :slight_smile:

Hi Allesandro,

I agree with you. Unfortunately yaml is just a scripting language with it’s limitations. The only way to make the code more efficient is transform it into an integration (integration documentation) but then we need to know python, that you and I unfortunately don’t know. An integration can have language files (internationalization). So maybe in the future I can see if I manage to learn python, but that will definitely then be after the summer holiday season.

Maybe, after your effort, the people at Nuki, now know how to integrate it in HA and will do it…

True, we are limited in what we can do, but many times while developing this package/automation with plain yaml, I learned that it’s possible to overcome many problems that initially I thought required a custom integration. That’s why I told you to give me some time to think about it…I love solving problems due to specific constraints, it spikes my creativity. :slight_smile:

If I don’t come up with an elegant solution, I will tell you. I’m already thinking about something: a compact JSON structure, to be saved somewhere, that can be referenced in the code…:wink:

Good idea :joy:
the automation only controls the callback registry?

unfortunately I’ve experienced 2 bugs in the meantime…

  1. the lock became unavailable for 3 hours during the daytime so it’s not related to the battery saving
  2. the automation registered 2 new callbacks even though an earlier one was register correctly. So when I manually checked the bridge I got 3 callbacks registered.

I think the the two might be related…
any ideas?

I have no answers to your questions, but I experience the same issues.

I don’t think I fully understood the question: there’s no registry. The callback is done by the bridge, that calls an HTTP url pointing to HA, basically it refreshes the status of the lock/doorsensor immediately.

Yes it happened to me too yesterday, and I found the problem in my case: HA is not resolving DNS names, it happens every 1 hour:

➜  ~ curl -X GET 'http://nuki-bridge.axel.dom:8080/callback/list?token=tyzyzyz'
{"callbacks": [{"id": 0, "url": "http://hass.axel.dom:8123/api/webhook/xTE4NzYzzzzzzzzzzsImlhdCI6MTYyMTcyODg0MSwiyyyyyyyxxxxxxRJwRTfJsoW-Rrrrrrrrrrrrr"}]}

➜  ~ date
Wed Jul 21 05:41:03 CEST 2021

➜  ~ curl -X GET 'http://nuki-bridge.axel.dom:8080/callback/list?token=tyzyzyz'
curl: (6) Could not resolve host: nuki-bridge.axel.dom
➜  ~ curl -X GET 'http://nuki-bridge.axel.dom:8080/callback/list?token=tyzyzyz'
curl: (6) Could not resolve host: nuki-bridge.axel.dom

➜  ~ ha dns restart
Processing... Done.
Command completed successfully.

➜  ~ curl -X GET 'http://nuki-bridge.axel.dom:8080/callback/list?token=tyzyzyz'
{"callbacks": [{"id": 0, "url": "http://hass.axel.dom:8123/api/webhook/xTE4NzYzzzzzzzzzzsImlhdCI6MTYyMTcyODg0MSwiyyyyyyyxxxxxxRJwRTfJsoW-Rrrrrrrrrrrrr"}]}

It never happened to me before, and it seems that many users are having this issue and the solution is not available yet. (in case someone’s interested, I’m discussing the issue in this old thread).

So back to the Nuki Card bug: the code regarding the reconfiguration of the bridge didn’t take into account several things, I’m modifying it so it can be more resilient to these issues.

In your case, it would be interesting to see what happened: for sure HA was not able to communicate with the bridge, that’s what triggers the bug. While I complete the new version, you can delete the 2 duplicated callback entries from the bridge manually (use curl).

Can you show me your nuki_bridge_url in the secrets?

One workaround, while I complete the updated version, if the problem is the DNS, is using the ip address:

so, from this:

nuki_bridge_url: "http://nuki-bridge.axel.dom:8080"

to this:

nuki_bridge_url: "http://10.1.10.126:8080"

Sorry and thanks for the feedback…

Alessandro

Sorry for this, I’m working on the fix.

Can you do a little bit of analysis of the logs and tell me if there’s any indication of no communication with the bridge?

Also, can you show me your nuki_bridge_url in the secrets?

One workaround, while I complete the updated version, if the problem is the DNS, is using the ip address:

so, from this:

nuki_bridge_url: "http://nuki-bridge.axel.dom:8080"

to this:

nuki_bridge_url: "http://10.1.10.126:8080"

Thanks.

My nuki_bridge_url was already set to an IP.

Here’s my log:

2021-07-20 13:37:41 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with Server disconnected without sending a response.
2021-07-20 13:37:41 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/callback/list?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/callback/list?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest_command] Client error http://192.168.178.46:8080/callback/add?url=http%3A//192.168.178.46%3A8080/api/webhook/*****************&token=*****************
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/callback/list?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:37:42 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-20 17:13:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_list is taking over 10 seconds
2021-07-20 17:13:53 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with 
2021-07-20 17:13:53 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 17:13:53 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-20 17:15:41 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-20 17:15:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_info is taking over 10 seconds
2021-07-20 17:15:51 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with 
2021-07-20 17:15:51 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 17:15:52 WARNING (MainThread) [homeassistant.components.rest_command] Timeout call http://192.168.178.46:8080/callback/add?url=http%3A//192.168.178.46%3A8080/api/webhook/*****************&token=*****************
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_callback_list is taking over 10 seconds
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_list is taking over 10 seconds
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_info is taking over 10 seconds
2021-07-21 05:59:51 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/callback/list?&token=***************** failed with 
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 05:59:51 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with 
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 05:59:51 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with 
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 05:59:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 05:59:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 05:59:52 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/callback/list?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-21 05:59:52 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 05:59:52 ERROR (MainThread) [homeassistant.components.rest_command] Client error http://192.168.178.46:8080/callback/add?url=http%3A//192.168.178.46%3A8080/api/webhook/*****************&token=*****************
2021-07-21 05:59:52 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/callback/list?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-21 05:59:52 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 06:01:42 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 08:09:52 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_info is taking over 10 seconds
2021-07-21 08:09:52 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with 
2021-07-21 08:09:52 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 08:11:52 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_list is taking over 10 seconds
2021-07-21 08:11:52 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with 
2021-07-21 08:11:52 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 08:11:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 08:13:42 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 08:15:52 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_list is taking over 10 seconds
2021-07-21 08:15:52 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with 
2021-07-21 08:15:52 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 08:15:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 08:17:42 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 08:27:52 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_list is taking over 10 seconds
2021-07-21 08:27:52 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with 
2021-07-21 08:27:52 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 08:27:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 08:29:42 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running

Hi @alexdelprete and thanks for your quick reply!
In my case the bridge address was an IP from the beginning, so for me its probably not a dns issue.
I think the problem resolves when I delete the extra callbacks from the bridge.
for now, I disabled the Nuki Card automation.
sending you some pictures, hope it will help
URL in secrets
image
errors:

You shouldn’t have all those errors. It’s not DNS in your case.

Looking at the timings, I see something happened at 13.37 and 16.35 yesterday, then at 5.59 and 8.11 this morning.

2021-07-20 13:37:41 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with Server disconnected without sending a response.
2021-07-20 13:37:41 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-20 16:35:42 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with [Errno 111] Connect call failed ('192.168.178.46', 8080)
2021-07-20 16:35:42 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
url=http%3A//192.168.178.46%3A8080/api/webhook/*****************&token=*****************
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_callback_list is taking over 10 seconds
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_list is taking over 10 seconds
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nuki_bridge_endpoint_info is taking over 10 seconds
2021-07-21 05:59:51 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/callback/list?&token=***************** failed with 
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 05:59:51 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/info?&token=***************** failed with 
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 05:59:51 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.178.46:8080/list?&token=***************** failed with 
2021-07-21 05:59:51 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 05:59:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 05:59:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running
2021-07-21 08:11:52 WARNING (MainThread) [homeassistant.components.rest.sensor] Empty reply found when expecting JSON data
2021-07-21 08:11:52 WARNING (MainThread) [homeassistant.components.automation.nuki_card_callback] Nuki Card Callback: Already running

Can you send this command to the bridge and post the log please? Thanks.

curl -X GET 'http://nuki-ip:8080/log?token=xxxyyy'