1
0
Fork 0

设备数据同步命令

develop
李静 2023-05-05 16:27:17 +08:00
parent 180f2e070d
commit 3f43e9953f
3 changed files with 154 additions and 4 deletions

View File

@ -0,0 +1,83 @@
<?php
namespace App\Console\Commands;
use App\Models\Device;
use App\Services\DeviceLogService;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Throwable;
class DeviceLogSyncCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'device-log:sync
{factory}
{--sleep=60 : 设备数据同步完成后的休眠时间()}';
/**
* The console command description.
*
* @var string
*/
protected $description = '按设备厂商同步数据';
/**
* @var \App\Services\DeviceLogService
*/
protected $deviceLogService;
/**
* Execute the console command.
*/
public function handle(DeviceLogService $deviceLogService)
{
$this->deviceLogService = $deviceLogService;
$sleep = value(fn ($sleep) => is_numeric($sleep) ? (int) $sleep : 60, $this->option('sleep'));
while (true) {
$end = now();
$start = $end->copy()->subHours(1);
$this->info('------------------------------------------');
$this->info('开始时间: '. $start);
$this->info('结束时间: '. $end);
$this->performSync($start, $end);
$this->info('------------------------------------------');
$this->newLine();
sleep($sleep);
};
}
protected function performSync(Carbon $start, Carbon $end): void
{
/** @var \Illuminate\Database\Eloquent\Collection */
$devices = Device::poweredBy($this->argument('factory'))->get();
foreach ($devices as $device) {
$this->info('==========================================');
$this->info('设备编号: ' . $device->sn);
$this->info('设备名称: ' . $device->name);
try {
$this->deviceLogService->sync($device, $start, $end);
$this->info('同步成功!');
} catch (Throwable $e) {
report($e);
$this->error('同步失败: '. $e->getMessage());
}
$this->info('==========================================');
}
}
}

View File

@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Device extends Model
@ -22,15 +23,21 @@ class Device extends Model
public const STATE_OFFLINE = 2;
public const STATE_FAULT = 3;
protected $casts = [
'extends' => 'json'
];
protected $fillable = [
'name', 'sn', 'powered_by', 'type', 'model_sn', 'state', 'extends',
'is_enable', 'sort', 'is_recommend',
'group_tags'
];
protected $casts = [
'extends' => 'json'
];
public function scopePoweredBy(Builder $query, string $factory): void
{
$query->whereHas('factory', fn ($query) => $query->where('key', $factory));
}
protected function serializeDate(\DateTimeInterface $date){
return $date->format('Y-m-d H:i:s');
@ -53,7 +60,8 @@ class Device extends Model
return $this->hasMany(DeviceLog::class);
}
public function factory(){
public function factory()
{
return $this->belongsTo(Keyword::class, 'powered_by');
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Services;
use App\Iot\Linkos\HttpClient as LinkosHttpClient;
use App\Models\Device;
use Illuminate\Support\Carbon;
class DeviceLogService
{
/**
* 同步设备历史流水
*/
public function sync(Device $device, Carbon $start, Carbon $end): void
{
switch ($device->factory?->key) {
case 'link-os':
$this->syncLinkosDeviceLogs($device, $start, $end);
break;
}
}
/**
* 同步 Linkos 设备历史流水
*/
protected function syncLinkosDeviceLogs(Device $device, Carbon $start, Carbon $end): void
{
/** @var \App\Iot\Linkos\HttpClient */
$httpClient = app(LinkosHttpClient::class);
$page = 1;
$perPage = 50;
do {
$data = $httpClient->getDeviceFlowList(
$device->sn, $start, $end, $page, $perPage
);
$countResults = count($data['content']);
if ($countResults === 0) {
break;
}
foreach ($data['content'] as $item) {
$device->logs()->firstOrCreate([
'reported_at' => $item['createTime'],
], [
'data' => empty($item['data']) ? (new \stdClass) : $item['data'],
]);
}
unset($data);
$page++;
} while ($countResults === $perPage);
}
}