Better Deals ink monitoring — inkagent-portal
  • PHP 87.3%
  • CSS 7.4%
  • Shell 5.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ramon ca33452169 portal: pause per printer (not just per client)
devices.paused + a pause/resume button per printer in the client-detail
accordion, with a 'gepauzeerd' badge. A paused printer is excluded from alerts
(supply_low + stock_short demand) and from the ink ordering counts, same as a
paused client.
2026-08-06 12:27:38 -04:00
bin portal: delete-printer button + auto-prune of gone devices 2026-08-05 12:39:09 -04:00
deploy portal: stock-short alerts + sortable ink page + stock card 2026-08-06 10:52:24 -04:00
docs docs: English version of the client data-transparency addendum 2026-07-27 09:41:50 -04:00
public portal: pause per printer (not just per client) 2026-08-06 12:27:38 -04:00
sql portal: pause per printer (not just per client) 2026-08-06 12:27:38 -04:00
src portal: pause per printer (not just per client) 2026-08-06 12:27:38 -04:00
warehouse portal: Inkt & voorraad page linked to warehouse stock 2026-08-06 10:40:39 -04:00
.gitignore Phase 2: portal + ingest API (PHP 8.2, MariaDB, Caddy) 2026-07-21 12:42:39 -04:00
README.md Phase 2: portal + ingest API (PHP 8.2, MariaDB, Caddy) 2026-07-21 12:42:39 -04:00

inkagent-portal

Central portal + ingest API for Better Deals ink monitoring. Radxa E20C agents poll printers over SNMP and push HMAC-signed batches here; the portal ranks the fleet by predicted depletion date (not by percentage) and drives alerts.

Stack: PHP 8.2 + MariaDB + Caddy, native in a Debian 12 LXC. No framework.

Layout

sql/schema.sql                 MariaDB schema
src/                           app classes (no framework)
  Config Db Crypto Http        infra
  Enroll Ingest                API logic
  Forecast Overview            depletion forecast + fleet assembly
  Color View                   presentation helpers
public/
  index.php                    fleet overview (sorted by depletion date)
  admin/tokens.php             clients + enrollment tokens (Caddy basic-auth)
  api/v1/enroll.php            POST /api/v1/enroll
  api/v1/ingest.php            POST /api/v1/ingest
deploy/
  bootstrap.sh                 idempotent LXC installer
  Caddyfile config.php.example
docs/printer-snmp-support.md   fleet SNMP capability (risk #1)

API

POST /api/v1/enroll

Body {token, agent_id, client_ref, machine_id}. Redeems a single-use token, provisions the agent, returns {secret, ingest_url, newt_id, newt_secret, newt_endpoint}. The token is burned on success.

POST /api/v1/ingest

Headers X-Agent-Id, X-Timestamp, X-Signature. X-Signature = HMAC-SHA256(secret, timestamp + "." + raw_body). Timestamps older than 300s are rejected. Body is the agent's batch (readings[], see the agent's read_printer). Response may carry a config object (poll_interval, community, extra_hosts, discovery_interval) that the agent applies itself.

Security

  • Agent HMAC secrets are stored AES-256-GCM encrypted (app_key in the config file, outside the DB). The server needs the raw secret to verify signatures.
  • Enrollment tokens are stored as SHA-256 hashes; the plaintext is shown once.
  • /admin is gated by Caddy basic-auth.

Forecast

Least-squares regression of level_pct over the last ~30 readings gives a percent-per-day decline and a projected empty date. Page-count run-rate is the second signal — and the only usable one for tier-C ink tanks (EcoTank / HP Smart Tank) that report no reliable percentage. Those are shown as pages-only rather than given a false date. See docs/printer-snmp-support.md.

Deploy

On a fresh Debian 12 LXC, as root:

REPO_SRC=<git-url-or-path> DOMAIN=ink.4betterdeals.com bash deploy/bootstrap.sh

Generates the DB password, app_key, and an admin password (printed once).