Skip to content

feat: UI for pairing Whisperer sensors to zones; prefer sensor over daily forecast #54

Description

@simons-plugins

Problem

Today a user observed their Pixie zone showing 89% moisture in Indigo while the Netro mobile app showed 24% for the same zone. Investigation confirmed:

  • /moistures.json returns Netro's smart-model daily prediction (model assumes saturation post-irrigation and decays over days) — for this zone today, 89%.
  • The Whisperer sensor paired to that zone shows the actual soil reading, ~22–31% throughout the day, currently 24%.
  • Netro's mobile app renders the Whisperer reading on the zone tile when a Whisperer is paired in the account. The public API doesn't expose this pairing.

Confirmed by comparing yesterday's data on the same zone:

  • Whisperer sensor range for 2026-04-21: 19–29% (24 readings, hourly)
  • /moistures.json row for same zone, same date: 89%

So /moistures.json is not the sensor reading — it's a model prediction that can be dramatically different from ground truth. Plugin reads both correctly, but they surface on different Indigo devices with no linkage.

Proposed solution

Add a per-zone Whisperer pairing in device config UI (Devices.xml + ConfigUI callback):

  1. On the zone device config, add a dropdown linkedWhispererDeviceId populated with this plugin's Whisperer devices + an "(unpaired)" option.
  2. In _update_zone_devices / process_zone_moisture, when a Whisperer is paired: write the Whisperer's latest soilMoisture / sensorValue into the zone's moisture state instead of (or in addition to) the daily forecast row.
  3. Add a separate state moistureForecast on the zone so the daily /moistures.json value is still observable (useful for comparing model vs reality, tuning schedules, etc.).
  4. No auto-pairing — explicit config only, to avoid brittle name-matching.

Out of scope

Documentation follow-up

docs/API_NOTES.md §6 currently says moisture "can be 12–24 hours old" — update to clarify it's a model prediction, not a sampled sensor value, and can diverge significantly from a paired Whisperer's actual reading.

Acceptance

  • Zone device config has a Whisperer dropdown
  • When paired, zone moisture state mirrors Whisperer's current reading
  • moistureForecast state exposes the /moistures.json daily value
  • Tests covering paired / unpaired / Whisperer unavailable paths
  • API_NOTES.md updated to describe /moistures.json as predicted, not observed

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions