-
-
Notifications
You must be signed in to change notification settings - Fork 27
MQTT
The project is exclusively using MQTT for updating state and publishing authentication data.
This also means that you might see the Lock in the Home app "stuck in a loop" if you don't have automations setup to ingest the MQTT data and handle the update of the state.
Whenever a HomeKey would get authenticated, a.k.a tap the phone and get a check mark, data that identifies that device would be published to the MQTT_AUTH_TOPIC
(see HomeKey data format below). Additionally if you enabled MQTT_CUSTOM_STATE_ENABLED
and defined its topics(MQTT_CUSTOM_STATE_TOPIC
and MQTT_CUSTOM_STATE_CTRL_TOPIC
), it will also publish the toggled state according to how customLockStates
was assigned.
If you enabled MQTT_HOMEKEY_ALWAYS_UNLOCK
or MQTT_HOMEKEY_ALWAYS_LOCK
then it will always send the UNLOCK
or LOCK
state as assigned on customLockActions
.
See below for more info about the lock state and custom states.
Whenever the lock state would be changed, either through MQTT or the Home App, the value would then be published on the MQTT_STATE_TOPIC
topic and if MQTT_CUSTOM_STATE_ENABLED
is enabled also on the MQTT_CUSTOM_STATE_TOPIC
topic according to its assignments, more on that below. Note that the topic MQTT_STATE_TOPIC
is marked as retained.
Below you can find all the values that can be expected on the MQTT_STATE_TOPIC
topic:
- UNLOCKED = 0
- LOCKED = 1
- JAMMED = 2
- UNKNOWN = 3
- UNLOCKING = 4
- LOCKING = 5
The state UNLOCKING
(4) and LOCKING
(5) is only used on the context of the MQTT_STATE_TOPIC
topic and is being published whenever the target state is set to either of the two possible values(UNLOCK
(0) or LOCK
(1)) accordingly.
HAP implements a target state architecture, updating the state of a HomeKit entity is achieved as follows:
- Setting the target state, which is the desired state of the lock and what gives it an "Unlocking" or "Locking" UI cue in the Home app, this occurs when you interact with the lock in the Home App or you can set it manually by publishing the value
0
forUNLOCK
or1
forLOCK
to theMQTT_SET_TARGET_STATE_TOPIC
topic - This is where your automation logic come in play, if your result is "yes lock unlocked/locked" we proceed to the next step
- Setting the current state, which would be the state that the lock is actually in right now and can only be set by publishing any of the following values to the
MQTT_SET_CURRENT_STATE_TOPIC
topic:
- 0 -
UNLOCK
- 1 -
LOCK
- 2 -
JAMMED
- 3 -
UNKNOWN
Alternatively to setting the current and target states separately, you can also set them all at once by publishing the value 0
for UNLOCK
or 1
for LOCK
to the MQTT_SET_STATE_TOPIC
topic. You might have noticed i didn't mentioned the other two states from above and that is because you cannot have a target state JAMMED
or UNKNOWN
as that is not a valid value per HAP spec and also who wants their lock to be JAMMED
🤨.
If you have MQTT_HOMEKEY_ALWAYS_UNLOCK
or MQTT_HOMEKEY_ALWAYS_LOCK
enabled then upon a succesful HomeKey authentication, the lock state will be set accordingly and published to MQTT_STATE_TOPIC
, however, if neither of those options are enabled then the state will remain as it is and nothing will be published to MQTT_STATE_TOPIC
, only the MQTT_AUTH_TOPIC
topic will receive data.
Quick recap:
- HomeKit has two types of a state, the current one and the target state
- You can set the current state on the
MQTT_SET_CURRENT_STATE_TOPIC
topic - You can set the target state on the
MQTT_SET_TARGET_STATE_TOPIC
topic - You can set both the current and the target state on the
MQTT_SET_STATE_TOPIC
topic - You can enable
MQTT_HOMEKEY_ALWAYS_UNLOCK
orMQTT_HOMEKEY_ALWAYS_LOCK
so it always sets and publishes the value ofUNLOCK
orLOCK
respectively on every successful HomeKey authentication.
In addition to the above, as mentioned in the introduction you can also enable MQTT_CUSTOM_STATE_ENABLED
which allows you to assign additional topics for setting the internal state(MQTT_CUSTOM_STATE_CTRL_TOPIC
) and publishing the state(MQTT_CUSTOM_STATE_TOPIC
) that accept custom values as assigned in customLockStates
and customLockActions
respectively, this can be useful if you have a lock with an MQTT API and want to leverage this to interact directly with the lock and often has different values than HAP for all its states.
If you have MQTT_HOMEKEY_ALWAYS_UNLOCK
or MQTT_HOMEKEY_ALWAYS_LOCK
enabled then upon a succesful HomeKey authentication, the lock state will be set accordingly and published to the MQTT_CUSTOM_STATE_TOPIC
topic according to the values set in customLockActions
, however, contrary to the MQTT_STATE_TOPIC
topic, when MQTT_CUSTOM_STATE_ENABLED
is enabled and if neither of the two "always" options are enabled then the flipped state is published to MQTT_CUSTOM_STATE_TOPIC
in addition of the homekey data to the MQTT_AUTH_TOPIC
topic.
Important to mention that upon a succesful HomeKey authentication, the HomeKit state is automatically updated only if you have MQTT_HOMEKEY_ALWAYS_UNLOCK
or MQTT_HOMEKEY_ALWAYS_LOCK
enabled, otherwise it needs to be done through the appropriate topics(e.g. MQTT_CUSTOM_STATE_CTRL_TOPIC
).
Quick recap:
- You can enable custom states by setting
MQTT_CUSTOM_STATE_ENABLED
to1
- State and Control topics can be set on
MQTT_CUSTOM_STATE_TOPIC
andMQTT_CUSTOM_STATE_CTRL_TOPIC
respectively - On
customLockActions
you can assign custom values to which the HomeKit states will be translated to and published on theMQTT_CUSTOM_STATE_TOPIC
topic - On
customLockStates
you can assign custom values that are accepted onMQTT_CUSTOM_STATE_CTRL_TOPIC
and will be translated to their HomeKit equivalents - You can enable
MQTT_HOMEKEY_ALWAYS_UNLOCK
orMQTT_HOMEKEY_ALWAYS_LOCK
so it always sets and publishes the value ofUNLOCK
orLOCK
respectively according to the custom values set incustomLockActions
on every successful HomeKey authentication and if neither option is enabled then a flipped state will be published to theMQTT_CUSTOM_STATE_TOPIC
according to the custom values set incustomLockActions
HomeKey Authentication data is published to the MQTT_AUTH_TOPIC
topic upon a successful(checkmark) HomeKey transaction in JSON format with the following data structure:
{
"endpointId": "000000000000", # This is unique per device
"homekey": true,
"issuerId": "0000000000000000" # This is unique per Apple ID
}
If you wish to just only grant access to the lock only to some persons or only to some devices, you can check the endpointId
or issuerId
against your list of allowed devices/persons.
If any other NFC Target is detected(e.g. MiFare Classic Card), data will be published in JSON format to the same MQTT_AUTH_TOPIC
topic with the homekey
field will be set to false
and will have the following data structure:
{
"atqa": "0004",
"homekey": false,
"sak": "08",
"uid": "00000000" # This is the ID of the NFC Tag
}