虫情设备/昆虫性诱设备状态检查

dev
Jing Li 2023-08-12 18:14:55 +08:00
parent f491a1bf84
commit 5c28b8c093
2 changed files with 90 additions and 69 deletions

View File

@ -4,9 +4,13 @@ namespace App\Console\Commands\BiAng;
use App\Enums\DeviceStatus;
use App\Enums\DeviceType;
use App\Iot\BiAng\HttpClient;
use App\Models\Device;
use App\Services\BiAngDeviceService;
use App\Models\DeviceLog;
use App\Models\InsecticidalLampReport;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use RuntimeException;
use Throwable;
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'));
while (true) {
$this->runSync();
$this->sync();
sleep($sleep);
};
@ -43,7 +47,7 @@ class DeviceLogSyncCommand extends Command
/**
* 执行同步
*/
protected function runSync(): void
protected function sync(): void
{
$now = now();
@ -61,6 +65,8 @@ class DeviceLogSyncCommand extends Command
if (! in_array($device->type, [
DeviceType::Soil,
DeviceType::Meteorological,
DeviceType::Worm,
DeviceType::InsectSexLure,
DeviceType::InsecticidalLamp,
])) {
continue;
@ -72,11 +78,77 @@ class DeviceLogSyncCommand extends Command
$this->info('设备类型: ' . match ($device->type) {
DeviceType::Soil => '土壤设备',
DeviceType::Meteorological => '气象设备',
DeviceType::Worm => '虫情设备',
DeviceType::InsectSexLure => '昆虫性诱设备',
DeviceType::InsecticidalLamp => '杀虫灯设备',
});
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('同步成功!');
} catch (Throwable $e) {
@ -91,4 +163,18 @@ class DeviceLogSyncCommand extends Command
$this->info('------------------------------------------');
$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'] ?? '');
}
}

View File

@ -2,7 +2,6 @@
namespace App\Services;
use App\Enums\DeviceStatus;
use App\Enums\DeviceType;
use App\Exceptions\BizException;
use App\Iot\BiAng\HttpClient;
@ -14,7 +13,6 @@ use App\Models\MeteorologicalMonitoringDailyLog;
use App\Models\MeteorologicalMonitoringLog;
use App\Models\SoilMonitoringDailyLog;
use App\Models\SoilMonitoringLog;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
@ -48,69 +46,6 @@ class BiAngDeviceService
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;
}
}
/**
* 创建设备报告
*/