Local-first HVAC control for high-end residential integrations: Mitsubishi
mini-splits via ProtoART ClimateControl (ME_CN105_ATA_WIFI) Wi-Fi modules —
no cloud, no Kumo, native Savant thermostat tiles. This is the working code
behind Part 2 of the
Local-First Control for Mitsubishi Minisplit
blog series.
Part 1 chose the hardware (ProtoART over Kumo Cloud / Airzone). Part 2 — this repo — gets it talking locally and wires it into Savant as native thermostats, with adapters so you can use it without Savant too.
The four estate heads are live: read + two-way control on the LAN, and three of
four show as native °F thermostat tiles in Savant (the fourth is offline on
a weak Wi-Fi link — see below). The CoolMasterNet bridge runs as a launchd
service on the Mac mini. Two-way control is verified end-to-end by
tests/cc_selftest.py, which proves each command persists through a poll cycle
and Savant's status refresh (62/62 checks green) — see
docs/SAVANT-INTEGRATION.md.
src/climatecontrol/ Python client + `cc` CLI for the /control HTTP API
bridge/ CoolMasterNet->ProtoART bridge (the Savant adapter)
deploy/ launchd plist for the bridge (read-only/-control, scale)
docs/API.md reverse-engineered ProtoART HTTP API reference
docs/SAVANT-INTEGRATION.md how the Savant native-thermostat path works
blog/ the Part 2 draft (review-gated; not auto-published)
tests/ hermetic tests (test_*.py) + cc_selftest.py (live E2E)
units.yaml the unit inventory
Core library + CLI + bridge are standard-library only. Optional extras:
zeroconf (nicer discovery), paho-mqtt (MQTT transport).
A dev venv with a cc console script (the repo is pip install -e-able):
python3 -m venv .venv && .venv/bin/pip install -e .
cc discover # mDNS scan for units
cc status # one-line status per unit (native °F)
cc get PrimarySuite-HVAC # full /control JSON for one unit
cc monitor # live table; what Savant sees, in °F (or --unit C)
cc set GreatRoom-HVAC --mode cool --temp 72 # DRY-RUN by default
cc set GreatRoom-HVAC --mode cool --temp 72 --apply # actually send
No venv needed to run ad hoc — PYTHONPATH=src python3 -m climatecontrol.cli …
works too. As a library:
from climatecontrol import ClimateControl
cc = ClimateControl("192.168.20.41")
print(cc.heatpump().line())
cc.set(mode="cool", set_temperature=72, fan="high", dry_run=True)
| Friendly name | IP | UID | Savant zone | State |
|---|---|---|---|---|
| GreatRoom-HVAC | 192.168.20.41 | L1.100 | Great Room | ✅ live |
| GuestSuite-HVAC | 192.168.20.42 | L1.101 | Guest Suite | ✅ live |
| PrimarySuite-HVAC | 192.168.20.43 | L1.102 | Primary Suite | ✅ live |
| PoolHouse-HVAC | 192.168.20.40 | L1.103 | Pool House | ⚠️ offline (weak RF) |
All four: ME_CN105_ATA_WIFI, firmware 3.4.1, Fahrenheit. The Savant zone
labels differ from the device names by design (Savant maps UID→zone its side).
Savant is one option, not the point:
cc CLI — works the moment the modules are on your network.bridge/) — emulates a CoolAutomation CoolMasterNet
so Savant (or anything that speaks CoolMasterNet) renders the heads as native
thermostats. See docs/SAVANT-INTEGRATION.md.These talk to real heat pumps in an occupied house:
cc set is dry-run unless --apply.--allow-control.MIT — see LICENSE.
1 commits
Python
100.0%
Local-first HVAC control for high-end residential integrations: Mitsubishi
mini-splits via ProtoART ClimateControl (ME_CN105_ATA_WIFI) Wi-Fi modules —
no cloud, no Kumo, native Savant thermostat tiles. This is the working code
behind Part 2 of the
Local-First Control for Mitsubishi Minisplit
blog series.
Part 1 chose the hardware (ProtoART over Kumo Cloud / Airzone). Part 2 — this repo — gets it talking locally and wires it into Savant as native thermostats, with adapters so you can use it without Savant too.
The four estate heads are live: read + two-way control on the LAN, and three of
four show as native °F thermostat tiles in Savant (the fourth is offline on
a weak Wi-Fi link — see below). The CoolMasterNet bridge runs as a launchd
service on the Mac mini. Two-way control is verified end-to-end by
tests/cc_selftest.py, which proves each command persists through a poll cycle
and Savant's status refresh (62/62 checks green) — see
docs/SAVANT-INTEGRATION.md.
src/climatecontrol/ Python client + `cc` CLI for the /control HTTP API
bridge/ CoolMasterNet->ProtoART bridge (the Savant adapter)
deploy/ launchd plist for the bridge (read-only/-control, scale)
docs/API.md reverse-engineered ProtoART HTTP API reference
docs/SAVANT-INTEGRATION.md how the Savant native-thermostat path works
blog/ the Part 2 draft (review-gated; not auto-published)
tests/ hermetic tests (test_*.py) + cc_selftest.py (live E2E)
units.yaml the unit inventory
Core library + CLI + bridge are standard-library only. Optional extras:
zeroconf (nicer discovery), paho-mqtt (MQTT transport).
A dev venv with a cc console script (the repo is pip install -e-able):
python3 -m venv .venv && .venv/bin/pip install -e .
cc discover # mDNS scan for units
cc status # one-line status per unit (native °F)
cc get PrimarySuite-HVAC # full /control JSON for one unit
cc monitor # live table; what Savant sees, in °F (or --unit C)
cc set GreatRoom-HVAC --mode cool --temp 72 # DRY-RUN by default
cc set GreatRoom-HVAC --mode cool --temp 72 --apply # actually send
No venv needed to run ad hoc — PYTHONPATH=src python3 -m climatecontrol.cli …
works too. As a library:
from climatecontrol import ClimateControl
cc = ClimateControl("192.168.20.41")
print(cc.heatpump().line())
cc.set(mode="cool", set_temperature=72, fan="high", dry_run=True)
| Friendly name | IP | UID | Savant zone | State |
|---|---|---|---|---|
| GreatRoom-HVAC | 192.168.20.41 | L1.100 | Great Room | ✅ live |
| GuestSuite-HVAC | 192.168.20.42 | L1.101 | Guest Suite | ✅ live |
| PrimarySuite-HVAC | 192.168.20.43 | L1.102 | Primary Suite | ✅ live |
| PoolHouse-HVAC | 192.168.20.40 | L1.103 | Pool House | ⚠️ offline (weak RF) |
All four: ME_CN105_ATA_WIFI, firmware 3.4.1, Fahrenheit. The Savant zone
labels differ from the device names by design (Savant maps UID→zone its side).
Savant is one option, not the point:
cc CLI — works the moment the modules are on your network.bridge/) — emulates a CoolAutomation CoolMasterNet
so Savant (or anything that speaks CoolMasterNet) renders the heads as native
thermostats. See docs/SAVANT-INTEGRATION.md.These talk to real heat pumps in an occupied house:
cc set is dry-run unless --apply.--allow-control.MIT — see LICENSE.
1 commits
Python
100.0%