Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Raspberry Pi Temperature Sensor Client

Python client for a Raspberry Pi Zero W with an AHT20 temperature/humidity sensor. The Pi reads temperature and humidity on a polling interval and sends JSON readings to a backend API using bearer-token authentication.

This is the device-side repo for a larger temperature monitoring project. The Flask API/dashboard lives in a separate repo. This client can point at either a local development API or the production API by switching the active .env file.

Hardware

Current test device:

  • Raspberry Pi Zero W
  • Raspberry Pi OS Lite
  • AHT20 temperature/humidity sensor over I2C

I2C wiring:

  • VIN → 3.3V
  • GND → GND
  • SCL → GPIO 3 / Pin 5
  • SDA → GPIO 2 / Pin 3

What it does

run.py:

  1. Loads config from .env
  2. Initializes the AHT20 sensor
  3. Reads temperature and humidity
  4. Builds a JSON payload
  5. Sends it to the configured API endpoint
  6. Logs failures and keeps retrying if the API is unavailable

Successful sends are intentionally quiet. Failed sends are logged and retried on the next polling interval.

Example payload:

{
  "type": "temp_and_humidity_reading",
  "timestamp": 1718840000.123,
  "device_id": "pi_zero_001",
  "payload": {
    "temperature_f": 72.41,
    "humidity_percent": 54.82
  }
}

Project layout

.
├── run.py
├── requirements-dev.txt
├── requirements.lock.txt
├── requirements.txt
├── scripts/
│   ├── log_sensor_overnight.py
│   ├── read_sensor_loop.py
│   └── use-env.sh
├── src/
│   └── utils/
│       ├── logging.py
│       ├── payload.py
│       ├── sensor.py
│       └── transmitter.py
└── tests/
    ├── test_payload.py
    ├── test_run_config.py
    ├── test_sensor.py
    └── test_transmitter.py

Main files:

  • run.py — main polling loop
  • src/utils/sensor.py — initializes and reads the AHT20 sensor
  • src/utils/payload.py — builds the backend API payload
  • src/utils/transmitter.py — sends readings to the API
  • src/utils/logging.py — configures Loguru logging
  • scripts/use-env.sh — switches between local and production configs
  • scripts/read_sensor_loop.py — quick live AHT20 hardware check
  • scripts/log_sensor_overnight.py — long-running AHT20 hardware logging script
  • tests/test_*.py — pytest coverage for sensor, payload, transmitter, and startup config helpers

Setup

Create and activate a virtual environment:

python3 -m venv venv
source venv/bin/activate

For a reproducible Pi install, prefer the pinned lock file:

pip install -r requirements.lock.txt

For local development tests:

pip install -r requirements-dev.txt

requirements.txt lists the top-level runtime dependencies. requirements.lock.txt pins the full dependency set used for deployment. requirements-dev.txt is for local pytest tooling.

Create local environment files in the project root:

.env.local
.env.production
.env

.env.local and .env.production store the local and production configs. .env is the active config used by run.py and systemd.

Local development example:

API_URL=http://<backend-host>:5000/api/device/readings
AUTH_TOKEN=replace_me
DEVICE_ID=pi_zero_001
POLL_INTERVAL_SEC=60

Production example:

API_URL=https://<your-domain>/api/device/readings
AUTH_TOKEN=replace_me
DEVICE_ID=pi_zero_001
POLL_INTERVAL_SEC=300

Notes:

  • API_URL must point directly to the backend /api/device/readings endpoint.
  • AUTH_TOKEN must match the backend’s bearer token.
  • DEVICE_ID identifies this Pi in the backend.
  • POLL_INTERVAL_SEC controls how often readings are sent.
  • Startup validates DEVICE_ID, API_URL, AUTH_TOKEN, and POLL_INTERVAL_SEC.
  • .env files are ignored by Git.

Switching environments

Use the helper script to switch the active .env file.

./scripts/use-env.sh local
./scripts/use-env.sh production

If the service is running, restart it after switching:

sudo systemctl restart temp-sensor.service

The script prints the active API_URL, DEVICE_ID, and POLL_INTERVAL_SEC, while redacting AUTH_TOKEN.

Manual hardware scripts

Use this before testing the full API loop:

source venv/bin/activate
python -m scripts.read_sensor_loop

This uses the real AHT20 sensor through the shared sensor utility and prints readings every 10 seconds. It does not send anything to the API.

For a longer hardware logging check:

source venv/bin/activate
python -m scripts.log_sensor_overnight

This writes periodic readings to logs/overnight_test.log. These hardware scripts are not part of the pytest suite.

Automated tests

The pytest suite covers sensor reading conversion, payload shape, transmitter behavior, and startup config parsing.

source venv/bin/activate
pip install -r requirements-dev.txt
python -m pytest

Run manually

source venv/bin/activate
python run.py

systemd service

The Pi can run the client as a systemd service.

Example service file:

[Unit]
Description=Temperature Sensor Monitor
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=tyspi-temp
WorkingDirectory=/home/tyspi-temp/temp-sensor
EnvironmentFile=/home/tyspi-temp/temp-sensor/.env
Environment="PYTHONUNBUFFERED=1"
ExecStart=/home/tyspi-temp/temp-sensor/venv/bin/python3 /home/tyspi-temp/temp-sensor/run.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Useful commands:

sudo systemctl start temp-sensor.service
sudo systemctl stop temp-sensor.service
sudo systemctl restart temp-sensor.service
systemctl status temp-sensor.service --no-pager

Enable at boot:

sudo systemctl enable temp-sensor.service

Logs

Logs are written with Loguru to:

logs/sensor_{time}.log

Warnings/errors also go to stderr, so manual runs and journalctl show useful output. Log files rotate at 2 MB and are retained for 7 days.

Dependencies

Key Python packages:

  • adafruit-circuitpython-ahtx0
  • adafruit-blinka
  • adafruit-circuitpython-busdevice
  • requests
  • python-dotenv
  • loguru

Current status

Tested on a Raspberry Pi Zero W with an AHT20 sensor. The client can send readings to the Flask backend over the local network and can run under systemd.

Production deployment is handled by the separate Flask backend repo. This client only needs the correct production API_URL and matching AUTH_TOKEN to send readings to the deployed API.

About

Python client for reading temperature and humidity data from an AHT20 sensor on a Raspberry Pi Zero W. Sends periodic readings to a Flask-based API for storage and monitoring. Designed for lightweight, headless operation with 5-minute polling.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages