Last active
October 14, 2022 17:46
-
-
Save alexdelprete/296f50a4e5b35c0ea4bbed99a7420f5e to your computer and use it in GitHub Desktop.
Nuki Card v11.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###################################### | |
# # | |
# -= Nuki Card v11.0 =- # | |
# # | |
# by # | |
# @alexdelprete # | |
# # | |
# contributions from: # | |
# @spokin # | |
# # | |
###################################### | |
####################################################################################################################### | |
### ### | |
### Automations ### | |
### ### | |
####################################################################################################################### | |
automation: | |
- id: "nuki_card_callback" | |
alias: Nuki Card Callback | |
description: Automation for the Nuki doorlock | |
mode: queued | |
max: 10 | |
max_exceeded: warning | |
trigger: | |
- platform: homeassistant | |
id: "trigger_nuki_ha_start" | |
event: start | |
- platform: webhook | |
id: "trigger_nuki_bridge_webhook" | |
webhook_id: !secret nuki_bridge_webhook | |
- platform: state | |
id: "trigger_nuki_bridge_endpoint_list_lock" | |
entity_id: sensor.nuki_bridge_endpoint_list_lock | |
- platform: state | |
id: "trigger_nuki_bridge_endpoint_list_opener" | |
entity_id: sensor.nuki_bridge_endpoint_list_opener | |
- platform: state | |
id: "trigger_nuki_opener_ring_action_state" | |
entity_id: binary_sensor.nuki_opener_ring_action_state | |
to: "on" | |
for: "00:00:30" | |
condition: [] | |
action: | |
- choose: | |
- conditions: > | |
{{ trigger.id == 'trigger_nuki_ha_start' }} | |
sequence: | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_callback_url | |
data: | |
value: > | |
{{ states('input_text.nuki_ha_internal_url') | urlencode }}/api/webhook/{{ states('input_text.nuki_bridge_webhook') | urlencode }} | |
- service: script.turn_on | |
target: | |
entity_id: script.nuki_bridge_polling_queue | |
- conditions: > | |
{{ trigger.id == 'trigger_nuki_opener_ring_action_state' }} | |
sequence: | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_ringaction_state | |
data: | |
value: "false" | |
- conditions: > | |
{{ trigger.id == 'trigger_nuki_bridge_endpoint_list_lock' or trigger.id == 'trigger_nuki_bridge_endpoint_list_opener'}} | |
sequence: | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_door_state_id | |
data: | |
value: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['doorsensorState'] if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['doorsensorState'] != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_door_state | |
data: | |
value: > | |
{{ (states('input_text.nuki_door_states') | from_json)[state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['doorsensorState'] | string ] if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['doorsensorState'] != null }} | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_lock_state_id | |
data: | |
value: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['state'] if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['state'] != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_lock_state | |
data: | |
value: > | |
{{ (states('input_text.nuki_lock_states') | from_json)[state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['state'] | string] if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['state'] != null }} | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_lock_mode_id | |
data: | |
value: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['mode'] if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['mode'] != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_lock_mode | |
data: | |
value: > | |
{{ (states('input_text.nuki_lock_modes') | from_json)[state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['mode'] | string] if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['mode'] != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_lock_last_update | |
data: | |
value: > | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['timestamp'] != null %} | |
{{ as_timestamp(state_attr('sensor.nuki_bridge_endpoint_list_lock','lastKnownState')['timestamp']) | timestamp_custom("%H:%M:%S (%b %d)") }} | |
{% endif %} | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_opener_state_id | |
data: | |
value: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['state'] if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['state'] != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_state | |
data: | |
value: > | |
{{ (states('input_text.nuki_opener_states') | from_json)[state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['state'] | string] if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['state'] != null }} | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_opener_mode_id | |
data: | |
value: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['mode'] if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['mode'] != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_mode | |
data: | |
value: > | |
{{ (states('input_text.nuki_opener_modes') | from_json)[state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['mode'] | string] if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['mode'] != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_last_update | |
data: | |
value: > | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['timestamp'] != null %} | |
{{ as_timestamp(state_attr('sensor.nuki_bridge_endpoint_list_opener','lastKnownState')['timestamp']) | timestamp_custom("%H:%M:%S (%b %d)") }} | |
{% endif %} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_ringaction_state | |
data: | |
value: > | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['ringactionState'] != null %} | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','lastKnownState')['ringactionState'] }} | |
{% endif %} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_last_ringaction | |
data: | |
value: > | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['ringactionTimestamp'] != null %} | |
{{ as_timestamp(state_attr('sensor.nuki_bridge_endpoint_list_opener','lastKnownState')['ringactionTimestamp']) | timestamp_custom("%H:%M:%S (%b %d)") }} | |
{% endif %} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_trigger_id | |
data: | |
value: > | |
{{ trigger.id }} | |
- conditions: > | |
{{ trigger.id == 'trigger_nuki_bridge_webhook' and trigger.json.deviceType|int == 0 }} | |
sequence: | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_door_state_id | |
data: | |
value: > | |
{{ trigger.json.doorsensorState|int if trigger.json.doorsensorState != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_door_state | |
data: | |
value: > | |
{{ (states('input_text.nuki_door_states')|from_json)[trigger.json.doorsensorState|int|string] if trigger.json.doorsensorState != null }} | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_lock_state_id | |
data: | |
value: > | |
{{ trigger.json.state|int if trigger.json.state != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_lock_state | |
data: | |
value: > | |
{{ (states('input_text.nuki_lock_states')|from_json)[trigger.json.state|int|string] if trigger.json.state != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_lock_last_update | |
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_id | |
data: | |
value: > | |
{{ trigger.id }} | |
- service: homeassistant.update_entity | |
target: | |
entity_id: binary_sensor.nuki_door_state | |
- service: homeassistant.update_entity | |
target: | |
entity_id: lock.nuki_lock_action | |
- service: homeassistant.update_entity | |
target: | |
entity_id: lock.nuki_opener_action | |
- service: script.turn_on | |
target: | |
entity_id: script.nuki_bridge_polling_queue | |
- conditions: > | |
{{ trigger.id == 'trigger_nuki_bridge_webhook' and trigger.json.deviceType|int == 2 }} | |
sequence: | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_opener_state_id | |
data: | |
value: > | |
{{ trigger.json.state|int if trigger.json.state != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_state | |
data: | |
value: > | |
{{ (states('input_text.nuki_opener_states')|from_json)[trigger.json.state|int|string] if trigger.json.state != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_ringaction_state | |
data: | |
value: > | |
{{ trigger.json.ringactionState|string if trigger.json.ringactionState != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_last_ringaction | |
data: | |
value: > | |
{{ as_timestamp(trigger.json.ringactionTimestamp)|timestamp_custom("%H:%M:%S (%b %d)") if trigger.json.ringactionTimestamp != null }} | |
- service: input_number.set_value | |
target: | |
entity_id: input_number.nuki_bridge_opener_mode_id | |
data: | |
value: > | |
{{ trigger.json.mode|int if trigger.json.mode != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_mode | |
data: | |
value: > | |
{{ (states('input_text.nuki_opener_modes')|from_json)[trigger.json.mode|int|string] if trigger.json.mode != null }} | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_opener_last_update | |
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_id | |
data: | |
value: > | |
{{ trigger.id }} | |
- service: homeassistant.update_entity | |
target: | |
entity_id: binary_sensor.nuki_door_state | |
- service: homeassistant.update_entity | |
target: | |
entity_id: lock.nuki_lock_action | |
- service: homeassistant.update_entity | |
target: | |
entity_id: lock.nuki_opener_action | |
- service: script.turn_on | |
target: | |
entity_id: script.nuki_bridge_polling_queue | |
####################################################################################################################### | |
### ### | |
### Input Selects ### | |
### ### | |
####################################################################################################################### | |
input_select: | |
nuki_choose_lock_action: | |
name: "Nuki Card (lock action)" | |
icon: mdi:lock-question | |
options: | |
- Unlock | |
- Lock | |
- Unlatch | |
- Lock ‘n’ Go | |
- Lock ‘n’ Go + Unlatch | |
nuki_choose_unlock_action: | |
name: "Nuki Card (unlock action)" | |
icon: mdi:lock-question | |
options: | |
- Unlock | |
- Lock | |
- Unlatch | |
- Lock ‘n’ Go | |
- Lock ‘n’ Go + Unlatch | |
nuki_choose_opener_lock_action: | |
name: "Nuki Card (opener lock action)" | |
icon: mdi:lock-question | |
options: | |
- Activate Ring To Open | |
- Deactivate Ring To Open | |
- Electric Strike Actuation | |
- Activate Continuous Mode | |
- Dectivate Continuous Mode | |
nuki_choose_opener_unlock_action: | |
name: "Nuki Card (opener unlock action)" | |
icon: mdi:lock-question | |
options: | |
- Activate Ring To Open | |
- Deactivate Ring To Open | |
- Electric Strike Actuation | |
- Activate Continuous Mode | |
- Dectivate Continuous Mode | |
####################################################################################################################### | |
### ### | |
### Input Numbers ### | |
### ### | |
####################################################################################################################### | |
input_number: | |
nuki_bridge_door_state_id: | |
name: "Nuki Card (door state ID)" | |
min: 0 | |
max: 255 | |
mode: box | |
nuki_bridge_lock_state_id: | |
name: "Nuki Card (lock state ID)" | |
min: 0 | |
max: 255 | |
mode: box | |
nuki_bridge_opener_state_id: | |
name: "Nuki Card (opener state ID)" | |
min: 0 | |
max: 255 | |
mode: box | |
nuki_bridge_lock_mode_id: | |
name: "Nuki Card (lock mode ID)" | |
min: 0 | |
max: 255 | |
mode: box | |
nuki_bridge_opener_mode_id: | |
name: "Nuki Card (opener mode ID)" | |
min: 0 | |
max: 255 | |
mode: box | |
####################################################################################################################### | |
### ### | |
### Input Texts ### | |
### ### | |
####################################################################################################################### | |
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: 500 | |
nuki_ha_internal_url: | |
name: "Nuki Card (HA internal URL)" | |
initial: !secret nuki_ha_internal_url | |
nuki_bridge_callback_list: | |
name: "Nuki Card (bridge callback list)" | |
nuki_bridge_callback_url: | |
name: "Nuki Card (bridge callback url)" | |
max: 500 | |
nuki_bridge_door_state: | |
name: "Nuki Card (door state)" | |
nuki_bridge_lock_state: | |
name: "Nuki Card (lock state)" | |
nuki_bridge_opener_state: | |
name: "Nuki Card (opener state)" | |
nuki_bridge_lock_mode: | |
name: "Nuki Card (lock mode)" | |
nuki_bridge_opener_mode: | |
name: "Nuki Card (opener mode)" | |
nuki_bridge_lock_last_update: | |
name: "Nuki Card (lock last update)" | |
nuki_bridge_opener_last_update: | |
name: "Nuki Card (opener last update)" | |
nuki_bridge_opener_last_ringaction: | |
name: "Nuki Card (opener last ring action)" | |
nuki_bridge_opener_ringaction_state: | |
name: "Nuki Card (opener ring action state)" | |
nuki_bridge_trigger_id: | |
name: "Nuki Card (trigger id)" | |
nuki_door_states: | |
name: "Nuki Card (door states)" | |
initial: '{"1": "deactivated", "2": "closed", "3": "open", "4": "unknown", "5": "calibrating"}' | |
max: 255 | |
nuki_lock_states: | |
name: "Nuki Card (lock states)" | |
initial: '{"0": "uncalibrated", "1": "locked", "2": "unlocking", "3": "unlocked", "4": "locking", "5": "unlatched", "6": "unlocked (lock ‘n’ go)", "7": "unlatching", "253": "n/a", "254": "motor blocked", "255": "undefined"}' | |
max: 255 | |
nuki_opener_states: | |
name: "Nuki Card (opener states)" | |
initial: '{"0": "untrained", "1": "online", "2": "n/a", "3": "rto active", "4": "n/a", "5": "open", "6": "n/a", "7": "opening", "253": "boot run", "254": "n/a", "255": "undefined"}' | |
max: 255 | |
nuki_lock_modes: | |
name: "Nuki Card (lock modes)" | |
initial: '{"2": "door mode", "3": "n/a"}' | |
max: 255 | |
nuki_opener_modes: | |
name: "Nuki Card (opener modes)" | |
initial: '{"2": "door mode", "3": "continuous mode"}' | |
max: 255 | |
####################################################################################################################### | |
### ### | |
### Scripts ### | |
### ### | |
####################################################################################################################### | |
script: | |
nuki_bridge_polling_queue: | |
mode: queued | |
max: 5 | |
max_exceeded: warning | |
sequence: | |
- delay: 1 | |
- alias: "Refresh List REST sensor" | |
service: homeassistant.update_entity | |
target: | |
entity_id: sensor.nuki_bridge_endpoint_list_lock | |
- delay: 1 | |
- alias: "Refresh Info REST sensor" | |
service: homeassistant.update_entity | |
target: | |
entity_id: sensor.nuki_bridge_endpoint_info_lock | |
- delay: 1 | |
- alias: "Refresh Callback List REST sensor" | |
service: homeassistant.update_entity | |
target: | |
entity_id: sensor.nuki_bridge_callback_list | |
- alias: "Sync Callback List input text" | |
service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_callback_list | |
data: | |
value: > | |
{{ (states('sensor.nuki_bridge_callback_list')|from_json) if states('sensor.nuki_bridge_callback_list') != 'unknown' }} | |
- alias: "Refresh Callback List state sensor" | |
service: homeassistant.update_entity | |
target: | |
entity_id: binary_sensor.nuki_bridge_callback | |
- delay: 1 | |
- alias: "Add callback to bridge" | |
repeat: | |
while: "{{ states('binary_sensor.nuki_bridge_callback') == 'off' and states('input_text.nuki_bridge_callback_list')|from_json|count == 0 }}" | |
sequence: | |
- service: rest_command.nuki_bridge_add_callback | |
- delay: 1 | |
- service: homeassistant.update_entity | |
target: | |
entity_id: sensor.nuki_bridge_callback_list | |
- delay: 1 | |
- service: homeassistant.update_entity | |
target: | |
entity_id: binary_sensor.nuki_bridge_callback | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_callback_list | |
data: | |
value: > | |
{{ states('sensor.nuki_bridge_callback_list')|from_json if states('sensor.nuki_bridge_callback_list') != 'unknown' }} | |
- wait_template: "{{ is_state('binary_sensor.nuki_bridge_callback', 'on') and states('input_text.nuki_bridge_callback_list')|from_json|count == 1 }}" | |
timeout: 10 | |
- service: persistent_notification.create | |
data: | |
notification_id: "nuki_card_persistent" | |
title: Nuki Card (added callback to bridge) | |
message: > | |
* [**Script nuki_bridge_polling_queue**] ran at {{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }} | |
* [**Bridge Callback ID:**] "{{ states('input_text.nuki_bridge_callback_list') }}" | |
* [**Callback Raw List:**] {{ state_attr('sensor.nuki_bridge_callback_list','callbacks') }} | |
- alias: "Delete callbacks from bridge" | |
repeat: | |
while: "{{ (states('input_text.nuki_bridge_callback_list')|from_json|count > 1) }}" | |
sequence: | |
- service: rest_command.nuki_bridge_del_callback | |
data: | |
callback_id: "{{ (states('input_text.nuki_bridge_callback_list')|from_json)[-1] }}" | |
- delay: 1 | |
- service: homeassistant.update_entity | |
target: | |
entity_id: sensor.nuki_bridge_callback_list | |
- delay: 1 | |
- service: homeassistant.update_entity | |
target: | |
entity_id: binary_sensor.nuki_bridge_callback | |
- service: input_text.set_value | |
target: | |
entity_id: input_text.nuki_bridge_callback_list | |
data: | |
value: > | |
{{ states('sensor.nuki_bridge_callback_list')|from_json if states('sensor.nuki_bridge_callback_list') != 'unknown' }} | |
- service: persistent_notification.create | |
data: | |
notification_id: "nuki_card_persistent" | |
title: Nuki Card (deleted callback to bridge) | |
message: > | |
* [**Script nuki_bridge_polling_queue**] ran at {{ as_timestamp(now()) | timestamp_custom("%H:%M:%S (%b %d)") }} | |
* [**Bridge Callback ID:**] "{{ states('input_text.nuki_bridge_callback_list') }}" | |
* [**Callback Raw List:**] {{ state_attr('sensor.nuki_bridge_callback_list','callbacks') }} | |
####################################################################################################################### | |
### ### | |
### Locks ### | |
### ### | |
####################################################################################################################### | |
lock: | |
- platform: template | |
name: "Nuki Lock Action" | |
unique_id: nuki_lock_action | |
value_template: > | |
{{ states('input_number.nuki_bridge_lock_state_id') | int == 1 if states('input_number.nuki_bridge_lock_state_id') | int != 'unknown' }} | |
availability_template: > | |
{{ states('input_text.nuki_bridge_lock_state') != 'unknown' }} | |
lock: | |
service: rest_command.nuki_lock_action | |
data: | |
dev_type: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock','deviceType') }} | |
action: > | |
{{ state_attr('input_select.nuki_choose_lock_action','options').index(states('input_select.nuki_choose_lock_action')) + 1 }} | |
nuki_id: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock','nukiId') }} | |
unlock: | |
service: rest_command.nuki_lock_action | |
data: | |
dev_type: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock','deviceType') }} | |
action: > | |
{{ state_attr('input_select.nuki_choose_unlock_action','options').index(states('input_select.nuki_choose_unlock_action')) + 1 }} | |
nuki_id: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock','nukiId') }} | |
- platform: template | |
name: "Nuki Opener Action" | |
unique_id: nuki_opener_action | |
value_template: > | |
{{ states('input_number.nuki_bridge_opener_state_id') | int == 1 if states('input_number.nuki_bridge_opener_state_id') | int != 'unknown' }} | |
availability_template: > | |
{{ states('input_text.nuki_bridge_opener_state') != 'unknown' }} | |
lock: | |
service: rest_command.nuki_lock_action | |
data: | |
dev_type: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','deviceType') }} | |
action: > | |
{{ state_attr('input_select.nuki_choose_opener_lock_action','options').index(states('input_select.nuki_choose_opener_lock_action')) + 1 }} | |
nuki_id: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','nukiId') }} | |
unlock: | |
service: rest_command.nuki_lock_action | |
data: | |
dev_type: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','deviceType') }} | |
action: > | |
{{ state_attr('input_select.nuki_choose_opener_unlock_action','options').index(states('input_select.nuki_choose_opener_unlock_action')) + 1 }} | |
nuki_id: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','nukiId') }} | |
####################################################################################################################### | |
### ### | |
### Binary sensors ### | |
### ### | |
####################################################################################################################### | |
binary_sensor: | |
- platform: template | |
sensors: | |
nuki_bridge_callback: | |
unique_id: nuki_bridge_callback | |
device_class: connectivity | |
friendly_name: "Nuki Bridge Callback" | |
icon_template: mdi:arrow-vertical-lock | |
value_template: > | |
{% if states('sensor.nuki_bridge_callback_list') != 'unknown' and states('input_text.nuki_bridge_callback_list')|count > 0 %} | |
{{ 'on' if states('input_text.nuki_bridge_callback_list')|from_json|count == 1 else 'off' }} | |
{% else %} | |
off | |
{% endif %} | |
attribute_templates: | |
callback_id_list: > | |
{{ states('sensor.nuki_bridge_callback_list') if states('sensor.nuki_bridge_callback_list') != 'unknown' }} | |
nuki_door_state: | |
unique_id: nuki_door_state | |
device_class: door | |
friendly_name: "Nuki Door State" | |
icon_template: > | |
{% set door_icon = states('input_number.nuki_bridge_door_state_id') | int %} | |
{% set lock_icon = states('input_number.nuki_bridge_lock_state_id') | int %} | |
{% 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: > | |
{{ states('input_number.nuki_bridge_door_state_id') | int == 3 }} | |
attribute_templates: | |
trigger_id: > | |
{{ states('input_text.nuki_bridge_trigger_id') if states('input_text.nuki_bridge_trigger_id') != 'unknown' }} | |
bridge_callback_id_list: > | |
{{ states('input_text.nuki_bridge_callback_list')|from_json if is_state('binary_sensor.nuki_bridge_callback', 'on') }} | |
door_state_id: > | |
{{ states('input_number.nuki_bridge_door_state_id') if states('input_number.nuki_bridge_door_state_id') != 'unknown' }} | |
door_state: > | |
{{ states('input_text.nuki_bridge_door_state') if states('input_text.nuki_bridge_door_state') != 'unknown' }} | |
keypad_battery_critical: > | |
{{ states('binary_sensor.nuki_keypad_battery_critical_state') if states('binary_sensor.nuki_keypad_battery_critical_state') != 'unknown' else "n/a" }} | |
lock_id: > | |
{{ states('sensor.nuki_lock_id') if states('sensor.nuki_lock_id') != 'unknown' }} | |
lock_state_id: > | |
{{ states('input_number.nuki_bridge_lock_state_id') if states('input_number.nuki_bridge_lock_state_id') != 'unknown' }} | |
lock_state: > | |
{{ states('input_text.nuki_bridge_lock_state') if states('input_text.nuki_bridge_lock_state') != 'unknown' }} | |
lock_battery_level: > | |
{{ states('sensor.nuki_lock_battery_level') if states('sensor.nuki_lock_battery_level') != 'unknown' }} | |
lock_battery_critical: > | |
{{ states('binary_sensor.nuki_lock_battery_critical_state') if states('binary_sensor.nuki_lock_battery_critical_state') != 'unknown' }} | |
lock_last_update_callback: > | |
{{ states('input_text.nuki_bridge_lock_last_update') if states('input_text.nuki_bridge_lock_last_update') != 'unknown' }} | |
lock_last_update_polled: > | |
{{ states('sensor.nuki_lock_last_update') if states('sensor.nuki_lock_last_update') != 'unknown' }} | |
nuki_lock_bridge_bt_state: | |
unique_id: nuki_lock_bridge_bt_state | |
device_class: connectivity | |
friendly_name: "Nuki Lock<->Bridge BT State" | |
icon_template: > | |
{% if states('input_number.nuki_bt_state') | int == 1 %} | |
mdi:bluetooth-connect | |
{% elif states('input_number.nuki_bt_state') | int == 2 %} | |
mdi:bluetooth-off | |
{% else %} | |
mdi:bluetooth-audio | |
{% endif %} | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info_lock','paired') if states('sensor.nuki_bridge_endpoint_info_lock') != "unknown" }} | |
nuki_lock_battery_critical_state: | |
unique_id: nuki_lock_battery_critical_state | |
device_class: battery | |
friendly_name: "Nuki Lock Battery Critical State" | |
icon_template: mdi:battery-alert-variant-outline | |
value_template: > | |
{% if states('sensor.nuki_bridge_endpoint_list_lock') != "unknown" %} | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['batteryCritical'] != null %} | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['batteryCritical'] }} | |
{% endif %} | |
{% endif %} | |
nuki_keypad_battery_critical_state: | |
unique_id: nuki_keypad_battery_critical_state | |
device_class: battery | |
friendly_name: "Nuki Keypad Battery Critical State" | |
icon_template: mdi:battery-alert-variant-outline | |
value_template: > | |
{% if states('sensor.nuki_bridge_endpoint_list_lock') != "unknown" %} | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['keypadBatteryCritical'] != null %} | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['keypadBatteryCritical'] }} | |
{% else %} | |
not installed | |
{% endif %} | |
{% endif %} | |
nuki_bridge_wifi_connected: | |
unique_id: nuki_bridge_wifi_connected | |
device_class: connectivity | |
friendly_name: "Nuki Bridge WiFi Connected" | |
icon_template: mdi:wifi-cog | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info','wlanConnected') if states('sensor.nuki_bridge_endpoint_info') != "unknown" }} | |
nuki_bridge_cloud_connected: | |
unique_id: nuki_bridge_cloud_connected | |
device_class: connectivity | |
friendly_name: "Nuki Bridge Cloud Connected" | |
icon_template: mdi:server-network | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info','serverConnected') if states('sensor.nuki_bridge_endpoint_info') != "unknown" }} | |
nuki_opener_battery_critical_state: | |
unique_id: nuki_opener_battery_critical_state | |
device_class: battery | |
friendly_name: "Nuki Opener Battery Critical State" | |
icon_template: mdi:battery-alert-variant-outline | |
value_template: > | |
{% if states('sensor.nuki_bridge_endpoint_list_opener') != "unknown" %} | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['batteryCritical'] != null %} | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['batteryCritical'] }} | |
{% endif %} | |
{% endif %} | |
nuki_opener_ring_action_state: | |
unique_id: nuki_opener_ring_action_state | |
friendly_name: "Nuki Opener Ring Action State" | |
icon_template: mdi:bell-ring-outline | |
value_template: > | |
{{ states('input_text.nuki_bridge_opener_ringaction_state') if states('input_text.nuki_bridge_opener_ringaction_state') != 'unknown' }} | |
nuki_opener_bridge_bt_state: | |
unique_id: nuki_opener_bridge_bt_state | |
device_class: connectivity | |
friendly_name: "Nuki Opener<->Bridge BT State" | |
icon_template: > | |
{% if states('input_number.nuki_bt_state') | int == 1 %} | |
mdi:bluetooth-connect | |
{% elif states('input_number.nuki_bt_state') | int == 2 %} | |
mdi:bluetooth-off | |
{% else %} | |
mdi:bluetooth-audio | |
{% endif %} | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info_opener','paired') if states('sensor.nuki_bridge_endpoint_info_opener') != "unknown" }} | |
####################################################################################################################### | |
### ### | |
### REST commands ### | |
### ### | |
####################################################################################################################### | |
rest_command: | |
nuki_lock_action: | |
url: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
{{ states('input_text.nuki_bridge_url') }}/lockAction?deviceType={{ dev_type }}&action={{ action }}&nowait=1&nukiId={{ nuki_id }}&token={{ states('input_text.nuki_bridge_token') | urlencode }} | |
{% else %} | |
http:// | |
{% endif %} | |
nuki_bridge_add_callback: | |
url: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
{{ states('input_text.nuki_bridge_url') }}/callback/add?url={{ states('input_text.nuki_bridge_callback_url') }}&token={{ states('input_text.nuki_bridge_token') | urlencode }} | |
{% else %} | |
http:// | |
{% endif %} | |
nuki_bridge_del_callback: | |
url: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
{{ states('input_text.nuki_bridge_url') }}/callback/remove?id={{ callback_id|int }}&token={{ states('input_text.nuki_bridge_token') | urlencode }} | |
{% else %} | |
http:// | |
{% endif %} | |
####################################################################################################################### | |
### ### | |
### REST sensors ### | |
### ### | |
####################################################################################################################### | |
rest: | |
- resource_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
{{ states('input_text.nuki_bridge_url') }}/list?&token={{ states('input_text.nuki_bridge_token') | urlencode }} | |
{% else %} | |
http:// | |
{% endif %} | |
scan_interval: 31536000 | |
sensor: | |
- name: "Nuki Bridge Endpoint List Lock" | |
json_attributes_path: "$.[?(@.deviceType==0)]" | |
force_update: true | |
value_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
OK | |
{% else %} | |
KO | |
{% endif %} | |
json_attributes: | |
- deviceType | |
- nukiId | |
- name | |
- firmwareVersion | |
- lastKnownState | |
- name: "Nuki Bridge Endpoint List Opener" | |
json_attributes_path: "$.[?(@.deviceType==2)]" | |
force_update: true | |
value_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
OK | |
{% else %} | |
KO | |
{% endif %} | |
json_attributes: | |
- deviceType | |
- nukiId | |
- name | |
- firmwareVersion | |
- lastKnownState | |
- resource_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
{{ states('input_text.nuki_bridge_url') }}/info?&token={{ states('input_text.nuki_bridge_token') | urlencode }} | |
{% else %} | |
http:// | |
{% endif %} | |
scan_interval: 31536000 | |
sensor: | |
- name: "Nuki Bridge Endpoint Info" | |
force_update: true | |
value_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
OK | |
{% else %} | |
KO | |
{% endif %} | |
json_attributes: | |
- bridgeType | |
- ids | |
- versions | |
- uptime | |
- currentTime | |
- wlanConnected | |
- serverConnected | |
- scanResults | |
- name: "Nuki Bridge Endpoint Info Lock" | |
json_attributes_path: "$.scanResults.[?(@.deviceType==0)]" | |
force_update: true | |
value_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
OK | |
{% else %} | |
KO | |
{% endif %} | |
json_attributes: | |
- deviceType | |
- nukiId | |
- name | |
- rssi | |
- paired | |
- name: "Nuki Bridge Endpoint Info Opener" | |
json_attributes_path: "$.scanResults.[?(@.deviceType==2)]" | |
force_update: true | |
value_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
OK | |
{% else %} | |
KO | |
{% endif %} | |
json_attributes: | |
- deviceType | |
- nukiId | |
- name | |
- rssi | |
- paired | |
- resource_template: > | |
{% if states('input_text.nuki_bridge_url') != 'unknown' and states('input_text.nuki_bridge_token') != 'unknown' %} | |
{{ states('input_text.nuki_bridge_url') }}/callback/list?&token={{ states('input_text.nuki_bridge_token') | urlencode }} | |
{% else %} | |
http:// | |
{% endif %} | |
scan_interval: 31536000 | |
sensor: | |
- name: "Nuki Bridge Callback List" | |
force_update: true | |
value_template: > | |
{% set ns = namespace() %} | |
{% set ns.callback_list = [] %} | |
{% if (value_json.callbacks | count) > 0 %} | |
{% set hook = states('input_text.nuki_bridge_callback_url') %} | |
{% for callback in value_json.callbacks %} | |
{% if hook == (callback.url|urlencode) %} | |
{% set ns.callback_list = ns.callback_list + [ callback.id ] %} | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{{ ns.callback_list }} | |
json_attributes: | |
- callbacks | |
####################################################################################################################### | |
### ### | |
### Template sensors ### | |
### ### | |
####################################################################################################################### | |
sensor: | |
- 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: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info','versions')['firmwareVersion'] if states('sensor.nuki_bridge_endpoint_info') != "unknown" }} | |
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: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info','versions')['wifiFirmwareVersion'] if states('sensor.nuki_bridge_endpoint_info') != "unknown" }} | |
nuki_lock_bridge_bt_rssi: | |
unique_id: nuki_lock_bridge_bt_rssi | |
device_class: signal_strength | |
unit_of_measurement: dB | |
friendly_name: "Nuki Lock<->Bridge BT RSSI" | |
icon_template: mdi:signal-distance-variant | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info_lock','rssi') if states('sensor.nuki_bridge_endpoint_info_lock') != "unknown" }} | |
nuki_lock_device_name: | |
unique_id: nuki_lock_device_name | |
friendly_name: "Nuki Lock Device Name" | |
icon_template: mdi:alphabetical-variant | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info_lock','name') if states('sensor.nuki_bridge_endpoint_info_lock') != "unknown" }} | |
nuki_lock_id: | |
unique_id: nuki_lock_id | |
friendly_name: "Nuki Lock ID" | |
icon_template: mdi:numeric | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock','nukiId') if states('sensor.nuki_bridge_endpoint_list_lock') != "unknown" }} | |
nuki_lock_fw_version: | |
unique_id: nuki_lock_fw_version | |
friendly_name: "Nuki Lock FW Version" | |
icon_template: mdi:numeric | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock','firmwareVersion') if states('sensor.nuki_bridge_endpoint_list_lock') != "unknown" }} | |
nuki_lock_friendly_name: | |
unique_id: nuki_lock_friendly_name | |
friendly_name: "Nuki Lock Friendly Name" | |
icon_template: mdi:alphabetical-variant | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_lock','name') if states('sensor.nuki_bridge_endpoint_list_lock') != "unknown" }} | |
nuki_lock_mode: | |
unique_id: nuki_lock_mode | |
friendly_name: "Nuki Friendly Name" | |
icon_template: mdi:alphabetical-variant | |
value_template: > | |
{{ (states('input_text.nuki_lock_modes') | from_json)[state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['mode'] | string] if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['mode'] != null }} | |
nuki_lock_last_update: | |
unique_id: nuki_lock_last_update | |
friendly_name: "Nuki Lock Last Update" | |
icon_template: mdi:clock-check-outline | |
value_template: > | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['timestamp'] != null %} | |
{{ as_timestamp(state_attr('sensor.nuki_bridge_endpoint_list_lock','lastKnownState')['timestamp']) | timestamp_custom("%H:%M:%S (%b %d)") }} | |
{% endif %} | |
nuki_lock_battery_level: | |
unique_id: nuki_lock_battery_level | |
device_class: battery | |
friendly_name: "Nuki Lock Battery Level" | |
unit_of_measurement: "%" | |
icon_template: > | |
{% if states('sensor.nuki_bridge_endpoint_list_lock') != "unknown" %} | |
{% set battery_level = state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['batteryChargeState'] | default(0) | int %} | |
{% set battery_charging = state_attr('sensor.nuki_bridge_endpoint_list_lock', '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_lock') != "unknown" %} | |
{% set battery_level = state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['batteryChargeState'] | default(0) | int %} | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_lock', 'lastKnownState')['batteryCharging'] %} | |
{{ battery_level }} | |
{% else %} | |
{{ battery_level }} | |
{% endif %} | |
{% endif %} | |
nuki_opener_bridge_bt_rssi: | |
unique_id: nuki_bridge_opener_bt_rssi | |
device_class: signal_strength | |
unit_of_measurement: dB | |
friendly_name: "Nuki Opener<->Bridge BT RSSI" | |
icon_template: mdi:signal-distance-variant | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info_opener','rssi') if states('sensor.nuki_bridge_endpoint_info_opener') != "unknown" }} | |
nuki_opener_device_name: | |
unique_id: nuki_opener_device_name | |
friendly_name: "Nuki Opener Device Name" | |
icon_template: mdi:alphabetical-variant | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_info_opener','name') if states('sensor.nuki_bridge_endpoint_info_opener') != "unknown" }} | |
nuki_opener_id: | |
unique_id: nuki_opener_id | |
friendly_name: "Nuki Opener ID" | |
icon_template: mdi:numeric | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','nukiId') if states('sensor.nuki_bridge_endpoint_list_opener') != "unknown" }} | |
nuki_opener_fw_version: | |
unique_id: nuki_opener_fw_version | |
friendly_name: "Nuki Opener FW Version" | |
icon_template: mdi:numeric | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','firmwareVersion') if states('sensor.nuki_bridge_endpoint_list_opener') != "unknown" }} | |
nuki_opener_friendly_name: | |
unique_id: nuki_opener_friendly_name | |
friendly_name: "Nuki Opener Friendly Name" | |
icon_template: mdi:alphabetical-variant | |
value_template: > | |
{{ state_attr('sensor.nuki_bridge_endpoint_list_opener','name') if states('sensor.nuki_bridge_endpoint_list_opener') != "unknown" }} | |
nuki_opener_mode: | |
unique_id: nuki_opener_mode | |
friendly_name: "Nuki Opener Mode" | |
icon_template: mdi:alphabetical-variant | |
value_template: > | |
{{ (states('input_text.nuki_opener_modes')|from_json)[states('input_number.nuki_bridge_opener_mode_id')|int|string] if states('input_number.nuki_bridge_opener_mode_id') != 'unknown' }} | |
nuki_opener_state: | |
unique_id: nuki_opener_state | |
friendly_name: "Nuki Opener State" | |
icon_template: mdi:alphabetical-variant | |
value_template: > | |
{{ states('input_text.nuki_bridge_opener_state') if states('input_text.nuki_bridge_opener_state') != 'unknown' }} | |
attribute_templates: | |
opener_id: > | |
{{ states('sensor.nuki_opener_id') if states('sensor.nuki_opener_id') != 'unknown' }} | |
opener_mode_id: > | |
{{ states('input_number.nuki_bridge_opener_mode_id') if states('input_number.nuki_bridge_opener_mode_id') != 'unknown' }} | |
opener_mode: > | |
{{ (states('input_text.nuki_opener_modes')|from_json)[states('input_number.nuki_bridge_opener_mode_id')|int|string] }} | |
opener_state_id: > | |
{{ states('input_number.nuki_bridge_opener_state_id') if states('input_number.nuki_bridge_opener_state_id') != 'unknown' }} | |
opener_state: > | |
{{ states('input_text.nuki_bridge_opener_state') if states('input_text.nuki_bridge_opener_state') != 'unknown' }} | |
opener_ringaction_state: > | |
{{ states('input_text.nuki_bridge_opener_ringaction_state') if states('input_text.nuki_bridge_opener_ringaction_state') != 'unknown' }} | |
opener_last_ringaction: > | |
{{ states('input_text.nuki_bridge_opener_last_ringaction') if states('input_text.nuki_bridge_opener_last_ringaction') != 'unknown' }} | |
opener_battery_critical: > | |
{{ states('binary_sensor.nuki_opener_battery_critical_state') if states('binary_sensor.nuki_opener_battery_critical_state') != 'unknown' }} | |
opener_last_update_callback: > | |
{{ states('input_text.nuki_bridge_opener_last_update') if states('input_text.nuki_bridge_opener_last_update') != 'unknown' }} | |
opener_last_update_polled: > | |
{{ states('sensor.nuki_opener_last_update') if states('sensor.nuki_opener_last_update') != 'unknown' }} | |
nuki_opener_last_update: | |
unique_id: nuki_opener_last_update | |
friendly_name: "Nuki Opener Last Update" | |
icon_template: mdi:clock-check-outline | |
value_template: > | |
{% if state_attr('sensor.nuki_bridge_endpoint_list_opener', 'lastKnownState')['timestamp'] != null %} | |
{{ as_timestamp(state_attr('sensor.nuki_bridge_endpoint_list_opener','lastKnownState')['timestamp']) | timestamp_custom("%H:%M:%S (%b %d)") }} | |
{% endif %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment