Public: anyone can read this; the crew can change it.
Migrated from github.com/Trevato/SO-ARM100
Grow light schedule: a switch driver (smart plug, GPIO relay, or uhubctl only when it switches the light alone) with a photoperiod that runs on the Pi #582
Correction (steward, from research): the spinach default photoperiod is 12 h, capped at 14 h. Spinach is long-day sensitive: older lines bolt at 14 h or more, modern lines at about 16 h (Organic Seed Alliance manual; UAF). Cornell runs 16–24 h only for a 14–16 day baby-leaf crop where bolting does not matter. The schedule default is 06:00 + 12 h; the UI warns above 14 h for spinach.
Also a pump (owner: the target system is a vertical tower, see #585): the Switch interface and schedule must support interval cycles (N min on / M min off) as well as a daily photoperiod, with one schedule per switch and both shown on the grow card.
Night light caution (owner asked whether turning the shop light on affects growth): spinach is photoperiod-sensitive, so room light during its dark period can count as day and push bolting. The grow card shows "Dark period: keep room lights off" during the schedule's off-hours, and photos in the dark period use only a ≤2 s photo light (if one is set up).
Already done on main in 82337a2 (#596): the daily photoperiod in the Pi's time zone (light-schedule.ts), the shelly, gpio and uhubctl drivers behind the Switch interface, with uhubctl refusing a ganged hub with a camera on it (light-switch.ts), the grow card with "Dark period: keep room lights off" (light-panel.ts), the owner-only /grow routes and terminal door, and the README Grow section. The pump came in the same commit. Pull #588 is now narrowed to one stricter body-cap test. A person can close this issue as done; my token is refused the close.
Planner: not split. There is nothing left to build. This issue is at its run cap because every run finds the work already on main in 82337a2 (#596), as my note above says. The stricter body-cap test is now #600. Splitting would only hand builders finished work again. My done close is refused (forbidden, missing scope), so a person needs to close this as done. I removed #586's wait on it, so this issue holds nothing up now.
Planner, 2026-10-27. State: done, but I can't close it. The work is on main in 82337a2 (#596) and 0ea35e6 (#599, the switch driver and photoperiod this issue names). My close as done is refused (forbidden: my credentials lack the scope). There is nothing left to split, so a person needs to close this as done. It holds nothing up.
Planner, 2026-10-27 (run 2): done, waiting for a person to close it. I tried the close as done again just now and got forbidden ("your credentials lack the scope for this action"). The work is on main in 82337a2 (#596) and 0ea35e6 (#599). I did not split it: there is nothing left to build, so a split would only hand finished work back to a builder. It holds nothing up.
Planner, 2026-10-27 (run 3): done, waiting for a person to close it. I retried the close as done just now and it was again refused with forbidden (missing scope). The work is on main in 82337a2 (#596) and 0ea35e6 (#599). There is nothing to split, and it holds nothing up.
Hardware facts from the Pi (steward, 2026-10-27 02:40Z):
- The grow light is power-only on hub
1-1, port 2 or 4. The cameras are on1-1port 1 (XWF-1080P) and port 3 (eMeet C960). uhubctl -l 1-1 -p 2,4 -a offreported off, but the light stayed on (the owner checked). The uhubctl README confirms the RPi 4B hub1-1has "4 ports ganged, dual to USB3 hub2", and the VL805 firmware is up to date. The driver's refusal is correct on this Pi.
The plan: a uhubctl-listed hub with real per-port switching. The README lists the UUGear MEGA4 (for Raspberry Pi 4B), 4 ports, USB 3.0. With the light on its own MEGA4 port, {driver:"uhubctl", hub:<MEGA4 location>, port:<n>, cameras:[]} passes verify().
Setup check: it toggles the configured port off for 2 s, checks that no listed camera disappeared from lsusb, and asks the owner to confirm "did the light go off?" in the app before saving the switch. It notes in the UI that a port showing "off" isn't proof on ganged hubs.
Part of the workshop issue. Owner: "setup the light schedule probably by turning the power off and on for the light!"
The hardware truth (probe this first, write it in the README): a Pi 4 cannot switch one USB port alone.
uhubctltoggles all USB ports together (ganged on the VL805, and on this external VIA hub, checkuhubctl -l 1-1). Cutting the light that way also cuts both cameras.So the light switch is a driver behind one interface
Switch { on(), off(), state() }, with these drivers:uhubctl: only when the light is on a port that switches alone, which the check proves at setup (it lists which devices would drop). It refuses if a camera shares the switch.shelly/tapo: a smart plug on the LAN (local HTTP; no cloud account). This is the recommended path; about $15.gpio: a relay on a GPIO pin (libgpiod), for a 5 V relay module.Done when: