PhloMetricWater Meter System
Receiver · FW 2.15.2-sx915

Water Meter Node

The Node is the device that hears your water meter. It's an ESP32 with a 900 MHz FSK radio that locks onto the utility meter you own, decodes its readings, shows that one meter on a built-in dashboard, and forwards each new reading to the Gateway over a long-range LoRa link carried by the same radio.

It's designed to be drop-in: the firmware auto-detects the SX1262's clock source, runs a small AP fallback so you can always reach the setup page, and updates over the air from any browser, including iPhone. By design it surfaces only your default meter; see Privacy and liability below.

Water Meter Node dashboard at 192.168.0.104 in normal mode: status chips for the LoRa mesh link (Mesh TX and Mesh ACK counters), and the Meters table labelled 'Showing your default meter only' listing a single row, the owner's meter 00114524, with volume, RSSI and last-seen.
live: 192.168.0.104 · SX1262 · LoRa mesh · normal mode · shows only your default meter

What it does, in plain English

Utility water meters transmit a small radio packet a few times a minute reporting their cumulative volume. The Node tunes to that signal, validates the CRC, looks up the meter in its memory by serial number, and updates the volume reading. If the volume went backwards or didn't move, the reading is suppressed. Otherwise it gets forwarded to the Gateway and shown on the dashboard.

The Node is bound to one default meter, the meter you own. Even though the radio can hear other meters in range, normal operation shows, emails, and forwards only that one (see Privacy and liability).

Three different meter protocols are supported, covering a range of utility meters deployed in U.S. utilities since the mid-2000s. The Node picks the right one based on its /setup configuration.

Privacy and liability: the Node works on your meter

The 900 MHz band these meters use is shared, so any receiver in range can physically demodulate nearby utility meters, not just one. That is a liability question as much as a technical one: whoever runs the Node should not be collecting, displaying, or transmitting a neighbor's consumption data.

So the Node is bound to a single default meter: the meter owned by the utility customer who installs the Node. In normal operation the dashboard, the JSON API, the email reports, and the mesh upload to the Gateway all surface only that one meter. Everything else the radio happens to hear is withheld at the source. The filter is server-side on the device, not cosmetic page-hiding, so it holds for scripts and agents hitting the API too.

The full list of in-range meters and the radio internals are reachable only in debug mode, which is gated by the access-point password and lives in RAM only: it is off at every boot and after any power loss. There is no persistent "see everything" switch to leave on by accident.

Node dashboard in normal mode: the Meters table reads 'Showing your default meter only' and lists a single row, the owner's meter 00114524.
normal mode · one row: your default meter (00114524)
The same Node dashboard in debug mode: the Meters table reads '29 meters (debug)' and now lists the full in-range list, including neighbor meter 02699697 that the radio can hear but normally hides.
debug mode (password-gated, RAM-only) · reveals the full in-range list (29 meters here), e.g. neighbor 02699697, hidden in normal mode

Same Node, same minute; the only difference is the debug flag. The frequency-hopping engine (the "2014WOSE Hopping" block) and the per-protocol decode counters are likewise debug-only diagnostics. The owner's normal view stays scoped to a single meter.

Key features

  • Privacy by default. Bound to a single default meter, the one you own. The dashboard, API, email reports, and mesh upload surface only that meter; every other in-range meter is withheld server-side. A full view requires debug mode, which is access-point-password gated and RAM-only (off after every reboot). See Privacy and liability.
  • One radio, meter receive and mesh. The SX1262 decodes the meters and carries the LoRa mesh uplink from the same chip; no second transceiver. It also auto-detects the clock source, falling back from TCXO to a plain crystal if the oscillator doesn't start, so both TCXO and crystal-clocked SX1262 modules just work without a separate build.
  • Three meter families. GIF2006B (fixed 916.45 MHz, 100 kbps, sub-minute reading updates), GIF2014W-OSE (50-channel frequency hopping across 904.9–924.5 MHz, hourly reading updates), and GIF2020OCECNA (200 kbps). See reporting cadence.
  • One radio, two jobs. The same SX1262 that decodes the meter also carries the mesh: the Node briefly switches it to LoRa at 903.9 MHz, transmits the reading, listens for the Gateway's acknowledgment (or a queued command riding in its place), and returns to meter scanning. Deliveries are ACK-gated and retried until confirmed, an idle Node still checks in every minute so the Gateway can vouch for its health, and there is no second radio to buy or wire.
  • Embedded live dashboard. Your default meter's volume, RSSI, packet count and last-seen, plus a real-time view of GIF2014W-OSE frequency-hopping state. The full per-meter table appears only in debug mode.
  • Diagnostic forensics. Last CRC-fail dump (raw FIFO + decoded bytes), per-protocol decode/CRC/stale counters, sweep logs, all built in for field troubleshooting under debug mode.
  • Email reports. Configurable daily / weekly / monthly summaries via Zoho, with per-meter baseline tracking. Sent to every configured recipient, one message per address so recipients never see each other.
  • OTA updates. Drop a new .bin file on /update from any browser, including iPhone Safari.
  • Local data reset. A password-gated "Clear Meter Data" button on /setup wipes the stored meter table (RAM and flash) on demand, keeping your settings; no gateway command needed.
  • Always-on setup AP. Falls back to its own 192.168.4.1 access point if WiFi credentials are unset or wrong, so it's never permanently bricked by a typo.
  • JSON everywhere. All dashboard data is also available at /api/* as plain JSON for scripts and agents.

Standalone mode: no gateway needed

For small clusters (a single building, a small park, one property), a single Node can be the entire system. It still receives in the band, still surfaces your default meter on its dashboard, still emails that meter's daily report, and still accepts OTA updates. It just doesn't relay anything: the reading lives on the device, visible at its IP on your local WiFi.

The dashboard at the top of this page is exactly this case: one Node at 192.168.0.104 on local WiFi, showing the single meter its owner configured, with no Gateway involved. The Node is reachable directly from any browser on the same LAN; agents and scripts hit its /api/meters endpoint, which returns that same default-meter-only view, without a gateway in the path.

Powering the Node

The recommended hardware installation powers each Node from the 24 V AC supply that's already present in most U.S. residential irrigation controllers. A small inline 24 V AC → 5 V DC converter (with adjustable output to compensate for voltage drop on long cable runs) feeds the ESP32 through its 5 V pin. The Node then lives next to the irrigation valves, on a wire that's already there, and stays online whenever the irrigation system has power.

Input 24 V AC, 50/60 Hz, drawn from the irrigation transformer's common bus
Output Adjustable 5–6 V DC at ~500 mA continuous (sized for the Node's ~250 mA peak draw plus cable losses)
Why adjustable? On long runs the converter can be set slightly above 5 V at the source so the Node still sees a clean 5 V at the far end after IR drop
Why this mattersNo extra wall-wart, no extra outlet; you reuse the wiring that already reaches the valve manifold

Will it read your meter? Check for the endpoint disk

The Node reads a radio endpoint the utility has fitted to the meter, not the dial itself. Before committing to a deployment, confirm the meter you want to read has one. Lift the meter well cover at the property line and look at its center: a readable installation has a round plastic disk seated in the middle of the lid, like the one pictured. That disk is what the Node hears over 900 MHz. If the center of the lid is solid metal with no disk, the meter is a non-transmitting type and this system cannot read it as-is.

A water meter well cover viewed from above, with a round black plastic ORION radio endpoint disk seated in a recess at its center, molded with an ORION logo and an FCC ID. This is the part the Node receives over 900 MHz.
match this · the round plastic ORION endpoint disk in the center of the meter well cover is what the Node reads · see the Installation page for details

The other side of the radio: meter protocols

Whichever meter you point it at, the Node runs one of three decoders. GIF2006B is fixed-frequency at 916.45 MHz, 100 kbps. GIF2014W-OSE frequency-hops across 50 channels from 904.9 to 924.5 MHz, and the firmware tracks that hop schedule in real time to stay locked on your meter. GIF2020OCECNA runs at 200 kbps. The hop engine includes a watchdog that follows the default meter specifically: if your meter goes unheard, the Node re-scans all 50 channels rather than camping on a stronger neighbor it happens to hear.

The debug view above exposes this machinery: the "2014WOSE Hopping" block (current channel, frequency, lock or scan state) and a "Last CRC Fail" panel that keeps the most recent raw FIFO and decoded bytes for postmortem. In normal mode none of that is shown; you just see your meter's latest reading.

Reporting cadence: sub-minute vs. hourly meters

The families differ in more than frequency plan. The decisive difference for analytics is how often the reading inside the packet actually moves. A GIF2006B updates the volume it broadcasts on a sub-minute basis: successive packets track the meter's register nearly in real time, so a Node on a 2006B yields true per-minute interval data. (This is also the dominant meter generation in the Boulder area: AMR-only hardware that micro-AMI upgrades to AMI capability without waiting for the utility to replace the fleet.) A GIF2014W-OSE transmits just as busily, but the volume field it sends refreshes only about once per hour, at a fixed minute characteristic of each individual meter; in between, every packet repeats the same total. The Node suppresses those unchanged rebroadcasts, so a 2014W-OSE naturally produces about one stored reading for each hour in which water actually flowed.

Hourly totals are entirely adequate for daily budgets, usage trends, and after-hours leak alerts, and the Gateway's alert tiers work fine on 2014W-OSE meters. The 2006B's sub-minute cadence unlocks a further level: valve-level fault detection. With per-minute data, an irrigation program resolves into its individual valve steps, each with a characteristic volume and flow rate, and that fingerprint makes single-valve faults observable from the utility meter alone. A clogged or partially closed valve shows up as a low-flow step, a broken head or stuck-open valve as a high one, and an abnormal cycle (wrong start time, a valve cut short, sagging line pressure) stands out the night it happens, not weeks later on a bill.

The Data Matters case study is exactly this capability in the field: a 2006B-cadence meter resolving a six-valve program to within a percent or two per valve, night after night, and surfacing unscheduled watering cycles that a monthly reading could never show.

Specs

MCU ESP32 dual-core (Heltec CT62 / WiFi LoRa 32 footprint)
FSK radio SX1262 (clock source, TCXO or crystal, auto-detected at boot)
Mesh link Shared SX1262, LoRa @ 903.9 MHz (SF10 / 500 kHz), ACK-gated uplinks, 60 s heartbeat liveness
Meter families GIF2006B, GIF2014W-OSE, GIF2020OCECNA (one at a time)
Reading cadence GIF2006B: sub-minute register updates (per-minute interval data); GIF2014W-OSE: hourly register updates at a per-meter fixed minute
Privacy Normal mode exposes only the configured default meter (dashboard, API, email, mesh); the full view requires RAM-only, password-gated debug mode
Network WiFi 802.11 b/g/n STA + fallback AP at 192.168.4.1
Power direct 5 V; ~120 mA idle RX, ~250 mA peak TX
Firmware 2.15.2-sx915 (observable at /api/diag)
OTA POST /update with the new .bin

Web endpoints

All endpoints are HTTP on port 80 of the Node's WiFi IP. JSON endpoints return clean structured data; the HTML dashboard pulls from these same routes.

GET / Live dashboard (meter table, hopping state, mesh counters).
GET /setup Configuration page: WiFi credentials, protocol, mesh ID / node ID, email recipients.
POST /update Firmware upload (multipart). Works from iPhone Safari.
GET /api/diag JSON: uptime, free heap, radio chip, per-protocol decode/CRC counters.
GET /api/meters JSON: in normal mode, your default meter only (id, volume in gal, RSSI, count, last seen); the full list requires debug mode.
GET /api/debug JSON: current debug-mode flag. POST {"enable":true,"password":"…"} (AP password) to reveal all meters + RF internals; RAM-only, off at next boot.
POST /api/clear_db Erase the stored meter table (RAM + flash). {"password":"…"} (AP password) required; returns the number of meters cleared. Default-meter and other config are kept.
GET /api/config JSON: current config; POST the same shape to save.
GET /api/email JSON: scheduled report config; POST to change interval / recipients.
POST /api/email/send_now Trigger an immediate report send (useful for testing SMTP).

Setup page

The /setup endpoint is a single-page configuration UI served straight from the Node. From here you set WiFi credentials, pick the meter family, switch the GIF2014W-OSE receive mode, toggle metering on/off, and configure email reports, all without re-flashing firmware. This is also where you choose the default meter: the page lists the meters in range and lets you pick the one you own; from then on the public dashboard and reports show only that one. The page itself spells it out: "Pick your meter, then the public dashboard shows only this one."

It's also where you clear the node's stored data. The Clear Meter Data button wipes the entire meter table, both the in-RAM copy and the persisted flash database, so a reboot won't reload it. It's protected by the Debug password and prompts for confirmation, and it leaves your default-meter choice, WiFi, and other settings untouched; the table simply rebuilds as meters are heard again. This lets an owner purge any accumulated readings (including stray non-default meters) directly from the device, with no gateway command needed.

The Passwords section lets you change the device's three independent passwords, all shipping as a factory default: the AP/OTA password that secures the WiFi access point and firmware updates, the Setup password for this configuration login, and the Debug password that gates debug mode and Clear Meter Data. A one-click reset returns all three to the factory default using the current AP password, so a forgotten setup or debug password is never a lock-out.

Node /setup page (firmware 2.15.0-sx915): Debug Mode toggle, mesh ID and node ID, protocol and WiFi station settings, meter sampling, the Default Meter selector ('Pick your meter, then the public dashboard shows only this one'), the Debug-password-gated red Clear Meter Data button, the Passwords section for changing the AP/OTA, Setup, and Debug passwords, email-report configuration, and a Gateway Test section with Send Meter Data and Ping Gateway buttons.
live capture of http://<node-ip>/setup · the Default Meter picker scopes the device; the red Clear Meter Data button wipes stored readings; the Gateway Test section sends a reading or pings the gateway on demand · WiFi network name and password masked

$120 / unit Buy a Node or request a quote

For agents

A structured spec of this device is available at /api/node.json. The page above is also annotated with schema.org/Product JSON-LD in <head>.