Handle relay command job timeouts for edge gateways

- Introduce `expireTimedOutRelayStatusCommandJobs` to clean up long-pending relay status command jobs.
- Add `TIMED_OUT` status for relay command jobs and incorporate it into job status evaluations.
- Refactor command job finalization to support timeout-specific error messaging.
- Improve handling of fast-path failures in edge broker commands.
This commit is contained in:
Jeppe Bundgaard
2026-04-27 16:47:09 +02:00
parent 86eec9a51e
commit feb9aac4f7
16 changed files with 636 additions and 108 deletions
@@ -423,6 +423,68 @@ it('uses direct set/switch and seeds cache so immediate status read does not cal
expect(array_key_exists('toggle_after', $harness->shellyCalls[0]['payload']))->toBeFalse();
});
it('preserves local gateway diagnostic metadata on relay status snapshots', function (): void {
$harness = selfserve_lane_shelly_test_harness();
$harness->queueShellyResponse('/v2/devices/api/get', [
[
'id' => 'relay-machine',
'relay_id' => 'relay-machine',
'online' => true,
'on' => true,
'status' => ['switch:0' => ['output' => true]],
'binding' => [
'logical_relay_id' => 'relay-machine',
'device_id' => 'device-machine',
'local_ip' => '192.168.1.50',
'channel' => 0,
],
'execution' => [
'transport' => 'gateway',
'fallback_mode' => 'PREFER_LOCAL',
],
'raw' => [
'source' => 'edge-gateway',
],
],
]);
$status = $harness->getMachineRelayStatus();
expect($status)->toMatchArray([
'relay_id' => 'relay-machine',
'online' => true,
'on' => true,
'status' => ['switch:0' => ['output' => true]],
'binding' => [
'logical_relay_id' => 'relay-machine',
'device_id' => 'device-machine',
'local_ip' => '192.168.1.50',
'channel' => 0,
],
'execution' => [
'transport' => 'gateway',
'fallback_mode' => 'PREFER_LOCAL',
],
'raw' => [
'source' => 'edge-gateway',
],
]);
});
it('includes positive relay timers in Shelly switch payloads', function (): void {
$harness = selfserve_lane_shelly_test_harness();
$harness->forceTurnOnMachineRelay(9);
expect($harness->getShellyCallCount('/v2/devices/api/set/switch'))->toBe(1);
expect($harness->shellyCalls[0]['payload'])->toMatchArray([
'id' => 'relay-machine',
'channel' => 0,
'on' => true,
'toggle_after' => 9,
]);
});
it('supports hard relay set even when lane status is CLOSED', function (): void {
$harness = selfserve_lane_shelly_test_harness();
$harness->setLaneStatus(selfserve_lane_status::CLOSED);