Public: anyone can read this; the crew can change it.
Migrated from github.com/Trevato/SO-ARM100
Off-due as a real reminder in the care log (follow-up to #639) #642
Check · Review · Land done · Live — Landed; nothing deploys from this branch, so this is the end of its path.
**Stacked on #640:** this branch starts from #640's head (c5b064e), since `lightOn`/`lightOff` and `src/light-day.ts` exist only there. Merge #640 first; after that, this diff is just the one commit on top.
shipped merged
Stacked on #640: this branch starts from #640's head (c5b064e), since lightOn/lightOff and src/light-day.ts exist only there. Merge #640 first; after that, this diff is just the one commit on top.
The off-time is now a real care reminder, Switch the grow light off (light-off). It appears in reminders() whenever the light is logged on. Because the care page, /care/api, the terminal, the health strip, the grow card's "Next" and the watchdog's overdue list all read that function, it reaches all of them without more wiring.
- Due time: the latest
lightOnplus the schedule's hours, using thelightSeen.hoursthe relay already keeps from the Pi. It falls back to 12 h before the Pi has answered and is held to 10–14 h, throughopenDay()insrc/light-day.ts. A laterlightOffremoves the reminder, and the nextlightOnstarts a new one. - Done posts to
/care/reminderand logs alightOffwithcause: "owner", so the day closes on the grow card too. On the page the button reads "It's off". - Snooze is 1 h on the page. A new
lightOnclears the snooze inCareLog.push, so last night's snooze can't hide today's off-time. - Cadence can't be edited:
everyonlight-offis refused, because the day length belongs to the light's schedule. - Citations are the current stage's photoperiod sources, so the reminder is cited like every other one.
- Plumbing:
snapshot(log, lightHours?), plusCareContext.lightHoursandCareView.lightHours, carry the Pi's hours to the care route and page.
src/light-off.test.ts covers the due time and the 14 h cap, reset on lightOff, the overdue list and health line, snooze expiry and its clearing on lightOn, the grow card's next-due, the page buttons, and the route (Done logs lightOff, every gets a 400, the reminder shows in /care/api). Those 6 tests and the 15 test files that touch care, the grow card or the watchdog pass (184 tests). The type check shows no errors in the changed files; the ones it reports elsewhere are in files this change doesn't touch. I didn't look at the preview.
Not done: the profile's daily "Light ran" reminder still doesn't reset on lightOn.
To try it: as the owner, tap Light on on /care/checkin (or /care checkin light on 08:30). /care then lists "Switch the grow light off" due 12 h later; It's off clears it and closes the day on the grow card.
🤖 Generated with Claude Code
The off-time is now a real care reminder, Switch the grow light off (light-off), shown while the light is logged on. It lives in reminders(), so the care page, /care/api, the terminal, the health strip, the grow card's "Next" and the watchdog's overdue list all show it. #640 has merged into main, so this pull's diff is just the reminder.
- Due time: the latest
lightOnplus the schedule's hours as the Pi last reported them. Before the Pi has answered it uses 12 h, and it is always held to 10–14 h (openDay()insrc/light-day.ts). LogginglightOffremoves the reminder, and the nextlightOnstarts a new one. - Done logs a
lightOff, so the day also closes on the grow card. On the page the button reads "It's off". - Snooze is 1 h on the page. A new
lightOnclears it, so last night's snooze can't hide today's off-time. - Cadence: changing the cadence (
every) onlight-offis refused, because the day length comes from the light's schedule. - Citations: it uses the current stage's photoperiod sources, like every other reminder.
- Plumbing:
snapshot(log, lightHours?),CareContext.lightHoursandCareView.lightHourscarry the Pi's hours to the care route and page.
src/light-off.test.ts covers the due time and the 14 h cap, reset on lightOff, the overdue list and health line, the snooze expiring and being cleared by lightOn, the grow card's "Next", the page buttons, and the route (Done logs lightOff, every is refused with 400, the reminder appears in /care/api). After merging main, the care, light, watchdog, workshop and night-switch tests pass (103), and the type check reports no errors in the changed files. The merge conflicts in care-routes.ts, light-day.ts and relay.ts came only from #640's squash, which matches the commit this branch was built on, so I kept this branch's side. I didn't check the preview.
Not done: the profile's daily "Light ran" reminder still doesn't reset on lightOn.
To try it: as the owner, tap Light on on /care/checkin (or run /care checkin light on 08:30). /care then lists "Switch the grow light off" due 12 h later, and It's off clears it.
🤖 Generated with Claude Code
Approved. The light-off reminder is in reminders(), so the page, /care/api, health strip, grow card and watchdog all get it. The owner check on /care/reminder is unchanged. The terminal (/care done light-off, /care snooze light-off) goes through the same route, so it logs lightOff. Tests cover the due time, the 14 h cap, the snooze, the page buttons and the route. The preview answers on /care/api. I did not see the reminder on the preview, since no lightOn is logged there.
Two things next:
/care snooze light-offfrom the terminal defaults to 24 h, while the page snoozes for 1 h. Default light-off to 1 h in src/care-terminal.ts, or cap it in the route, so a terminal snooze cannot hide tonight's off-time.- Make the daily "Light ran" reminder reset on lightOn (you listed this as not done). Until then it can sit overdue beside a light that is on.
Stacked on #640: this branch starts from #640's head (c5b064e), since
lightOn/lightOffandsrc/light-day.tsexist only there. Merge #640 first; after that, this diff is just the one commit on top.The off-time is now a real care reminder, Switch the grow light off (
light-off). It appears inreminders()whenever the light is logged on. Because the care page,/care/api, the terminal, the health strip, the grow card's "Next" and the watchdog's overdue list all read that function, it reaches all of them without more wiring.lightOnplus the schedule's hours, using thelightSeen.hoursthe relay already keeps from the Pi. It falls back to 12 h before the Pi has answered and is held to 10–14 h, throughopenDay()insrc/light-day.ts. A laterlightOffremoves the reminder, and the nextlightOnstarts a new one./care/reminderand logs alightOffwithcause: "owner", so the day closes on the grow card too. On the page the button reads "It's off".lightOnclears the snooze inCareLog.push, so last night's snooze can't hide today's off-time.everyonlight-offis refused, because the day length belongs to the light's schedule.snapshot(log, lightHours?), plusCareContext.lightHoursandCareView.lightHours, carry the Pi's hours to the care route and page.src/light-off.test.tscovers the due time and the 14 h cap, reset onlightOff, the overdue list and health line, snooze expiry and its clearing onlightOn, the grow card's next-due, the page buttons, and the route (Done logslightOff,everygets a 400, the reminder shows in/care/api). Those 6 tests and the 15 test files that touch care, the grow card or the watchdog pass (184 tests). The type check shows no errors in the changed files; the ones it reports elsewhere are in files this change doesn't touch. I didn't look at the preview.Not done: the profile's daily "Light ran" reminder still doesn't reset on
lightOn.To try it: as the owner, tap Light on on
/care/checkin(or/care checkin light on 08:30)./carethen lists "Switch the grow light off" due 12 h later; It's off clears it and closes the day on the grow card.🤖 Generated with Claude Code
Closes #641