diff --git a/app/Services/DeviceLogService.php b/app/Services/DeviceLogService.php index 4a6778d..885c203 100644 --- a/app/Services/DeviceLogService.php +++ b/app/Services/DeviceLogService.php @@ -237,116 +237,116 @@ class DeviceLogService return; } - $result = $meteorologicalReports->reduce(function (array $carry, MeteorologicalReport $meteorologicalReport) { - foreach ($carry as $key => $item) { - if (is_null($v = $meteorologicalReport->{$key})) { - continue; - } + $attributes = value(function ($meteorologicalReports) { + $data = [ + 'today_rainfall' => ['sum' => 0, 'count' => 0], + 'yesterday_rainfall' => ['sum' => 0, 'count' => 0], + 'accumulate_rainfall' => ['sum' => 0, 'count' => 0], + 'moment_rainfall' => ['sum' => 0, 'count' => 0], + 'pm10' => ['sum' => 0, 'count' => 0], + 'pm25' => ['sum' => 0, 'count' => 0], + 'box_illumination' => ['sum' => 0, 'count' => 0], + 'box_pressure' => ['sum' => 0, 'count' => 0], + 'box_co2' => ['sum' => 0, 'count' => 0], + 'box_temperature' => ['sum' => 0, 'count' => 0], + 'box_humidity' => ['sum' => 0, 'count' => 0], + 'box_noise' => ['sum' => 0, 'count' => 0], + 'wind_samples' => [], + ]; + foreach ($meteorologicalReports as $meteorologicalReport) { + foreach ($data as $k => $item) { + if ($k === 'wind_samples') { + if (is_null($meteorologicalReport->wind_degree) || is_null($meteorologicalReport->wind_speed)) { + continue; + } + + $item[] = [ + 'wind_degree' => $meteorologicalReport->wind_degree, // 风向度数 + 'wind_speed' => $meteorologicalReport->wind_speed, // 风速 + ]; + } elseif (! is_null($v = $meteorologicalReport->{$k})) { + $item['sum'] = bcadd($item['sum'], $v, 2); + $item['count']++; + } + + $data[$k] = $item; + } + } + + $attributes = []; + + foreach ($data as $key => $item) { switch ($key) { case 'wind_samples': - if (! is_null($meteorologicalReport->wind_degree) && ! is_null($meteorologicalReport->wind_speed)) { - $item['wind_samples'][] = [ - 'wind_degree' => $meteorologicalReport->wind_degree, // 风向度数 - 'wind_speed' => $meteorologicalReport->wind_speed, // 风速 - ]; - } + $attributes['wind_degree'] = value(function (array $windSamples) { + $x = 0; + $y = 0; + + foreach ($windSamples as $sample) { + if ($sample['wind_degree'] == 0 && $sample['wind_speed'] == 0) { + continue; + } + + // 角度转弧度 + $radian = deg2rad($sample['wind_degree']); + + // $x += $sample['wind_speed'] * sin($radian); + // $y += $sample['wind_speed'] * cos($radian); + $x += sin($radian); + $y += cos($radian); + } + + $degree = round(rad2deg(atan2($y, $x))); + + if (($x > 0 || $x < 0) && $y < 0) { + $degree += 180; + } elseif ($x < 0 && $y > 0) { + $degree += 360; + } + + return $degree; + }, $item); + + $attributes['wind_direction'] = value(function ($windDegree) { + if ($windDegree >= 22.5 && $windDegree < 67.5) { + return MeteorologicalDailyReport::WIND_DIRECTION_NORTHEAST; + } elseif ($windDegree >= 67.5 && $windDegree < 112.5) { + return MeteorologicalDailyReport::WIND_DIRECTION_EAST; + } elseif ($windDegree >= 112.5 && $windDegree < 157.5) { + return MeteorologicalDailyReport::WIND_DIRECTION_SOUTHEAST; + } elseif ($windDegree >= 157.5 && $windDegree < 202.5) { + return MeteorologicalDailyReport::WIND_DIRECTION_SOUTH; + } elseif ($windDegree >= 202.5 && $windDegree < 247.5) { + return MeteorologicalDailyReport::WIND_DIRECTION_SOUTHWEST; + } elseif ($windDegree >= 247.5 && $windDegree < 292.5) { + return MeteorologicalDailyReport::WIND_DIRECTION_WEST; + } elseif ($windDegree >= 292.5 && $windDegree < 337.5) { + return MeteorologicalDailyReport::WIND_DIRECTION_NORTHWEST; + } + + return MeteorologicalDailyReport::WIND_DIRECTION_NORTH; + }, $attributes['wind_degree']); break; default: - $item['sum'] = bcadd($item['sum'], $v, 2); - $item['count']++; + $attributes[$key] = $item['count'] > 0 ? round(bcdiv($item['sum'], $item['count'], 2), 2) : null; break; } - - $carry[$key] = $item; } - return $carry; - }, [ - 'today_rainfall' => ['sum' => 0, 'count' => 0], - 'yesterday_rainfall' => ['sum' => 0, 'count' => 0], - 'accumulate_rainfall' => ['sum' => 0, 'count' => 0], - 'moment_rainfall' => ['sum' => 0, 'count' => 0], - 'pm10' => ['sum' => 0, 'count' => 0], - 'pm25' => ['sum' => 0, 'count' => 0], - 'box_illumination' => ['sum' => 0, 'count' => 0], - 'box_pressure' => ['sum' => 0, 'count' => 0], - 'box_co2' => ['sum' => 0, 'count' => 0], - 'box_temperature' => ['sum' => 0, 'count' => 0], - 'box_humidity' => ['sum' => 0, 'count' => 0], - 'box_noise' => ['sum' => 0, 'count' => 0], - 'wind_samples' => [], - ]); + return $attributes; + }, $meteorologicalReports); + /** @var \App\Models\MeteorologicalDailyReport */ $meteorologicalDailyReport = MeteorologicalDailyReport::firstOrCreate([ 'device_id' => $device->id, 'reported_at' => $date, - ]); + ], $attributes); - foreach ($result as $key => $item) { - switch ($key) { - case 'wind_samples': - $meteorologicalDailyReport->wind_degree = value(function (array $windSamples) { - $x = 0; - $y = 0; - - foreach ($windSamples as $sample) { - if ($sample['wind_degree'] == 0 && $sample['wind_speed'] == 0) { - continue; - } - - // 角度转弧度 - $radian = deg2rad($sample['wind_degree']); - - // $x += $sample['wind_speed'] * sin($radian); - // $y += $sample['wind_speed'] * cos($radian); - $x += sin($radian); - $y += cos($radian); - } - - $degree = round(rad2deg(atan2($y, $x))); - - if (($x > 0 || $x < 0) && $y < 0) { - $degree += 180; - } elseif ($x < 0 && $y > 0) { - $degree += 360; - } - - return $degree; - }, $item); - - $meteorologicalDailyReport->wind_direction = value(function ($windDegree) { - if ($windDegree >= 22.5 && $windDegree < 67.5) { - return MeteorologicalDailyReport::WIND_DIRECTION_NORTHEAST; - } elseif ($windDegree >= 67.5 && $windDegree < 112.5) { - return MeteorologicalDailyReport::WIND_DIRECTION_EAST; - } elseif ($windDegree >= 112.5 && $windDegree < 157.5) { - return MeteorologicalDailyReport::WIND_DIRECTION_SOUTHEAST; - } elseif ($windDegree >= 157.5 && $windDegree < 202.5) { - return MeteorologicalDailyReport::WIND_DIRECTION_SOUTH; - } elseif ($windDegree >= 202.5 && $windDegree < 247.5) { - return MeteorologicalDailyReport::WIND_DIRECTION_SOUTHWEST; - } elseif ($windDegree >= 247.5 && $windDegree < 292.5) { - return MeteorologicalDailyReport::WIND_DIRECTION_WEST; - } elseif ($windDegree >= 292.5 && $windDegree < 337.5) { - return MeteorologicalDailyReport::WIND_DIRECTION_NORTHWEST; - } - - return MeteorologicalDailyReport::WIND_DIRECTION_NORTH; - }, $meteorologicalDailyReport->wind_degree); - - break; - - default: - if ($item['count'] > 0) { - $meteorologicalDailyReport->{$key} = round(bcdiv($item['sum'], $item['count'], 2), 2); - } - break; - } + if (! $meteorologicalDailyReport->wasRecentlyCreated) { + $meteorologicalDailyReport->update($attributes); } - - $meteorologicalDailyReport->save(); } /** @@ -364,39 +364,46 @@ class DeviceLogService return; } - $result = $waterQualityReports->reduce(function (array $carry, WaterQualityReport $waterQualityReport) { - foreach ($carry as $key => $item) { - if (is_null($v = $waterQualityReport->{$key})) { - continue; + $attributes = value(function ($waterQualityReports) { + $data = [ + 'chlorine' => ['sum' => 0, 'count' => 0], + 'conductivity' => ['sum' => 0, 'count' => 0], + 'oxygen' => ['sum' => 0, 'count' => 0], + 'ph' => ['sum' => 0, 'count' => 0], + 'temperature' => ['sum' => 0, 'count' => 0], + 'turbidity' => ['sum' => 0, 'count' => 0], + ]; + + foreach ($waterQualityReports as $waterQualityReport) { + foreach ($data as $k => $item) { + if (is_null($v = $waterQualityReport->{$k})) { + continue; + } + + $item['sum'] = bcadd($item['sum'], $v, 2); + $item['count']++; + + $data[$k] = $item; } - - $item['sum'] = bcadd($item['sum'], $v, 2); - $item['count']++; - - $carry[$key] = $item; } - return $carry; - }, [ - 'chlorine' => ['sum' => 0, 'count' => 0], - 'conductivity' => ['sum' => 0, 'count' => 0], - 'oxygen' => ['sum' => 0, 'count' => 0], - 'ph' => ['sum' => 0, 'count' => 0], - 'temperature' => ['sum' => 0, 'count' => 0], - 'turbidity' => ['sum' => 0, 'count' => 0], - ]); + $attributes = []; + foreach ($data as $key => $item) { + $attributes[$key] = $item['count'] > 0 ? round(bcdiv($item['sum'], $item['count'], 2), 2) : null; + } + + return $attributes; + }, $waterQualityReports); + + /** @var \App\Models\WaterQualityDailyReport */ $waterQualityDailyReport = WaterQualityDailyReport::firstOrCreate([ 'device_id' => $device->id, 'reported_at' => $date->format('Y-m-d'), - ]); + ], $attributes); - foreach ($result as $key => $item) { - if ($item['count'] > 0) { - $waterQualityDailyReport->{$key} = round(bcdiv($item['sum'], $item['count'], 2), 2); - } + if (! $waterQualityDailyReport->wasRecentlyCreated) { + $waterQualityDailyReport->update($attributes); } - - $waterQualityDailyReport->save(); } }