Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 43 additions & 54 deletions 53-municipal-wastewater-lift-station-monitor/README.md

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

Hardware:
- Notecarrier CX (Cygnet STM32L433 host)
- Notecard Cell+WiFi MBGLW (M.2 slot)
- Notecard for Skylo NOTE-NBGLWX (M.2 slot) — cellular + WiFi + Skylo
satellite (NTN) on one board; card.transport selects cellular-primary
with automatic satellite fallback (see notecardConfigure()).
- 4-20 mA submersible level transducer → A0 (150 Ω shunt to GND)
- SCT-013-030 split-core CT, pump 1 → A1 (bias circuit)
- SCT-013-030 split-core CT, pump 2 → A2 (bias circuit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ float clampF(double v, float minv, float maxv, float fallback) {
}

// ---------------------------------------------------------------------------
// notecardConfigure — cold-boot hub.set (periodic mode) and accelerometer
// disable. PRODUCT_UID is included here and in applyHubSetIfChanged() so that
// any successful hub.set, regardless of call site, binds the device to the
// intended Notehub project.
// notecardConfigure — cold-boot hub.set (periodic mode), transport selection,
// and accelerometer disable. PRODUCT_UID is included here and in
// applyHubSetIfChanged() so that any successful hub.set, regardless of call
// site, binds the device to the intended Notehub project.
// ---------------------------------------------------------------------------
void notecardConfigure(void) {
J *req = notecard.newRequest("hub.set");
Expand All @@ -86,6 +86,27 @@ void notecardConfigure(void) {
Serial.println("[CONFIG] hub.set (cold boot) failed; applyHubSetIfChanged() will retry.");
}

// Transport selection for the Notecard for Skylo (NOTE-NBGLWX).
// The board carries WiFi, cellular, and Skylo satellite (NTN) radios, but
// satellite fallback is NOT enabled by default — the factory transport is
// "wifi-cell" (WiFi preferred, cellular fallback, no NTN). Set "wifi-cell-ntn"
// so the Notecard prefers WiFi where an AP is reachable, falls back to
// cellular (the de-facto primary at most stations), and finally to Skylo
// satellite at stations beyond terrestrial coverage — automatic failover
// with no firmware branching. The Notecard persists this setting in its own
// flash, so issuing it once on cold boot is sufficient.
//
// Note: Skylo requires at least one non-NTN (cellular or WiFi) sync to
// associate with Notehub and register templates before NTN can be used.
// In "periodic" mode the cold-boot hub.set above triggers that first sync
// over cellular/WiFi, so commission each unit where it has terrestrial
// coverage even if it will routinely operate over satellite.
req = notecard.newRequest("card.transport");
JAddStringToObject(req, "method", "wifi-cell-ntn");
if (!notecard.sendRequestWithRetry(req, 10)) {
Serial.println("[CONFIG] card.transport (wifi-cell-ntn) failed; will retry on next cold boot.");
}

// Disable the onboard accelerometer to keep scope traces clean during
// bench validation — removes occasional interrupt-driven current blips.
req = notecard.newRequest("card.motion.mode");
Expand All @@ -104,7 +125,8 @@ bool defineTemplates(void) {

// lift_alert.qo: immediate-sync alert notes (low volume, real-time).
// format:"compact" produces a fixed-width binary encoding that keeps
// each Note well within Starnote for Skylo's 256-byte payload ceiling.
// each Note well within the 256-byte payload ceiling enforced when the
// Notecard for Skylo is transmitting over the satellite (NTN) link.
// level_pct may carry LEVEL_INVALID_SENTINEL (-9999) when the level sensor
// is faulted; the 4-byte float field accommodates any float value.
J *req = notecard.newRequest("note.template");
Expand All @@ -123,7 +145,7 @@ bool defineTemplates(void) {
}

// lift_summary.qo: hourly aggregates (batched outbound sync).
// format:"compact" keeps the note within the 256-byte satellite ceiling.
// format:"compact" keeps the note within the 256-byte NTN (satellite) ceiling.
// level_pct and level_avg_pct may carry LEVEL_INVALID_SENTINEL; the 4-byte
// float field accommodates any float value. level_faults counts samples in
// the window where the level sensor returned an out-of-range ADC value
Expand Down
14 changes: 7 additions & 7 deletions 54-multi-site-walk-in-cooler-energy-setpoint-monitor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ This project is a cellular [energy savings](https://blues.com/energy-savings/) r

## 1. Project Overview

**The problem.** For a chain QSR (quick-service restaurant), c-store (convenience store), or grocery operator, the walk-in cooler is one of the most expensive assets in a store, and one of the least visible. Energy cost per location is second only to labor, and a significant fraction of that energy budget runs through the compressor of one or more walk-in boxes. Operators who get visibility into compressor runtime, door discipline, and temperature trends across their fleet can cut energy spend materially: a door held open five minutes longer than necessary during a busy lunch rush costs real money in wasted refrigeration, and a compressor running six hours a day instead of four because box air temperature has quietly drifted 2 °F above the corporate temperature target costs even more at scale.
**The problem.** For a chain QSR (quick-service restaurant), convenience store, or grocery operator, the walk-in cooler is one of the most expensive assets in a store, and one of the least visible. Energy cost per location is second only to labor, and a significant fraction of that energy budget runs through the compressor of one or more walk-in boxes. Operators who get visibility into compressor runtime, door discipline, and temperature trends across their fleet can cut energy spend materially: a door held open five minutes longer than necessary during a busy lunch rush costs real money in wasted refrigeration, and a compressor running six hours a day instead of four because box air temperature has quietly drifted 2 °F above the corporate temperature target costs even more at scale.

The harder problem is that an operator running 800 locations has 800 different network environments — franchisees on consumer ISPs, independent operators with POS (point-of-sale) systems that their IT vendors won't let anyone touch, c-stores with back-office networks that preclude any new guest devices. Getting corporate visibility through all of that friction is the barrier that keeps most energy-monitoring pilots from becoming fleet-wide programs. The pilot sites get instrumented; the rollout stalls at 50.
The harder problem is that an operator running 800 locations has 800 different network environments — franchisees on consumer ISPs, independent operators with POS (point-of-sale) systems that their IT vendors won't let anyone touch, convenience stores with back-office networks that preclude any new guest devices. Getting corporate visibility through all of that friction is the barrier that keeps most energy-monitoring pilots from becoming fleet-wide programs. The pilot sites get instrumented; the rollout stalls at 50.

This project is the device that gets past that barrier. One SKU, cellular-connected, no IT ticket required. Stick a temperature probe inside the box, clamp a split-core current transformer on the compressor hot leg, mount a magnetic reed switch on the door, and you get a per-unit compressor energy proxy — compressor apparent kWh per summary window (per-day totals derived downstream by summing `kwh_window` records), door-open events, and temperature-to-target deviation — delivered to Notehub and routed wherever corporate needs it.

Expand All @@ -30,11 +30,11 @@ This project is the device that gets past that barrier. One SKU, cellular-connec

**Device-side responsibilities.** Inside the cooler's mechanical-room enclosure, the Cygnet STM32 host on the Notecarrier CX comes up every `sample_interval_sec` seconds (default 60), reads all three sensors, updates the per-window accumulators (kWh proxy, compressor runtime, door open seconds and event count), and runs the two alert rules. Then it either queues a summary [Note](https://dev.blues.io/api-reference/glossary/#note) for the next window or goes straight back to sleep. Between wakes the host is fully powered down via [`card.attn`](https://dev.blues.io/api-reference/notecard-api/card-requests/#card-attn) — the Notecard holds the sleep state and brings the host back when the next interval lands.

**Notecard responsibilities.** Whatever the host queues, the Notecard takes care of. Notes wait in the on-device queue until the [`hub.set`](https://dev.blues.io/api-reference/notecard-api/hub-requests/#hub-set) `outbound` cadence (default 60 minutes) opens a cellular (or opportunistic WiFi) session and flushes them in one batch. Anything tagged `sync:true` skips the queue and the radio comes up immediately. The Notecard also pulls [environment variables](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables/) from Notehub on every inbound sync — setpoint targets, alert timers, and cadences all tunable from a browser, no firmware reflash, no field visit.
**Notecard responsibilities.** Whatever the host queues, the Notecard takes care of. Notes wait in the on-device queue until the [`hub.set`](https://dev.blues.io/api-reference/notecard-api/hub-requests/#hub-set) `outbound` cadence (default 60 minutes) opens a cellular (or opportunistic WiFi) session and flushes them in one batch. Anything tagged `sync:true` skips the queue and the radio comes up immediately. The Notecard also pulls [environment variables](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables/) from Notehub on every inbound sync — setpoint targets, alert timers, and cadences all tunable from a browser, no firmware updates or field visits required.

**Notehub responsibilities.** The Notecard's embedded global SIM lands events in [Notehub](https://notehub.io), which ingests them, stores every one, and runs the project-level routes. Summaries and alerts go to separate [Notefiles](https://dev.blues.io/api-reference/glossary/#notefile) on purpose: `cooler_summary.qo` for the hourly telemetry that flows to BI or a long-term store, and `cooler_alert.qo` for the immediate notifications that need to land on a phone or a Slack channel — no filter logic inside the route, just two streams pointed at the right destinations. [Fleets](https://dev.blues.io/guides-and-tutorials/fleet-admin-guide/) and [Smart Fleets](https://dev.blues.io/notehub/notehub-walkthrough/#using-smart-fleet-rules) make it easy to set a corporate temperature target per banner or region while still overriding the one flagship that runs tighter.
**Notehub responsibilities.** The Notecard's embedded global SIM lands events in [Blues Notehub](https://notehub.io), which ingests them, stores every one, and runs the project-level routes to your cloud application of choice. Summaries and alerts go to separate JSON-based [Notefiles](https://dev.blues.io/api-reference/glossary/#notefile) on purpose: `cooler_summary.qo` for the hourly telemetry that flows to BI or a long-term store, and `cooler_alert.qo` for the immediate notifications that need to land on a phone or a Slack channel — no filter logic inside the route, just two streams pointed at the right destinations. [Fleets](https://dev.blues.io/guides-and-tutorials/fleet-admin-guide/) and [Smart Fleets](https://dev.blues.io/notehub/notehub-walkthrough/#using-smart-fleet-rules) make it easy to set a corporate temperature target per banner or region while still overriding the one flagship that runs tighter.

**Routing to the cloud (high level).** Notehub supports HTTP, MQTT, AWS, Azure, GCP, Snowflake, and other destinations. Route configuration is project-specific — this project ships no downstream endpoint. See the [Notehub routing docs](https://dev.blues.io/notehub/notehub-walkthrough/#routing-data-with-notehub) for setup details.
**Routing to the cloud.** Notehub supports HTTP, MQTT, AWS, Azure, GCP, Snowflake, and other destinations. Route configuration is project-specific — this project ships no downstream endpoint. See the [Notehub routing docs](https://dev.blues.io/notehub/notehub-walkthrough/#routing-data-with-notehub) for setup details.

## 3. Technical Summary

Expand Down Expand Up @@ -82,7 +82,7 @@ After completing this project, you will deploy a complete cellular-connected wal

1. **Three non-invasive sensors** mounted on the cooler (temperature probe in the box, current transformer clamp on the compressor hot leg, magnetic reed switch on the door) — no electrical changes required, no cooperation from the cooler's OEM.

2. **A local enclosure** (Notecarrier CX with onboard Cygnet host, Notecard Cell+WiFi, power supply, and bias/pull-up circuits) that samples all three sensors every 60 seconds and automatically sleeps between samples.
2. **A local enclosure** (Notecarrier CX with onboard Cygnet STM32 host, Notecard Cell+WiFi, power supply, and bias/pull-up circuits) that samples all three sensors every 60 seconds and automatically sleeps between samples.

3. **Notehub as your cloud backend**, storing and routing two streams of data:
- **Telemetry**: One summary event per hour per cooler, containing averages (temperature, compressor amps) and totals (runtime minutes, door-open events, apparent kWh, window duration).
Expand Down Expand Up @@ -165,7 +165,7 @@ Pin-by-pin connections:
1. **Create a project.** Sign up at [notehub.io](https://notehub.io) and create a project. Copy the [ProductUID](https://dev.blues.io/notehub/notehub-walkthrough/#finding-a-productuid) and paste it into `firmware/cooler_monitor/cooler_monitor.ino` as the `PRODUCT_UID` constant before flashing.
2. **Claim the Notecard.** Power the unit; on first cellular connection the Notecard associates with your project automatically.
3. **Create Fleets.** The natural grouping for a multi-site cooler program is one [Fleet](https://dev.blues.io/guides-and-tutorials/fleet-admin-guide/) per banner or region — every store in a given franchise territory typically shares the same setpoint targets and alert thresholds. [Smart Fleet](https://dev.blues.io/notehub/notehub-walkthrough/#using-smart-fleet-rules) rules let you break out exceptions automatically (e.g., flagship stores with tighter temperature tolerances) without manual device reassignment.
4. **Set environment variables.** All variables below are optional; firmware defaults apply until overridden. Any variable set in Notehub takes effect on the device's next inbound sync — no reflash required. **To set a variable in Notehub:** navigate to your project → Devices (or Fleet) → scroll down to Environment Variables → click "Edit" (JSON view) → add or update the variable and save. The firmware configures the Notecard's `inbound` sync interval to `2 × summary_interval_min` (so 120 minutes at the default `summary_interval_min = 60`), which is when the Notecard pulls fresh env-var values from Notehub into its on-device cache. The host then picks the new values up on its next 60-second wake. **Worst-case time from "save in Notehub" to "value applied on the device" is therefore roughly the inbound interval (up to 120 minutes by default) plus one sample cycle (~60 seconds).** To exercise the full path quickly during commissioning, lower `summary_interval_min` (which also halves the inbound interval) or trigger an immediate session via `hub.sync` from the [Blues In-Browser Terminal](https://dev.blues.io/terminal/).
4. **Set environment variables.** All variables below are optional; firmware defaults apply until overridden. Any variable set in Notehub takes effect on the device's next inbound sync — no reflash required. **To set a variable in Notehub:** navigate to your project → Devices (or Fleet) → scroll down to Settings/Environment Variables → add or update the variable and save. The firmware configures the Notecard's `inbound` sync interval to `2 × summary_interval_min` (so 120 minutes at the default `summary_interval_min = 60`), which is when the Notecard pulls fresh env-var values from Notehub into its on-device cache. The host then picks the new values up on its next 60-second wake. **Worst-case time from "save in Notehub" to "value applied on the device" is therefore roughly the inbound interval (up to 120 minutes by default) plus one sample cycle (~60 seconds).** To exercise the full path quickly during commissioning, lower `summary_interval_min` (which also halves the inbound interval) or trigger an immediate session via `hub.sync` from the [Blues In-Browser Terminal](https://dev.blues.io/terminal/).

| Variable | Default | Purpose |
|---|---|---|
Expand Down
Loading
Loading