diff --git a/app/Console/Commands/BiAng/DeviceLogReportCommand.php b/app/Console/Commands/BiAng/DeviceLogReportCommand.php index deef87a..92b1ee9 100644 --- a/app/Console/Commands/BiAng/DeviceLogReportCommand.php +++ b/app/Console/Commands/BiAng/DeviceLogReportCommand.php @@ -5,6 +5,7 @@ namespace App\Console\Commands\BiAng; use App\Enums\DeviceType; use App\Models\Device; use App\Models\DeviceLog; +use App\Models\InsecticidalLampReport; use App\Models\MeteorologicalMonitoringLog; use App\Models\SoilMonitoringLog; use App\Services\BiAngDeviceService; @@ -59,6 +60,7 @@ class DeviceLogReportCommand extends Command $lastReportedAt = match ($device->type) { DeviceType::Soil => SoilMonitoringLog::where('device_id', $device->id)->latest('monitored_at')->value('monitored_at'), DeviceType::Meteorological => MeteorologicalMonitoringLog::where('device_id', $device->id)->latest('monitored_at')->value('monitored_at'), + DeviceType::InsecticidalLamp => InsecticidalLampReport::where('device_id', $device->id)->latest('reported_at')->value('reported_at'), default => null, }; diff --git a/app/Console/Commands/BiAng/DeviceLogSyncCommand.php b/app/Console/Commands/BiAng/DeviceLogSyncCommand.php index 21a2492..75fb623 100644 --- a/app/Console/Commands/BiAng/DeviceLogSyncCommand.php +++ b/app/Console/Commands/BiAng/DeviceLogSyncCommand.php @@ -120,23 +120,15 @@ class DeviceLogSyncCommand extends Command 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'], - 'charging_vol' => $data['sunVol'], - 'high_vol' => $data['highVol'], - ]); - } + $log = DeviceLog::firstOrCreate([ + 'device_id' => $device->id, + 'reported_at' => $data['time'], + ], [ + 'data' => Arr::except($data, ['deviceId', 'time']), + ]); $device->update([ - 'status' => $data['status'] === 'online' ? DeviceStatus::Online : DeviceStatus::Offline, + 'status' => $now->copy()->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, ]); break; diff --git a/app/Services/BiAngDeviceService.php b/app/Services/BiAngDeviceService.php index 12660db..d536d54 100644 --- a/app/Services/BiAngDeviceService.php +++ b/app/Services/BiAngDeviceService.php @@ -59,6 +59,10 @@ class BiAngDeviceService case DeviceType::Meteorological: $this->createMeteorologicalReport($device, $time); break; + + case DeviceType::InsecticidalLamp: + $this->createInsecticidalLampReport($device, $time); + break; } } @@ -218,6 +222,90 @@ class BiAngDeviceService $meteorologicalReport->fill($attributes)->save(); } + /** + * 创建杀虫灯设备报告 + */ + protected function createInsecticidalLampReport(Device $device, Carbon $time): void + { + $reportedAt = $time->copy()->startOfHour(); + + /** @var \Illuminate\Database\Eloquent\Collection */ + $logs = DeviceLog::where('device_id', $device->id) + ->whereBetween('reported_at', [$reportedAt, $reportedAt->copy()->endOfHour()]) + ->oldest('reported_at') + ->get(); + + if ($logs->isEmpty()) { + return; + } + + $attributes = value(function ($logs) { + $data = [ + 'vol' => ['sum' => 0, 'count' => 0], + 'sunVol' => ['sum' => 0, 'count' => 0], + 'dct' => ['sum' => 0, 'count' => 0], + 'temp' => ['sum' => 0, 'count' => 0], + 'humidity' => ['sum' => 0, 'count' => 0], + 'highVol' => ['sum' => 0, 'count' => 0], + ]; + + /** @var \App\Models\DeviceLog */ + foreach ($logs as $log) { + if (! is_array($log->data)) { + continue; + } + + foreach ($data as $k => $item) { + $v = $log->data[$k] ?? null; + + if (is_null($v)) { + continue; + } + + $item['sum'] = bcadd($item['sum'], $v, 2); + $item['count']++; + + $data[$k] = $item; + } + } + + $attributes = []; + + foreach ($data as $key => $item) { + $attribute = match ($key) { + 'vol' => 'battery_vol', + 'sunVol' => 'charging_vol', + 'dct' => 'killed_num', + 'temp' => 'air_temperature', + 'humidity' => 'air_humidity', + 'highVol' => 'high_vol', + }; + + if ($item['count'] > 0) { + if ($attribute === 'killed_num') { + $attributes[$attribute] = (int) $item['sum']; + } else { + $attributes[$attribute] = round(bcdiv($item['sum'], $item['count'], 2), 2); + } + } else { + $attributes[$attribute] = null; + } + } + + return $attributes; + }, $logs); + + /** @var \App\Models\InsecticidalLampReport */ + $insecticidalLampReport = InsecticidalLampReport::firstOrNew([ + 'device_id' => $device->id, + 'reported_at' => $reportedAt, + ], [ + 'agricultural_base_id' => $device->agricultural_base_id, + ]); + + $insecticidalLampReport->fill($attributes)->save(); + } + /** * 创建设备每日报告 */