Skip to content
White Red edited this page Jun 16, 2024 · 1 revision

1. Lock State

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.

1.1 Handling Lock State

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:

  1. 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 for UNLOCK or 1 for LOCK to the MQTT_SET_TARGET_STATE_TOPIC topic
  2. This is where your automation logic come in play, if your result is "yes lock unlocked/locked" we proceed to the next step
  3. 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:

  1. HomeKit has two types of a state, the current one and the target state
  2. You can set the current state on the MQTT_SET_CURRENT_STATE_TOPIC topic
  3. You can set the target state on the MQTT_SET_TARGET_STATE_TOPIC topic
  4. You can set both the current and the target state on the MQTT_SET_STATE_TOPIC topic
  5. You can enable MQTT_HOMEKEY_ALWAYS_UNLOCK or MQTT_HOMEKEY_ALWAYS_LOCK so it always sets and publishes the value of UNLOCK or LOCK respectively on every successful HomeKey authentication.

1.1.1 MQTT Custom States

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:

  1. You can enable custom states by setting MQTT_CUSTOM_STATE_ENABLED to 1
  2. State and Control topics can be set on MQTT_CUSTOM_STATE_TOPIC and MQTT_CUSTOM_STATE_CTRL_TOPIC respectively
  3. On customLockActions you can assign custom values to which the HomeKit states will be translated to and published on the MQTT_CUSTOM_STATE_TOPIC topic
  4. On customLockStates you can assign custom values that are accepted on MQTT_CUSTOM_STATE_CTRL_TOPIC and will be translated to their HomeKit equivalents
  5. You can enable MQTT_HOMEKEY_ALWAYS_UNLOCK or MQTT_HOMEKEY_ALWAYS_LOCK so it always sets and publishes the value of UNLOCK or LOCK respectively according to the custom values set in customLockActions on every successful HomeKey authentication and if neither option is enabled then a flipped state will be published to the MQTT_CUSTOM_STATE_TOPIC according to the custom values set in customLockActions

2. HomeKey Data

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
}
Clone this wiki locally