diff --git a/app/Console/Commands/DeviceLogDailyReportCommand.php b/app/Console/Commands/BiAng/DeviceLogDailyReportCommand.php similarity index 82% rename from app/Console/Commands/DeviceLogDailyReportCommand.php rename to app/Console/Commands/BiAng/DeviceLogDailyReportCommand.php index 4e2feef..6997306 100644 --- a/app/Console/Commands/DeviceLogDailyReportCommand.php +++ b/app/Console/Commands/BiAng/DeviceLogDailyReportCommand.php @@ -1,6 +1,6 @@ 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(['supplier'])->supplierBy("device-supplier-{$factory}")->get(); + $devices = Device::supplierBy("device-supplier-biang")->get(); foreach ($devices as $device) { - switch ($device->supplier?->key) { - case 'device-supplier-biang': - $this->createReportToBiAngDevice($device); - break; - } + $this->createReport($device); } sleep($sleep); }; } - /** - * 创建 linkos 设备报告 - */ - protected function createReportToBiAngDevice(Device $device): void + protected function createReport(Device $device): void { [$lastReportedAt, $latestReportedAt] = value(function (Device $device) { $lastReportedAt = null; diff --git a/app/Console/Commands/DeviceLogReportCommand.php b/app/Console/Commands/BiAng/DeviceLogReportCommand.php similarity index 79% rename from app/Console/Commands/DeviceLogReportCommand.php rename to app/Console/Commands/BiAng/DeviceLogReportCommand.php index bc8fbe5..2233061 100644 --- a/app/Console/Commands/DeviceLogReportCommand.php +++ b/app/Console/Commands/BiAng/DeviceLogReportCommand.php @@ -1,6 +1,6 @@ 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(['supplier'])->supplierBy("device-supplier-{$factory}")->get(); + $devices = Device::supplierBy("device-supplier-biang")->get(); foreach ($devices as $device) { - switch ($device->supplier?->key) { - case 'device-supplier-biang': - $this->createReportToBiAngDevice($device); - break; - } + $this->createReport($device); } sleep($sleep); @@ -61,7 +54,7 @@ class DeviceLogReportCommand extends Command /** * 创建比昂设备报告 */ - protected function createReportToBiAngDevice(Device $device): void + protected function createReport(Device $device): void { $lastReportedAt = match ($device->type) { DeviceType::Soil => SoilMonitoringLog::where('device_id', $device->id)->latest('monitored_at')->value('monitored_at'), diff --git a/app/Console/Commands/DeviceLogSyncCommand.php b/app/Console/Commands/BiAng/DeviceLogSyncCommand.php similarity index 68% rename from app/Console/Commands/DeviceLogSyncCommand.php rename to app/Console/Commands/BiAng/DeviceLogSyncCommand.php index b596575..7f7fb6c 100644 --- a/app/Console/Commands/DeviceLogSyncCommand.php +++ b/app/Console/Commands/BiAng/DeviceLogSyncCommand.php @@ -1,7 +1,8 @@ argument('factory'); - $sleep = (int) value(fn ($sleep) => is_numeric($sleep) ? $sleep : 60, $this->option('sleep')); while (true) { - $this->runSync($factory); + $this->runSync(); sleep($sleep); }; @@ -45,36 +43,40 @@ class DeviceLogSyncCommand extends Command /** * 执行同步 */ - protected function runSync(string $factory): void + protected function runSync(): void { - $end = now(); - $start = $end->copy()->subHours(1); + $now = now(); $this->info('------------------------------------------'); - $this->info('开始时间: '. $start); - $this->info('结束时间: '. $end); + $this->info('同步时间: '. $now); /** @var \Illuminate\Database\Eloquent\Collection */ - $devices = Device::with(['supplier', 'project'])->supplierBy("device-supplier-{$factory}")->get(); + $devices = Device::with(['project']) + ->supplierBy("device-supplier-biang") + ->whereIn('status', [DeviceStatus::Online, DeviceStatus::Offline]) + ->get(); /** @var \App\Models\Device */ foreach ($devices as $device) { + if (! in_array($device->type, [ + DeviceType::Soil, + DeviceType::Meteorological, + DeviceType::InsecticidalLamp, + ])) { + continue; + } + $this->info('=========================================='); $this->info('设备编号: ' . $device->sn); $this->info('设备名称: ' . $device->name); $this->info('设备类型: ' . match ($device->type) { DeviceType::Soil => '土壤设备', - DeviceType::WaterQuality => '水质设备', DeviceType::Meteorological => '气象设备', - default => '其它', + DeviceType::InsecticidalLamp => '杀虫灯设备', }); try { - switch ($device->supplier?->key) { - case 'device-supplier-biang': - (new BiAngDeviceLogService())->sync($device, $start, $end); - break; - } + (new BiAngDeviceLogService())->sync($device, $now); $this->info('同步成功!'); } catch (Throwable $e) { diff --git a/app/Enums/DeviceType.php b/app/Enums/DeviceType.php index ce0cc34..548c381 100644 --- a/app/Enums/DeviceType.php +++ b/app/Enums/DeviceType.php @@ -8,7 +8,9 @@ enum DeviceType: int case Soil = 2; // 土壤设备 case WaterQuality = 3; // 水质设备 case Meteorological = 4; // 气象设备 - case Insect = 5; // 虫情设备 + case Worm = 5; // 虫情设备 + case InsectSexLure = 6; // 昆虫性诱设备 + case InsecticidalLamp = 7; // 杀虫灯设备 /** * @return string @@ -28,7 +30,9 @@ enum DeviceType: int static::Soil->value => '土壤设备', static::WaterQuality->value => '水质设备', static::Meteorological->value => '气象设备', - static::Insect->value => '虫情设备', + static::Worm->value => '虫情设备', + static::InsectSexLure->value => '昆虫性诱设备', + static::InsecticidalLamp->value => '杀虫灯设备', ]; } } diff --git a/app/Exceptions/BiAngException.php b/app/Exceptions/BiAngException.php new file mode 100644 index 0000000..7726028 --- /dev/null +++ b/app/Exceptions/BiAngException.php @@ -0,0 +1,9 @@ +get( + $this->apiUrl2('/open-api/open/getCurrentLampData'), + [ + 'deviceId' => $deviceId, + ] ); + + return $result['data']; + } + + /** + * 虫情设备/昆虫性诱设备 - 查询某个时间段内的图片 + */ + public function getWormPhotos(string $deviceId, Carbon $start, Carbon $end) + { + $result = $this->get( + $this->apiUrl('/api/open-api/open/getDevicePhotos'), + [ + 'deviceId' => $deviceId, + 'startTime' => $start->toDateString(), + 'endTime' => $end->toDateString(), + ] + ); + + return $result['data']; + } + + /** + * 虫情设备 - (识别款)图片虫数识别统计 + */ + public function getWormStatistics(string $deviceId, Carbon $start, Carbon $end) + { + $result = $this->get( + $this->apiUrl('/api/open-api/open/getAllStatistics'), + [ + 'imei' => $deviceId, + 'startAt' => $start->toDateString(), + 'endAt' => $end->toDateString(), + ] + ); + + return $result['data']; } public function get(string $url, array $query = []): array @@ -108,7 +146,13 @@ class HttpClient 'Content-Type' => 'application/json', ])->send($method, $url, $options); - return $response->throw()->json(); + $result = $response->throw()->json(); + + if (data_get($result, 'code') === 200) { + return $result; + } + + throw new BiAngException($result['code'].':'.($result['msg']??'出错啦!'), 500); } protected function apiUrl(string $path): string diff --git a/app/Models/InsecticidalLampReport.php b/app/Models/InsecticidalLampReport.php new file mode 100644 index 0000000..99c5b22 --- /dev/null +++ b/app/Models/InsecticidalLampReport.php @@ -0,0 +1,28 @@ + 'datetime', + ]; + + protected $fillable = [ + 'device_id', + 'battery_vol', + 'killed_num', + 'air_temperature', + 'air_humidity', + 'lng', + 'lat', + 'solar_panel_vol', + 'high_vol', + 'reported_at', + ]; +} diff --git a/app/Services/BiAngDeviceLogService.php b/app/Services/BiAngDeviceLogService.php index 5f31bdd..fb6a2c5 100644 --- a/app/Services/BiAngDeviceLogService.php +++ b/app/Services/BiAngDeviceLogService.php @@ -7,6 +7,7 @@ use App\Enums\DeviceType; use App\Iot\BiAng\HttpClient as BiAngHttpClient; use App\Models\Device; use App\Models\DeviceLog; +use App\Models\InsecticidalLampReport; use App\Models\MeteorologicalMonitoringDailyLog; use App\Models\MeteorologicalMonitoringLog; use App\Models\SoilMonitoringDailyLog; @@ -17,7 +18,7 @@ use Illuminate\Support\Facades\DB; class BiAngDeviceLogService { - public function sync(Device $device, Carbon $startAt, Carbon $endAt): void + public function sync(Device $device, Carbon $syncTime): void { $config = json_decode($device->project?->value, true); if (! isset($config['username'], $config['password'])) { @@ -36,11 +37,9 @@ class BiAngDeviceLogService 'data' => Arr::except($data, ['deviceId', 'time']), ]); - if (in_array($device->status, [DeviceStatus::Online, DeviceStatus::Offline])) { - $device->update([ - 'status' => $startAt->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, - ]); - } + $device->update([ + 'status' => $syncTime->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, + ]); break; case DeviceType::Meteorological: $data = $httpClient->getLatestMeteorologicalReport($device->sn); @@ -52,11 +51,33 @@ class BiAngDeviceLogService 'data' => Arr::except($data, ['deviceId', 'time']), ]); - if (in_array($device->status, [DeviceStatus::Online, DeviceStatus::Offline])) { - $device->update([ - 'status' => $startAt->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, + $device->update([ + 'status' => $syncTime->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline, + ]); + break; + + case DeviceType::InsecticidalLamp: + $data = $httpClient->getLatestLampReport($device->sn); + + if ($data['status'] === 'online') { + InsecticidalLampReport::updateOrCreate([ + 'device_id' => $device->id, + 'reported_at' => $syncTime->copy()->startOfHour(), + ], [ + 'battery_vol' => $data['vol'], + 'killed_num' => $data['dct'], + 'air_temperature' => $data['temp'], + 'air_humidity' => $data['humidity'], + 'lng' => $data['lng'], + 'lat' => $data['lat'], + 'solar_panel_vol' => $data['sunVol'], + 'high_vol' => $data['highVol'], ]); } + + $device->update([ + 'status' => $data['status'] === 'online' ? DeviceStatus::Online : DeviceStatus::Offline, + ]); break; } } diff --git a/database/migrations/2023_08_11_172337_create_insecticidal_lamp_reports_table.php b/database/migrations/2023_08_11_172337_create_insecticidal_lamp_reports_table.php new file mode 100644 index 0000000..daf6f95 --- /dev/null +++ b/database/migrations/2023_08_11_172337_create_insecticidal_lamp_reports_table.php @@ -0,0 +1,41 @@ +id(); + $table->unsignedBigInteger('device_id'); + $table->double('battery_vol')->nullable()->comment('蓄电池电压'); + $table->unsignedInteger('killed_num')->default(0)->comment('杀虫树'); + $table->double('air_temperature')->nullable()->comment('大气气温'); + $table->double('air_humidity')->nullable()->comment('大气湿度'); + $table->double('lng')->nullable()->comment('经度'); + $table->double('lat')->nullable()->comment('纬度'); + $table->double('solar_panel_vol')->nullable()->comment('太阳板电压'); + $table->double('high_vol')->nullable()->comment('高压值'); + $table->timestamp('reported_at')->comment('监控日期'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('insecticidal_lamp_reports'); + } +};