虫情设备/昆虫性诱设备状态检查
parent
f491a1bf84
commit
5c28b8c093
|
|
@ -4,9 +4,13 @@ namespace App\Console\Commands\BiAng;
|
||||||
|
|
||||||
use App\Enums\DeviceStatus;
|
use App\Enums\DeviceStatus;
|
||||||
use App\Enums\DeviceType;
|
use App\Enums\DeviceType;
|
||||||
|
use App\Iot\BiAng\HttpClient;
|
||||||
use App\Models\Device;
|
use App\Models\Device;
|
||||||
use App\Services\BiAngDeviceService;
|
use App\Models\DeviceLog;
|
||||||
|
use App\Models\InsecticidalLampReport;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use RuntimeException;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class DeviceLogSyncCommand extends Command
|
class DeviceLogSyncCommand extends Command
|
||||||
|
|
@ -34,7 +38,7 @@ class DeviceLogSyncCommand extends Command
|
||||||
$sleep = (int) value(fn ($sleep) => is_numeric($sleep) ? $sleep : 60, $this->option('sleep'));
|
$sleep = (int) value(fn ($sleep) => is_numeric($sleep) ? $sleep : 60, $this->option('sleep'));
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
$this->runSync();
|
$this->sync();
|
||||||
|
|
||||||
sleep($sleep);
|
sleep($sleep);
|
||||||
};
|
};
|
||||||
|
|
@ -43,7 +47,7 @@ class DeviceLogSyncCommand extends Command
|
||||||
/**
|
/**
|
||||||
* 执行同步
|
* 执行同步
|
||||||
*/
|
*/
|
||||||
protected function runSync(): void
|
protected function sync(): void
|
||||||
{
|
{
|
||||||
$now = now();
|
$now = now();
|
||||||
|
|
||||||
|
|
@ -61,6 +65,8 @@ class DeviceLogSyncCommand extends Command
|
||||||
if (! in_array($device->type, [
|
if (! in_array($device->type, [
|
||||||
DeviceType::Soil,
|
DeviceType::Soil,
|
||||||
DeviceType::Meteorological,
|
DeviceType::Meteorological,
|
||||||
|
DeviceType::Worm,
|
||||||
|
DeviceType::InsectSexLure,
|
||||||
DeviceType::InsecticidalLamp,
|
DeviceType::InsecticidalLamp,
|
||||||
])) {
|
])) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -72,11 +78,77 @@ class DeviceLogSyncCommand extends Command
|
||||||
$this->info('设备类型: ' . match ($device->type) {
|
$this->info('设备类型: ' . match ($device->type) {
|
||||||
DeviceType::Soil => '土壤设备',
|
DeviceType::Soil => '土壤设备',
|
||||||
DeviceType::Meteorological => '气象设备',
|
DeviceType::Meteorological => '气象设备',
|
||||||
|
DeviceType::Worm => '虫情设备',
|
||||||
|
DeviceType::InsectSexLure => '昆虫性诱设备',
|
||||||
DeviceType::InsecticidalLamp => '杀虫灯设备',
|
DeviceType::InsecticidalLamp => '杀虫灯设备',
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
(new BiAngDeviceService())->sync($device, $now->copy());
|
$httpClient = $this->buildHttpClient($device);
|
||||||
|
|
||||||
|
switch ($device->type) {
|
||||||
|
case DeviceType::Soil:
|
||||||
|
$data = $httpClient->getLatestSoilReport($device->sn);
|
||||||
|
|
||||||
|
$log = DeviceLog::firstOrCreate([
|
||||||
|
'device_id' => $device->id,
|
||||||
|
'reported_at' => $data['time'],
|
||||||
|
], [
|
||||||
|
'data' => Arr::except($data, ['deviceId', 'time']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$device->update([
|
||||||
|
'status' => $now->copy()->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline,
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType::Meteorological:
|
||||||
|
$data = $httpClient->getLatestMeteorologicalReport($device->sn);
|
||||||
|
|
||||||
|
$log = DeviceLog::firstOrCreate([
|
||||||
|
'device_id' => $device->id,
|
||||||
|
'reported_at' => $data['time'],
|
||||||
|
], [
|
||||||
|
'data' => Arr::except($data, ['deviceId', 'time']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$device->update([
|
||||||
|
'status' => $now->copy()->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' => $now->copy()->startOfHour(),
|
||||||
|
], [
|
||||||
|
'agricultural_base_id' => $device->agricultural_base_id,
|
||||||
|
'battery_vol' => $data['vol'],
|
||||||
|
'killed_num' => $data['dct'],
|
||||||
|
'air_temperature' => $data['temp'],
|
||||||
|
'air_humidity' => $data['humidity'],
|
||||||
|
'solar_panel_vol' => $data['sunVol'],
|
||||||
|
'high_vol' => $data['highVol'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$device->update([
|
||||||
|
'status' => $data['status'] === 'online' ? DeviceStatus::Online : DeviceStatus::Offline,
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType::Worm:
|
||||||
|
case DeviceType::InsectSexLure:
|
||||||
|
$data = $httpClient->getWormPhotos($device->sn, $now->copy()->subHours(24), $now);
|
||||||
|
|
||||||
|
$device->update([
|
||||||
|
'status' => count($data['imgUrl'] ?? []) > 0 ? DeviceStatus::Online : DeviceStatus::Offline,
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$this->info('同步成功!');
|
$this->info('同步成功!');
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
|
|
@ -91,4 +163,18 @@ class DeviceLogSyncCommand extends Command
|
||||||
$this->info('------------------------------------------');
|
$this->info('------------------------------------------');
|
||||||
$this->newLine();
|
$this->newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 HTTP 客户端
|
||||||
|
*/
|
||||||
|
public function buildHttpClient(Device $device): HttpClient
|
||||||
|
{
|
||||||
|
$config = json_decode($device->project?->value, true);
|
||||||
|
|
||||||
|
if (! is_array($config)) {
|
||||||
|
throw new RuntimeException('账户信息未找到');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HttpClient($config['username'] ?? '', $config['password'] ?? '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Enums\DeviceStatus;
|
|
||||||
use App\Enums\DeviceType;
|
use App\Enums\DeviceType;
|
||||||
use App\Exceptions\BizException;
|
use App\Exceptions\BizException;
|
||||||
use App\Iot\BiAng\HttpClient;
|
use App\Iot\BiAng\HttpClient;
|
||||||
|
|
@ -14,7 +13,6 @@ use App\Models\MeteorologicalMonitoringDailyLog;
|
||||||
use App\Models\MeteorologicalMonitoringLog;
|
use App\Models\MeteorologicalMonitoringLog;
|
||||||
use App\Models\SoilMonitoringDailyLog;
|
use App\Models\SoilMonitoringDailyLog;
|
||||||
use App\Models\SoilMonitoringLog;
|
use App\Models\SoilMonitoringLog;
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
|
@ -48,69 +46,6 @@ class BiAngDeviceService
|
||||||
return $httpClient->getWormStatistics($device->sn, $start, $end);
|
return $httpClient->getWormStatistics($device->sn, $start, $end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sync(Device $device, Carbon $syncTime): void
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$httpClient = $this->buildHttpClient($device);
|
|
||||||
} catch (BizException $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($device->type) {
|
|
||||||
case DeviceType::Soil:
|
|
||||||
$data = $httpClient->getLatestSoilReport($device->sn);
|
|
||||||
|
|
||||||
$log = DeviceLog::firstOrCreate([
|
|
||||||
'device_id' => $device->id,
|
|
||||||
'reported_at' => $data['time'],
|
|
||||||
], [
|
|
||||||
'data' => Arr::except($data, ['deviceId', 'time']),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$device->update([
|
|
||||||
'status' => $syncTime->subMinutes(60)->lt($log->reported_at) ? DeviceStatus::Online : DeviceStatus::Offline,
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
case DeviceType::Meteorological:
|
|
||||||
$data = $httpClient->getLatestMeteorologicalReport($device->sn);
|
|
||||||
|
|
||||||
$log = DeviceLog::firstOrCreate([
|
|
||||||
'device_id' => $device->id,
|
|
||||||
'reported_at' => $data['time'],
|
|
||||||
], [
|
|
||||||
'data' => Arr::except($data, ['deviceId', 'time']),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$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->startOfHour(),
|
|
||||||
], [
|
|
||||||
'agricultural_base_id' => $device->agricultural_base_id,
|
|
||||||
'battery_vol' => $data['vol'],
|
|
||||||
'killed_num' => $data['dct'],
|
|
||||||
'air_temperature' => $data['temp'],
|
|
||||||
'air_humidity' => $data['humidity'],
|
|
||||||
'solar_panel_vol' => $data['sunVol'],
|
|
||||||
'high_vol' => $data['highVol'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$device->update([
|
|
||||||
'status' => $data['status'] === 'online' ? DeviceStatus::Online : DeviceStatus::Offline,
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建设备报告
|
* 创建设备报告
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue