type) { case DeviceType::InsecticidalLamp: $this->createInsecticidalLampReport($device, $time); break; } } /** * 创建杀虫灯设备报告 */ 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 = [ 'battery_vol' => ['sum' => 0, 'count' => 0], 'charging_vol' => ['sum' => 0, 'count' => 0], 'killed_num' => ['sum' => 0, 'count' => 0], 'air_temperature' => ['sum' => 0, 'count' => 0], 'air_humidity' => ['sum' => 0, 'count' => 0], ]; /** @var \App\Models\DeviceLog */ foreach ($logs as $log) { if (! is_array($log->data)) { continue; } foreach ($data as $key => $item) { switch ($key) { // 电池电压 case 'battery_vol': if (! is_null($bv = Arr::get($log->data, 'bv'))) { $item['sum'] = bcadd($item['sum'], $bv, 2); $item['count'] += 1; } break; // 充电电压 case 'charging_vol': if (! is_null($cv = Arr::get($log->data, 'cv'))) { $item['sum'] = bcadd($item['sum'], $cv, 2); $item['count'] += 1; } break; // 杀虫数 case 'killed_num': if (! is_null($ct = Arr::get($log->data, 'ct'))) { $item['sum'] += $ct; $item['count'] += 1; } break; // 温度 case 'air_temperature': if (! is_null($at = Arr::get($log->data, 'at'))) { $item['sum'] = bcadd($item['sum'], $at, 2); $item['count'] += 1; } break; // 湿度 case 'air_humidity': if (! is_null($ah = Arr::get($log->data, 'ah'))) { $item['sum'] = bcadd($item['sum'], $ah, 2); $item['count'] += 1; } break; } $data[$key] = $item; } } $attributes = []; foreach ($data as $key => $item) { if ($item['count'] > 0) { if ($key === 'killed_num') { $attributes[$key] = (int) $item['sum']; } else { $attributes[$key] = round(bcdiv($item['sum'], $item['count'], 2), 2); } } else { $attributes[$key] = 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(); } /** * 创建设备每日报告 */ public function createDailyReport(Device $device, Carbon $time): void { switch ($device->type) { case DeviceType::InsecticidalLamp: $this->createInsecticidalLampDailyReport($device, $time); break; } } /** * 杀虫灯每日报告 */ protected function createInsecticidalLampDailyReport(Device $device, Carbon $date): void { /** @var \Illuminate\Database\Eloquent\Collection */ $insecticidalLampReports = InsecticidalLampReport::where('device_id', $device->id) ->whereDate('reported_at', $date) ->oldest('reported_at') ->get(); if ($insecticidalLampReports->isEmpty()) { return; } $attributes = value(function ($insecticidalLampReports) { $data = [ 'battery_vol' => ['sum' => 0, 'count' => 0], 'charging_vol' => ['sum' => 0, 'count' => 0], 'killed_num' => ['sum' => 0, 'count' => 0], 'air_temperature' => ['sum' => 0, 'count' => 0], 'air_humidity' => ['sum' => 0, 'count' => 0], 'high_vol' => ['sum' => 0, 'count' => 0], ]; foreach ($insecticidalLampReports as $insecticidalLampReport) { foreach ($data as $k => $item) { if (is_null($v = $insecticidalLampReport->{$k})) { continue; } $item['sum'] = bcadd($item['sum'], $v, 2); $item['count']++; $data[$k] = $item; } } $attributes = []; foreach ($data as $key => $item) { if ($item['count'] > 0) { if ($key === 'killed_num') { $attributes[$key] = (int) $item['sum']; } else { $attributes[$key] = round(bcdiv($item['sum'], $item['count'], 2), 2); } } else { $attributes[$key] = null; } } return $attributes; }, $insecticidalLampReports); /** @var \App\Models\InsecticidalLampDailyReport */ $insecticidalLampDailyReport = InsecticidalLampDailyReport::firstOrNew([ 'device_id' => $device->id, 'reported_at' => $date->format('Y-m-d'), ], [ 'agricultural_base_id' => $device->agricultural_base_id, ]); $insecticidalLampDailyReport->fill($attributes)->save(); } }