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
@@ -207,5 +207,97 @@ class moduleSelfServeRoute
}, [
'modules_selfserve_lane_relay_enable_machine' => 'Manually enable MACHINE relay for a lane (requires allowed task to be present)'
]);
/** Modules > Self Serve > Lane > Force > MACHINE enable (simulate started wash) */
$this->post('/modules/self-serve/lane/force/machine/enable', function () {
global $response;
self::requirePermission('modules_selfserve_lane_force_machine_enable');
$selfserve = new selfserve();
// Validate parameters
self::requireParameters(['lane_id']);
$lane_id = (int)$this->getParameter('lane_id');
self::requireType($lane_id, self::type_int());
self::requireMinValue($lane_id, 1);
$duration = null;
if ($this->isParametersSet(['duration'])) {
$duration = (int)$this->getParameter('duration');
self::requireMinValue($duration, 1);
}
$license_plate = $this->isParametersSet(['license_plate']) ? (string)$this->getParameter('license_plate') : null;
$lane = $selfserve->lane($lane_id);
try {
// If lane looks idle/available, mark as occupied and in wash, set timers
if ($lane->getLaneStatus()->equals(\modules\selfserve\helpers\selfserve_lane_status::AVAILABLE)) {
$lane->setLaneStatus(\modules\selfserve\helpers\selfserve_lane_status::OCCUPIED);
}
if (!$lane->getLaneState()->equals(\modules\selfserve\helpers\selfserve_lane_state::IN_WASH)) {
$lane->setLaneState(\modules\selfserve\helpers\selfserve_lane_state::IN_WASH);
}
if ($license_plate !== null && $license_plate !== '') {
$lane->setLicensePlate($license_plate);
}
if ((int)$lane->getWashStartTime() <= 0) {
$lane->setWashStartTime(time());
}
// Force enable the machine relay (bypass gating)
$lane->forceTurnOnMachineRelay($duration);
$response->success([
'lane_id' => $lane_id,
'forced' => true,
'machine' => 'ENABLED',
'duration' => $duration,
'status' => $lane->getLaneStatus()->name,
'state' => $lane->getLaneState()->name,
'wash_start_time' => $lane->getWashStartTime(),
]);
} catch (\Exception $e) {
$response->error('Failed to force-enable MACHINE: ' . $e->getMessage(), 400);
}
}, [
'modules_selfserve_lane_force_machine_enable' => 'Force enable MACHINE relay and mark lane as in-wash (superusers only)'
]);
/** Modules > Self Serve > Lane > Force > MACHINE disable (simulate started wash without machine) */
$this->post('/modules/self-serve/lane/force/machine/disable', function () {
global $response;
self::requirePermission('modules_selfserve_lane_force_machine_disable');
$selfserve = new selfserve();
// Validate parameters
self::requireParameters(['lane_id']);
$lane_id = (int)$this->getParameter('lane_id');
self::requireType($lane_id, self::type_int());
self::requireMinValue($lane_id, 1);
$license_plate = $this->isParametersSet(['license_plate']) ? (string)$this->getParameter('license_plate') : null;
$lane = $selfserve->lane($lane_id);
try {
// Ensure lane reflects an ongoing wash, but with machine off
if ($lane->getLaneStatus()->equals(\modules\selfserve\helpers\selfserve_lane_status::AVAILABLE)) {
$lane->setLaneStatus(\modules\selfserve\helpers\selfserve_lane_status::OCCUPIED);
}
if (!$lane->getLaneState()->equals(\modules\selfserve\helpers\selfserve_lane_state::IN_WASH)) {
$lane->setLaneState(\modules\selfserve\helpers\selfserve_lane_state::IN_WASH);
}
if ($license_plate !== null && $license_plate !== '') {
$lane->setLicensePlate($license_plate);
}
if ((int)$lane->getWashStartTime() <= 0) {
$lane->setWashStartTime(time());
}
// Turn off the machine relay if currently on
try { $lane->turnOffRelay(\modules\selfserve\helpers\selfserve_lane_relay::MACHINE); } catch (\Throwable $ignored) {}
$response->success([
'lane_id' => $lane_id,
'forced' => true,
'machine' => 'DISABLED',
'status' => $lane->getLaneStatus()->name,
'state' => $lane->getLaneState()->name,
'wash_start_time' => $lane->getWashStartTime(),
]);
} catch (\Exception $e) {
$response->error('Failed to force-disable MACHINE: ' . $e->getMessage(), 400);
}
}, [
'modules_selfserve_lane_force_machine_disable' => 'Force disable MACHINE relay but keep lane as in-wash (superusers only)'
]);
}
}