get_plate_scanner(); if (!$plate_scanner) { $response->error('Invalid plate scanner session', 403); } $lane_id = $this->resolveLaneId($plate_scanner); $reg = self::isParametersSet(['reg']) ? selfserve::standardize_registration((string)self::getParameter('reg')) : null; $payload = $this->getParametersAsArray(); unset($payload['token']); try { $summary = (new selfserve_wash_flow())->recordMachineStartWebhook($lane_id, $reg, $payload); } catch (\RuntimeException $e) { $response->error($e->getMessage(), 404); } (new logs_o())->add('relay', $plate_scanner->department_id->value(), 1, 0, 'TRIGGER_BUTTON_PRESS', 'Button was pressed on the machine with the plate scanner: ' . $plate_scanner->id . ' for lane ' . $lane_id); $response->success([ 'message' => 'Button press recorded.', 'scanner' => $plate_scanner->name->value(), 'lane_id' => $lane_id, 'selfserve' => $summary, ], 201); }; $this->get('/relay/button/press/post', $handler, [ 'add_button_press' => 'Add a button press' ]); $this->post('/relay/button/press/post', $handler, [ 'add_button_press' => 'Add a button press' ]); $shellyHandler = function () { global $response; self::requirePlateScannerAuth(); $plate_scanner = (new authentication())->get_plate_scanner(); if (!$plate_scanner) { $response->error('Invalid plate scanner session', 403); } $payload = $this->getParametersAsArray(); unset($payload['token']); $lane_id = self::isParametersSet(['lane_id']) ? (int)self::getParameter('lane_id') : null; try { $result = (new selfserve_machine_signal())->recordCloudShellySignal( (int)$plate_scanner->department_id->value(), $lane_id, $payload, [ 'scanner_id' => (int)$plate_scanner->id, 'scanner_name' => (string)$plate_scanner->name->value(), ] ); } catch (\Throwable $e) { $response->error($e->getMessage(), 400); } (new logs_o())->add( 'relay', $plate_scanner->department_id->value(), 1, 0, 'TRIGGER_MACHINE_ON_SIGNAL', 'Shelly machine ON signal received from plate scanner: ' . $plate_scanner->id ); $response->success([ 'message' => !empty($result['recorded']) ? 'Machine ON signal recorded.' : 'Shelly signal ignored.', 'scanner' => $plate_scanner->name->value(), 'lane_id' => $result['lane_id'] ?? $lane_id, 'signal' => $result['signal'] ?? null, 'selfserve' => $result['selfserve'] ?? null, 'ignored' => $result['ignored'] ?? false, 'reason' => $result['reason'] ?? null, ], !empty($result['recorded']) ? 201 : 202); }; $this->get('/relay/machine/on/post', $shellyHandler, [ 'add_button_press' => 'Record a Shelly machine ON signal' ]); $this->post('/relay/machine/on/post', $shellyHandler, [ 'add_button_press' => 'Record a Shelly machine ON signal' ]); } private function resolveLaneId(plate_scanners_o $plateScanner): int { global $response; if (self::isParametersSet(['lane_id'])) { $lane = (new department_lanes_o())->select((int)self::getParameter('lane_id')); if (!$lane->exists()) { $response->error('Department lane not found', 404); } if ((int)$lane->department->value() !== (int)$plateScanner->department_id->value()) { $response->error('The lane does not belong to the plate scanner department', 403); } return (int)$lane->id; } if ($plateScanner->lane_id->value() !== null) { $lane = (new department_lanes_o())->select((int)$plateScanner->lane_id->value()); if (!$lane->exists()) { $response->error('The default lane configured for the plate scanner no longer exists', 404); } if ((int)$lane->department->value() !== (int)$plateScanner->department_id->value()) { $response->error('The default lane does not belong to the plate scanner department', 403); } return (int)$lane->id; } $lanes = (new department_lanes_o())->getDepartmentLanes((int)$plateScanner->department_id->value()); if (count($lanes) === 1) { return (int)$lanes[0]->id; } $response->error('lane_id is required when the department has multiple self-serve lanes', 400); } }