Add relay control functionality to selfserve_lane with selfserve_lane_relay_controller_t trait

Integrate relay control methods to turn on/off machine relays, introduce `selfserve_lane_relay` enum, and ensure proper validation of lane states and relay IDs.
This commit is contained in:
Jeppe Bundgaard
2026-01-21 11:01:16 +01:00
parent ca4432374c
commit f5d430c0c7
3 changed files with 115 additions and 0 deletions
@@ -13,6 +13,7 @@ require_once WD . '/modules/selfserve/traits/selfserve_lane_license_plate_t.php'
require_once WD . '/modules/selfserve/traits/selfserve_lane_customer_number_t.php';
require_once WD . '/modules/selfserve/traits/selfserve_lane_invoice_t.php';
require_once WD . '/modules/selfserve/traits/selfserve_lane_reservation_timer_t.php';
require_once WD . '/modules/selfserve/traits/selfserve_lane_relay_controller_t.php';
require_once WD . '/modules/selfserve/traits/selfserve_lane_log_t.php';
use modules\selfserve\interfaces\selfserve_lane_i;
@@ -28,6 +29,7 @@ use modules\selfserve\traits\selfserve_lane_reservation_timer_t;
use modules\selfserve\traits\selfserve_lane_state_t;
use modules\selfserve\traits\selfserve_lane_status_t;
use modules\selfserve\traits\selfserve_lane_timer_t;
use modules\selfserve\traits\selfserve_lane_relay_controller_t;
class selfserve_lane implements selfserve_lane_i
{
@@ -42,6 +44,7 @@ class selfserve_lane implements selfserve_lane_i
selfserve_lane_customer_number_t,
selfserve_lane_invoice_t,
selfserve_lane_reservation_timer_t,
selfserve_lane_relay_controller_t,
selfserve_lane_log_t;
/**
@@ -0,0 +1,8 @@
<?php
namespace modules\selfserve\helpers;
enum selfserve_lane_relay
{
case MACHINE; // Relay that controls the machine power
}
@@ -0,0 +1,104 @@
<?php
namespace modules\selfserve\traits;
require_once WD . '/modules/selfserve/helpers/selfserve_lane_relay.php';
require_once WD . '/modules/selfserve/classes/selfserve_lane.php';
use classes\shelly;
use modules\selfserve\helpers\selfserve_lane_log_action;
use modules\selfserve\helpers\selfserve_lane_relay;
use modules\selfserve\helpers\selfserve_lane_state;
use modules\selfserve\helpers\selfserve_lane_status;
use modules\shelly\helpers\shelly_device_switch;
use modules\shelly\helpers\shelly_request_body_get_states;
trait selfserve_lane_relay_controller_t
{
/**
* Turn on the lane relay
* @param selfserve_lane_relay $relay The relay to turn on (MACHINE)
* @parm int|null $duration The duration in seconds to keep the relay on (optional)
* @return bool True if the relay was successfully turned on
* @throws \Exception If an invalid relay is specified or if the lane is not in a state to turn on the relay
*/
public function turnOnRelay(selfserve_lane_relay $relay, ?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}");
// Check lane status
if ($this->status->equals(selfserve_lane_status::CLOSED)) throw new \Exception("Cannot turn on relay on CLOSED lane");
if ($this->status->equals(selfserve_lane_status::MAINTENANCE)) throw new \Exception("Cannot turn on relay on MAINTENANCE lane");
if ($this->status->equals(selfserve_lane_status::FAULT)) throw new \Exception("Cannot turn on relay on FAULT lane");
// Get the relay ID based on the relay type
$relay_id = match ($relay) {
selfserve_lane_relay::MACHINE => $this->department_lane->relay_machine_id->value(),
default => throw new \Exception("Invalid relay specified, must be MACHINE"),
};
// Make sure relay ID is valid
if (empty($relay_id)) {
throw new \Exception("Invalid relay ID for relay {$relay->name}");
}
$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; // Set the duration to turn off the relay (if specified)
$device->switch(true);
}
return true;
}
/**
* Turn off the lane relay
* @param selfserve_lane_relay $relay The relay to turn off (MACHINE)
* @return bool True if the relay was successfully turned off
* @throws \Exception If an invalid relay is specified or if the lane is not in a state to turn off the relay
*/
public function turnOffRelay(selfserve_lane_relay $relay): bool
{
// Require department lane object
if (empty($this->department_lane)) throw new \Exception("Department lane object not found for lane ID {$this->id}");
// Check lane status
if ($this->status->equals(selfserve_lane_status::CLOSED)) throw new \Exception("Cannot turn off relay on CLOSED lane");
if ($this->status->equals(selfserve_lane_status::MAINTENANCE)) throw new \Exception("Cannot turn off relay on MAINTENANCE lane");
if ($this->status->equals(selfserve_lane_status::FAULT)) throw new \Exception("Cannot turn off relay on FAULT lane");
// Get the relay ID based on the relay type
$relay_id = match ($relay) {
selfserve_lane_relay::MACHINE => $this->department_lane->relay_machine_id->value(),
default => throw new \Exception("Invalid relay specified, must be MACHINE"),
};
// Make sure relay ID is valid
if (empty($relay_id)) {
throw new \Exception("Invalid relay ID for relay {$relay->name}");
}
$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;
}
}