argument('factory'); $sleep = (int) value(fn ($sleep) => is_numeric($sleep) ? $sleep : 300, $this->option('sleep')); while (true) { /** @var \Illuminate\Database\Eloquent\Collection */ $devices = Device::with(['factory'])->poweredBy($factory)->get(); foreach ($devices as $device) { $this->createMonitoringReport($device); } sleep($sleep); }; } protected function createMonitoringReport(Device $device) { switch ($device->factory?->key) { case 'link-os': $this->createLinkosDeviceMonitoringReport($device); break; } } protected function createLinkosDeviceMonitoringReport(Device $device) { switch ($device->type) { case Device::TYPE_SOIL: $lastMonitoringReport = SoilMonitoringReport::where('device_id', $device->id) ->latest('reported_at') ->first(); $lastReportedAt = $lastMonitoringReport?->reported_at; $device->logs() ->when($lastReportedAt, fn ($query, $lastReportedAt) => $query->where('reported_at', '>=', $lastReportedAt->reported_at)) ->oldest('reported_at') ->chunkById(500, function ($deviceLogs) use ($device, &$lastMonitoringReport) { /** @var \App\Models\DeviceLog */ foreach ($deviceLogs as $deviceLog) { $monitoringReport = SoilMonitoringReport::firstOrCreate( [ 'device_id' => $device->id, 'reported_at' => $deviceLog->reported_at->startOfHour(), ], Arr::except($lastMonitoringReport?->setHidden([])?->attributesToArray() ?: [], ['reported_at']) ); foreach ([ 'conductivity' => 'conductivity', 'soil_humidity' => 'humidity', 'soil_temperature' => 'temperature', 'nitrogen_content' => 'n', 'potassium_content' => 'k', 'phosphorus_content' => 'p', ] as $key => $attribute) { if (! is_array($deviceLog->data) || ! array_key_exists($key, $deviceLog->data)) { continue; } $monitoringReport->{$attribute} = $deviceLog->data[$key]; } $lastMonitoringReport = tap($monitoringReport)->save(); } }); break; case Device::TYPE_WATER_QUALITY: $lastMonitoringReport = WaterQualityMonitoringReport::where('device_id', $device->id) ->latest('reported_at') ->first(); $lastReportedAt = $lastMonitoringReport?->reported_at; $device->logs() ->when($lastReportedAt, fn ($query, $lastReportedAt) => $query->where('reported_at', '>=', $lastReportedAt->reported_at)) ->oldest('reported_at') ->chunkById(500, function ($deviceLogs) use ($device, &$lastMonitoringReport) { /** @var \App\Models\DeviceLog */ foreach ($deviceLogs as $deviceLog) { $monitoringReport = WaterQualityMonitoringReport::firstOrCreate( [ 'device_id' => $device->id, 'reported_at' => $deviceLog->reported_at->startOfHour(), ], Arr::except($lastMonitoringReport?->setHidden([])?->attributesToArray() ?: [], ['reported_at']) ); foreach ([ 'chlorine' => 'chlorine', 'conductivity' => 'conductivity', 'oxygen' => 'oxygen', 'ph' => 'ph', 'temp' => 'temperature', 'turbidity' => 'turbidity', ] as $key => $attribute) { if (! is_array($deviceLog->data) || ! array_key_exists($key, $deviceLog->data)) { continue; } $monitoringReport->{$attribute} = $deviceLog->data[$key]; } $lastMonitoringReport = tap($monitoringReport)->save(); } }); break; case Device::TYPE_METEOROLOGICAL: $lastMonitoringReport = MeteorologicalMonitoringReport::where('device_id', $device->id) ->latest('reported_at') ->first(); $lastReportedAt = $lastMonitoringReport?->reported_at; $device->logs() ->when($lastReportedAt, fn ($query, $lastReportedAt) => $query->where('reported_at', '>=', $lastReportedAt->reported_at)) ->oldest('reported_at') ->chunkById(500, function ($deviceLogs) use ($device, &$lastMonitoringReport) { /** @var \App\Models\DeviceLog */ foreach ($deviceLogs as $deviceLog) { $monitoringReport = MeteorologicalMonitoringReport::firstOrCreate( [ 'device_id' => $device->id, 'reported_at' => $deviceLog->reported_at->startOfHour(), ], Arr::except($lastMonitoringReport?->setHidden([])?->attributesToArray() ?: [], ['reported_at']) ); foreach ([ 'current_rainfall' => 'today_rainfall', 'day_rainfall' => 'yesterday_rainfall', 'accumulate_rainfall' => 'accumulate_rainfall', 'moment_rainfall' => 'moment_rainfall', 'pm10_concentration' => 'pm10', 'pm25_concentration' => 'pm25', 'box_illumination' => 'box_illumination', 'box_pressure' => 'box_pressure', 'box_carbon' => 'box_co2', 'box_temperature' => 'box_temperature', 'box_humidity' => 'box_humidity', 'box_noise' => 'box_noise', 'wind_degree' => 'wind_degree', 'wind_direction' => 'wind_direction', 'wind_power' => 'wind_power', 'wind_speed' => 'wind_speed', ] as $key => $attribute) { if (! is_array($deviceLog->data) || ! array_key_exists($key, $deviceLog->data)) { continue; } $monitoringReport->{$attribute} = $deviceLog->data[$key]; } $lastMonitoringReport = tap($monitoringReport)->save(); } }); break; } } }