Diagnostic Temperature Simulator (temp_sim)
Manual troubleshooting tool that pretends to be the Temperature Daemon without reading 1-Wire or GPIO. It publishes the same Redis keys/channels as the real daemon (temp/redis_out.py) so Control, Health, and Web can be tested on a desk or Pi without probes.
What it is / is not
| Yes | No |
|---|---|
Reads control:latest from Redis |
Reads DS18B20 / sysfs |
Publishes temps:latest, temps.reading, temps:setup, health:temps, etc. |
Drives relays or GPIO |
| Prints every tick to stdout | systemd service (run manually only) |
| Simulates tub + hot-in dynamics from Control heat state | Replaces Control daemon |
Important: Stop the real temperature service before running the simulator, or both will fight over temps:latest:
sudo systemctl stop hot-tub-temps
Prerequisites
- Redis running locally (
redis-server) -
python3-redis(Debian:sudo apt install python3-redis) - For realistic behavior: Control daemon publishing
control:latest, or inject fake control state yourself (below)
Run
From the repo src directory:
cd /path/to/hot-tub/src
PYTHONPATH=. python3 -m temp_sim
Options:
PYTHONPATH=. python3 -m temp_sim --interval 2
PYTHONPATH=. python3 -m temp_sim --redis-url redis://127.0.0.1:6379/0
Each line on stdout shows mode (HEAT / COOL), Control heat_phase / heat_pump, simulated tub and hot_in °F, and Redis publish status. Ctrl+C to exit.
When finished testing, restart the real daemon if needed:
sudo systemctl start hot-tub-temps
Simulated physics
Starting values: tub average 70 °F, hot-in 70 °F. Step size: 5 °F per interval (default interval 5 s).
| Condition | Hot-in | Tub average (each tick) |
|---|---|---|
Heat-up — heat_phase is startup_1, startup_2, startup_3, or heating, and heat_pump is not off
|
Fixed 130 °F | +5 °F (capped at 140 °F) |
Cool-down — heat_phase is idle, error_startup, or anything else; or heat_pump is off; or no control:latest
|
Matches current tub | −5 °F until floor 70 °F |
Four fake tub probes in Redis all equal tub_avg_f; hot probe equals hot_in_f. Setup is always ready with stable fake ROM ids (28-sim-tub1 … 28-sim-hot).
Inject Control state (no Control daemon)
Minimal heating example:
redis-cli SET control:latest '{"heat_phase":"heating","heat_pump":"on","heat_mode":"maintain","target_f":102}'
Cool / idle example:
redis-cli SET control:latest '{"heat_phase":"idle","heat_pump":"off","heat_mode":"sleep","target_f":102}'
Startup attempt (Control checks hot-in rise after ~20 s):
redis-cli SET control:latest '{"heat_phase":"startup_1","heat_pump":"on","heat_mode":"maintain","target_f":102}'
Failed startup:
redis-cli SET control:latest '{"heat_phase":"error_startup","heat_pump":"off","heat_mode":"maintain","target_f":102}'
Run temp_sim in one terminal; change control:latest in another and watch stdout / temps:latest.
Verify Redis output
redis-cli GET temps:latest
redis-cli GET health:temps
redis-cli SUBSCRIBE temps.reading
Health payload includes "detail": "temp_sim (diagnostic simulator)" so you can tell it apart from the real daemon.
Related docs
- Real daemon: ../temp/README.md, ../temp/INSTALL.md
- Control state fields: ../control/README.md