Context
PR #50 rewrote the standard Indigo ZoneOn sprinkler action handler. The new branch contains real logic (seconds → minutes conversion, clamp to maxZoneRunTime, max(1, round(...)) floor) that has zero direct test coverage because plugin.py historically can't be unit-tested — it needs the indigo runtime.
The conversion math itself is pure and doesn't need Indigo. PR review pointed out that extracting it into a module-level helper would close the only meaningful logic gap introduced by #50.
Proposed change
Pull the duration conversion out into a helper that can live in utils.py or device_handlers.py:
def compute_zone_duration_minutes(zone_max_seconds: int, cap_seconds: int) -> int:
\"\"\"Compute the Netro API duration for a zone.
Netro takes minutes on the wire; Indigo's zoneMaxDurations is in seconds.
Returns at least 1 (Netro rejects 0) and never exceeds `cap_seconds`
converted to minutes.
\"\"\"
seconds = min(zone_max_seconds, cap_seconds)
return max(1, int(round(seconds / 60)))
Then plugin.py ZoneOn becomes:
duration_minutes = compute_zone_duration_minutes(
zone_max_seconds, self.maxZoneRunTime
)
Test cases to add
- Basic conversion (3600s cap, 1800s zone → 30min)
- Cap lower than zone max (1800s cap, 3600s zone → 30min)
- Fractional minutes round correctly (90s → 2min via
round)
- 30 seconds floors to 1 minute, not 0
- Zero zone max still returns 1 (even though ZoneOn refuses
<= 0 upstream, this keeps the helper safe)
Scope
Small. Pure refactor + ~5 unit tests. Follow-up from #50 review, non-blocking.
Context
PR #50 rewrote the standard Indigo
ZoneOnsprinkler action handler. The new branch contains real logic (seconds → minutes conversion, clamp tomaxZoneRunTime,max(1, round(...))floor) that has zero direct test coverage becauseplugin.pyhistorically can't be unit-tested — it needs theindigoruntime.The conversion math itself is pure and doesn't need Indigo. PR review pointed out that extracting it into a module-level helper would close the only meaningful logic gap introduced by #50.
Proposed change
Pull the duration conversion out into a helper that can live in
utils.pyordevice_handlers.py:Then
plugin.pyZoneOn becomes:Test cases to add
round)<= 0upstream, this keeps the helper safe)Scope
Small. Pure refactor + ~5 unit tests. Follow-up from #50 review, non-blocking.