From 1ae0e0d8f411bfa02ee383800b7dc22748c3cabd Mon Sep 17 00:00:00 2001 From: Timothy Finnegan Date: Tue, 21 Apr 2026 16:28:29 +0000 Subject: [PATCH] Fix install failures from PyPI package collision and systemd misplacement requirements.txt pinned weatherhat==1.0.0 from PyPI, which shadowed the local package in this repo and masked the ha_discovery, i2c_recovery, and other modules added here. Fresh installs via install-service.sh ended with ModuleNotFoundError: No module named 'weatherhat.ha_discovery' (reported in issue #3). update.sh happened to work because it reinstalls the local package with --no-deps after syncing. - Drop weatherhat==1.0.0 from requirements.txt - Install the local package in install-service.sh (matches update.sh) - Move StartLimitBurst/StartLimitIntervalSec from [Service] to [Unit] in both unit files; systemd was silently ignoring them - Document swap setup in README for Pi Zero/Zero 2 W/3A+ where numpy source-builds OOM on 512 MB boards Fixes #3 --- README.md | 12 ++++++++++++ requirements.txt | 3 +-- scripts/install-service.sh | 6 ++++++ weatherhat-display.service | 6 ++++-- weatherhat.service | 10 +++++----- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1a8ce51..1ac422f 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,18 @@ A Python weather station for Raspberry Pi using the Pimoroni Weather HAT. Reads - Pimoroni Weather HAT - I2C and SPI enabled (`sudo raspi-config`) +> **Low-RAM Pis (Zero/Zero 2 W/3A+):** numpy is built from source during +> install and will OOM on boards with ≤512 MB RAM. Enable swap first: +> +> ```bash +> sudo dphys-swapfile swapoff +> sudo sed -i 's/^CONF_SWAPSIZE=.*/CONF_SWAPSIZE=1024/' /etc/dphys-swapfile +> sudo dphys-swapfile setup +> sudo dphys-swapfile swapon +> ``` +> +> A Pi 4 or newer has enough RAM that this is not required. + ### Install ```bash diff --git a/requirements.txt b/requirements.txt index 038924a..2c207f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,5 +13,4 @@ setuptools==80.9.0 smbus2==0.5.0 spidev==3.8 st7789==1.0.1 -toml==0.10.2 -weatherhat==1.0.0 \ No newline at end of file +toml==0.10.2 \ No newline at end of file diff --git a/scripts/install-service.sh b/scripts/install-service.sh index 79c1806..db88721 100755 --- a/scripts/install-service.sh +++ b/scripts/install-service.sh @@ -118,6 +118,12 @@ setup_virtualenv() { sudo -u "$SERVICE_USER" "$VENV_PATH/bin/pip" install --upgrade pip sudo -u "$SERVICE_USER" "$VENV_PATH/bin/pip" install -r "$TARGET_PROJECT/requirements.txt" info "Dependencies installed" + + # Install local weatherhat package (contains ha_discovery, i2c_recovery, etc. + # that aren't in the upstream PyPI release) + info "Installing local weatherhat package..." + sudo -u "$SERVICE_USER" "$VENV_PATH/bin/pip" install --no-deps "$TARGET_PROJECT" + info "weatherhat package installed" } # Check and setup environment file diff --git a/weatherhat-display.service b/weatherhat-display.service index b8b1dd8..3c1fe81 100644 --- a/weatherhat-display.service +++ b/weatherhat-display.service @@ -4,6 +4,10 @@ Documentation=https://github.com/pimoroni/weather-station After=weatherhat.service # Optional: start after main weather service +# Restart rate-limit: stop retrying after 3 failures in 5 minutes. +StartLimitBurst=3 +StartLimitIntervalSec=300 + [Service] Type=simple User=weather @@ -27,8 +31,6 @@ ExecStart=/home/weather/.virtualenvs/pimoroni/bin/python /home/weather/weather-s # Restart on failure Restart=on-failure RestartSec=10 -StartLimitBurst=3 -StartLimitIntervalSec=300 # Resource limits - display uses minimal resources when sleeping MemoryMax=128M diff --git a/weatherhat.service b/weatherhat.service index 6a5fba4..3546719 100644 --- a/weatherhat.service +++ b/weatherhat.service @@ -7,6 +7,11 @@ Wants=network-online.target time-sync.target # Optional: if using lgpiod daemon # After=lgpiod.service +# Restart rate-limit: 10 restarts per hour prevents permanent death +# while still absorbing transient I2C/hardware glitches. +StartLimitBurst=10 +StartLimitIntervalSec=3600 + [Service] Type=simple User=weather @@ -30,14 +35,9 @@ ExecStartPre=/bin/sleep 15 ExecStart=/home/weather/.virtualenvs/pimoroni/bin/python /home/weather/weather-station/bin/mqtt-publisher.py # Restart configuration - robust for remote deployment -# Generous limits: transient I2C/hardware glitches can cause several -# rapid restarts. 10 restarts per hour prevents permanent death while -# still catching genuine boot loops. Restart=on-failure RestartSec=60 TimeoutStopSec=15 -StartLimitBurst=10 -StartLimitIntervalSec=3600 # Resource limits - improved version uses less CPU MemoryMax=128M