41 lines
1.1 KiB
PHP
41 lines
1.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Device;
|
|
use App\Support\Shelly\ShellyRpc;
|
|
|
|
/**
|
|
* Polls a local (HTTP) Shelly's status and applies it through the shared applier. This is how
|
|
* local-API devices get their state — no MQTT, no device-side config, just its IP (like HA).
|
|
*/
|
|
class ShellyPoller
|
|
{
|
|
public function __construct(
|
|
private readonly ShellyRpc $rpc,
|
|
private readonly ShellyStatusApplier $applier,
|
|
) {}
|
|
|
|
public function poll(Device $device): bool
|
|
{
|
|
$ip = data_get($device->config, 'ip');
|
|
if (blank($ip)) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
$status = $this->rpc->status($ip);
|
|
} catch (\Throwable) {
|
|
// Unreachable — normal for a powered-off device. Don't advance last_seen (it falls
|
|
// offline after the timeout) and don't spam the log on every poll.
|
|
return false;
|
|
}
|
|
|
|
$observedAt = (int) round(microtime(true) * 1_000_000);
|
|
$device->forceFill(['last_seen_at' => now()])->save();
|
|
$this->applier->applyStatus($device, $status, $observedAt);
|
|
|
|
return true;
|
|
}
|
|
}
|