Skip to content
⚠️ This wiki is versioned — you are currently viewing the docs for the bleeding edge (main), not the latest release.
MQTT

MQTT

Your HomeKey-ESP32’s Secret Language

Welcome to the world of MQTT, where your HomeKey-ESP32 whispers secrets to your smart home! This project uses MQTT (Message Queuing Telemetry Transport) for reporting its status and receiving commands. Think of it as a super-efficient postal service for your smart devices.

1. Understanding Lock States

Your HomeKey-ESP32 manages the lock’s state using a state machine. Here are the states you’ll encounter:

  • UNLOCKED (0)
  • LOCKED (1)
  • JAMMED (2) - Uh oh, something’s stuck!
  • UNKNOWN (3) - The lock’s current state is a mystery.
  • UNLOCKING (4) - The lock is busy opening its heart (or door).
  • LOCKING (5) - The lock is diligently securing things.

The UNLOCKING and LOCKING states are used to indicate that the lock is in the process of changing state. The JAMMED state means the lock encountered an issue during an operation.

Important

Because the project doesn’t actually implement a real lock, we cannot know what the current state should be, which means when the state is UNLOCKING or LOCKING, it is up to you to update the current state to one of the states seen above, see Core MQTT Topics below

2. Core MQTT Topics: The Main Conversation

Your HomeKey-ESP32 communicates its status and listens for commands on these core MQTT topics. Remember, you can customize these topics in the device’s Web Interface Configuration!

TopicDescriptionPayload Examples
<CLIENT_ID>/homekit/statePublishes the current state of the lock. This topic is retained, meaning new subscribers will immediately receive the last known state.0 (UNLOCKED), 1 (LOCKED), 2 (JAMMED), 3 (UNKNOWN), 4 (UNLOCKING), 5 (LOCKING)
<CLIENT_ID>/homekit/set_stateSubscribes to this topic to set both the current and target state of the lock.To unlock: 0 To lock: 1
<CLIENT_ID>/homekit/set_current_stateSubscribes to this topic to set the current state of the lock. Useful for external systems to update the device’s perceived state.0 (UNLOCKED), 1 (LOCKED), 2 (JAMMED), 3 (UNKNOWN)
<CLIENT_ID>/homekit/set_target_stateSubscribes to this topic to set the target state of the lock.To unlock: 0 To lock: 1
<CLIENT_ID>/homekit/set_battery_lvlSubscribes to this topic to set the battery level to be shown in HomeKit. This is used if “Proxy Battery Enabled” is active in the WebUI.85 (for 85% battery)
<CLIENT_ID>/alt_actionPublishes the status of the Alternate Action.1 (sent when the alternate action is triggered)

Note

You will notice all topics set by default are prefixed by the client id, this was done so the topics are nicely organized under a unique identifier, however, you can set the topics to whatever you wish from the WebUI

Example: Manually Locking Your Door via MQTT

Let’s say you want to lock your door using a command-line MQTT client like mosquitto_pub.

mosquitto_pub -h your_mqtt_broker_address -p 1883 -t homekit/set_state -m "1"

(Replace your_mqtt_broker_address with your actual broker’s IP or hostname.)

Example: Subscribing to Lock State Updates

To see your lock’s current state in real-time:

mosquitto_sub -h your_mqtt_broker_address -p 1883 -t homekit/state

2.1. MQTT Connection Status

The MQTT connection status is available internally and displayed in the WebUI. It is not published to an MQTT topic. The status includes:

  • connected: Whether the MQTT client is currently connected to the broker
  • errorCode: The last error code that occurred
  • errorMessage: Human-readable error message

Error Codes:

CodeNameDescription
0NONENo error, connection successful or active
1CONNECTION_REFUSEDBroker refused the connection
2AUTH_FAILEDAuthentication failed (bad username/password)
3NETWORK_ERRORNetwork connectivity issue
4SSL_ERRORTLS/SSL handshake or certificate error
5TIMEOUTConnection or operation timed out
255UNKNOWNUnknown error occurred

To monitor MQTT connection health programmatically, check the WebSocket interface or use the MqttManager::getLastErrorCode() and MqttManager::getLastErrorMessage() methods if building custom firmware.

3. Custom States: Speaking Your Lock’s Dialect

The project supports custom states, allowing you to map the lock’s internal states to values that might be more familiar to your specific MQTT-based lock or system. This is super handy for seamless integration!

  • <CLIENT_ID>/homekit/custom_state: Publishes the custom lock action. When custom states are enabled, this topic receives an update whenever the lock reaches a final state — it publishes the configured Unlock action value when the target state becomes UNLOCKED, and the configured Lock action value when the target state becomes LOCKED (e.g., after a HomeKey tap, Home app control, or MQTT command). Transitional states (UNLOCKING/LOCKING) are not published to this topic.
  • <CLIENT_ID>/homekit/set_custom_state: Subscribes to this topic to set the custom lock state. Accepts the configured numeric values for Unlocking, Locking, Unlocked, Locked, Jammed, and Unknown.

You can enable and configure custom states, including defining your own custom lock actions and states, in the Web Interface Configuration under the “Custom Lock States & Actions” section.

4. NFC Data: Who Just Tapped? 🕵️‍♀️

When a HomeKey is used to authenticate, or a generic NFC tag is scanned, the device publishes data to the <CLIENT_ID>/homekey/auth topic in a neat JSON format.

4.1. HomeKey Authentication Data

If a HomeKey is used:

{
  "endpointId": "000000000000",
  "homekey": true,
  "issuerId": "0000000000000000",
  "readerId": "0000000000000000"
}
  • endpointId: A unique identifier for the Apple device (iPhone, Apple Watch) that was used to authenticate.
  • issuerId: A unique identifier for the Apple ID of the user who authenticated.
  • readerId: The unique identifier of the HomeKey reader that processed the authentication.

4.2. Generic NFC Tag Data

If a generic NFC tag (not a HomeKey) is scanned:

{
  "atqa": "0004",
  "homekey": false,
  "sak": "08",
  "uid": "00000000",
  "readerId": "A1B2C3D4E5F6"
}
  • atqa: The ATQA of the NFC tag.
  • sak: The SAK of the NFC tag.
  • uid: The UID of the NFC tag.
  • readerId: The HomeKey reader’s accessory ID (a 12-character hex string, unique per device and persisted in NVS).

5. Home Assistant Integration: Making Friends with Your Hub

This project plays nicely with Home Assistant, allowing you to manage your lock and unleash the power of NFC tags!

5.1. Automatic Discovery - Magic! 🔮

Home Assistant has a feature called MQTT Discovery used to automatically configure a component.

If HASS MQTT Discovery is enabled in your device’s MQTT Configuration, the project will automatically publish the necessary configuration for Home Assistant to discover and control the lock. No manual YAML configuration needed – Home Assistant will just find it!

  • Important: MQTT Discovery is enabled by default. You can disable it in the device’s WebUI configuration if you don’t want the entities to be auto-discovered.
  • The following entities are published:
    • A Lock entity for controlling the lock.
    • A HomeKey Issuer tag (triggered by the issuerId in the auth payload).
    • A HomeKey Endpoint tag (triggered by the endpointId in the auth payload).
    • An NFC Tag entity (triggered by the uid in the auth payload), published only when generic NFC tag publishing is not disabled.
  • The lock’s online/offline status is published to <MQTT_CLIENTID>/status via MQTT Last Will and Testament (LWT). This helps Home Assistant know if your device is alive and kicking.

5.2. Lock Control

Once discovered, you can control your lock directly from Home Assistant’s UI, just like any other lock entity.

Note

In order to simplify things, interacting with the lock entity within Home Assistant will override the internal state of HomeKey-ESP32 through the set_state MQTT Topic.

You can control the current and target state separately through their respective MQTT Topics.

5.3. NFC Tag Integration: Automate All the Things!

This is where the real fun begins! Your HomeKey-ESP32 can integrate with Home Assistant’s powerful Tag functionality, letting you trigger automations by simply scanning an NFC tag.

  • To find tags: Navigate to the ‘Tags’ section in your Home Assistant instance (usually under Settings -> Devices & Services -> Tags).

Note

When tapping a HomeKey, two Tags will appear here. This is because HomeKey carries two IDs:

  • Issuer ID (16 characters) - A unique identifier for the Apple ID of the user who authenticated.
  • Endpoint ID (12 characters) - A unique identifier for the Apple device (iPhone, Apple Watch) that was used to authenticate.
  • Prerequisites: Ensure your Home Assistant MQTT integration is configured with the same broker as the ESP32, and the discovery prefix is the default homeassistant.
  • Creating Automations: Once a tag is discovered in Home Assistant, you can name it and create custom automations based on its scan. For example, scan a tag to:
    • Unlock the door.
    • Turn on lights.
    • Disarm your alarm system.
    • Brew coffee (if you have a smart coffee maker, of course!).

Example Home Assistant Automation (Conceptual):

Let’s imagine you want to turn on a light when a specific NFC tag is scanned.

automation:
  - alias: "NFC Tag Scanned - Turn on Living Room Light"
    trigger:
      platform: event
      event_type: tag_scanned
      event_data:
        tag_id: "your_nfc_tag_uid_here" # Replace with the UID of your NFC tag
    action:
      - service: light.turn_on
        target:
          entity_id: light.living_room_light

(You’ll find the tag_id in Home Assistant’s ‘Tags’ section after scanning your tag with the HomeKey-ESP32.)


By leveraging MQTT, your HomeKey-ESP32 becomes a powerful component in your smart home ecosystem, enabling seamless communication and automation!

Last updated on