Skip to content

Ale9992/climate-pi

Repository files navigation

🌡️ Climate Pi

A self-hosted, open smart-home project — developed in the open, running in a real home.

🇮🇹 Italiano · 🇬🇧 English

Python FastAPI React Raspberry Pi License: MIT

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.


💡 Why Climate Pi

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.


📸 Screenshots

Home overview — comfort gauge, outdoor weather, the MPC's live read (Home Engine), energy, plant health, alerts and recent events.

Home dashboard

Per-room page — thermostat with a live real-temperature gauge, environment, system health, quick actions and the day's runtime/consumption/cost.

Room page


✨ Features

Smart climate automation

  • 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.

Presence (per-room radar + phone, no app to install)

  • 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.

Living with the real world

  • 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.

IKEA lights

  • 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.

Energy & cost

  • 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.

Boiler (optional, fully local)

  • 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.

Web dashboard

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.

🧠 Predictive control (MPC) — validated, advisory

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.

Thermal model — grey-box lumped-parameter (RC)

Each room is modelled as a single thermal node with two conductive paths, toward the rest of the conditioned house and toward the outdoors:

$$ C,\frac{dT}{dt} ;=; UA_{house},(T_{house}-T) ;+; UA_{ext},(T_{out}-T) ;+; Q_{int} ;+; Q_{solar} ;+; Q_{ac} $$

with thermal capacitance $C$ [J/°C], conductances $UA$ [W/°C], internal/solar/HVAC heat flows $Q$ [W], and time constant $\tau = C/(UA_{house}+UA_{ext})$. $T_{out}$ is an Open-Meteo forecast; $T_{house}$ is taken from the other rooms' sensors. Empirically each room couples mostly to the rest of the house (five interior surfaces vs. one external wall), so $UA_{house}\approx 2\text{–}3,UA_{ext}$; this was confirmed against measured free-response (the asymptote sits near the indoor house temperature, not the outdoor one).

Parameter identification — grey-box, self-calibrating

Structural conductances $UA$ are fixed from building geometry; the uncertain effective gain $Q_{int}$ is identified from free-response ("natural") experiments — the open-loop drift recorded whenever the AC is off (night setback, empty room) — via an output-error trajectory fit:

$$ \hat{Q}_{int} ;=; \arg\min_{Q}\ \sum_{k}\big(,\hat{T}(t_k;Q)-T^{meas}(t_k),\big)^2 $$

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.

Control formulation

Receding horizon $H = 6$ h, step $\Delta t = 15$ min, discrete candidate inputs $u \in {\text{Off, Cool, Dry, Pre-cool}}$. Each candidate is simulated forward and selection is lexicographic multi-objective: (1) keep $T$ inside the comfort band, (2) bound humidity, (3) minimise energy cost $\sum |Q_{ac}|/\mathrm{COP}\cdot\Delta t \times \text{tariff}$. A single arbiter evaluates all rooms jointly, so hardware collisions — one indoor unit and one mode per room, a shared ~3 kW power budget, pre-cool vs. an empty room — are resolved inside the optimisation, not as fights between separate controllers. The optimiser emits the recommended $u^\star$ as advice; closed-loop actuation stays gated behind the existing safety rules.

Validation (real, held-out data)

  • 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.

Positioning vs. conventional smart-thermostats

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.


📊 Current Status

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

🧰 Tech stack

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

🔌 Hardware requirements

  • 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).

The room sensor node (DIY)

Each room can host a small self-built presence + environment node, in a 3D-printed case:

Assembled room sensor node

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.


🚀 Installation

1. Configuration

Credentials are not in the repository. Copy the template and fill in your data:

cp config/config.example.yaml config/config.yaml

Then 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.

2. Hardware mapping

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.)

3. Build dashboard + run

# 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 logs

Dashboard and API at http://localhost:8000.

4. Deploy on Raspberry Pi (24/7)

The setup.sh script creates the venv, builds the dashboard (if Node is present) and installs the systemd service:

./setup.sh

Useful commands:

sudo systemctl status climate-automation     # status
journalctl -u climate-automation -f          # live logs
sudo systemctl restart climate-automation    # restart

The 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, avoiding npm on the Pi.


⚙️ Main configuration (config.yaml)

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 fixture

The full, commented template is in config/config.example.yaml.


🗂️ Project structure

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

🌐 REST API (excerpt)

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

🔐 Privacy & security

  • 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).

❤️ Support the Project

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

GitHub Sponsors Ko-fi Buy Me a Coffee

Not able to contribute financially? A ⭐ on the repo, a bug report, or a pull request helps just as much.


💼 Commercial Support

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.


📄 License

MIT — see LICENSE. The core will always remain open source.


Built with care for a home that runs itself. 🏠

About

Self-hosted home climate automation on a Raspberry Pi: predictive (MPC) control of Panasonic ACs by temperature, humidity, season & presence, IKEA lights, energy tracking, and an iOS-style React dashboard.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors