jasonandClaude Sonnet 5 05708cb64f CLAUDE.md: document commit-message conventions
The history had to be rewritten today: plant values and confidential
document names sat in commit messages even after the working tree was
cleaned (61c7d0c), and several messages ran longer than the diff they
described. Writing the rule down so it doesn't happen again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CBgcWynhMWssnCEV2xM5FU
2026-09-08 16:16:50 +02:00
2026-09-08 15:59:13 +02:00
2026-09-08 15:59:13 +02:00

vibrato

Data collector for condition monitoring of a vibratory conveyor. It reads sensor values over IO-Link (an ifm AL1352 master, 8 ports) and Modbus RTU (an Eastron energy meter), and writes them as raw daily CSV files for a reporting tool (Power BI) to read.

vibrato does not evaluate anything — no thresholds, no alarms, no aggregation at write time. Raw rows can always be turned into aggregates later; the reverse is never true, and which aggregate will actually matter isn't known yet. So vibrato collects and stores; the analysis — reference bands, thresholds, charts — happens downstream against the same files, in whatever tool is chosen for that, deliberately not decided here.

Data sources

  • Six Balluff BCM0003 vibration sensors (bearings, trough sides, drive motor, counterweight) — time-domain statistics cyclically via a configurable Custom Process Data Profile, the rest acyclically over ISDU; frequency bands acyclically; full spectra over IO-Link BLOB Transfer (transport implemented, payload decoding still pending — see "Status").
  • One Balluff BCM0001 ambient-temperature sensor (contact temperature, the reference for every other temperature channel) — a different device on the wire despite the physical resemblance to the BCM0003; see internal/decode's package doc.
  • One ifm DI6004 speed/runtime-hours sensor.
  • One Eastron SDM630MCT V2 energy meter over Modbus RTU.

Storage format

One CSV file per day per data set, UTC-dated, completed days compressed to .csv.gz. Wide format for most data sets, long format for spectra. Keys instead of free text, with a catalog (internal/catalog) carrying the display names and units — written out as CSV into <data_dir>/catalog/ on every start, next to the data it describes. No database — a documented, open format any successor can read without tooling or a running service.

<data_dir>/
  catalog/                                measurement-point/quantity lookup CSVs
  status/status_<date>.csv                port-watch snapshot, once a minute
  devices/devices_<date>.csv              which sensor sat where, once a day
  ambient/ambient_<date>.csv
  power/power_<date>.csv
  speed/speed_<date>.csv
  vibration/<CODE>/vibration_<CODE>_<date>.csv
  vibration_acyclic/<CODE>/vibration_acyclic_<CODE>_<date>.csv
  spectra/<CODE>/spectra_<CODE>_<date>.csv        long format, one row per band

<CODE> is one of the six vibration locations (config/example.toml, [[location]]); those three data sets are split per location because each location's profile gives it its own column set, which would otherwise collide in one file. A header change within a day gets a numeric suffix (..._<date>_2.csv) rather than breaking the existing file's columns. state_dir (default /var/lib/vibrato/state) holds vibrato's own operating state — currently just the runtime-hours counter — deliberately outside data_dir, since Power BI reads data_dir as a whole tree.

Layout

cmd/vibrato/          the collector service
cmd/vibrato-probe/     commissioning tool: dump raw process data, ISDU
                       parameters, or full-spectrum BLOBs from real
                       hardware
cmd/vibrato-sim/       dependency-free simulator (IoT Core HTTP + Modbus
                       TCP) for development without hardware
internal/config/       TOML configuration
internal/catalog/      measurement-point and quantity catalogs
internal/iolink/       AL1352 IoT Core client (JSON/HTTP), incl. generic
                       BLOB Transfer
internal/decode/       device-specific byte layouts (BCM0003, BCM0001,
                       DI6004)
internal/modbus/       Eastron SDM630 client (Modbus RTU)
internal/sink/         CSV writer: daily rotation, compression,
                       per-location partitioning
internal/scheduler/    per-channel-group polling
internal/portwatch/    read-failure tracking, feeds the "status" data set
internal/runstate/     tracks whether the machine is running
internal/runtimehours/ monotonic persistence of the runtime-hours counter
internal/clocksync/    system clock sync check (platform-specific)
config/example.toml    generic configuration template, no plant reference
deploy/vibrato.service systemd unit — the Linux option, not a decision that
                       Linux is the target platform; that choice is still open
deploy/vibrato-windows-install.ps1
                       registers vibrato as a Windows service (incl.
                       its Event Log source) — the Windows option,
                       equally not a requirement

Build

go build ./...

Static binaries, no external runtime dependencies. Go 1.27; the module is git.streifling.com/jason/vibrato.

Configure

Copy config/example.toml (a generic template — no plant reference) to a config.local.toml or similar (anything matching *.local.toml is git-ignored) and fill in the real addresses, port mapping, and sample rates. Nothing plant-specific belongs in the repository.

Run

Against the bundled simulator, no hardware needed:

go build -o bin/ ./...
bin/vibrato-sim &
bin/vibrato -config config/example.toml

vibrato-sim takes -http, -modbus, -speed-port, and -ambient-port to match a given configuration; see cmd/vibrato-sim -h.

Against real hardware, first confirm the wire format with vibrato-probe: -isdu index[.subindex] reads any ISDU parameter raw, and -full-spectrum (with -full-spectrum-axis) captures a full-spectrum BLOB and dumps its raw bytes. Neither writes to the data directory — they exist to let a decoder table be checked against a real device in minutes, not to run the collector.

Test

gofmt -l .
go vet ./...
go test -race ./...

Status

Collecting real data end to end: all six vibration locations, ambient temperature, speed/runtime-hours, and the energy meter read their real sources — no placeholders anywhere in the code. Frequency bands and the acyclic time-domain statistics that don't fit the cyclic profile are both implemented. Full-spectrum acquisition over BLOB Transfer is implemented as far as the transport goes (vibrato-probe -full-spectrum); decoding the payload into frequency lines isn't — its internal byte layout isn't documented in any specification obtained so far, and a wrong guess would silently mislabel every value rather than fail loudly, so it stays undecoded until a captured BLOB or further documentation settles the format. The target operating system for the collector itself is not yet decided; the code is kept platform-independent accordingly.

License

MIT — see LICENSE. The plant this runs against is not public: no plant or company names, addresses, credentials, measured values, or manufacturer document text belong in this repository.

S
Description
Auswertung von Sensordaten einer Industriemaschine.
Readme MIT
311 KiB
Languages
Go 98.4%
PowerShell 1.6%