Add superuser endpoints for forced MACHINE relay control

- Implement emergency operations to forcibly enable or disable MACHINE relays (`forceTurnOnMachineRelay`).
- Add OpenAPI specifications for `/modules/self-serve/lane/force/machine/enable` and `/modules/self-serve/lane/force/machine/disable`.
- Update route definitions and introduce validation for input parameters.
This commit is contained in:
Jeppe Bundgaard
2026-02-19 10:39:43 +01:00
parent 54160659fc
commit 4bdbe40329
3 changed files with 239 additions and 0 deletions
@@ -68,6 +68,47 @@ trait selfserve_lane_relay_controller_t
return true;
}
/**
* Force turn on the MACHINE relay, bypassing allowed services gating.
* Intended for superuser/emergency operations.
* @param int|null $duration Optional auto-off duration in seconds
* @return bool
* @throws \Exception
*/
public function forceTurnOnMachineRelay(?int $duration = null): bool
{
// Require department lane object
if (empty($this->department_lane)) throw new \Exception("Department lane object not found for lane ID {$this->id}");
// Basic sanity checks on lane status (still disallow clearly invalid states)
if ($this->getLaneStatus()->equals(selfserve_lane_status::CLOSED)) throw new \Exception("Cannot turn on relay on CLOSED lane");
if ($this->getLaneStatus()->equals(selfserve_lane_status::MAINTENANCE)) throw new \Exception("Cannot turn on relay on MAINTENANCE lane");
if ($this->getLaneStatus()->equals(selfserve_lane_status::FAULT)) throw new \Exception("Cannot turn on relay on FAULT lane");
// Directly control Shelly without checking allowed services
$relay_id = $this->department_lane->relay_machine_id->value();
if (empty($relay_id)) {
throw new \Exception("Invalid relay ID for MACHINE relay");
}
$shelly = new shelly();
$shelly->requireModuleEnabled();
$shelly->requireValidSecretKey();
$parameters = new shelly_request_body_get_states();
$parameters->ids = [$relay_id];
$parameters->select = ['status'];
$result = $shelly->sendPostRequest('/v2/devices/api/get', (array)$parameters);
// Wait 1 second
sleep(1);
// Format the result
$result = array_map(function ($device) {
return (new shelly_device_switch())->populate($device);
}, $result);
// Turn on the switch
foreach ($result as $device) {
if ($duration !== null) $device->toggle_after = $duration;
$device->switch(true);
}
return true;
}
/**
* Turn off the lane relay
* @param selfserve_lane_relay $relay The relay to turn off (MACHINE)