PiWeM is a highly configurable, modern system of PHP frontend services, database APIs, Python weather station daemons, and desktop clients to gather, log, transmit, and visualize telemetry from local weather sensors.
Project Phase: Beta
Project Version: v2.1
License: GNU General Public License v2
- Fully migrated the Central Server frontend from Smarty to the modern Twig template engine.
- Standardized layouts under
.twigmarkup, eliminating the legacysmarty/folder and.tpldependencies.
- Built a custom theme override engine supporting directory overrides under
/templates/themes/{theme_name}/. - Custom themes only need to override specific templates (like
header.twigorgraphing_head.twigfor styling); Twig automatically falls back to/templates/default/for all other templates. - Comes with two premium pre-built styles:
- Dark: A clean, modern dark-mode aesthetic.
- Space: A flashy cosmic theme featuring radial background gradients, CSS-animated scrolling starfields, nebulae glows, and custom Google Fonts (Orbitron and Space Grotesk).
- Robust State Persistence: Persists selected themes across page navigation via GET/POST query parameters, persistent cookies, and standard PHP Sessions (
$_SESSION) for strict browser/subdirectory isolation.
- Consolidated weather data queries to fetch from individual sensor tables (
bmp280,dht22,photoresistor, etc.) instead of a monolithic single table. - Implemented automatic fallback probing in
GetStationSensors()that checks the individual tables if the metadata lookup table is empty. - Isolated the Central Server UI to only display physical weather stations, filtering out desktop client registrations.
- Removed obsolete power-grid layout visual cards and endpoints.
- Swapped out row-based limits for dynamic time-series history filters (e.g.
30 MINUTE,12 HOUR,24 HOUR,7 DAY,30 DAY,all). - Compares UTC database timestamps directly against
UTC_TIMESTAMP()to avoid timezone mismatches. - Automatically normalizes plural/singular user input (e.g.,
24 HOURS$\rightarrow$ 24 HOUR) to comply with SQLINTERVALsyntax rules. -
$O(N)$ Telemetry Merging: Optimized the API data merger to aggregate rows in an$O(N \log N)$ sorting and$O(N)$ linear pass. Grouping timestamps within a 5-second window resolves sub-second sensor reading offsets, reducing response times for large datasets (5,000+ rows) from 10+ seconds to under 0.8 seconds.
- A fully functional GUI client (
client.py) supporting PyQt6, PyQt5, and PySide2 fallbacks. - Features a premium dark mode stylesheet, active station lists, automatic refresh toggles, and real-time telemetry panels.
- QPainter Vector Plotting: Supports rendering historical line charts (with 5-Point Simple Moving Average dashed lines and minimum, maximum, current, and average statistics) dynamically via built-in
QPaintergraphics.
- Added an interactive command-line client (
cli_client.py) utilizing Python's standardcmdmodule. - Runs in any standard terminal shell with zero external dependencies.
- Integrated ASCII Plotting: Plots high-resolution charts in the terminal (with 5-Point Simple Moving Average curves
~and statistics) for fields like temperature, humidity, pressure, and wind speed. - Safe string formatting handling prevents crashes from database
NULLvalues. - Live Shell Watch: Added the
live(aliaswatch) command, enabling a full-screen, 10-second auto-refresh terminal monitoring panel.
- Raspberry Pi (any version)
- One or more of the following sensors:
- DHT11, DHT22, AM2302
- BMP085, BMP180, BMP280
- PCF8591 (8-bit 4-channel A/D converter for photoresistors, analog thermistors, etc.)
- Anemometer / Wind direction sensors
- PHP 8.0 or later
- PHP Extensions:
pdo,pdo_mysql,session - Twig template engine (loaded from
/usr/share/php/Twig/autoload.phpvia standard package configuration) - MariaDB / MySQL Server
- Apache / Nginx Web Server
- Python 3
- For GUI Client: PyQt6
- For CLI Client: Standard Python library only (no external packages required)
/CentralServer/piwem/- Core PHP viewer pages (
index.php,station.php,graphs.php). lib/: Includes DB logic (SQL.php), Central API (PiWeMAPI.inc.php), and Frontend controller (PiWeMFront.inc.php).templates/default/: The baseline default Twig template layouts.templates/themes/: Contains customized visual styles (e.g.dark,space).Scripts/: Command-line server tools (likeregister.phpnode registering script).
- Core PHP viewer pages (
/WeatherStation/monitor.py: Daemon/cron script to read local sensors and upload data.settings.ini: Settings file configuring active pins, sensors, and Central Server details.register.py: CLI script to request credentials from the Central Server.
/DesktopClient/client.py: The PyQt GUI client.cli_client.py: The new interactive terminal client.settings.ini: Connection credentials pointing to the Central Server.
Import the baseline database structure to your MariaDB/MySQL instance:
mysql -u root -p < blank.sql- Copy the contents of
/CentralServer/piwem/to your web server root (e.g.,/var/www/html/piwem/). - Create your site configuration by copying the sample:
cp lib/config.php.sample lib/config.php
- Edit
lib/config.phpand fill in your database credentials and default settings.
Register your station node to get an API credential hash:
python3 register.py --StationName="ThinkPad-X1-Station" --ServerURL="http://192.168.1.155/piwem"This automatically updates your local settings.ini with the credentials.
Run the monitor script on the Raspberry Pi:
python3 monitor.py --VerboseTip: Set up a crontab entry to run run.sh periodically (e.g., every hour).
Launch the interactive telemetry shell from the DesktopClient folder:
./cli_client.pylist(orls): Fetches and prints all registered stations, their last update timestamps, and unique hashes.select <ID_or_Hash>(orsel): Selects a station to monitor.telemetry(ortel): Displays the latest real-time sensor readings.plot <field> [interval](orgraph): Plots a high-resolution terminal ASCII line chart.- Fields:
c_temp,f_temp,humidity,pressure,altitude,photolevel,wind_mps - Intervals:
12 HOURS,24 HOURS,7 DAYS, or limit numbers (default:24 HOUR). - Example:
plot pressure 24 HOURS
- Fields:
live(orwatch): Enters full-screen monitoring mode, automatically clearing the screen and updating telemetry every 10 seconds. Exit withCtrl+C.settings: View or update server URLs and credentials.exit(orquit): Exits the shell.
Create a ticket on the GitHub issues tracker at: https://github.com/pferland/PiWeM/issues
The RanInt Dev Team
- PFerland