The Bedroom Light HS200 dropped off Wi-Fi for 5 s at 03:01 and came back
reporting "on"; the Bedroom On device trigger treated unavailable -> on as
someone flipping the switch and lit the bedroom Hue lamps at 100%.
Bedroom On/Off and TV On/Off now use state triggers with not_from
unavailable/unknown, so reconnects and HA restarts no longer count as a
flip. The driveway's switch-reconnect catch-up is dropped for the same
reason (it would undo a manual off); the HA-restart catch-up stays.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sunset automation required TV mode off, so an afternoon of TV skipped
the driveway string lights entirely (Sep 22 and 23) - not an outage. The
driveway now has its own sunset -1h automation, with catch-up on restart
or switch reconnect before 23:00.
Evening brightness lives in one script (evening_lights_apply) that blends
between the old step levels; a 5-minute ramp from 20:30 eases lights that
are on and leaves alone any a person has changed by hand. The Dining Hall
no longer bumps to 50% at 21:30.
TV off after 23:30 now only turns off the living room glow instead of
bringing the whole house back to full brightness, and TV on/off leave the
lights alone in daylight. Lights-out moves to 23:30, and a 01:00 sweep
catches anything switched back on at the wall.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.26.1 -> 1.27.3 picks up the security fixes in 1.27.0 through 1.27.3.
The image was one shared variable, so the two instances could only move
together; split it into gitea_debyl_image / gitea_skudak_image and tag
the debyl tasks gitea-debyl so each can be upgraded and verified on its
own. Skudak stays on 1.26.1 in this commit.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The daily quote keeps a ledger of what it has posted and re-rolls ZenQuotes
until it finds something the channel has not read, with the header framing and
the offline fallback pool drawn against that same ledger.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The runner's job images were built by ansible into localhost/ only, so the
nightly CI prune deleted them and every idle stretch ended with CI failing in
under a second on `docker pull localhost/gitea-ci:latest` until someone re-ran
the role and waited out a rebuild. The previous commit moved them to the Gitea
registry; this moves the *build* off the deploy path entirely.
- .gitea/workflows/ci-images.yml builds files/Containerfile.* and pushes to
git.debyl.io/gitbot/. Per-image change detection, so an ESP-IDF pin bump does
not rebuild the other two; weekly schedule for base-image updates; a
workflow_dispatch selector. PRs build under a throwaway :pr-<n> tag and drop
it -- the build lands in the live runner's store, and act_runner will not
re-pull a tag it already has, so a PR using the real tag would hand every
later job on this host an unmerged image.
- The Containerfiles stop being ansible templates: their version vars are now
--build-arg, read by the workflow out of the same defaults/main.yml the role
interpolates, so CI and ansible build the same bytes from one set of pins.
- LABEL io.debyl.ci-base moves into each Containerfile so neither builder can
forget the prune exemption; the workflow re-checks it before pushing.
- roles/gitea-actions pulls instead of building. gitea_ci_build_local=true
restores the local build+push for seeding a cold registry or when CI is
down -- the workflow that builds gitea-ci runs in gitea-ci.
- Lint .gitea/ alongside ansible/, and document the flow in the role README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The CI job images only existed under localhost/ in the gitea-runner store,
and the nightly CI prune deletes any image older than 48h that no container
holds. After every idle stretch CI failed in 0-1s pulling
localhost/gitea-ci:latest until the role was re-run and the images rebuilt.
- Build under git.debyl.io/gitbot/..., push after every run, and pull from the
registry instead of rebuilding when the Containerfile is unchanged.
- Log gitea-runner in via ~/.docker/config.json, which both act_runner (job
image pulls) and podman read.
- Label the base images io.debyl.ci-base and skip that label in the CI prune;
its `until` counts from build time, so a re-pulled image would otherwise be
deleted again the next night.
Workflows pinning `container: image: localhost/gitea-ci-*` must move to the
registry paths.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>