Enhance MACHINE relay control logic and add emergency override functionality
- Add `forceTurnOffMachineRelay` method for superuser/emergency operations to bypass gating restrictions. - Enforce `toggle_after = 0` to prevent auto-toggle behavior. - Update routes to explicitly reflect relay state when modifying MACHINE relay. - Extend Shelly device switch handling with optional `skip_toggle_after` parameter.
This commit is contained in:
@@ -17,4 +17,9 @@ enum selfserve_lane_state
|
||||
case FAULT; // The lane is in a fault state
|
||||
case MAINTENANCE; // The lane is under maintenance
|
||||
case CLOSED; // The lane is closed
|
||||
|
||||
public function equals(selfserve_lane_state $state): bool
|
||||
{
|
||||
return $this === $state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@ trait selfserve_lane_relay_controller_t
|
||||
}, $result);
|
||||
// Turn on the switch
|
||||
foreach ($result as $device) {
|
||||
if ($duration !== null) $device->toggle_after = $duration; // Set the duration to turn off the relay (if specified)
|
||||
// Ensure machine switches never auto-toggle off; enforce toggle_after = 0
|
||||
$device->toggle_after = 0;
|
||||
$device->switch(true);
|
||||
}
|
||||
return true;
|
||||
@@ -103,12 +104,52 @@ trait selfserve_lane_relay_controller_t
|
||||
}, $result);
|
||||
// Turn on the switch
|
||||
foreach ($result as $device) {
|
||||
if ($duration !== null) $device->toggle_after = $duration;
|
||||
// Ensure machine switches never auto-toggle off; enforce toggle_after = 0
|
||||
$device->toggle_after = 0;
|
||||
$device->switch(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force turn off the MACHINE relay, bypassing allowed services gating.
|
||||
* Intended for superuser/emergency operations.
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function forceTurnOffMachineRelay(): 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 off relay on CLOSED lane");
|
||||
if ($this->getLaneStatus()->equals(selfserve_lane_status::MAINTENANCE)) throw new \Exception("Cannot turn off relay on MAINTENANCE lane");
|
||||
if ($this->getLaneStatus()->equals(selfserve_lane_status::FAULT)) throw new \Exception("Cannot turn off 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 off the switch
|
||||
foreach ($result as $device) {
|
||||
$device->switch(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off the lane relay
|
||||
* @param selfserve_lane_relay $relay The relay to turn off (MACHINE)
|
||||
|
||||
@@ -35,16 +35,17 @@ class shelly_device_switch extends shelly_device_state
|
||||
/**
|
||||
* Send a request to the shelly API to switch the output
|
||||
* @param bool $on
|
||||
* @param bool|null $skip_toggle_after Whether to prevent the toggle_after parameter from being sent (if null, will use the value of $this->toggle_after)
|
||||
* @return array|object|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function switch(bool $on): array|object|null
|
||||
public function switch(bool $on, ?bool $skip_toggle_after = false): array|object|null
|
||||
{
|
||||
$parameters = [
|
||||
'id' => (string)$this->id,
|
||||
'channel' => (int)$this->channel,
|
||||
'on' => $on,
|
||||
'toggle_after' => (int)$this->toggle_after,
|
||||
'toggle_after' => $skip_toggle_after ? 0 : (int)$this->toggle_after,
|
||||
];
|
||||
return (new shelly())->sendPostRequest('/v2/devices/api/set/switch', $parameters);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user