Skip to content

Releases: powerpco/pwrp-edge-tools

S7 Probe v0.1.0 (diagnostic)

Choose a tag to compare

@felipevallejo felipevallejo released this 29 Apr 19:55

S7 read-only probe (.NET 10 single-file, ~190KB). Reads DBs from JSON config and prints values. Requires Microsoft.NETCore.App 10.x runtime. Sample config s7-probe-laflorida.json targets PCH La Florida S7-1500 @ 10.10.2.30 with WKV template DBs (DB120/121/281/191/280/290/100) for one unit.

pwrp-edge-s7 v0.2.0 — once + serve commands + YAML config

Choose a tag to compare

@felipevallejo felipevallejo released this 30 Apr 14:56

Adds:

  • YAML config schema (Plc/Mqtt/Sparkplug/Runtime/Groups/Tags)
  • once command: load config, single read cycle, print all tags, exit (no MQTT)
  • serve command: long-running daemon with Sparkplug B publish over MQTT, reconnect logic

Framework-dependent build (.NET 10 runtime required on gateway).

SHA256: e3f7e6b56577bae6486b4009c28b875afcbf1f8a7de5d7d902ee0d1ff0b83071

pwrp-edge-s7 v0.1.0 — initial scaffold + dump command

Choose a tag to compare

@felipevallejo felipevallejo released this 30 Apr 13:23

First release of the new S7 client (.NET 10).

This release: framework-dependent build, .NET 10 runtime required on the gateway.

Includes:

  • dump subcommand: bulk-read raw bytes from a DB and reinterpret as REAL/DINT/INT/WORD in parallel columns.
  • read / once / serve subcommands: stubs (next iterations).

Tarball SHA256: cbe4130deec5507bf4507d484c73843ecec6f0956edb0b9924eaed85bb801b1e

Source: https://github.com/powerpco/pwrp-edge-s7

pwrp-edge-mqtt2http — fix: pass Sparkplug BooleanValue (datatype 11) as 0/1 numeric

Choose a tag to compare

Fixes BOOL metrics from IEC-104 (TypeID 1, M_SP_NA_1) being silently dropped.

Root cause: SparkplugMessageConverter.TryCreateField() switch had no case for BooleanValue, falling to default → return false → metric rejected.

Fix: 3 lines, map true→1.0, false→0.0, append to F64 like the rest.

SHA256: ce8fdee4b28c6bc7caecaff2818e9eee6fa33bae541d04c5b12005016af1d5a1

Branch: fix/sparkplug-boolean-passthrough

pwrp-agent v0.6.3 — credential rotation snapshot/restore + CIS-compliant password gen

Choose a tag to compare

@felipevallejo felipevallejo released this 06 May 16:55

Hardens credential rotation against partial chpasswd failures on CIS-hardened Ubuntu fleet gateways.

Fixes

  • pp-0054 incident (2026-05-06): chpasswd processed pp-admin successfully then failed on root (pwquality rule violation), leaving pp-admin with an unknown password and no automatic recovery path.

Changes

  • RotateCredentialsReportFirst now snapshots /etc/shadow hashes before applying changes; on partial failure, restores via usermod -p '<old_hash>' (which writes to /etc/shadow without going through PAM, bypassing pam_pwhistory rejection of the prior password).
  • Per-user chpasswd application with abort-early semantics.
  • Post-change verification: confirms both hashes actually changed before reporting success to cloud.
  • Password generator now guarantees CIS pwquality compliance (minclass=3, ucredit=-2, lcredit=-2, dcredit=-1, maxsequence=3, maxrepeat=3, usercheck). Validates each candidate in-process and retries on rule violation.

SHA256
614927c030b4bfac4221b9f595cddc7762a5fe1c235f73e4afb714e7ef606fee

pwrp-agent v0.6.2

Choose a tag to compare

@felipevallejo felipevallejo released this 29 Apr 20:25

Edge agent v0.6.2 - eliminates systemd service-name dependency by exiting cleanly (os.Exit) instead of calling systemctl restart from inside the service. Companion to server-side Fix B (transactional cert revoke).

SHA256: 82e32e5ff4cbb82dd47ef662923c3cc1e1981fada52a35a516faef32953cf285

Edge MQTT→HTTP forwarder v1.0.1 (net10)

Choose a tag to compare

Sparkplug MQTT subscriber forwarding batches via HTTP POST /ingest. TFM bumped to net10.0 to match runtime already deployed on gateways. Single-file no-self-contained; tarball includes pwrp-edge-mqtt2http + libnironcompress.so.

Edge MQTT→HTTP forwarder v1.0.0

Choose a tag to compare

@felipevallejo felipevallejo released this 29 Apr 20:27

Sparkplug MQTT subscriber that forwards batches via HTTP POST /ingest (with x-api-key). Single-file .NET 8, no-self-contained. Tarball includes pwrp-edge-mqtt2http (3.8MB) + libnironcompress.so (2MB native dep). Requires .NET 8 runtime (apt: aspnetcore-runtime-8.0 or similar). Sample env attached.

Edge MQTT→HTTP forwarder v1.1.0 (resilience: auto-heal + systemd watchdog)

Choose a tag to compare

Resilience release of pwrp-edge-mqtt2http after the 2026-05-01 silent-stall incident at pp-0022-gw (PCH La Florida) where the worker stopped forwarding for ~12.6h with the systemd unit reporting active running.

Includes the BooleanValue Sparkplug fix that was deployed as a custom binary on 2026-04-30 (originally PR #3 in pwrp-data-ingest).

Resilience changes (no new dependencies)

  • No more silent stalls: HttpBatchService.SendBatchAsync catches all exception types (not only HttpRequestException/TaskCanceledException). ExecuteAsync wraps the drain loop in an outer recovery loop — only OperationCanceledException from shutdown stops the worker.
  • Per-request timeout via linked CancellationTokenSource: a hung socket cannot wedge the pipeline beyond HTTP_TIMEOUT_SEC. Default is now 5s (was 30s) — tuned for realtime cadence.
  • Bounded retries with quarantine: HTTP_MAX_ATTEMPTS=5 (default) per batch with exponential backoff. After exhaustion the batch is marked Quarantined in the manifest and the loop continues. Terminal 4xx (except 408/429) skips retries.
  • SocketsHttpHandler with bounded connection lifetimes: PooledConnectionLifetime=2m, PooledConnectionIdleTimeout=30s. Stale TCP sockets in the pool are recycled automatically.
  • Active recovery on Offline: ConnectivityMonitor.OfflineEntered event fires when the FSM drops to Offline; the HTTP worker recreates its HttpClient and underlying handler to drop every cached TCP connection.
  • systemd watchdog: unit must be Type=notify with WatchdogSec=120. The worker only sends WATCHDOG=1 when there has been a recent successful POST — a zombie loop cannot keep systemd happy. If the loop ever stalls, systemd SIGTERMs and restarts within ~120s.
  • Visible backpressure: MqttWorker emits a rate-limited LogWarning when the channel is full and the oldest batch is being dropped. New EdgeMetrics counters: channel_full_drops_total, batches_quarantined_total, http_client_recreations_total.
  • Liveness heartbeat: an Info-level summary every HTTP_HEARTBEAT_SEC (default 60s) — alert on LastSuccessAgoSec rising without bound.

Default config changes

Variable Old New Why
HTTP_TIMEOUT_SEC 30 5 timeout > realtime update interval makes channel drain slower than fill
HTTP_INITIAL_RETRY_SEC 2 1 fail-fast and recover-fast
HTTP_MAX_RETRY_SEC 30 10 bound worst-case stall per batch
HTTP_MAX_ATTEMPTS (∞) 5 new — quarantine after budget exhausted
HTTP_HEARTBEAT_SEC 60 new — liveness log cadence

Deployment

Required steps (existing deployments):

  1. Stop service: systemctl stop pwrp-edge-mqtt2http
  2. Backup binary: cp -a /opt/pwrp-edge-mqtt2http /opt/pwrp-edge-mqtt2http.bak.$(date +%Y%m%d-%H%M%S)
  3. Extract new binary: tar xzf pwrp-edge-mqtt2http-resilience-v1.0.tar.gz -C /opt/pwrp-edge-mqtt2http
  4. Replace systemd unit: cp pwrp-edge-mqtt2http.service /etc/systemd/system/ then systemctl daemon-reload
  5. Update env: merge new keys (HTTP_MAX_ATTEMPTS, HTTP_HEARTBEAT_SEC) into /etc/pwrp/edge-mqtt2http/.env. Bring HTTP_TIMEOUT_SEC, HTTP_INITIAL_RETRY_SEC, HTTP_MAX_RETRY_SEC to the new defaults.
  6. Start: systemctl start pwrp-edge-mqtt2http
  7. Validate: journalctl -u pwrp-edge-mqtt2http -f — expect to see HTTP forwarder alive. LastSuccessAgoSec=... heartbeats and HTTP ingest request succeeded lines.

Requires .NET 10 runtime on the gateway (framework-dependent build).

SHA256

fb9c0e2aa818352bcc0b1e6fd58995592bf5d42941fb173749cc684458068fcb pwrp-edge-mqtt2http-resilience-v1.0.tar.gz

References

  • Incident analysis: docs/sites/pchlaflorida/incident-2026-05-01-mqtt2http-stall.md in the operations repo.
  • Resilience design contract: docs/MQTT2HTTP_RESILIENCE.md in pwrp-data-ingest.
  • Source branch (pending PR + merge in pwrp-data-ingest): fix/mqtt2http-resilience.

Modbus client v1.0.0 (gateway + console)

Choose a tag to compare

@felipevallejo felipevallejo released this 29 Apr 20:27

Modbus TCP client + Sparkplug B publisher (libmodbus, libmosquitto). Gateway = production runner. Console = diagnostic with --once / --tag / --list. x86_64 Linux, dynamic libmodbus + libmosquitto1 required (apt-get install libmodbus5 libmosquitto1).