Files
Ferme/src/Service/PontBasculeService.php
2026-05-21 14:10:35 +02:00

101 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Service;
use App\Dto\PontBasculeHealth;
use App\Dto\PontBasculeReading;
use App\Exception\PontBasculeException;
use DateTimeImmutable;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
final class PontBasculeService
{
public function __construct(
private readonly HttpClientInterface $httpClient,
private readonly PontBasculePayloadDecoder $payloadDecoder,
private readonly string $baseUrl,
private readonly bool $bypass,
) {}
/**
* @TODO Voir pour que le pont-bascule retourne la date
*/
public function fetch(): PontBasculeReading
{
if ($this->bypass) {
$body = $this->getBypassPayload();
} else {
try {
$response = $this->httpClient->request('POST', $this->buildUrl('/send/dsd'));
$body = $response->getContent(false);
} catch (TransportExceptionInterface $exception) {
throw PontBasculeException::transportFailure($exception->getMessage());
}
}
$reading = $this->payloadDecoder->decode($body);
return new PontBasculeReading(
$reading->getDsd(),
$reading->getWeight(),
new DateTimeImmutable(),
);
}
public function checkHealth(): PontBasculeHealth
{
if ($this->bypass) {
return new PontBasculeHealth(
healthy: true,
ok: true,
busy: false,
portConnected: true,
portError: null,
hostname: 'bypass',
);
}
try {
$response = $this->httpClient->request('GET', $this->buildUrl('/health'));
$body = $response->getContent(false);
} catch (TransportExceptionInterface) {
return PontBasculeHealth::unhealthy();
}
$payload = json_decode($body, true);
if (!is_array($payload)) {
return PontBasculeHealth::unhealthy();
}
$ok = true === ($payload['ok'] ?? null);
$busy = true === ($payload['busy'] ?? null);
$portConnected = true === ($payload['port_connected'] ?? null);
$portError = $payload['port_error'] ?? null;
$hostname = $payload['hostname'] ?? null;
$healthy = $ok && $portConnected && !$busy && null === $portError;
return new PontBasculeHealth(
healthy: $healthy,
ok: $ok,
busy: $busy,
portConnected: $portConnected,
portError: is_string($portError) ? $portError : null,
hostname: is_string($hostname) ? $hostname : null,
);
}
private function buildUrl(string $path): string
{
return rtrim($this->baseUrl, '/').$path;
}
private function getBypassPayload(): string
{
return '{"ok":true,"busy":false,"mode":"serial","port":"/dev/ttyUSB0","baudrate":9600,"request_hex":"01 10 39 39 4D 0D 0A","response_hex":"01 02 30 34 30 32 30 30 02 30 31 30 30 31 34 32 30 2E 6B 67 20 02 30 32 30 30 30 30 30 30 2E 6B 67 20 02 30 33 30 30 31 34 32 30 2E 6B 67 20 02 39 39 30 30 31 32 31 0D 0A","response_ascii":"\u0001\u0002040200\u000201001420.kg \u000202000000.kg \u000203001420.kg \u00029900121"}';
}
}