Strangely enough, the official integration does not seem to use the local callback proposed by the NUKI bridge API. So, for those not satisfied with pooling:
- Create a long-term token on your profile page
- Register a callback on your bridge by running:
curl -X GET -H "Content-Type: application/json" 'http://your_nuki_bridge_IP:8080/callback/add?token=your_NUKI_API_token&url=http://your_HA_IP:8123/api/webhook/your_long-term_webhook_id'
.
You should get a {"success": true}
in response.
- Optionnally, you can check it is correctly registered by running:
curl -X GET -H "Content-Type: application/json" 'http://your_nuki_bridge_IP:8080/callback/list?token=your_NUKI_API_token'
- Once the state of the door or of the lock changes, the bridge will now call your HA instance with a payload like this:
{'deviceType': 0, 'nukiId': your_lock_id, 'mode': 2, 'state': 3, 'stateName': 'unlocked', 'batteryCritical': False, 'batteryCharging': False, 'batteryChargeState': 44, 'keypadBatteryCritical': False, 'doorsensorState': 2, 'doorsensorStateName': 'door closed'}
Based on this, you can now create a new trigger-based template sensor. Here is mine (sorry for the French):
- trigger:
- platform: webhook
webhook_id: your_webhook_id
binary_sensor:
- unique_id: porte_principale
device_class: door
state: >
{{ trigger.json.doorsensorState == 3 }}
availability: "{{ (trigger.json.doorsensorState == 3) or (trigger.json.doorsensorState == 2) }}"
icon: >
{% if trigger.json.doorsensorState == 3 %}
mdi:door-open
{% elif (trigger.json.doorsensorState == 2) and (trigger.json.state == 1) %}
mdi:door-closed-lock
{% elif trigger.json.doorsensorState == 2 %}
mdi:door-closed
{% else %}
mdi:door
{% endif %}
attributes:
friendly_name: "Porte principale"
batteries: "{{ trigger.json.batteryChargeState }}%"
Problème_keypad: "{{ trigger.json.keypadBatteryCritical == True }}" # if you have a keypad, obviously.
porte: >
{% set my_state = {0: 'indisponible', 1: 'désactivée', 2: 'porte fermée', 3: 'porte ouverte', 4: 'inconnu', 5: 'calibration'} -%}
{{ my_state[trigger.json.doorsensorState] }}
serrure: >
{% set my_state = {0: 'non calibrée', 1: 'verrouillée', 2:'déverrouillage', 3: 'déverrouillée', 4: 'verrouillage', 5: 'ouverte', 6: "déverrouillée (lock 'n' go)", 7: 'ouverture', 254: 'moteur bloqué', 255: 'indéfini'} -%}
{{ my_state[trigger.json.state] }}
màj: "{{ strptime(as_timestamp(now()) | timestamp_local, '%Y-%m-%d %H:%M:00') }}"
I wanted to translate the lock and door states in French, you can just replace the FR terms with those in your language, but if you are happy with EN, then you can simply use the stateName and doorsensorStateName from the callback payload.
I am personnaly satisfied with the battery info in an attribute, but you can create sensors for this in the same template if you want (see the doc.)