lcly-data-admin/app/Console/Commands/Linkos/WormReportCommand.php

160 lines
4.9 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\Console\Commands\Linkos;
use App\Enums\DeviceStatus;
use App\Enums\DeviceType;
use App\Iot\Linkos\FarmClient;
use App\Models\Device;
use App\Models\WormPhoto;
use App\Models\WormReport;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
use Throwable;
class WormReportCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'linkos:worm-report';
/**
* The console command description.
*
* @var string
*/
protected $description = 'linkos 虫情设备数据同步';
/**
* Execute the console command.
*/
public function handle()
{
$this->info('------------------------------------------');
$this->info(now());
try {
$this->sync();
} catch (Throwable $e) {
report($e);
}
$this->info('------------------------------------------');
}
protected function sync(): void
{
// 接口接口限制每分钟最多访问6次因此每次访问后需休眠10秒
$client = new FarmClient('xunwang', 'qwer1234');
$now = now();
/** @var \Illuminate\Database\Eloquent\Collection */
$devices = Device::supplierBy('device-supplier-linkos')
->where('type', DeviceType::Worm)
->whereIn('status', [DeviceStatus::Online, DeviceStatus::Offline])
->get();
if ($devices->isEmpty()) {
$this->warn('没有找到虫情设备');
return;
}
$this->info('==================================');
$this->info('尝试更新设备状态...');
$realTimeData = $client->realTimeData($devices->pluck('sn')->all());
foreach ($realTimeData as $item) {
foreach ($devices as $device) {
if ($item['deviceAddr'] != $device->sn) {
continue;
}
// 更新设备状态
$device->update([
'status' => $item['status'] === 'online' ? DeviceStatus::Online : DeviceStatus::Offline,
]);
}
}
$this->info("设备状态更新完成");
$this->info('==================================');
$this->info('尝试同步虫情区域统计...');
for ($i=2; $i > 0; $i--) {
$reportedAt = $now->copy()->subDays($i);
$statistics = collect(
$client->wormStatistics(
'E05F10DAIB6F4I4977IB95FI82554A48DE7C',
$reportedAt->copy()->startOfDay(),
$reportedAt->copy()->endOfDay(),
)
)->mapWithKeys(fn ($item) => [$item['deviceAddr'] => $item['wornData']]);
foreach ($devices as $device) {
$data = $statistics[$device->sn] ?? [];
WormReport::updateOrCreate([
'device_id' => $device->id,
'reported_at' => $reportedAt->toDateString(),
], [
'agricultural_base_id' => $device->agricultural_base_id,
'worm_num' => collect($data)->sum('num'),
'data' => $data,
]);
}
}
$this->info("同步虫情区域统计完成");
$this->info('==================================');
// 接口请求次数
$requests = 4;
// 同步最近7天的分析报表记录
$this->info('尝试同步分析报表记录...');
foreach ($devices->pluck('sn') as $sn) {
$data = $client->wormAnalyseData($sn, $now->copy()->subDays(7), $now, 1, 100);
foreach ($data['rows'] as $item) {
foreach ($devices as $device) {
if ($item['deviceAddr'] != $device->sn) {
continue;
}
$url = $item['analyseCoordUrl'] ?: $item['imagesUrl'];
// 下载图片
$name = md5($url);
if ($ext = pathinfo($url, PATHINFO_EXTENSION)) {
$name .= ".{$ext}";
}
$path = "worm-photos/{$device->id}/{$name}";
$disk = Storage::disk('public');
if (! $disk->exists($path)) {
$disk->put($path, file_get_contents($url));
}
WormPhoto::updateOrCreate([
'device_id' => $device->id,
'uploaded_at' => $item['createTime'],
], [
'url' => $path,
]);
}
}
$requests++;
// 接口请求频率: 每分钟6次
if ($requests == 6) {
$requests = 0;
sleep(61);
}
}
$this->info("同步分析报表记录完成");
}
}