Reverse-engineering and Home Assistant integration for QuietCool Smart Attic Fans (AFR/AFG SMT PRO-2.0, controller model IT-AF-SMT) over Bluetooth Low Energy — monitor-only, no firmware flashing.
The goal: read attic temperature and humidity off the fan's stock BLE controller and publish them into Home Assistant, without opening the unit, without an FTDI programmer, and while leaving the factory firmware (and the QuietCool app) intact.
The community-documented path to get this fan into Home Assistant is to open the controller, attach an FTDI adapter, and flash ESPHome — which permanently replaces the firmware and kills the phone app. That's great for control, overkill for monitoring.
This project takes the non-destructive route: the controller is an ESP32-WROOM-32 that exposes a JSON-over-BLE serial channel. We talk to it directly.
| Milestone | State |
|---|---|
| Detect the fan over BLE | ✅ done |
| Confirm identity (model string in adv. data) | ✅ done — FR SMT PRO-2.0 |
| Map GATT services / find data channel | ✅ done — char ff01 |
| Decode response framing | ✅ done — QQ magic + JSON |
Enumerate the {"A":N} command set |
✅ done — see PROTOCOL.md |
Pass the Login auth gate |
✅ done — PhoneID = iOS identifierForVendor UUID |
| Read live temp/humidity | ✅ working — tools/monitor.py |
| Home Assistant integration | ✅ deployed & working — custom_components/quietcool_ble (HACS); running in a real HA, entities live |
$ python tools/monitor.py <PhoneID>
<== login: Success
<== ATTIC temp=104.2°F humidity=22% speed=HIGH mode=TH status=OK
...
Two things made this work, both the opposite of first guesses:
- The
PhoneIDis the iOSidentifierForVendorUUID, not a phone number — recovered from a PacketLogger capture of the app (see docs/CAPTURE.md). - The fan isn't push-based and disconnects an idle client (~2 s). You hold the connection
and read data by polling
{"A":1}every ~2 s, exactly like the app. Full command set and telemetry schema in docs/PROTOCOL.md.
- iPhone: install Apple's Bluetooth logging profile (developer.apple.com/bug-reporting/profiles-and-logs).
- Mac: install PacketLogger (from "Additional Tools for Xcode").
- Near the fan: iPhone→Mac over USB, start PacketLogger, open the QuietCool app and let it
connect, stop the capture, save the
.pklg. python tools/decode_capture.py capture.pklg→ prints the recoveredPhoneID.python tools/monitor.py <PhoneID>→ logs in (R:"Success") and streams live temp/humidity.
HCI captures decrypt above the BLE link layer, so the Login JSON appears in plaintext.
All scripts use bleak. Install with pip install -r requirements.txt
(or a venv). The target device address defaults to the value in tools/config.py — override
with QUIETCOOL_MAC.
| Script | What it does |
|---|---|
tools/scan.py |
Scan for the fan, print address + advertised manufacturer data |
tools/probe.py |
Connect, subscribe to ff01, run a handshake sequence, dump replies |
tools/login_probe.py |
Try candidate PhoneID formats (or your recovered one) against the login gate |
tools/decode_capture.py |
Pull the real PhoneID out of a Bluetooth capture (plaintext scan) |
tools/parse_pklg.py |
Full PacketLogger .pklg parse — ordered ff01 conversation with direction + timing |
tools/monitor.py |
Log in and stream live temp/humidity (polls {"A":1}) |
python tools/scan.py # find it
python tools/probe.py # connect + talk to itFull walkthrough: docs/CAPTURE.md — find the fan, recover the PhoneID
(iOS+Mac, iOS-only, or Android routes), decode the capture, log in, and read temp/humidity.
Home Assistant: docs/HOME_ASSISTANT.md — install the
quietcool_ble HACS integration for temp/humidity entities, configurable polled/persistent
modes, a Refresh button, and transparent Bluetooth-proxy support for attic range.
- Controller: QuietCool IT-AF-SMT, an ESP32-WROOM-32.
- Transport: BLE, advertised name
ATTICFAN_<macsuffix>. - Because the fan sits in the attic, RSSI at a floor below is ~−75 to −82 dBm — connectable but marginal. If the HA host can't hold it reliably, add an ESPHome Bluetooth proxy (a cheap ESP32) near the attic; HA routes through it automatically (see docs/HOME_ASSISTANT.md).
MIT — see LICENSE.