Back to Projects
Next.jsInfluxDB 3MQTTK3s

SpectraIO — Industrial Vibration Observability

A condition-monitoring platform for rotating equipment: battery-powered wireless vibration sensors on the machine, an IIoT gateway with its own cellular uplink, and a self-hosted pipeline that turns every reading into a stored spectrum, a trend, and — when a threshold is crossed — an alert on somebody's phone.

Running in production today on a live fleet at an operating cement plant — crushers, vane compressors, gearboxes and motors — streaming over 4G, and serving two organizations from a single codebase.

The Problem

Vibration analysis is how you catch a failing bearing weeks before it seizes. Doing it properly has traditionally meant one of two things: a technician walking the plant with a handheld collector on a monthly route, or a six-figure enterprise platform wired into the plant network.

The first misses anything that develops between routes. The second was not available here, for a reason that has nothing to do with budget: the plant network is off limits. Nothing plugs into it, and no inbound port is opened anywhere — not at the plant, not at the platform.

That single constraint rules out most of the market.

The Constraints That Defined the Design

ConstraintConsequence
The link is cellular, metered, and shared by the whole siteEvery byte is a design decision. A full reading costs about 1 MB, so it has to be worth sending
The plant network is off limitsNo inbound ports anywhere. Nothing plugs into OT
An analyst needs resolution, not a pretty chart~31 CPM at the frequencies where bearing faults live, with every stored point rendered
The site is unattendedAn outage nobody is notified about is an outage that lasts 19 hours — measured, not hypothetical

The Solution

  • Edge: CTC wireless vibration sensors → Access360 gateway → HiveMQ over MQTT 5.0, on a cellular uplink independent of the plant network
  • Ingestion: a purpose-built multi-gateway ingester microservice writing into InfluxDB 3 Enterprise, queried over Flight SQL
  • Application: Next.js and TypeScript with Apache ECharts on Canvas, rendering 4,000 stored FFT bins per axis
  • Exposure: Cloudflare Tunnel — no port forwarding, no public IP, and the data plane stays entirely private
  • Analysis: bearing fault-frequency markers (BPFO, BPFI, BSF, FTF), a harmonic ruler, band zoom and per-axis statistics

Multi-Tenant From the Start

One codebase serves two organizations, with white-labelled instances carrying each customer's own branding. Tenant separation, per-tenant thresholds and role separation are part of the data model rather than a deployment trick — which is what makes adding the third organization a configuration change instead of a fork.

Engineering Decisions Worth Naming

Server-side downsampling. Frontend payloads are held to roughly 2,000 points per request. On a metered cellular link shared with the plant's own traffic, the query engine does the reduction, not the browser.

SQL over Flux. InfluxDB 3 is queried via Flight SQL exclusively. Committing to one query path kept the data layer legible as the schema grew.

Alerting is part of the product, not an add-on. The 19-hour outage in the table above is a real measurement from an early deployment. An unattended site with no alerting is not monitored — it is merely instrumented.

Stack

  • Frontend: Next.js, TypeScript, Apache ECharts
  • Data: InfluxDB 3 Enterprise, Flight SQL
  • Messaging: HiveMQ, MQTT 5.0
  • Edge: CTC dynamic sensors, Access360 gateway, cellular router
  • Platform: Docker for beta, K3s for production, Cloudflare Tunnel
  • Observability: Grafana, structured logs, query latency and error metrics

Links

The application source is private. Live demo on request.