Skip to Content
User guideDebugging

Debugging

If something here does not match what you see on your unit, please open an issue  with the output.

Get a shell

ssh pi@seedypod.local

Check the hardware daemon

hald --check # validate /etc/seedypod/hal.toml and print the planned devices journalctl -u hald -f # follow the daemon's log curl localhost:3001/health # {ok, uptime_s, mqtt_connected} curl localhost:3001/state # every sensor, actuator and alert in one snapshot

To see everything hald publishes:

mosquitto_sub -t 'seedypod/#' -v

Logs only last until reboot

install-hal keeps the system journal in RAM to spare the SD card (ADR 0021). Alerts and faults are still in the database (the Alerts screen, GET /api/alerts). To chase a crash that needs logs from before a reboot, keep the journal on the card for a while, then turn it back off:

sudo mkdir -p /etc/systemd/journald.conf.d printf '[Journal]\nStorage=persistent\n' | sudo tee /etc/systemd/journald.conf.d/99-debug-persistent.conf sudo systemctl restart systemd-journald # logs now survive reboots # … reproduce, reboot, then: journalctl -b -1 -u hald -u seedypod-core sudo rm /etc/systemd/journald.conf.d/99-debug-persistent.conf && sudo systemctl restart systemd-journald

Check core

journalctl -u seedypod-core -f curl localhost:3000/api/system

The About section at the bottom of Settings shows the core and daemon versions and the unit id. If it says the hardware daemon is offline, core cannot reach hald over MQTT; check HAL_MQTT_URL in /etc/systemd/system/seedypod-core.service.

Probe the I²C bus

sudo i2cdetect -y 1

Expect 0x40 (INA219 pump power monitor), 0x48 (PCT2075 board temperature), and 0x38 (DHT20 air sensor, Gardyn 3.0 and later). The AM2320 used in Gardyn 1.0 and 2.0 sits at 0x5C but does not answer i2cdetect; that is expected.

The pump will not start

If the pump state shows fault: "dry-run" or fault: "over-temp", the fault is latched: the pump stays off until a person acknowledges it. Refill the tank or let the board cool, then acknowledge from any of:

  • the Alerts screen in the web UI;
  • the Acknowledge pump fault button in Home Assistant;
  • a long press of the physical button;
  • the API: POST /api/alerts/{id}/acknowledge with the alert’s id from GET /api/alerts.

If there is no latched fault but the pump still refuses, the tank probably reads low: check the Water screen’s distance against your tank calibration in Settings.

A restore that didn’t finish

The restore helper logs each step to /var/lib/seedypod-restore/status.json, and sudo seedypod-restore --status prints the last run. A restore started from the web UI runs as its own transient unit:

journalctl -u 'seedypod-restore-*'

If the web UI says restore isn’t installed, scripts/install hasn’t put the helper and its sudoers rule in place. Run as core’s user, sudo -n -l /usr/local/sbin/seedypod-restore should print the path. A failed restore puts the old files back by itself, and sudo seedypod-restore --undo reverses the last restore that did finish.

SD card writes

Settings → Storage (or GET /api/storage/flash) shows how much the unit writes to its card per day. To see which process is writing, use sudo iotop -ao or cat /proc/<pid>/io. swapon --show should list only /dev/zram0.

Reproduce without hardware

Run the daemon against simulated hardware, with time running 60 times faster, and core against it:

hald --sim --time-scale 60 HAL_MQTT_URL= pnpm dev

Source: docs/DEBUGGING.md

Last updated on