diff --git a/app/Console/Commands/BiAng/DeviceLogSyncCommand.php b/app/Console/Commands/BiAng/DeviceLogSyncCommand.php index 7b931a6..2f120ee 100644 --- a/app/Console/Commands/BiAng/DeviceLogSyncCommand.php +++ b/app/Console/Commands/BiAng/DeviceLogSyncCommand.php @@ -4,9 +4,13 @@ namespace App\Console\Commands\BiAng; use App\Enums\DeviceStatus; use App\Enums\DeviceType; +use App\Iot\BiAng\HttpClient; use App\Models\Device; -use App\Services\BiAngDeviceService; +use App\Models\DeviceLog; +use App\Models\InsecticidalLampReport; use Illuminate\Console\Command; +use Illuminate\Support\Arr; +use RuntimeException; use Throwable; class DeviceLogSyncCommand extends Command @@ -34,7 +38,7 @@ class DeviceLogSyncCommand extends Command $sleep = (int) value(fn ($sleep) => is_numeric($sleep) ? $sleep : 60, $this->option('sleep')); while (true) { - $this->runSync(); + $this->sync(); sleep($sleep); }; @@ -43,7 +47,7 @@ class DeviceLogSyncCommand extends Command /** * 执行同步 */ - protected function runSync(): void + protected function sync(): void { $now = now(); @@ -61,6 +65,8 @@ class DeviceLogSyncCommand extends Command if (! in_array($device->type, [ DeviceType::Soil, DeviceType::Meteorological, + DeviceType::Worm, + DeviceType::InsectSexLure, DeviceType::InsecticidalLamp, ])) { continue; @@ -72,11 +78,77 @@ class DeviceLogSyncCommand extends Command $this->info('设备类型: ' . match ($device->type) { DeviceType::Soil => '土壤设备', DeviceType::Meteorological => '气象设备', + DeviceType::Worm => '虫情设备', + DeviceType::InsectSexLure => '昆虫性诱设备', DeviceType::InsecticidalLamp => '杀虫灯设备', }); try { - (new BiAngDeviceService())->sync($device, $now->copy()); + $httpClient = $this->buildHttpClient($device); + + switch ($device->type) { + case DeviceType::Soil: + $data = $httpClient->getLatestSoilReport($device->sn); + + $log = DeviceLog::firstOrCreate([ + 'device_id' => $device->id, + 'reported_at' => $data['time'], + ], [ + 'data' => Arr::except($data, ['deviceId', 'time']), + ]); + + $device->update([ + 'status' => $now->copy()->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, + ]); + break; + + case DeviceType::Meteorological: + $data = $httpClient->getLatestMeteorologicalReport($device->sn); + + $log = DeviceLog::firstOrCreate([ + 'device_id' => $device->id, + 'reported_at' => $data['time'], + ], [ + 'data' => Arr::except($data, ['deviceId', 'time']), + ]); + + $device->update([ + 'status' => $now->copy()->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, + ]); + break; + + case DeviceType::InsecticidalLamp: + $data = $httpClient->getLatestLampReport($device->sn); + + if ($data['status'] === 'online') { + InsecticidalLampReport::updateOrCreate([ + 'device_id' => $device->id, + 'reported_at' => $now->copy()->startOfHour(), + ], [ + 'agricultural_base_id' => $device->agricultural_base_id, + 'battery_vol' => $data['vol'], + 'killed_num' => $data['dct'], + 'air_temperature' => $data['temp'], + 'air_humidity' => $data['humidity'], + 'solar_panel_vol' => $data['sunVol'], + 'high_vol' => $data['highVol'], + ]); + } + + $device->update([ + 'status' => $data['status'] === 'online' ? DeviceStatus::Online : DeviceStatus::Offline, + ]); + break; + + case DeviceType::Worm: + case DeviceType::InsectSexLure: + $data = $httpClient->getWormPhotos($device->sn, $now->copy()->subHours(24), $now); + + $device->update([ + 'status' => count($data['imgUrl'] ?? []) > 0 ? DeviceStatus::Online : DeviceStatus::Offline, + ]); + break; + } $this->info('同步成功!'); } catch (Throwable $e) { @@ -91,4 +163,18 @@ class DeviceLogSyncCommand extends Command $this->info('------------------------------------------'); $this->newLine(); } + + /** + * 创建 HTTP 客户端 + */ + public function buildHttpClient(Device $device): HttpClient + { + $config = json_decode($device->project?->value, true); + + if (! is_array($config)) { + throw new RuntimeException('账户信息未找到'); + } + + return new HttpClient($config['username'] ?? '', $config['password'] ?? ''); + } } diff --git a/app/Services/BiAngDeviceService.php b/app/Services/BiAngDeviceService.php index ef44425..1e6bd95 100644 --- a/app/Services/BiAngDeviceService.php +++ b/app/Services/BiAngDeviceService.php @@ -2,7 +2,6 @@ namespace App\Services; -use App\Enums\DeviceStatus; use App\Enums\DeviceType; use App\Exceptions\BizException; use App\Iot\BiAng\HttpClient; @@ -14,7 +13,6 @@ use App\Models\MeteorologicalMonitoringDailyLog; use App\Models\MeteorologicalMonitoringLog; use App\Models\SoilMonitoringDailyLog; use App\Models\SoilMonitoringLog; -use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; @@ -48,69 +46,6 @@ class BiAngDeviceService return $httpClient->getWormStatistics($device->sn, $start, $end); } - public function sync(Device $device, Carbon $syncTime): void - { - try { - $httpClient = $this->buildHttpClient($device); - } catch (BizException $e) { - return; - } - - switch ($device->type) { - case DeviceType::Soil: - $data = $httpClient->getLatestSoilReport($device->sn); - - $log = DeviceLog::firstOrCreate([ - 'device_id' => $device->id, - 'reported_at' => $data['time'], - ], [ - 'data' => Arr::except($data, ['deviceId', 'time']), - ]); - - $device->update([ - 'status' => $syncTime->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, - ]); - break; - case DeviceType::Meteorological: - $data = $httpClient->getLatestMeteorologicalReport($device->sn); - - $log = DeviceLog::firstOrCreate([ - 'device_id' => $device->id, - 'reported_at' => $data['time'], - ], [ - 'data' => Arr::except($data, ['deviceId', 'time']), - ]); - - $device->update([ - 'status' => $syncTime->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, - ]); - break; - - case DeviceType::InsecticidalLamp: - $data = $httpClient->getLatestLampReport($device->sn); - - if ($data['status'] === 'online') { - InsecticidalLampReport::updateOrCreate([ - 'device_id' => $device->id, - 'reported_at' => $syncTime->startOfHour(), - ], [ - 'agricultural_base_id' => $device->agricultural_base_id, - 'battery_vol' => $data['vol'], - 'killed_num' => $data['dct'], - 'air_temperature' => $data['temp'], - 'air_humidity' => $data['humidity'], - 'solar_panel_vol' => $data['sunVol'], - 'high_vol' => $data['highVol'], - ]); - } - - $device->update([ - 'status' => $data['status'] === 'online' ? DeviceStatus::Online : DeviceStatus::Offline, - ]); - break; - } - } - /** * 创建设备报告 */