M.2 UPS PMH Web Panel V02
25 October 2026 | Pi Modules Technologies L.P.

A responsive English browser panel hosted on Raspberry Pi 5.
Clients: modern Windows/Linux browsers, Android and iOS browsers.
Application firmware: 0x08B5, default I2C bus 1, status 0x69 and commands 0x6B.
This package includes its matching configurator 06 and status 0B modules.
It does not modify those modules, the MCU firmware or the protected bootloader.

INSTALLATION
Keep stable cable power connected. Install the normal M.2 Linux package first;
M2_PMH_i2c.service must already be running. Copy and extract this ZIP on the Pi:

cd ~ &&
unzip -o M2_UPS_PMH_WebPanel_V02.zip &&
cd ~/M2_UPS_PMH_WebPanel_V02 &&
sudo python3 install_webpanel.py

Dependencies are installed from apt: python3-flask, python3-waitress,
python3-smbus and i2c-tools. Raspberry Pi OS Bookworm/Trixie is the target.
Create the initial admin password at the visible terminal prompts (minimum 8
characters). There is no default real-device password. Existing accounts survive
an upgrade. Account name on first installation is admin.
Both initial entries are visible; later SSH password changes remain hidden.
The installer uses a separate unprivileged service account, m2web, with I2C access.
It does not stop, replace or reconfigure the existing heartbeat/shutdown daemon.
An earlier panel installation is backed up and restored if service setup fails.

OPEN THE PANEL
Use the Pi's address printed by the installer, for example:
http://192.168.1.7:8080
Open that URL on any client in the same LAN and sign in.
For external access use a VPN. V02 serves HTTP locally; use SSH tunneling or an
appropriately configured HTTPS endpoint on an untrusted network. A built-in TLS
certificate manager and public-Internet deployment are not included in V02.

READINGS
Overview shows power source, battery voltage, Pi CPU temperature, Linux fan
request, selected external ADC voltage, RTC and detected DS18B20 sensors.
Expanded tables include raw register values. Export JSON downloads the displayed
snapshot to the browser. Values are sampled sequentially and refreshed every
five seconds while a signed-in browser polls the panel. Idle browser polling
stops when hidden; server hardware polling pauses about 30 seconds after the
last status request. Monitoring counts as firmware host activity.
The actual battery charge percentage and fan RPM are not inferred. Current and
power fields retain their firmware meaning and need calibration/verification.
1-Wire uses the existing Linux driver and needs GPIO4 enabled separately.
Use the ESD-protected M.2 Advanced sensor connector, not bare Pi GPIO.

CONFIGURATION
Administrators can edit the configurator allowlist; viewers cannot write.
Select a new value, Review it, then type YES exactly and Apply and verify.
A preview expires after 90 seconds and can be applied only once. The server
checks the current value again and rejects stale changes. Firmware version,
assembly, stable cable mode, idle command state, range and mode interactions
are checked using the existing configurator. The Advanced-only ADC restriction
is retained. A transport failure or failed readback is never automatically retried.
After an uncertain result, refresh and inspect before another explicit change.
Saved settings retain the existing firmware-managed Flash behavior. UART-rate
changes can reset the MCU; save work and review the warning before applying.
Firmware upload, arbitrary raw writes, bootloader entry and factory reset are
not web actions in this first version.

ACCOUNTS AND SERVICE
Add/update a viewer account from SSH:
sudo python3 /opt/M2_UPS_PMH_WebPanel/accounts.py set viewer --role viewer
Change the administrator password:
sudo python3 /opt/M2_UPS_PMH_WebPanel/accounts.py set admin --role admin
Disable an account (at least one enabled administrator is required):
sudo python3 /opt/M2_UPS_PMH_WebPanel/accounts.py disable viewer

Account data and secret: /etc/M2_UPS_PMH_WebPanel/config.json
Audit: /var/lib/M2_UPS_PMH_WebPanel/audit.jsonl (rotated, no passwords)
Application: /opt/M2_UPS_PMH_WebPanel
Service: M2_PMH_web.service
Sessions expire after 30 minutes of inactivity. Changed credentials/roles and
disabled accounts invalidate existing sessions. CSRF tokens, same-origin POSTs,
HttpOnly/SameSite cookies, request-size limits and login throttling are applied.
No browser-supplied shell command or raw I2C address is executed.

DIAGNOSIS / REMOVAL
sudo python3 install_webpanel.py --check
sudo journalctl -u M2_PMH_web.service -b -n 30 --no-pager
sudo systemctl restart M2_PMH_web.service
sudo python3 install_webpanel.py --uninstall
Uninstall retains accounts, audit data, backups and the existing UPS daemon.
It removes only the optional web-panel service and application.
If you use a firewall, allow TCP 8080 only from the intended LAN/VPN clients.

DEVELOPER CHECKS
python3 -m unittest discover -s tests -v
The tests use simulated I2C; they do not flash or exercise a physical board.
A read-only localhost demo is available after installing Flask and Waitress:
python3 app/run.py --demo
Demo login: demo / demo-preview. Demo never opens SMBus and cannot write.
Do not use demo credentials for a real installation.
See TEST_RESULTS.txt and VALIDATION.txt for the checks completed here.
The browser preview runtime could not launch the Python server in the build
environment; visual/browser behavior and the actual Raspberry Pi installation
still require the first target-system test. Manual integration follows that test.

PRIMARY SOFTWARE REFERENCES
https://flask.palletsprojects.com/en/stable/deploying/waitress/
https://flask.palletsprojects.com/en/stable/web-security/

RESET AN EXISTING ADMIN PASSWORD
A repeated installation retains existing accounts and does not prompt again.
From the extracted package run:
sudo python3 install_webpanel.py --reset-password
Both password entries are visible; minimum 8 characters. Other accounts and the
server secret are retained. No reinstall, hardware access or service restart is
performed. The changed admin password invalidates its earlier sessions.

LAYOUT UPDATE
Full company name and clickable www.pimodules.com in the header/footer.
Detailed tables use independent columns on wide screens: temperature, ADC and
identity stack without waiting for the longer power table. Mobile uses one
column in logical reading order. Summary cards and hardware behavior unchanged.

DENSITY UPDATE
Compact summary cards (one six-card row on desktop), smaller table padding
and reduced section gaps. Detailed sections are balanced between two columns,
or three on screens at least 1500 pixels wide. Resizing rebuilds only the
readout columns; pending configuration input is preserved. No readings hidden.

V02: optional private Internet access via Tailscale. Use --with-tailscale when
installing/upgrading, or --tailscale-only afterwards. See REMOTE_ACCESS.txt
for complete phone/Windows/Linux pairing, validation and troubleshooting.
The compact V01 layout and all account/firmware guards are retained.
