From 550ea41ab7f01926cd071aa3c28d747ed9eb9b04 Mon Sep 17 00:00:00 2001 From: Jing Li Date: Sat, 12 Aug 2023 21:52:47 +0800 Subject: [PATCH] Update --- app/Http/Controllers/DeviceController.php | 277 +++++++++++++--------- 1 file changed, 170 insertions(+), 107 deletions(-) diff --git a/app/Http/Controllers/DeviceController.php b/app/Http/Controllers/DeviceController.php index b0f01e3..8b1ceab 100644 --- a/app/Http/Controllers/DeviceController.php +++ b/app/Http/Controllers/DeviceController.php @@ -10,6 +10,8 @@ use App\Http\Requestes\DeviceRequest; use App\Http\Resources\DeviceResource; use App\Models\AgriculturalBase; use App\Models\Device; +use App\Models\InsecticidalLampDailyReport; +use App\Models\InsecticidalLampReport; use App\Models\MeteorologicalMonitoringDailyLog; use App\Models\MeteorologicalMonitoringLog; use App\Models\SoilMonitoringDailyLog; @@ -21,6 +23,7 @@ use App\Services\OperationLogService; use Illuminate\Http\Request; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; +use Illuminate\Validation\ValidationException; use Peidikeji\Setting\Models\Setting; class DeviceController extends Controller @@ -416,48 +419,46 @@ class DeviceController extends Controller } } - /** - * 查询设备今天(按天),近一周(按天),近一个月(按天) - */ - public function timeZoneList(Request $request){ - $deviceId = $request->input('device_id'); - //不传开始时间,结束时间,则默认是查当天(按小时) - $startTime = $request->input('start_time'); - $endTime = $request->input('end_time'); - $diffDays = 0; - $day = date('Y-m-d'); - //如果传了开始时间和结束时间,计算中间天数 - if($startTime && $endTime){ - if($startTime == $endTime){//查询某一天 - $day = $startTime; - }else{ - $startDay = Carbon::parse($startTime); - $endDay = Carbon::parse($endTime); - $diffDays = $startDay->diffInDays($endDay, false); + public function timeZoneList(Request $request) + { + $request->validate([ + 'device_id' => ['bail', 'required'], + 'start_time' => ['bail', 'nullable', 'date_format:Y-m-d'], + 'end_time' => ['bail', 'nullable', 'date_format:Y-m-d'], + ]); + + $isSameDay = true; + + if ($request->filled('start_time') && $request->filled('end_time')) { + $startTime = Carbon::parse($request->input('start_time'))->startOfDay(); + $endTime = Carbon::parse($request->input('end_time'))->startOfDay(); + + if ($startTime->gt($endTime)) { + throw ValidationException::withMessages([ + 'start_time' => ['开始时间不能大于结束时间'], + ]); } + + // 如果开始时间和结束时间是同一天 + if ($startTime->eq($endTime)) { + $endTime = $startTime->isToday() ? now() : $startTime->copy()->endOfDay(); + } else { + $isSameDay = false; + } + } else { + $endTime = now(); + $startTime = $endTime->copy()->startOfDay(); } - $xKeys = []; - if($diffDays){ - for ($i = 0; $i<=$diffDays; $i++) { - $xKeys[] =(clone $startDay)->addDays($i)->startOfDay()->format('Y-m-d H:i:s'); - } - }else{ - //调整截至到当前小时 - $h = 23; - if($day == date('Y-m-d')){ - $h = date('H'); - } - for ($i = 0; $i < ($h+1); $i++) { - $xKeys[] = $day.' '.str_pad($i, 2, '0', STR_PAD_LEFT).':00:00'; - } - } - $device = Device::find($deviceId); - $modelQuery = null; - $getArr = []; + $device = Device::findOrFail($request->input('device_id')); + + $fields = []; + $monitoringLogs = collect(); + switch ($device->type) { - case DeviceType::Meteorological://气象设备 - $getArr = [ + // 气象设备 + case DeviceType::Meteorological: + $fields = [ 'wind_speed', 'wind_direction', 'wind_degree', @@ -469,17 +470,34 @@ class DeviceController extends Controller 'illumination', 'pm25', 'pm10', + 'rainfall', ]; - if($diffDays) { - $getArr[] = 'daily_rainfall'; - $modelQuery = MeteorologicalMonitoringDailyLog::query()->whereBetween('monitored_at', [$startTime, $endTime]); - }else{ - $getArr[] = 'current_rainfall'; - $modelQuery = MeteorologicalMonitoringLog::query()->whereDate('monitored_at', $day); - } + /** @var \Illuminate\Support\Collection */ + $monitoringLogs = ( + $isSameDay + ? MeteorologicalMonitoringLog::query() + : MeteorologicalMonitoringDailyLog::query() + ) + ->where('device_id', $device->id) + ->whereBetween('monitored_at', [$startTime, $endTime]) + ->get() + ->mapWithKeys(function ($item) use ($fields) { + $key = $item->monitored_at->toDateTimeString(); + $data = collect($fields)->mapWithKeys(fn ($field) => [$field => $field !== 'rainfall' ? $item[$field] : null])->all(); + + if ($item instanceof MeteorologicalMonitoringDailyLog) { + $data['rainfall'] = $item->daily_rainfall; + } else { + $data['rainfall'] = $item->current_rainfall; + } + + return [$key => $data]; + }); break; - case DeviceType::Soil://土壤设备 - $getArr = [ + + // 土壤设备 + case DeviceType::Soil: + $fields = [ 'conductivity', 'humidity', 'temperature', @@ -487,14 +505,25 @@ class DeviceController extends Controller 'p', 'k', ]; - if($diffDays) { - $modelQuery = SoilMonitoringDailyLog::query()->whereBetween('monitored_at', [$startTime, $endTime]); - }else{ - $modelQuery = SoilMonitoringLog::query()->whereDate('monitored_at', $day); - } + /** @var \Illuminate\Support\Collection */ + $monitoringLogs = ( + $isSameDay + ? SoilMonitoringLog::query() + : SoilMonitoringDailyLog::query() + ) + ->where('device_id', $device->id) + ->whereBetween('monitored_at', [$startTime, $endTime]) + ->get() + ->mapWithKeys(function ($item) use ($fields) { + $key = $item->monitored_at->toDateTimeString(); + $data = collect($fields)->mapWithKeys(fn ($field) => [$field => $item[$field]])->all(); + return [$key => $data]; + }); break; - case DeviceType::WaterQuality://水质设备 - $getArr = [ + + // 水质设备 + case DeviceType::WaterQuality: + $fields = [ 'chlorine', 'conductivity', 'oxygen', @@ -502,62 +531,96 @@ class DeviceController extends Controller 'temperature', 'turbidity', ]; - if($diffDays) { - $modelQuery = WaterQualityMonitoringDailyLog::query()->whereBetween('monitored_at', [$startTime, $endTime]); - }else{ - $modelQuery = WaterQualityMonitoringLog::query()->whereDate('monitored_at', $day); - } + /** @var \Illuminate\Support\Collection */ + $monitoringLogs = ( + $isSameDay + ? WaterQualityMonitoringLog::query() + : WaterQualityMonitoringDailyLog::query() + ) + ->where('device_id', $device->id) + ->whereBetween('monitored_at', [$startTime, $endTime]) + ->get() + ->mapWithKeys(function ($item) use ($fields) { + $key = $item->monitored_at->toDateTimeString(); + $data = collect($fields)->mapWithKeys(fn ($field) => [$field => $item[$field]])->all(); + return [$key => $data]; + }); + break; + + // 杀虫灯 + case DeviceType::InsecticidalLamp: + $fields = [ + 'battery_vol', + 'killed_num', + 'air_temperature', + 'air_humidity', + 'solar_panel_vol', + 'high_vol', + ]; + /** @var \Illuminate\Support\Collection */ + $monitoringLogs = ( + $isSameDay + ? InsecticidalLampReport::query() + : InsecticidalLampDailyReport::query() + ) + ->where('device_id', $device->id) + ->whereBetween('reported_at', [$startTime, $endTime]) + ->get() + ->mapWithKeys(function ($item) use ($fields) { + $key = $item->reported_at->toDateTimeString(); + $data = collect($fields)->mapWithKeys(fn ($field) => [$field => $item[$field]])->all(); + return [$key => $data]; + }); break; } - if($modelQuery){ - $datalist = $modelQuery->where('device_id', $deviceId)->get()->keyBy('monitored_at')->toArray(); - } - $data = []; - foreach ($getArr as $column){ - $data[$column] = []; - $_value = null; - foreach($xKeys as $key){ - if($device->type == DeviceType::WaterQuality){//如果是水质设备,则写死假数据 - switch($column){ - case 'chlorine': - $data[$column][$key] = 0.016; - break; - case 'conductivity': - $data[$column][$key] = 563 ;//电导率 - break; - case 'oxygen': - $data[$column][$key] = 0.09;//含氧量 - break; - case 'ph': - $data[$column][$key] = rand(750, 770) / 100; - break; - case 'temperature': - $data[$column][$key] = rand(2400, 2600) / 100; - break; - case 'turbidity': - $data[$column][$key] = 0.33; - break; + + return $this->json( + collect($fields)->mapWithKeys(function ($field) use ($device, $monitoringLogs, $isSameDay, $startTime, $endTime) { + $data = []; + + $beginTime = $startTime->copy(); + + do { + $key = $beginTime->toDateTimeString(); + + $monitoringLog = $monitoringLogs->get($key); + + if (is_null($monitoringLog)) { + // 如果是水质设备,则写死假数据 + if($device->type == DeviceType::WaterQuality){ + switch($field){ + case 'chlorine': + $data[$key] = 0.016; + break; + case 'conductivity': + $data[$key] = rand(560, 565);//电导率 + break; + case 'oxygen': + $data[$key] = 0.09;//含氧量 + break; + case 'ph': + $data[$key] = rand(750, 770) / 100; + break; + case 'temperature': + $data[$key] = rand(2400, 2600) / 100; + break; + case 'turbidity': + $data[$key] = 0.33; + break; + } + } else { + $data[$key] = null; + } + } else { + $data[$key] = $monitoringLog[$field]; } - }else{ - // if($datalist[$key][$column] ?? null){//如果存在数据则暂存该值 - // $_value = $datalist[$key][$column]; - // } - // //判断是否超过离线时间; - // if(true){//未超过, 判断和设备离线时间关系-todo - // $data[$column][$key] = $_value; - // }else{ - $data[$column][$key] = $datalist[$key][$column] ?? null; - // } - } - } - } - //强制统一气象降雨量,日和天字段不统一问题 - if(isset($data['daily_rainfall'])) { - $data['rainfall'] = $data['daily_rainfall']; - }elseif(isset($data['current_rainfall'])){ - $data['rainfall'] = $data['current_rainfall']; - } - return $this->json($data); + + $isSameDay ? $beginTime->addHours(1) : $beginTime->addDays(1); + } while ($beginTime->lte($endTime)); + + return [$field => $data]; + }) + ); } public function getFfmpegServiceIp(){