Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

heatwires

Automated, weather-based control of roof heat cables (de-icing / ice-dam prevention) via TP-Link Kasa KP400 smart outdoor plugs.

It queries the US National Weather Service for your location, decides whether icing conditions warrant running the cables, and switches your Kasa plugs directly over the LAN (no cloud account, no reverse-engineered web API).

How it decides

Ice dams form in a melt/refreeze window near freezing with snow present: snow melts, water runs to the cold eaves, and refreezes. So the cables run when:

  • the temperature is inside a configurable band (default 15–38 °F), and
  • frozen precipitation is present/forecast (can be disabled).

Extras for real-world robustness:

  • Hysteresis widens the band once the cables are on, to avoid flapping.
  • Minimum dwell time prevents rapid on/off cycling.
  • Fail-safe: if weather can't be fetched during winter months, bias to a safe state (default: ON).
  • Graceful degradation: an unreachable switch is logged and reported (and makes run exit non-zero) without aborting the rest of the cycle.

Install

Requires Python 3.10+. Run this on an always-on machine on the same LAN as the switches (e.g. a Raspberry Pi).

python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Configure

cp config.example.yaml config.yaml

Then edit config.yaml:

  • location — your roof's latitude/longitude (decimal degrees).
  • weather.user_agent_contact — an email; NWS requires an identifying User-Agent.
  • switches — the IP(s) of your KP400(s) and which outlets to control.
  • icing — the temperature band and behavior tunables.

Give each KP400 a reserved/static IP in your router so its address never changes. Find the switches on your network with:

heatwires discover

config.yaml and state.json are git-ignored (they're host-specific).

Use

heatwires -c config.yaml discover        # list Kasa devices on the LAN
heatwires -c config.yaml status          # show weather + switch state + decision (no change)
heatwires -c config.yaml run             # run one control cycle (turns cables on/off)
heatwires -c config.yaml run --dry-run   # decide + read switches, but don't change them
heatwires -c config.yaml loop -i 900     # run continuously, every 900s

Deploy

Option A — cron (runs one cycle every 15 minutes):

*/15 * * * * /path/to/.venv/bin/heatwires -c /path/to/config.yaml run >> /path/to/heatwires.log 2>&1

Option B — systemd service (long-running loop, auto-restart):

# /etc/systemd/system/heatwires.service
[Unit]
Description=Roof heat-cable weather controller
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/path/to/.venv/bin/heatwires -c /path/to/config.yaml loop -i 900
Restart=always
RestartSec=30
User=pi

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now heatwires
journalctl -u heatwires -f

The Kasa app keeps working independently as a manual override at any time.

Develop

pip install pytest
pytest -q          # offline tests for the decision logic and NWS parsing

Layout

File Purpose
heatwires/weather.py NWS client → temperature + snow/ice signal
heatwires/logic.py the icing decision (band + snow + hysteresis)
heatwires/switches.py Kasa control over the LAN (python-kasa)
heatwires/controller.py one cycle: weather → decision → switches → state
heatwires/state.py run-to-run state (last state, dwell timing)
heatwires/config.py YAML config loading/validation
heatwires/cli.py discover / status / run / loop commands

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages