A self-hosted, open smart-home project — developed in the open, running in a real home.
🇮🇹 Italiano · 🇬🇧 English
Self-hosted smart home for Panasonic air conditioners. No vendor cloud dashboards, no subscriptions — control your ACs by temperature, humidity, season and presence, plus IKEA lights, all from one Raspberry Pi.
A self-hosted home climate automation system that automatically controls Panasonic air conditioners based on temperature, humidity, season and presence, with an iOS-style web dashboard and IKEA light control.
Designed to run 24/7 on a Raspberry Pi, with no third-party cloud beyond the manufacturers' own, and no proprietary apps.
mmWave radar nodes ────┐ per-room presence + temp/humidity
IKEA / BME280 sensors ─┤
Panasonic AC state ────┤
Open-Meteo forecast ───┼─► Rule Engine ──► commands the ACs (Cool/Heat/Dry…)
FRITZ!Box presence ────┤ │
│ └─► MPC advisor (predict + recommend, advisory)
└──────────► Web dashboard (React) ◄── energy / health
IKEA Dirigera lights ──────────────► on/off + dimmer
Sonoff boiler relay ───────────────► local on/off (no cloud)
⚠️ Born as a personal project and running 24/7 in a real home — now developed in the open as a followed public project. It depends on specific hardware (see Requirements). Community-supported, with optional commercial support available.
Most "smart" climate control means a vendor app, a cloud account, a subscription, and your home's data on someone else's servers. Climate Pi is the opposite:
- Yours, end to end. One Raspberry Pi runs everything. No vendor dashboards, no subscriptions, no data leaving your home beyond the manufacturers' own APIs.
- Real comfort logic, not a timer. Decisions come from temperature, humidity, season and presence — with hysteresis, dehumidification and a night window — not from a schedule you have to babysit.
- It respects you. Grab the remote and the system notices and backs off. A network glitch never takes your comfort away (it fails safe to "home occupied").
- Transparent. Every decision is logged in plain language ("Cooling to 22°"). You can always see why it did what it did.
- Real, not a demo. It controls an actual home, every day.
If you want a home that runs itself on your terms, Climate Pi is built for you.
Home overview — comfort gauge, outdoor weather, the MPC's live read (Home Engine), energy, plant health, alerts and recent events.
Per-room page — thermostat with a live real-temperature gauge, environment, system health, quick actions and the day's runtime/consumption/cost.
- Comfort-band model: keeps the temperature within a band around a target, switching the AC on/off with hysteresis (no rapid cycling). Thresholds calibrated on real consumption history.
- Season awareness: the season is decided by the moving average of the outdoor temperature (read from the ACs), so heating never kicks in during summer and vice versa — with a safety override for extreme conditions.
- Automatic dehumidification: switches to Dry mode when humidity rises above a threshold (low power, better comfort).
- Forced off + night window: ACs stay off during a configurable time window (e.g. 03:00–08:00), even when it's hot.
- Per-room mmWave radar: each room can have a small ESP32 + LD2410 radar node that reports presence over MQTT. An anti-flicker grace keeps a room "occupied" for a short hold after the last detection (so a brief gap doesn't cycle the AC), and an arrival triggers an immediate re-evaluation of that room.
- Anti-pet heuristic: a room can be told to ignore false presence when nobody's phone is home (e.g. a cat on the bed) and not fire up the AC for it.
- Home presence via FRITZ!Box: detects whether smartphones are on WiFi (via TR-064). Empty home → everything off after a grace period; a room can also follow a specific phone. Used as the whole-home signal and per-room fallback.
- Fail-safe: if a radar node goes stale it falls back to the phone; if the FRITZ!Box doesn't respond it assumes "home occupied" — a glitch never takes comfort away.
- Remote-control aware: if you turn the AC on/off via the remote or the Panasonic app, the system notices and respects your choice (it doesn't "fight" you).
- Recovery after a blackout: on restart it reads the real AC state and resumes consistently; the Pi powers back on by itself when power returns.
- On/off + dimmer control of Dirigera lights, grouped by room.
- Physical fixtures: multiple bulbs forming a single light point (a mirror light, a hallway run) are controlled together as one control, configurable per room.
- Whole-plant consumption from the Panasonic cloud's monthly aggregation (the figure that matches the official app), broken down per day for the current month, with estimated cost from your configured tariff (variable €/kWh + VAT).
- Per-room AC runtime, consumption and cost for the day, estimated from the periodic state snapshots.
- A Sonoff dry-contact relay on the boiler is detected and controlled on the local network (eWeLink LAN protocol, AES-encrypted), with no cloud; its state is read passively via mDNS. Surfaced in the dashboard as its own room.
A responsive React interface in glassmorphism / iOS style, served by the same backend process and reachable from the whole local network.
- Home overview — a whole-house comfort gauge; an extended outdoor weather card (temperature, feels-like, UV, wind, rain probability, hourly trend, all from Open-Meteo); a Home Engine card that surfaces the MPC's live read (house stability, comfort %, projected consumption, next decision, suggestion); climate energy (today + month, estimated cost, daily chart); plant health (Home Engine / Panasonic / Dirigera / sensors / Wi-Fi); alerts and a recent-events feed (human-readable, e.g. "Cooling to 22°").
- Per-room pages — full thermostat (mode, setpoint with a live real-temperature gauge, fan, swing, nanoe™X, Powerful/Quiet), a 24-hour temperature + humidity chart, room environment (temperature, humidity, comfort, lux), quick actions, per-room device & system health, and a footer with the day's AC runtime, consumption and cost.
- Light-only rooms (no AC) show their light controls instead (toggle + dimmer), with multiple bulbs grouped into a single physical fixture where it makes sense (e.g. a bathroom mirror light, a hallway run).
- Light / dark theme (auto by sunrise/sunset), top-bar quick stats, responsive down to mobile.
A Model Predictive Control layer runs on top of the reactive rule engine, its models validated on real held-out data (see below). Instead of acting once a room is already out of comfort, at each step it solves a finite-horizon optimal-control problem: predict the thermal trajectory over the next hours and select the input that maintains comfort at minimum energy cost. It runs open-loop (advisory) — it predicts and recommends but does not actuate the ACs — a deliberate safety choice for a 24/7 system.
Each room is modelled as a single thermal node with two conductive paths, toward the rest of the conditioned house and toward the outdoors:
with thermal capacitance
Structural conductances
integrating the model forward at 5-min steps over the AC-off segments. No manual tuning; the estimate is refined as data accumulates. A coupled psychrometric humidity model — driven by an Open-Meteo outdoor-humidity forecast — and an occupancy model (arrival-time estimation) feed the same optimiser.
Receding horizon
- State estimate (nowcast) — predicted vs. measured current temperature: MAE 0.02–0.04 °C.
-
Open-loop
$k$ -step prediction on AC-off windows: MAE ≈ 0.15 °C at$h=1$ , ≈ 0.34 °C at$h=2$ (0.1 °C-resolution room), below the persistence baseline$\hat{T}(t{+}h)=T(t)$ at every horizon — i.e. the model carries genuine predictive information beyond "it stays the same". - Post-calibration +6 h forecast bias = −0.28 °C (sub-degree, well-sampled room); the long-range prediction is consistent with the room's measured free-running behaviour (≈ 32 °C without AC on hot days).
- Known limitations: closed-loop operation flattens excitation (few large drifts to identify from); a first-order RC under-models the fast-air / slow-mass two-time-constant response; 1 °C sensor quantisation caps identifiability where present.
| Conventional | This MPC |
|---|---|
| Reactive (feedback once out of band) | Predictive (finite-horizon, 2–6 h) |
| Black-box ML — data-hungry, opaque | Grey-box first-principles — interpretable, data-efficient |
| Cloud / vendor lock-in | Fully on-device (Raspberry Pi), local |
| Comfort or energy | Joint comfort + energy, tariff-aware |
| Fixed parameters | Online self-identification from natural drifts |
⚠️ Beta: advisory-only and under active development; parameters are refined as data accumulates and the model does not (yet) actuate the ACs autonomously.
Climate Pi runs a real home every day. Here's the honest state of each part:
| Area | Status |
|---|---|
| Climate automation (rules, presence, season, dehumidify, night window) | ✅ Stable — daily production |
| IKEA lights · energy & cost · web dashboard · boiler relay | ✅ Stable |
| Predictive control (MPC) | ✅ Validated, advisory — models validated on held-out data; predicts & recommends, doesn't command yet |
| Radar presence model (V1) | ✅ Validated on benchmarks — a lightweight per-room presence classifier from mmWave radar; not yet wired into the live decision loop |
| Layer | Technology |
|---|---|
| Backend | Python 3.11+ (asyncio), FastAPI + Uvicorn |
| Storage | SQLite (async, aiosqlite) |
| Scheduling | APScheduler |
| Integrations | dirigera (IKEA), aio-panasonic-comfort-cloud, fritzconnection, bleak (SwitchBot BLE) |
| Messaging | MQTT — Mosquitto broker + paho-mqtt (radar sensor nodes) |
| Frontend | React 18 + Vite + Tailwind CSS v4, Material Design Icons |
| Deploy | systemd on Raspberry Pi OS / Debian |
- Panasonic ACs compatible with Comfort Cloud (e.g. CS-TZ series)
- Room sensor nodes (recommended): ESP32 boards with an LD2410 mmWave radar + BME280 — per-room presence and temperature/humidity, over MQTT
- MQTT broker (Mosquitto) — for the radar/sensor nodes
- IKEA DIRIGERA hub (VINDSTYRKA environment sensors, lights) — local API
- FRITZ!Box (for home/phone presence via TR-064) — optional
- A host running 24/7: Raspberry Pi 3 or newer (tested), or any Linux/macOS machine for development
Without all components the system still works in reduced mode (e.g. no FRITZ!Box → presence disabled, no IKEA lights → the lights card doesn't appear).
Each room can host a small self-built presence + environment node, in a 3D-printed case:
| Component | Role |
|---|---|
| ESP32-S3 | Wi-Fi microcontroller — reads the sensors and publishes over MQTT |
| LD2410C | 24 GHz mmWave presence radar (behind the perforated front grille) |
| BME280 | temperature / humidity / pressure (in the vented lower bay, isolated from board heat) |
| USB-C | power |
It publishes per-room presence (from the radar) and temperature / humidity (from the BME280) to the MQTT broker, which the rule engine consumes.
Credentials are not in the repository. Copy the template and fill in your data:
cp config/config.example.yaml config/config.yamlThen edit config/config.yaml:
- Dirigera token — generated automatically by the mapping tool (step 2)
- Panasonic Comfort Cloud email/password
- FRITZ!Box credentials — create a dedicated user in System → Users
- Device IDs (ACs, IKEA sensors) — populated by the mapping tool
config/config.yaml is in .gitignore: secrets never end up on Git.
The interactive tool discovers your devices and populates the config:
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python tools/mapping_tool.py(For the first authentication to the Dirigera hub you'll need to press its physical button.)
# build the dashboard (requires Node.js)
cd dashboard && npm install && npm run build && cd ..
# run
.venv/bin/python main.py # production
DEV=1 .venv/bin/python main.py # verbose logsDashboard and API at http://localhost:8000.
The setup.sh script creates the venv, builds the dashboard (if Node is present)
and installs the systemd service:
./setup.shUseful commands:
sudo systemctl status climate-automation # status
journalctl -u climate-automation -f # live logs
sudo systemctl restart climate-automation # restartThe service is enabled: it restarts itself on every boot, crash or blackout.
Headless Pi note: the React build can exhaust RAM on a Pi 3. It's best to build
dashboard/dist/on another machine and copy it, avoidingnpmon the Pi.
rooms:
- name: "Bedroom"
ikea_sensor_id: "<SENSOR_ID>" # IKEA environment sensor (optional)
panasonic_device_id: "<DEVICE_ID>" # air conditioner
presence_device_ip: "192.168.1.50" # opt: this room follows this phone
comfort:
summer: { target_temp: 25, deadband: 1.5, setpoint: 25 }
winter: { target_temp: 21.5, deadband: 1.0, setpoint: 21 }
schedule:
force_off_time: "03:00" # start of the night window
night_off_end: "08:00" # end of window: ACs off 03:00–08:00
presence:
enabled: true
fritzbox: { address, user, password }
away_grace_minutes: 30
devices: [ { name, ip, mac } ]
lights:
ceiling_rooms: ["Living room", "Bedroom"] # bulbs controlled as one fixtureThe full, commented template is in config/config.example.yaml.
climate-automation/
├── main.py # entry point: asyncio orchestration + uvicorn
├── core/
│ ├── config.py # typed config loading
│ ├── rule_engine.py # the reactive brain: decides and commands the ACs
│ ├── ac_controller.py # async wrapper over Panasonic Comfort Cloud
│ ├── sensor_poller.py # IKEA sensor reading (WebSocket + polling)
│ ├── remote_sensor_reader.py # HTTP-pull sensors (BME280/BH1750 nodes)
│ ├── switchbot_reader.py # passive BLE read of SwitchBot sensors
│ ├── radar_presence.py # per-room mmWave radar presence over MQTT
│ ├── season.py # season algorithm (outdoor temp moving average)
│ ├── presence.py # home/person presence via FRITZ!Box
│ ├── occupancy_model.py # arrival-time / occupancy estimation
│ ├── light_controller.py # IKEA lights (+ grouped fixtures)
│ ├── scenes.py # named scenes (multi-device actions)
│ ├── boiler.py # Sonoff boiler relay over the LAN (eWeLink)
│ ├── heating.py # heating decision (heat-pump vs boiler) — WIP
│ ├── weather.py # Open-Meteo current + forecast
│ ├── energy_history.py # Panasonic monthly energy → daily series
│ ├── scheduler.py # nightly forced off
│ ├── mpc_advisor.py # MPC arbiter (advisory): predict + recommend
│ ├── mpc_logger.py # periodic state snapshots for identification
│ ├── thermal_model.py # grey-box RC room model
│ ├── thermal_calibrator.py # self-identification from natural drifts
│ ├── humidity_model.py # psychrometric humidity model
│ └── psychro.py # psychrometrics helpers
├── api/ # FastAPI: routes + models
├── db/ # async SQLite (history, logs, commands)
├── dashboard/ # React + Vite + Tailwind frontend
├── tools/mapping_tool.py # hardware discovery + config generation
├── setup.sh # install + systemd service
└── docs/ # analysis and technical notes
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/rooms |
state of all rooms (temp, AC, energy, override) |
GET |
/api/rooms/{room}/detail |
per-room derived data (comfort, AC runtime/cost today, next action) |
GET |
/api/status |
connections, season, presence |
GET |
/api/overview |
derived home data: comfort score, plant health, Wi-Fi, Home Engine read |
POST |
/api/rooms/{room}/ac/control |
direct AC control (mode/temp/fan/swing/nanoe/eco) |
GET |
/api/rooms/{room}/history |
sensor reading history |
GET |
/api/weather |
outdoor weather + short forecast (Open-Meteo) |
GET |
/api/energy/month |
per-day plant consumption + cost for the month |
GET |
/api/lights |
lights grouped by room |
POST |
/api/lights/{id} |
on/off + dimmer of a light/fixture |
GET·POST |
/api/boiler |
boiler state / on-off (Sonoff LAN) |
GET |
/api/logs |
automation decision logs |
- All credentials live only in
config/config.yaml, which is gitignored. - No data leaves the local network, except the manufacturers' official APIs (Panasonic Comfort Cloud).
- The dashboard has no authentication: expose it on the LAN only, never directly on the Internet (use a VPN for remote access).
Climate Pi is developed in the open, in real time, in a real home — and it's free and MIT-licensed. If it's useful to you, or you'd simply like to see it grow, you can help fund its development.
Your support goes directly into:
- 🚀 New features — more device integrations, automations and refinements
- 🔧 Test hardware — sensors, radar nodes and boards to develop and validate on
- 🛠️ Maintenance — staying stable across firmware, OS and vendor-API changes
- 📚 Documentation — guides, examples, and this ever-growing README
- ⏳ Dedicated development time — the scarcest resource of all
Not able to contribute financially? A ⭐ on the repo, a bug report, or a pull request helps just as much.
Climate Pi follows an open-core philosophy: the project stays public and MIT-licensed — always. Around it, optional professional services are available for those who want more than a DIY setup.
If you'd like to bring Climate Pi into your home or business, I'm available for:
- 🏠 Guided setup & integration on your specific hardware
- 🧩 Custom development — new devices, vendors, or automations
- 🏢 Business / multi-site deployments and tailored features
- 🛟 Priority support & maintenance
📬 Get in touch: your.contact@example.com
The open project and the commercial services fund each other: paid work keeps the free core alive and maintained for everyone.
MIT — see LICENSE. The core will always remain open source.
Built with care for a home that runs itself. 🏠


