So I promised to post a script here if there was anything to share. This will create an MQTT device in Home Assistant with the following entities:
- Lock
- Locked/unlocked state
- Battery level
- Battery charging state
- Battery critical state
- Open (unlatch) button, since the HA lock entity doesn’t seem to provide a simple way to do that, just lock/unlock buttons
Edit the first lines according to your setup and run it, a new device should appear in your MQTT integration.
This was just a first attempt to have the MQTT entities going in HA, make sure I’m on the right topics and payloads. In the near future I plan to rewrite this in Python, have it auto-discover all locks on the nuki base topic so you won’t have to manually specify the serial, model and name.
NUKI_SERIAL='12345678'
NUKI_MODEL='Lock 3 Pro'
LOCK_NAME='Nuki Front Door'
DISCOVERY_TOPIC='homeassistant'
MQTT_USER='myuser'
MQTT_PASS='mypass'
MQTT_HOST='mqtt.example.com'
# Editing below this line should not be necessary
# This is where the lock will post its messages
BASE_TOPIC="nuki/${NUKI_SERIAL}"
# Turn device name into lower case with underscores to use as identifier in HA
DEVICE_NAME="${LOCK_NAME,,}"
DEVICE_NAME="${DEVICE_NAME// /_}"
# MQTT connection parameters
MQTT_OPTS="-h ${MQTT_HOST} -p ${MQTT_PORT:-1883} -u ${MQTT_USER} -P ${MQTT_PASS}"
## Example line for removing incorrect config
# mosquitto_pub ${MQTT_OPTS} -t "${DISCOVERY_TOPIC}/lock/${DEVICE_NAME}/${DEVICE_NAME}_lock/config" -n -r
# Read firmware version
NUKI_FW=$(mosquitto_sub ${MQTT_OPTS} -t "${BASE_TOPIC}/firmware" -C 1)
# Define device so entities will be grouped
DEVICE="\"dev\":{\"name\":\"${LOCK_NAME}\",\"manufacturer\":\"Nuki\",\"model\":\"${NUKI_MODEL}\",\"sw_version\":\"${NUKI_FW:-0.0.0}\",\"identifiers\":[\"${NUKI_SERIAL}\"]}"
# Availability topic for all entities
AVTY="\"avty_t\":\"${BASE_TOPIC}/connected\",\"pl_avail\":\"true\",\"pl_not_avail\":\"false\""
# Lock
PAYLOAD="{\"uniq_id\":\"${DEVICE_NAME}_lock\",${DEVICE},\"name\":\"${LOCK_NAME} lock\",${AVTY},\"stat_t\":\"${BASE_TOPIC}/state\",\"stat_locked\":1,\"stat_unlocked\":3,\"cmd_t\":\"${BASE_TOPIC}/lockAction\",\"pl_unlock\":1,\"pl_lock\":2,\"pl_open\":3}"
mosquitto_pub ${MQTT_OPTS} -t "${DISCOVERY_TOPIC}/lock/${DEVICE_NAME}/${DEVICE_NAME}_lock/config" -m "${PAYLOAD}" -r
# Binary sensor for lock state (locked/unlocked)
PAYLOAD="{\"uniq_id\":\"${DEVICE_NAME}_state\",${DEVICE},\"name\":\"${LOCK_NAME} state\",${AVTY},\"stat_t\":\"${BASE_TOPIC}/state\",\"val_tpl\":\"{{ value }}\",\"pl_on\":3,\"pl_off\":1,\"device_class\":\"lock\"}"
mosquitto_pub ${MQTT_OPTS} -t "${DISCOVERY_TOPIC}/binary_sensor/${DEVICE_NAME}/${DEVICE_NAME}_state/config" -m "${PAYLOAD}" -r
# Sensor for battery percentage
PAYLOAD="{\"uniq_id\":\"${DEVICE_NAME}_battery\",${DEVICE},\"name\":\"${LOCK_NAME} battery\",${AVTY},\"stat_t\":\"${BASE_TOPIC}/batteryChargeState\",\"val_tpl\":\"{{ value }}\",\"device_class\":\"battery\",\"unit_of_meas\":\"%\",\"ent_cat\":\"diagnostic\"}"
mosquitto_pub ${MQTT_OPTS} -t "${DISCOVERY_TOPIC}/sensor/${DEVICE_NAME}/${DEVICE_NAME}_battery/config" -m "${PAYLOAD}" -r
# Binary sensor for battery charge state
PAYLOAD="{\"uniq_id\":\"${DEVICE_NAME}_battery_charging\",${DEVICE},\"name\":\"${LOCK_NAME} battery charging\",${AVTY},\"stat_t\":\"${BASE_TOPIC}/batteryCharging\",\"val_tpl\":\"{{ value }}\",\"pl_on\":1,\"pl_off\":0,\"device_class\":\"battery_charging\",\"ent_cat\":\"diagnostic\"}"
mosquitto_pub ${MQTT_OPTS} -t "${DISCOVERY_TOPIC}/binary_sensor/${DEVICE_NAME}/${DEVICE_NAME}_battery_charging/config" -m "${PAYLOAD}" -r
# Binary sensor for low battery level
PAYLOAD="{\"uniq_id\":\"${DEVICE_NAME}_battery_critical\",${DEVICE},\"name\":\"${LOCK_NAME} battery critical\",${AVTY},\"stat_t\":\"${BASE_TOPIC}/batteryCritical\",\"val_tpl\":\"{{ value }}\",\"pl_on\":1,\"pl_off\":0,\"device_class\":\"battery\",\"ent_cat\":\"diagnostic\"}"
mosquitto_pub ${MQTT_OPTS} -t "${DISCOVERY_TOPIC}/binary_sensor/${DEVICE_NAME}/${DEVICE_NAME}_battery_critical/config" -m "${PAYLOAD}" -r
# Button for opening, HA Lock entity doesn't seem to show this by itself.
PAYLOAD="{\"uniq_id\":\"${DEVICE_NAME}_open\",${DEVICE},\"name\":\"${LOCK_NAME} open\",${AVTY},\"cmd_t\":\"${BASE_TOPIC}/lockAction\",\"payload_press\":3}"
mosquitto_pub ${MQTT_OPTS} -t "${DISCOVERY_TOPIC}/button/${DEVICE_NAME}/${DEVICE_NAME}_open/config" -m "${PAYLOAD}" -r
@Juergen the 20220928 API doc shows true/false as example states for the boolean type topics, but it appears that they are in reality 1/0.