Symptom: with wakeTimes=[4 AM, 9 PM, 9:15 PM], the frame rotated to a
fresh photo at 10:14 AM when the device was reconnected and polled.
The wakeTimes only governed *when* the device polled (via X-Interval-Ms);
they didn't gate whether the server picked a new image when it did.
Power-on or button-press polls would always rotate.
Fix: move the existing isDue() logic from AdvanceRotationMessageHandler
into RotationService as a public method, and gate
DeviceImageController::image so off-schedule polls return the device's
current image (which 304s when X-Current-Image-Id matches) rather than
calling advance(). The scheduler-driven handler still uses the same
isDue — both code paths now share one source of truth.
Tests:
- DeviceImageControllerTest: new test asserting an off-schedule poll
returns 304 without rotating; existing wakeTimes tests reworked to
use slot lists that always have a past slot regardless of run time.
- AdvanceRotationMessageHandlerTest: existing AR-04 through AR-07
keep covering isDue's semantics — they now go through the service.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -83,8 +83,18 @@ class DeviceImageController extends AbstractController
|
||||
// the second flush triggers a second publish to keep it accurate.
|
||||
$this->mercure->publishDevice((int) $device->getId(), $this->serializer->serialize($device));
|
||||
|
||||
// Locked image bypasses rotation entirely.
|
||||
$image = $device->getLockedImage() ?? $this->rotation->advance($device);
|
||||
// Locked image bypasses rotation entirely. Otherwise, only advance the
|
||||
// rotation when the device's configured schedule says it's due —
|
||||
// off-schedule polls (boot, button-mash, scheduler-driven status check)
|
||||
// hand back the device's current image without rotating, so the user
|
||||
// doesn't see surprise refreshes between configured wake times.
|
||||
if ($device->getLockedImage() !== null) {
|
||||
$image = $device->getLockedImage();
|
||||
} elseif ($this->rotation->isDue($device)) {
|
||||
$image = $this->rotation->advance($device);
|
||||
} else {
|
||||
$image = $device->getCurrentImage();
|
||||
}
|
||||
|
||||
if ($image === null) {
|
||||
$this->logger->info('device.poll.no_image', [
|
||||
|
||||
Reference in New Issue
Block a user