First boot
Flash the firmware
Section titled “Flash the firmware”HeatSync builds with arduino-cli and the standard ESP32 core.
git clone https://github.com/dr-harper/heatsync.gitcd heatsync./build.sh upload # auto-detects the USB serial portThe first build pulls in the ESP32 platform, NimBLE (still linked
optionally — see HEATSYNC_BLE_ENABLED in config.h), and PubSubClient.
It takes a couple of minutes the first time and seconds after that.
After the upload, the LED does a 3-blink boot flash and then settles on amber — that’s WiFi config mode.
Connect to the captive portal
Section titled “Connect to the captive portal”Look for a WiFi network called HeatSync-Setup on your phone.
- Password:
heatsync - Once connected your phone should pop up the captive portal automatically.
If it doesn’t, open
http://192.168.4.1.
The portal scans for nearby WiFi networks. Pick yours, enter the password, save. The Atom restarts and joins your network.
Open the dashboard
Section titled “Open the dashboard”When it comes back online, two things happen:
- The LED turns green (or cyan if MQTT is already configured).
- The device announces itself on mDNS as
heatsync.local.
On a Mac: http://heatsync.local should just work. On Android: it
should work too (Chrome on Android 12+ resolves .local via the
system mDNS responder), but if the page hangs, use the device’s IP
directly — your router admin page or arp -a on your laptop will show
it. Bookmark the IP to skip the lookup next time.
Default password for the web UI is heatsync — change it on
Settings → Device → Web access after first sign-in.
Wire up Home Assistant
Section titled “Wire up Home Assistant”Two paths — pick one. Full comparison and entity list on the Home Assistant integration page.
Path A — HACS integration (no broker required):
- Generate an API token: HeatSync’s Settings → Home Assistant → API token → Generate. Copy it.
- In HACS: Integrations → ⋯ → Custom repositories, add
https://github.com/dr-harper/heatsync-haas type Integration, download, restart HA. - Settings → Devices & Services → Add Integration → HeatSync. Paste the token (host auto-discovered via mDNS).
Path B — MQTT auto-discovery (broker required):
- Open HeatSync’s Settings → Home Assistant.
- Fill in MQTT broker host (the HA box if you’re using the Mosquitto add-on) + port (1883) + credentials.
- Leave “HA discovery prefix” as
homeassistant. Toggle “HA discovery” on. Save.
Either way, within ~10 seconds Home Assistant has a HeatSync device with ~50 entities — climate, water heater, lifetime energy, fault sensor, plus today’s running cost/carbon/energy, learned COP, and per-mode kWh splits.
Enable bus writes (when you’re ready)
Section titled “Enable bus writes (when you’re ready)”Reads are always-on, writes are opt-in. If you only want monitoring, stop here.
If you want to control the unit (DHW target, mode, water-law offset, schedule), toggle “Allow bus writes” on Settings → Device → Bus & sensors. The web UI controls and Home Assistant command topics become live within a few seconds.
The hot-water schedule — Tariff / Carbon / Efficiency / Combo modes,
cylinder learning, Octopus auto-detect — lives on /hot-water or on
the Settings → Energy page. See
Smart hot water.
OTA updates
Section titled “OTA updates”Once HeatSync is on the network you don’t need to plug in the USB cable again for updates. The on-device updater (Settings → Maintenance → Firmware) pulls the latest release on demand.
For developers building from source:
./build.sh ota-http # TCP /update upload (recommended)HOST=192.168.1.121 ./build.sh ota-http # or by IPota-http goes over the device’s normal /update endpoint and works
on every network it’s been tested on, including Tailscale and phone
hotspots. The legacy ./build.sh ota (espota / UDP 3232) is faster
on a quiet LAN but loses packets reliably across NAT — keep it for
local-only use.