5.0 KiB
5.0 KiB
floorheating_svc – Floor Heating Control Service
floorheating_svc is a service responsible for controlling electric floor heating zones in a smart home. It uses MQTT v5 for communication and is implemented using Boost.Asio with asynchronous logic.
The service:
- Maintains and applies target floor temperature per room
- Reads temperature sensor data via MQTT (floor = required, air = optional)
- Sends regular state updates
- Handles critical errors (e.g., overheating)
- Listens to global
kill_switchfor emergency shutdown
🔧 Design Philosophy
- Each room (zone) is represented by a separate object
- Relay outputs are not controlled directly, but via a separate service (
io_output_svc) - The floor heater only controls floor temperature — it does not control air temperature
- Profiles, scheduling, automation are delegated to external tools (e.g., Node-RED)
📚 MQTT Topics
📥 Subscribed Topics (Inputs)
| Topic | Purpose |
|---|---|
home/heating/<room>/floor/temperature/command |
Set target floor temperature |
home/sensor/<room>/floor/temperature/state |
Floor temperature sensor input |
home/sensor/<room>/air/temperature/state |
(Optional) air temperature sensor |
home/control/kill_switch |
Global emergency shutdown |
All subscriptions use
no_local = yesto avoid receiving own messages.
📤 Published Topics (Outputs)
| Topic | Purpose | Retained |
|---|---|---|
home/heating/<room>/floor/temperature/state |
Periodic state report (current, target, heating status) | ✅ Yes |
home/heating/<room>/floor/temperature/result |
Response to /command (uses MQTT v5 correlation-data) |
❌ No |
home/error/floorheating/<room> |
Critical error events (e.g., temperature spike) | ❌ No |
home/control/kill_switch |
Global kill message (optional, emitted by this service) | ❌ No |
home/heating/<room>/floor/config |
(Optional) auto-discovery data | ✅ Yes |
🔁 Periodic State Updates
Every 60 seconds, the service publishes a message to:
home/heating/<room>/floor/temperature/state
Example payload:
{
"target": 22.5,
"current": 21.3,
"heating": true,
"mode": "manual",
"timestamp": "2025-08-05T21:12:00Z"
}
🧭 Command Handling
Topic:
home/heating/<room>/floor/temperature/command
Example payload:
{
"target": 23.0,
"mode": "manual"
}
Expected response:
Published to the specified response-topic, with matching correlation-data (MQTT v5):
{
"status": "ok",
"applied": 23.0
}
⚠️ Error Detection & Safety
Trigger conditions:
- Floor temperature exceeds critical threshold (e.g., > 40°C)
- Missing floor sensor updates (e.g., no message for 2+ minutes)
Actions:
- Publish error:
home/error/floorheating/<room>
{
"type": "temperature_spike",
"message": "Temperature exceeded 40°C",
"severity": "critical",
"source": "floorheating_svc"
}
- Trigger global shutdown:
home/control/kill_switch
{
"reason": "critical_overheat",
"targets": ["floorheating"],
"source": "floorheating_svc",
"timestamp": "2025-08-05T22:30:10Z"
}
- Internally:
- All outputs are disabled
- Heating logic is halted
- Manual restart is required to resume operation
🧪 Sensor Integration
Floor temperature (mandatory)
Topic:
home/sensor/<room>/floor/temperature/state
Payload:
{
"value": 22.4,
"timestamp": "2025-08-05T22:00:00Z"
}
Air temperature (optional)
Topic:
home/sensor/<room>/air/temperature/state
Payload:
{
"value": 23.1,
"timestamp": "2025-08-05T22:00:05Z"
}
Only floor temperature is used for heating logic. Air temperature may be logged or used for auxiliary conditions.
🚫 Unsupported Features
| Feature | Status |
|---|---|
Profile switching (/profile/command) |
❌ Not supported |
| Scheduling / automation | ❌ Not implemented internally |
| Direct relay access | ❌ Delegated to io_output_svc |
| Scene control | ❌ Should be handled externally |
📌 Operational Notes
- One shared MQTT client instance is used across all zone objects.
- The service handles messages using
boost::asio::awaitableandstd::expected-like error handling. - Own MQTT messages are ignored via
no_local = yes(available in MQTT v5 only). - All state and sensor inputs are cached internally with timestamps.
- Fail-safe design: on any error, heating stops immediately and cannot restart automatically.
🧪 Manual Testing Example
mosquitto_pub \
-t home/heating/bathroom/floor/temperature/command \
-m '{"target": 22.5, "mode": "manual"}' \
-V mqttv5 \
-D response-topic home/heating/bathroom/floor/temperature/result \
-D correlation-data test-uuid-1234
📁 File placement
This file should be placed in the project repo at:
services/floorheating_svc/README.md