lcly-data-admin/app/Http/Controllers/DeviceController.php

340 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers;
use App\Enums\DeviceStatus;
use App\Enums\DeviceType;
use App\Helpers\Paginator;
use App\Http\Requestes\DeviceRequest;
use App\Http\Resources\DeviceResource;
use App\Models\Device;
use App\Models\MeteorologicalMonitoringLog;
use App\Models\MeteorologicalMonitoringDailyLog;
use App\Models\SoilMonitoringLog;
use App\Models\SoilMonitoringDailyLog;
use App\Models\WaterQualityMonitoringLog;
use App\Models\WaterQualityMonitoringDailyLog;
use App\Models\AgriculturalBase;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
class DeviceController extends Controller
{
public function index(Request $request)
{
$query = Device::with('base')->filter($request->input());
$list = $query->paginate(Paginator::resolvePerPage('per_page', 20, 50));
return $this->json(DeviceResource::collection($list));
}
public function store(DeviceRequest $request)
{
$input = $request->input();
//如果不是监控设备移除extends
if ($input['type'] != DeviceType::Monitor->value) {
unset($input['extends']);
}
Device::create(array_merge($input, [
'created_by' => auth('api')->user()?->id ?? 0,
'updated_by' => auth('api')->user()?->id ?? 0,
]));
return $this->success('添加成功');
}
public function show(Device $device)
{
return $this->json(DeviceResource::make($device));
}
public function update(Device $device, DeviceRequest $request)
{
$input = $request->input();
//如果不是监控设备移除extends
if ($input['type'] != DeviceType::Monitor->value) {
$input['extends'] = null;
}
$device->update(array_merge($input, [
'updated_by' => auth('api')->user()?->id ?? 0,
]));
return $this->success('修改成功');
}
public function destroy(Device $device)
{
$device->delete();
return $this->success('删除成功');
}
public function types()
{
return $this->json(DeviceType::types());
}
/**
* 统计某个基地下所有设备状态数量
*/
public function typeStatusNum(Request $request)
{
$baseId = $request->input('base_id', 0);
$parent = $request->input('parent', 0);
$query = Device::query();
if($parent){
$baseIds = AgriculturalBase::where('parent_id', $parent)->pluck('id')->toArray();
if(count($baseIds) > 0){
$query->whereIn('agricultural_base_id', $baseIds);
}else{
$query->where('agricultural_base_id', 0);
}
}
//如果查了镇街就不查指定基地了
if(!$parent && $baseId){
$query->where('agricultural_base_id', $baseId);
}
$query->groupBy('type')->groupBy('status');
$list = $query->select(DB::raw('type, status, count(1) as num '))->get();
$resData = [];
foreach ($list as $item) {
$resData[$item->type->value][$item->status->value] = $item->num;
}
//初始化数据;
$data = [];
foreach (DeviceType::types() as $typeKey => $typeName) {
foreach (DeviceStatus::status() as $statusKey => $statusName) {
$data[$typeKey][$statusKey] = $resData[$typeKey][$statusKey] ?? 0;
}
}
return $this->json($data);
}
/**
* 设备数据
*/
public function dataStatics(Request $request)
{
$deviceId = $request->input('device_id');
$deviceColumn = $request->input('device_column'); //指定字段
$device = Device::find($deviceId);
$data = null;
switch ($device->type) {
case DeviceType::Monitor://监控设备
$data = DeviceResource::make($device);
break;
case DeviceType::Meteorological://气象设备
//当天最新一条
$log = MeteorologicalMonitoringLog::where('device_id', $deviceId)->orderBy('created_at', 'desc')->first();
$data = $log->toArray();
break;
case DeviceType::Soil://土壤设备
//当前时间往前推6个小时;
$startTime = now()->subHours(6);
$dataList = SoilMonitoringLog::where('device_id', $deviceId)->where('monitored_at', '>=', $startTime)->get()->keyBy('monitored_at')->toArray();
$data = [];
for ($i = 5; $i >= 0; $i--) {
$_key = now()->subHours($i)->format('Y-m-d H').':00:00';
$data[$_key] = null;
if (isset($dataList[$_key])) {
$data[$_key] = $dataList[$_key][$deviceColumn] ?? null;
}
}
break;
case DeviceType::WaterQuality://水质设备
//当天
$startTime = now()->subHours(6);
$dataList = WaterQualityMonitoringLog::where('device_id', $deviceId)->where('monitored_at', '>=', $startTime)->get()->keyBy('monitored_at')->toArray();
$data = [];
for ($i = 5; $i >= 0; $i--) {
$_key = now()->subHours($i)->format('Y-m-d H').':00:00';
$data[$_key] = null;
if (isset($dataList[$_key])) {
$data[$_key] = $dataList[$_key][$deviceColumn] ?? null;
}
}
break;
}
return $this->json([
'list' => $data,
]);
}
/**
* 获取指定基地指定设备类型的所有设备指定维度数据
*/
public function baseDataStatics(Request $request)
{
$baseId = $request->input('base_id');
$deviceType = $request->input('device_type');
$deviceColumn = $request->input('device_column'); //指定字段
//先获取基地下该类型所有设备
$deviceData = Device::where([
'agricultural_base_id' => $baseId,
'type' => $deviceType,
])->get();
$data = [];
switch ($deviceType) {
case DeviceType::Monitor->value://监控设备
$data = DeviceResource::collection($deviceData);
break;
case DeviceType::Soil->value:
$startTime = now()->subHours(6);
$dataList = SoilMonitoringLog::where('agricultural_base_id', $baseId)->where('monitored_at', '>=', $startTime)->get()->groupBy('device_id');
foreach ($deviceData as $device) {
$_dataList = $dataList->get($device->id);
$data[$device->monitoring_point] = [];
if ($_dataList) {
$_dataList = $_dataList->keyBy('monitored_at')->toArray();
}
for ($i = 5; $i >= 0; $i--) {
$_key = now()->subHours($i)->format('Y-m-d H').':00:00';
$data[$device->monitoring_point][$_key] = null;
if (isset($_dataList[$_key])) {
$data[$device->monitoring_point][$_key] = $_dataList[$_key][$deviceColumn] ?? null;
}
}
}
break;
case DeviceType::WaterQuality->value:
$startTime = now()->subHours(6);
$dataList = WaterQualityMonitoringLog::where('agricultural_base_id', $baseId)->where('monitored_at', '>=', $startTime)->get()->groupBy('device_id');
foreach ($deviceData as $device) {
$_dataList = $dataList->get($device->id);
$data[$device->monitoring_point] = [];
if ($_dataList) {
$_dataList = $_dataList->keyBy('monitored_at')->toArray();
}
for ($i = 5; $i >= 0; $i--) {
$_key = now()->subHours($i)->format('Y-m-d H').':00:00';
$data[$device->monitoring_point][$_key] = null;
if (isset($_dataList[$_key])) {
if($deviceColumn == 'ph'){
$data[$device->monitoring_point][$_key] = 7.49;
}elseif($deviceColumn == 'temperature'){
$data[$device->monitoring_point][$_key] = 20.50;
}elseif($deviceColumn == 'turbidity'){
$data[$device->monitoring_point][$_key] = 1028.60;
}else{
$data[$device->monitoring_point][$_key] = $_dataList[$_key][$deviceColumn] ?? null;
}
}
}
}
break;
}
return $this->json($data);
}
/**
* 查询设备今天(按天),近一周(按天),近一个月(按天)
*/
public function timeZoneList(Request $request){
$deviceId = $request->input('device_id');
//不传开始时间,结束时间,则默认是查当天(按小时)
$startTime = $request->input('start_time');
$endTime = $request->input('end_time');
$diffDays = 0;
//如果传了开始时间和结束时间,计算中间天数
if($startTime && $endTime){
$startDay = Carbon::parse($startTime);
$endDay = Carbon::parse($endTime);
$diffDays = $startDay->diffInDays($endDay, false);
}
$xKeys = [];
if($diffDays){
for ($i = 0; $i<=$diffDays; $i++) {
$xKeys[] =(clone $startDay)->addDays($i)->startOfDay()->format('Y-m-d H:i:s');
}
}else{
//调整截至到当前小时
$h = date('h');
for ($i = 0; $i < ($h+1); $i++) {
$xKeys[] = date('Y-m-d').' '.str_pad($i, 2, '0', STR_PAD_LEFT).':00:00';
}
}
$device = Device::find($deviceId);
$modelQuery = null;
$getArr = [];
switch ($device->type) {
case DeviceType::Meteorological://气象设备
$getArr = [
'wind_speed',
'wind_direction',
'wind_degree',
'air_humidity',
'air_temperature',
'air_pressure',
'co2',
'noise',
'illumination',
'daily_rainfall',
'pm25',
'pm10',
];
if($diffDays) {
$modelQuery = MeteorologicalMonitoringDailyLog::query()->whereBetween('monitored_at', [$startTime, $endTime]);
}else{
$modelQuery = MeteorologicalMonitoringLog::query()->whereDate('monitored_at', now());
}
break;
case DeviceType::Soil://土壤设备
$getArr = [
'conductivity',
'humidity',
'temperature',
'n',
'p',
'k',
];
if($diffDays) {
$modelQuery = SoilMonitoringDailyLog::query()->whereBetween('monitored_at', [$startTime, $endTime]);
}else{
$modelQuery = SoilMonitoringLog::query()->whereDate('monitored_at', now());
}
break;
case DeviceType::WaterQuality://水质设备
$getArr = [
'chlorine',
'conductivity',
'oxygen',
'ph',
'temperature',
'turbidity',
];
if($diffDays) {
$modelQuery = WaterQualityMonitoringDailyLog::query()->whereBetween('monitored_at', [$startTime, $endTime]);
}else{
$modelQuery = WaterQualityMonitoringLog::query()->whereDate('monitored_at', now());
}
break;
}
if($modelQuery){
$datalist = $modelQuery->where('device_id', $deviceId)->get()->keyBy('monitored_at')->toArray();
}
$data = [];
foreach ($getArr as $column){
$data[$column] = [];
foreach($xKeys as $key){
$data[$column][$key] = $datalist[$key][$column] ?? null;
}
}
return $this->json($data);
}
}