Bhargav Urs Sumantharaj

AgriPulse HMI

not publicly deployed

A real-time mobile control panel for a smart irrigation pump, built to behave like an industrial controller rather than a dashboard.

Architecture

  • React Native 0.86 (operator app), client. The operator's control panel: live telemetry, pump control, alert acknowledgement, and an SVG gauge drawn for the industrial look. Connected from Android native module over bridge. Connected to Safety interlocks over Socket.IO, operator namespace.
  • Android native module (NetworkDiagnosticsModule, Java), client. OS-level network diagnostics: connection type, reachability, and latency to the backend, measured with raw sockets. Connected to React Native 0.86 over bridge. Connected to Safety interlocks over TCP probes.
  • Safety interlocks (server-authoritative), service. The gate in front of every pump command: tank level, device online, emergency stop latch, already-running state, and a maximum-runtime auto-stop. Connected from React Native 0.86 over Socket.IO, operator namespace. Connected from Android native module over TCP probes. Connected to In-memory device state cache.
  • Weather automation (pure rule function), service. Decides irrigation from weather and telemetry as a pure rule function, and stores every decision with its inputs and its reasoning. Connected to In-memory device state cache. Connected to Open-Meteo over HTTPS.
  • In-memory device state cache, service. Holds current device state in memory to serve the hot paths: safety checks and automation decisions. Connected from Virtual IoT device simulator over Socket.IO, device namespace. Connected from Safety interlocks. Connected from Weather automation. Connected to Throttled writes.
  • Throttled writes, service. Flushes the telemetry stream to PostgreSQL at a bounded rate as the durable record. Connected from In-memory device state cache. Connected to PostgreSQL 16 over Prisma.
  • PostgreSQL 16 (via Prisma, 7 tables), datastore. The durable record: telemetry history, decisions with reasoning, alerts, and device configuration, with native enums and indexed time series. Connected from Throttled writes over Prisma.
  • Virtual IoT device simulator (swaps for ESP32 / Pi), service. A deterministic, physically grounded stand-in for the pump controller, speaking the exact protocol real hardware would. Connected to In-memory device state cache over Socket.IO, device namespace.
  • Open-Meteo, external. Supplies the forecast the automation engine folds into its irrigation decisions. Connected from Weather automation over HTTPS.
  • Boundary: Node 22 + Express backend.

Decisions

  • Two namespaces, two audiences

    The decision
    Device traffic and operator apps connect over two separate Socket.IO namespaces.
    The constraint that forced it
    Devices and operators have different message vocabularies and failure modes, and a real device-fleet backend keeps them apart.
    Rejected
    One namespace with message-type switching, which lets a buggy device broadcast into operator channels.
    Consequence accepted
    Two connection paths to test, and the separation the schematic shows survives into the code.
  • The server is the authority

    The decision
    Every safety-relevant decision runs server-side: low tank, offline device, latched emergency stop, already-running state, and a maximum-runtime auto-stop.
    The constraint that forced it
    The client can be stale, buggy, or hostile, and the pump is a physical actuator.
    Rejected
    Client-side guards in the app.
    Consequence accepted
    The server carries the full state machine, and UI affordances can only ever be hints.
  • Hot state in memory, history on disk

    The decision
    An in-memory device state cache serves safety checks and automation, with throttled writes to PostgreSQL as the durable record.
    The constraint that forced it
    A high-frequency telemetry stream would otherwise put a database round trip inside the safety path and grow the database without bound.
    Rejected
    Reading and writing Postgres on every message.
    Consequence accepted
    Bounded database growth and fast checks, in exchange for buffered-loss risk on crash and a single-process cache.
  • Decisions carry their reasoning

    The decision
    The automation engine is a pure rule function, and every decision is stored with its inputs and its reasoning.
    The constraint that forced it
    An automation that cannot explain a skipped irrigation is an automation operators will not trust.
    Rejected
    Logging outcomes only.
    Consequence accepted
    "Why did it skip irrigation at 6am" has an answer in the database, and the function is unit-testable without hardware.
  • A simulator with physics

    The decision
    The simulator is deterministic and physically grounded: a fixed daily temperature curve, relative humidity computed from temperature via the Magnus equation, temperature-scaled evaporation, and a stochastic rain probability model.
    The constraint that forced it
    There is no physical pump, and the system still has to be built and tested end to end.
    Rejected
    Canned telemetry replay, which cannot respond to commands.
    Consequence accepted
    It connects over the exact protocol a real ESP32 or Raspberry Pi controller would use, so hardware can replace it without changing the backend or the app.
  • Native code where JavaScript cannot go

    The decision
    A custom Android module in Java performs OS-level network diagnostics, running blocking checks on a background thread.
    The constraint that forced it
    Connection type, reachability, and honest latency to the backend are invisible to JavaScript.
    Rejected
    A community library reporting what the OS volunteers.
    Consequence accepted
    Real diagnostics in the app, and an iOS implementation still owed behind the same bridge.
  • Charts drawn by hand

    The decision
    Charts and the radial gauge are drawn directly in SVG rather than pulled from a charting library.
    The constraint that forced it
    The industrial look needs exact control of ticks, needles, and thresholds that chart libraries abstract away.
    Rejected
    A charting library themed to approximate the look.
    Consequence accepted
    More drawing code owned in the repository, zero library weight, and a gauge that reads as an instrument instead of a widget.

Known limitations

  • The device is simulated. That is a strength in one sense, a hardware-ready architecture built without hardware, but it must never be mistaken for a physical deployment.
  • There is no authentication on the operator app.
  • There is no fleet model: the system supervises one device.