Home Key Go on Home Assistant OS
Local installation (no published image required)
After adding these files to the root of the homekey-go source repository:
sh scripts/stage-ha-app.sh
Copy the resulting dist/homekey_go directory into HA OS's /addons directory,
using the Samba addons share or an SSH app. The result must be
/addons/homekey_go/config.yaml, alongside its Dockerfile and source directories.
In HA, open Settings > Apps > App store, select Check for updates from the
three-dot menu, then install Home Key Go under Local apps.
On older HA versions the UI calls these Add-ons.
Enable Start on boot, start the app, and open Logs. Use the pairing code printed by the Go service in Apple Home > Add Accessory > More Options > Go Home Key. The container image build downloads Go dependencies, including the patched HAP fork specified by go.mod. Internet access is needed during the initial build.
Configuration
name: Go Home Key
serial: GO-HOMEKEY-001
port: 51826
interface: ""
finish: silver
pin: ""
name: accessory name shown in Apple Home.serial: stable accessory serial; keep it unchanged after pairing.port: HAP TCP port on the HA OS host. Change it if 51826 is occupied.interface: HA OS LAN interface, e.g.end0orenp3s0; empty selects eligible interfaces. Use the actual HA host interface name.finish:silver,black,gold, ortanWallet artwork.pin: empty generates and saves a random PIN, then reuses it on later starts. An explicit PIN must have eight digits (hyphens are accepted by the CLI); prohibited HomeKit PIN patterns are rejected by the service.
Save configuration changes and restart the app.
The app uses host networking for HomeKit mDNS and binds HAP to :<port>.
Your phone must be able to reach the HA host and receive its mDNS advertisements.
Persistent state and moving an existing pairing
The service is started with -state /data/state. HomeKit identity, paired
controllers, Home Key credentials, and the generated PIN are stored together
in /data/state/state.json. This is the app's persistent data volume, not the
HA configuration directory. App backups use cold mode so the service is stopped
while its state is backed up.
For a first installation you can pair a fresh accessory. To preserve an existing
pairing from your Mac, stop the Mac service and the HA app, then copy the entire
existing state directory into the app's /data/state through a method with
access to that app's data volume. The ordinary /addons source folder and HA
/config directory are NOT that volume. Keep the same name, serial, and explicit
PIN, if one was configured. Run only one instance with that identity.
Do not delete state or uninstall the app as an update procedure: losing the state means losing its pairing identity and credentials. Keep an app backup.
Building a container outside HA
From the source repository root:
docker build -t homekey-go:0.0.1 .
On a Linux Docker host, run it with a persistent volume and host networking:
docker run --rm --network host -v homekey-state:/data homekey-go:0.0.1
Without /data/options.json, the CLI uses its default accessory settings with
state fixed to /data/state. Explicit container arguments are passed directly
to the CLI, so include -state /data/state when supplying custom arguments:
docker run --rm --network host -v homekey-state:/data homekey-go:0.0.1 \
-state /data/state -name 'Go Home Key' -addr :51827
Docker Desktop on macOS is not equivalent to a Linux HA OS host for LAN mDNS. Use HA OS for the actual discovery and pairing test.
Publishing and repository installation
ha-app/config.yaml is set up to pull ghcr.io/tgckpg/homekey-go:0.0.1.
That image has NOT been published by this packaging work. If you use another
registry/namespace, edit its image field. Build and push both supported
architectures before attempting repository installation:
docker login ghcr.io
docker buildx build --platform linux/amd64,linux/arm64 \
--build-arg BUILD_ARCH='aarch64|amd64' \
--build-arg BUILD_VERSION=0.0.1 \
-t ghcr.io/tgckpg/homekey-go:0.0.1 --push .
Make the package public if HA will pull it without registry credentials.
Commit the packaging files to a cloneable Git repository, then add its Git URL
under App store > Repositories. Use the real Git repository endpoint, not the
static sgit HTML tree URL. Supervisor pulls the image using config.yaml.
The root repository.yaml declares this repository; ha-app contains the app.
Once the image is published, those metadata files can instead live in your
separate HA app repository; the root Dockerfile and Go source stay here.
For releases, update the app version in config.yaml and CHANGELOG.md, build and publish the matching image tag, then commit the metadata. Preserve the app slug and repository identity to keep existing installs on their update path.
Current functionality
This packages the existing provisioning service unchanged. The HAP listener supports Apple Home pairing and Home Key provisioning; lock toggles are still simulated. No reader API, MQTT connection, Home Assistant entity integration, or ESP32/PN532 authentication transport is added by these files.
Initial BLE PING/PONG transport
Copy the files under homekey-go/ and homekey-relay/ into their corresponding
repositories. This bundle contains changed/new files only, plus unified patches.
Do not replace the whole repositories with these directories.
ESP32
Build and flash as before:
cd homekey-relay/esp32
idf.py set-target esp32c3
idf.py build
idf.py -p /dev/cu.usbmodem101 flash monitor
Copy BLE address AA:BB:CC:DD:EE:FF from the serial log.
The reader now continuously advertises a connectable GATT service until connected.
PN532 polling continues unchanged. The previous non-connectable UID broadcasts
are replaced; the old HACS UID sensor will no longer receive those events.
Card events are logged locally; forwarding them is a subsequent step.
Go / HA app
Publish the rebuilt image as ghcr.io/tgckpg/homekey-go:0.0.2 and update the app,
or use sh scripts/stage-ha-app.sh for a local build as before.
The app config enables host_dbus: true; no raw USB access is needed.
Keep the existing HomeKit options and add:
ble_reader: "AA:BB:CC:DD:EE:FF"
ble_adapter: "hci0"
Restart the app. Expected Go log:
BLE gateway: connected to AA:BB:CC:DD:EE:FF
BLE PONG reader=AA:BB:CC:DD:EE:FF seq=1 round_trip=...
Expected ESP32 log:
BLE gateway connected
BLE PING received; PONG ready
Empty ble_reader disables the probe. It sends every 10 seconds; failures retry
in 5 seconds without taking down HAP. The BlueZ adapter must be powered and
recognized by HA OS. If logs show D-Bus/AppArmor access denied, inspect the host
denial before changing permissions. This backend does not use ESPHome proxies.
Standalone Linux:
go run ./cmd/homekey -ble-reader AA:BB:CC:DD:EE:FF -ble-adapter hci0
Optional -ble-ping-interval 10s, minimum 1 second.
Protocol v0
Service UUID: 7a6b0001-5b21-4f36-8e5d-9c3a26d74210 Read/write characteristic: 7a6b0002-5b21-4f36-8e5d-9c3a26d74210 Write with response: 8 bytes = ASCII PING + uint32 sequence, big endian. Read: 8 bytes = ASCII PONG + matching sequence; empty before first PING. All messages fit the default ATT MTU. The ESP32 prepares PONG in the write callback. The Go client verifies the sequence and records write-plus-read elapsed time. No notifications, pairing, bonding, NFC authentication, or unlocking in this probe. Only one gateway should connect to the reader at a time.
Validation
Go tests, vet, Linux build, and shell syntax checked in the build environment. ESP-IDF compilation and end-to-end radio testing require your ESP-IDF toolchain and hardware and have not been performed here.