@alexdelprete I’ve managed to create a package which will update the sensors by both the webhook and rest interface. The sensors are updated from input_text fields that are set by either one of the 3 automations incorporated in the package. To force the update from a REST call, I set the according sensors to “force_update: true”. So every time a REST call is made from HA, the sensors are updated, which gave me the possibility to create automations that trigger when the according sensor is updated.
As you already stated the information from the REST call is less important so I kept the interval at 2,5 minutes. In the end this results in an update of all the sensors every 2,5 minutes unless an action is triggered at the lock, then the sensors are updated when the webhook is received.
So here is my code just for being complete:
#################################
# Nuki Card version from spokin #
#################################
#######################################################################################################################
### ###
### 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: event_template_reloaded
condition: []
action:
- choose:
- conditions: >
{{ trigger.platform == 'webhook' }}
sequence:
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_door_sensor_state
data:
value: >
{{ trigger.json.doorsensorState }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_sensor_state
data:
value: >
{{ trigger.json.state }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_sensor_state_name
data:
value: >
{{ trigger.json.stateName }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_mode
data:
value: >
{{ trigger.json.mode }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_nuki_id
data:
value: >
{{ trigger.json.nukiId }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_device_type
data:
value: >
{{ trigger.json.deviceType }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_battery_critical
data:
value: >
{{ trigger.json.batteryCritical }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_battery_charging
data:
value: >
{{ trigger.json.batteryCharging }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_battery_charge_state
data:
value: >
{{ trigger.json.batteryChargeState }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_door_sensor_state_name
data:
value: >
{% set my_state = {1: 'deactivated', 2: 'closed', 3: 'open', 4: 'unknown', 5: 'calibrating'} %}
{{ my_state[trigger.json.doorsensorState] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_last_activity_timestamp
data:
value: >
{{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_last_update_card_callback
data:
value: >
{{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }}
- service: input_text.set_value
target:
entity_id: input_text.trigger_platform
data:
value: >
{{ trigger.platform }}
- conditions: >
{{ trigger.platform == 'event' }}
sequence:
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_door_sensor_state
data:
value: >
{{ states('sensor.nuki_door_sensor_state') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_sensor_state
data:
value: >
{{ states('sensor.nuki_lock_sensor_state') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_last_activity_timestamp
data:
value: >
{{ states('sensor.nuki_last_activity') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_trigger_platform
data:
value: >
{{ trigger.platform }}
default: []
mode: single
automation 2:
- id: 'Nuki_endpoint_list'
alias: Nuki Endpoint List
description: 'Nuki Automation to update sensors based on the Nuki Endpoint List restfull call'
trigger:
- platform: state
entity_id: sensor.nuki_endpoint_list
condition: []
action:
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_mode
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['mode'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_sensor_state
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['state'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_sensor_state_name
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['stateName'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_battery_critical
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['batteryCritical'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_battery_charging
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['batteryCharging'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_battery_charge_state
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['batteryChargeState'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_door_sensor_state
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['doorsensorState'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_door_sensor_state_name
data:
value: >-
{% set my_state = {1: 'deactivated', 2: 'closed', 3: 'open', 4: 'unknown', 5: 'calibrating'} %}
{{ my_state[state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['doorsensorState']] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_last_activity_timestamp
data:
value: >-
{{ (as_timestamp(state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['timestamp'])) | timestamp_custom("%H:%M:%S (%b %d)") }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_last_update_endpoint_list
data:
value: >-
{{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_firmware_version
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'firmwareVersion') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_nuki_id
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'nukiId') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_bridge_name
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'name') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_keypad_battery_critical
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_list', 'lastKnownState')['keypadBatteryCritical'] }}
mode: single
automation 3:
- id: 'Nuki_endpoint_info'
alias: Nuki Endpoint Info
description: 'Nuki Automation to update sensors based on the Nuki Endpoint Info restfull call'
trigger:
- platform: state
entity_id: sensor.nuki_endpoint_info
condition: []
action:
- service: input_text.set_value
target:
entity_id: input_text.nuki_bridge_firmware_version
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_info','versions')['firmwareVersion'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_bridge_wifi_firmware_version
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_info','versions')['wifiFirmwareVersion'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_device_name
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_info','scanResults')[0]['name'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_rssi
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_info','scanResults')[0]['rssi'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_lock_paired
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_info','scanResults')[0]['paired'] }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_bridge_wlan_connected
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_info','wlanConnected') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_bridge_server_connected
data:
value: >-
{{ state_attr('sensor.nuki_endpoint_info','serverConnected') }}
- service: input_text.set_value
target:
entity_id: input_text.nuki_last_update_endpoint_info
data:
value: >-
{{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }}
mode: single
#######################################################################################################################
### ###
### 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('sensor.nuki_door_sensor_state', 'open') }}
availability_template: >
{{ (is_state('sensor.nuki_door_sensor_state', 'open') or is_state('sensor.nuki_door_sensor_state', 'closed')) }}
icon_template: >
{% set trigdoor = states('sensor.nuki_door_sensor_state') %}
{% set triglock = states('sensor.nuki_lock_sensor_state') %}
{% if (trigdoor == 'open') %}
mdi:door-open
{% elif trigdoor == 'closed' and triglock == 'locked' %}
mdi:door-closed-lock
{% elif trigdoor == 'closed' and triglock == 'unlocked' %}
mdi:door-closed
{% else %}
mdi:alert-box-outline
{% endif %}
attribute_templates:
trigger_platform: >
{{ states('input_text.nuki_bridge_trigger_platform') }}
nuki_id: >
{{ states('sensor.nuki_id') }}
door_state: >
{{ states('sensor.nuki_door_sensor_state') }}
lock_state: >
{{ states('sensor.nuki_lock_sensor_state') }}
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') != '' %}
{{ states('sensor.nuki_keypad_battery_critical_state') }}
{% else %}
not installed
{% endif %}
last_update_card_callback: >
{{ states('input_text.nuki_last_update_card_callback') }}
last_update_endpoint_info: >
{{ states('input_text.nuki_last_update_endpoint_info') }}
last_update_endpoint_list: >
{{ states('input_text.nuki_last_update_endpoint_list') }}
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') }}
#######################################################################################################################
### ###
### Input Texts ###
### ###
#######################################################################################################################
input_text:
nuki_bridge_host:
initial: !secret nuki_bridge_host
nuki_bridge_port:
initial: !secret nuki_bridge_port
nuki_bridge_token:
initial: !secret nuki_bridge_token
nuki_bridge_device_type:
nuki_bridge_firmware_version:
nuki_bridge_name:
nuki_bridge_server_connected:
nuki_bridge_wifi_firmware_version:
nuki_bridge_wlan_connected:
nuki_keypad_battery_critical:
nuki_lock_battery_critical:
nuki_lock_battery_charging:
nuki_lock_battery_charge_state:
nuki_lock_device_name:
nuki_lock_door_sensor_state:
nuki_lock_door_sensor_state_name:
nuki_lock_firmware_version:
nuki_lock_mode:
nuki_lock_nuki_id:
nuki_lock_paired:
nuki_lock_rssi:
nuki_lock_sensor_state:
nuki_lock_sensor_state_name:
nuki_lock_last_activity_timestamp:
nuki_last_update_card_callback:
nuki_last_update_endpoint_info:
nuki_last_update_endpoint_list:
nuki_trigger_platform:
#######################################################################################################################
### ###
### Locks ###
### ###
#######################################################################################################################
lock:
- platform: template
name: "Nuki Lock Action"
unique_id: nuki_lock_action
value_template: >
{{ is_state_attr('binary_sensor.nuki_door_state', 'lock_state', 'locked') }}
availability_template: >
{{ is_state_attr('binary_sensor.nuki_door_state', 'lock_state', 'locked') or
is_state_attr('binary_sensor.nuki_door_state', 'lock_state', 'unlocked')}}
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: "http://{{ states('input_text.nuki_bridge_host') }}:{{ states('input_text.nuki_bridge_port') }}/lockAction?nukiId={{ states('sensor.nuki_id') }}&token={{ states('input_text.nuki_bridge_token') }}&action={{ action }}"
#######################################################################################################################
### ###
### sensors ###
### ###
#######################################################################################################################
sensor:
- platform: rest
scan_interval: 150
force_update: true
resource_template: "http://{{ states('input_text.nuki_bridge_host') }}:{{ states('input_text.nuki_bridge_port') }}/list?&token={{ states('input_text.nuki_bridge_token') }}"
name: "Nuki Endpoint List"
value_template: "OK"
json_attributes:
- lastKnownState
- firmwareVersion
- nukiId
- name
- platform: rest
scan_interval: 150
force_update: true
resource_template: "http://{{ states('input_text.nuki_bridge_host') }}:{{ states('input_text.nuki_bridge_port') }}/info?&token={{ states('input_text.nuki_bridge_token') }}"
name: "Nuki 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: >
{{ states('input_text.nuki_lock_device_name') }}
- platform: template
sensors:
nuki_bridge_fw_version:
unique_id: nuki_bridge_fw_version
friendly_name: "Nuki Bridge FW Version"
icon_template: mdi:numeric
value_template: >
{{ states('input_text.nuki_bridge_firmware_version') }}
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: >
{{ states('input_text.nuki_lock_rssi') }}
nuki_bridge_wifi_connected:
unique_id: nuki_bridge_wifi_connected
friendly_name: "Nuki Bridge WiFi Connected"
icon_template: mdi:wifi-cog
value_template: >
{{ states('input_text.nuki_bridge_wlan_connected') }}
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: >
{{ states('input_text.nuki_bridge_wifi_firmware_version') }}
nuki_bridge_cloud_connected:
unique_id: nuki_bridge_cloud_connected
friendly_name: "Nuki Bridge Cloud Connected"
icon_template: mdi:server-network
value_template: >
{{ states('input_text.nuki_bridge_server_connected') }}
nuki_bridge_lock_bt_state:
unique_id: nuki_bridge_lock_bt_state
friendly_name: "Nuki Bridge<->Lock BT State"
icon_template: >
{% if states('input_text.nuki_lock_paired') %}
mdi:bluetooth-connect
{% elif states('input_text.nuki_lock_paired') %}
mdi:bluetooth-off
{% else %}
mdi:bluetooth-audio
{% endif %}
value_template: >
{% if states('input_text.nuki_lock_paired') %}
connected
{% elif not states('input_text.nuki_lock_paired') %}
disconnected
{% else %}
Unknown
{% endif %}
nuki_id:
unique_id: nuki_id
friendly_name: "Nuki ID"
icon_template: mdi:numeric
value_template: >
{{ states('input_text.nuki_lock_nuki_id') }}
nuki_lock_fw_version:
unique_id: nuki_lock_fw_version
friendly_name: "Nuki Lock FW Version"
icon_template: mdi:numeric
value_template: >
{{ states('input_text.nuki_lock_firmware_version') }}
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: >
{{ states('input_text.nuki_lock_battery_critical') }}
nuki_lock_battery_charging:
unique_id: nuki_lock_battery_charging
friendly_name: "Nuki Lock Battery Charging"
icon_template: mdi:battery-charging
value_template: >
{{ states('input_text.nuki_lock_battery_charging') }}
nuki_lock_battery_level:
unique_id: nuki_lock_battery_level
friendly_name: "Nuki Lock Battery Level"
device_class: "battery"
unit_of_measurement: "%"
icon_template: >
{% set battery_level = states('input_text.nuki_lock_battery_charge_state') | default(0) | int %}
{% set battery_charging = states('input_text.nuki_lock_battery_charging') %}
{% 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 %}
value_template: >
{% set battery_level = states('input_text.nuki_lock_battery_charge_state') | default(0) | int %}
{% set battery_charging = states('input_text.nuki_lock_battery_charging') %}
{% if battery_charging %}
{{ battery_level }}
{% else %}
{{ battery_level }}
{% endif %}
nuki_friendly_name:
unique_id: nuki_friendly_name
friendly_name: "Nuki Friendly Name"
icon_template: mdi:numeric
value_template: >
{{ states('input_text.nuki_bridge_name') }}
nuki_last_activity:
unique_id: nuki_last_activity
friendly_name: "Nuki Last Activity"
icon_template: mdi:clock-check-outline
value_template: >
{{ states('input_text.nuki_lock_last_activity_timestamp') }}
nuki_door_sensor_state:
unique_id: nuki_door_sensor_state
friendly_name: "Nuki Door Sensor State"
icon_template: >
{% set door_icon = states('input_text.nuki_lock_door_sensor_state') %}
{% set lock_icon = states('input_text.nuki_lock_sensor_state') %}
{% if door_icon == '2' and lock_icon == '3' %}
mdi:door-closed
{% elif door_icon == '2' and lock_icon == '1' %}
mdi:door-closed-lock
{% elif door_icon == '3' %}
mdi:door-open
{% endif %}
value_template: >
{% set my_state = {'1': 'deactivated', '2': 'closed', '3': 'open', '4': 'unknown', '5': 'calibrating'} %}
{{ my_state[states('input_text.nuki_lock_door_sensor_state')] }}
nuki_lock_sensor_state:
unique_id: nuki_lock_sensor_state
friendly_name: "Nuki Lock Sensor State"
icon_template: >
{% set lock_icon = states('input_text.nuki_lock_sensor_state') %}
{% if lock_icon == '1' %}
mdi:lock-outline
{% elif lock_icon == '3' %}
mdi:lock-open-outline
{% endif %}
value_template: >
{% 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'} %}
{{ my_state[states('input_text.nuki_lock_sensor_state')] }}
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('input_text.nuki_keypad_battery_critical') != '' %}
{{ states('input_text.nuki_keypad_battery_critical') }}
{% else %}
not installed
{% endif %}