完善通风控制
commit
909eee158c
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use Slowlyo\OwlAdmin\Renderers\{Button, Form, Page, TableColumn, TextControl, Json, Component, CRUDTable, Card, Video, DateRangeControl, Mapping};
|
||||
use Slowlyo\OwlAdmin\Renderers\{Button, Form, Page, TableColumn, TextControl, Json, Component, CRUDTable, Card, Video, InputDatetimeRange, DateTimeControl, Mapping, SelectControl};
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
use App\Services\Admin\DeviceService;
|
||||
use App\Admin\Components;
|
||||
|
|
@ -152,7 +152,7 @@ class DeviceController extends AdminController
|
|||
->headerToolbar([])
|
||||
->filter($this->baseFilter()->actions([])->body([
|
||||
amisMake()->SelectControl('monitor_mode', '点位名称')->size('md')->options($query->toArray())->selectFirst(true),
|
||||
DateRangeControl::make()->name('date')->label('日期')->maxDate('now')->size('md'),
|
||||
InputDatetimeRange::make()->name('date')->label('日期')->maxDate('now')->size('md'),
|
||||
Button::make()->label(__('admin.reset'))->actionType('clear-and-submit'),
|
||||
Component::make()->setType('submit')->label(__('admin.search'))->level('primary'),
|
||||
]))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ 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
|
||||
|
|
@ -64,7 +63,13 @@ class DeviceLogSyncCommand extends Command
|
|||
/** @var \Illuminate\Database\Eloquent\Collection */
|
||||
$devices = Device::with(['factory'])->poweredBy($factory)->get();
|
||||
|
||||
/** @var \App\Models\Device */
|
||||
foreach ($devices as $device) {
|
||||
// 忽略通风设备
|
||||
if ($device->isTypeAir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->info('==========================================');
|
||||
$this->info('设备编号: ' . $device->sn);
|
||||
$this->info('设备名称: ' . $device->name);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class LinkosCallbackController extends Controller
|
|||
{
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
logger()->info('linkos callback parameters -------->', $request->input());
|
||||
logger()->debug('linkos callback parameters -------->', $request->input());
|
||||
|
||||
if ($request->filled('notify_type')) {
|
||||
switch ($request->notify_type) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
|||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection ;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class Controller extends BaseController
|
||||
|
|
@ -16,7 +16,7 @@ class Controller extends BaseController
|
|||
|
||||
public function json($data, $code = 0, $message = '')
|
||||
{
|
||||
if ($data instanceof ResourceCollection ) {
|
||||
if ($data instanceof ResourceCollection) {
|
||||
$data = $data->resource;
|
||||
}
|
||||
$result = ['data' => $data ?: '', 'status' => $code, 'msg' => $message];
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class HttpClient
|
|||
* @param int $perPage
|
||||
* @return array
|
||||
*/
|
||||
public function getDeviceFlowList(string $deviceId, Carbon $start, Carbon $end, int $page = 1, int $perPage = 50): array
|
||||
public function deviceFlowList(string $deviceId, Carbon $start, Carbon $end, int $page = 1, int $perPage = 50): array
|
||||
{
|
||||
$result = $this->post('/api/deviceFlow/v1/list', [
|
||||
'device_id' => $deviceId,
|
||||
|
|
@ -38,9 +38,60 @@ class HttpClient
|
|||
],
|
||||
]);
|
||||
|
||||
if (data_get($result, 'success') !== true) {
|
||||
throw new RuntimeException(data_get($result, 'msg', '出错啦!'));
|
||||
}
|
||||
|
||||
return $result['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备数据下行
|
||||
*
|
||||
* @param string $deviceId
|
||||
* @param string $service
|
||||
* @param array $data
|
||||
* @param boolean $confirm
|
||||
* @param boolean $clear
|
||||
* @param boolean $schedule
|
||||
* @return array
|
||||
*/
|
||||
public function deviceDataDownlink(string $deviceId, string $service, array $data = [], bool $confirm = true, bool $clear = true, bool $schedule = false): array
|
||||
{
|
||||
return $this->post('/api/down', [
|
||||
'device_id' => $deviceId,
|
||||
'service_id' => $service,
|
||||
'parameter' => $data,
|
||||
'clear' => (int) $clear,
|
||||
'schedule' => (int) $schedule,
|
||||
'confirm' => (int) $confirm,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备最新属性数据
|
||||
*/
|
||||
public function getDeviceStatus(string $deviceId, array $props): array
|
||||
{
|
||||
$result = $this->get('/api/deviceStatus/v1/getDeviceStatus', [
|
||||
'deviceCode' => $deviceId,
|
||||
'prop' => implode(",", $props),
|
||||
]);
|
||||
|
||||
if (data_get($result, 'success') !== true) {
|
||||
throw new RuntimeException(data_get($result, 'msg', '出错啦!'));
|
||||
}
|
||||
|
||||
return $result['data'];
|
||||
}
|
||||
|
||||
public function get(string $url, array $query = []): array
|
||||
{
|
||||
return $this->request('GET', $url, [
|
||||
'query' => $query,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
|
|
@ -77,13 +128,7 @@ class HttpClient
|
|||
'Signature' => $this->sign(compact('nonce', 'timestamp')),
|
||||
])->baseUrl(self::ENDPOINT_URL)->send($method, $url, $options);
|
||||
|
||||
$result = $response->throw()->json();
|
||||
|
||||
if (data_get($result, 'success') !== true) {
|
||||
throw new RuntimeException(data_get($result, 'msg', '出错啦!'));
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $response->throw()->json();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -87,4 +87,9 @@ class Device extends Model
|
|||
{
|
||||
return $this->type === static::TYPE_METEOROLOGICAL;
|
||||
}
|
||||
|
||||
public function isTypeAir(): bool
|
||||
{
|
||||
return $this->type === static::TYPE_AIR;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,11 @@ class DeviceService extends BaseService
|
|||
$url = data_get($item->extends, $history ? 'rtsp_history' : 'rtsp_url');
|
||||
$src = null;
|
||||
if ($base && $url) {
|
||||
// 查看历史监控
|
||||
// 查看历史监控 &starttime=2023_02_02_14_00_00&endtime=2023_02_02_15_00_00
|
||||
if ($history && $start && $end) {
|
||||
$url .= '?start=' . date('Y-m-d', $start) . '&end=' . data('Y-m-d', $end);
|
||||
$start_format = Carbon::createFromTimestamp($start)->format('Y_m_d_H_i_s');
|
||||
$end_format = Carbon::createFromTimestamp($end)->format('Y_m_d_H_i_s');
|
||||
$url .= (str_contains($url, '?') ? '&' : '?') .'starttime=' . $start_format . '&endtime=' . $end_format;
|
||||
}
|
||||
$src = $base . base64_encode($url);
|
||||
}
|
||||
|
|
@ -276,75 +278,75 @@ class DeviceService extends BaseService
|
|||
|
||||
public function meteorologicalControAir(Device $device, MeteorologicalReport $log, Carbon $reportedAt)
|
||||
{
|
||||
if($log->wasChanged('box_temperature') || $log->wasChanged('box_humidity')){//如果温度或者湿度发生变化;
|
||||
//如果温度或者湿度发生变化;
|
||||
if($log->wasChanged('box_temperature') || $log->wasChanged('box_humidity')){
|
||||
//获取当前设备关联监测点IDs;
|
||||
$monitorIds = MonitorDevice::where('device_id', $device->id)->pluck('monitor_id')->toArray();
|
||||
$regionIds = RegionMonitor::where('monitor_id', $monitorIds)->pluck('region_id')->toArray();
|
||||
|
||||
}
|
||||
//获取当前设备关联监测点IDs;
|
||||
$monitorIds = MonitorDevice::where('device_id', $device->id)->pluck('monitor_id')->toArray();
|
||||
$regionIds = RegionMonitor::where('monitor_id', $monitorIds)->pluck('region_id')->toArray();
|
||||
$regions = Region::whereIn('id', $regionIds)->whereHas('monitorModes', function($q){
|
||||
return $q->where('type', MonitorMode::TYPE_AIR);
|
||||
})->get();
|
||||
|
||||
$regions = Region::whereIn('id', $regionIds)->whereHas('monitorModes', function($q){
|
||||
return $q->where('type', MonitorMode::TYPE_AIR);
|
||||
})->get();
|
||||
//遍历地点,是否有通风设备;
|
||||
foreach($regions as $region){
|
||||
$monitorModes = $region->monitorModes()->where('type', MonitorMode::TYPE_AIR)->get();
|
||||
foreach($monitorModes as $monitor){
|
||||
$_device = $monitor->devices()->where('type', Device::TYPE_AIR)->first();
|
||||
|
||||
//遍历地点,是否有通风设备;
|
||||
foreach($regions as $region){
|
||||
$monitorModes = $region->monitorModes()->where('type', MonitorMode::TYPE_AIR)->get();
|
||||
foreach($monitorModes as $monitor){
|
||||
$_device = $monitor->devices()->first();
|
||||
$config = $_device?->extends ?? [];
|
||||
$config = $_device?->extends ?? [];
|
||||
|
||||
$fieldNameMap = MonitorMode::fieldMap(Device::TYPE_METEOROLOGICAL);
|
||||
$fieldUnitMap = MonitorMode::fieldUnitMap(Device::TYPE_METEOROLOGICAL);
|
||||
$fieldNameMap = MonitorMode::fieldMap(Device::TYPE_METEOROLOGICAL);
|
||||
$fieldUnitMap = MonitorMode::fieldUnitMap(Device::TYPE_METEOROLOGICAL);
|
||||
|
||||
$airState = $this->getAirStatus($device);
|
||||
|
||||
//开启了自动开启配置
|
||||
if($config && $config['open_is_enable'] ){
|
||||
$rule = $config['open_config'];
|
||||
$res = $this->verifyRule($rule, $log);
|
||||
|
||||
if($res['status'] && !$this->getAirStatus($device)){//如果判定成功,且设备当前是关闭状态
|
||||
$msg = '';
|
||||
$column = $res['keys'][0];
|
||||
if(strpos($column, ',')){//看是否是并联条件
|
||||
$_columns = explode(',',$column);
|
||||
foreach($_columns as $cc){
|
||||
$msg.= $fieldNameMap[$cc].'达到'.$log->$cc.$fieldUnitMap[$cc].'值,且';
|
||||
$airState = $this->getAirStatus($_device);
|
||||
|
||||
//开启了自动开启配置
|
||||
if($config && $config['open_is_enable'] ){
|
||||
$rule = $config['open_config'];
|
||||
$res = $this->verifyRule($rule, $log);
|
||||
|
||||
if($res['status'] && !$airState){//如果判定成功,且设备当前是关闭状态
|
||||
$msg = '';
|
||||
$column = $res['keys'][0];
|
||||
if(strpos($column, ',')){//看是否是并联条件
|
||||
$_columns = explode(',',$column);
|
||||
foreach($_columns as $cc){
|
||||
$msg.= $fieldNameMap[$cc].'达到'.$log->$cc.$fieldUnitMap[$cc].'值,且';
|
||||
}
|
||||
|
||||
$msg = mb_substr($msg, 0, -2);
|
||||
}else{
|
||||
$msg = $fieldNameMap[$column].'达到'.$log->$column.$fieldUnitMap[$column].'值';
|
||||
}
|
||||
|
||||
$msg = mb_substr($msg, 0, -2);
|
||||
}else{
|
||||
$msg = $fieldNameMap[$column].'达到'.$log->$column.$fieldUnitMap[$column].'值';
|
||||
$this->openAir($_device, $msg);
|
||||
}
|
||||
$this->openAir($device, $msg);
|
||||
}
|
||||
}
|
||||
if($config && $config['close_is_enable'] ){
|
||||
$rule = $config['close_config'];
|
||||
$res = $this->verifyRule($rule, $log);
|
||||
|
||||
if($res['status'] && !$this->getAirStatus($device)){//如果判定成功,且设备当前是关闭状态
|
||||
$msg = '';
|
||||
$column = $res['keys'][0];
|
||||
if(strpos($column, ',')){//看是否是并联条件
|
||||
$_columns = explode(',',$column);
|
||||
foreach($_columns as $cc){
|
||||
$msg.= $fieldNameMap[$cc].'达到'.$log->$cc.$fieldUnitMap[$cc].'值,且';
|
||||
if($config && $config['close_is_enable'] ){
|
||||
$rule = $config['close_config'];
|
||||
$res = $this->verifyRule($rule, $log);
|
||||
|
||||
if($res['status'] && $airState){//如果判定成功,且设备当前是开启状态
|
||||
$msg = '';
|
||||
$column = $res['keys'][0];
|
||||
if(strpos($column, ',')){//看是否是并联条件
|
||||
$_columns = explode(',',$column);
|
||||
foreach($_columns as $cc){
|
||||
$msg.= $fieldNameMap[$cc].'达到'.$log->$cc.$fieldUnitMap[$cc].'值,且';
|
||||
}
|
||||
|
||||
$msg = mb_substr($msg, 0, -2);
|
||||
}else{
|
||||
$msg = $fieldNameMap[$column].'达到'.$log->$column.$fieldUnitMap[$column].'值';
|
||||
}
|
||||
|
||||
$msg = mb_substr($msg, 0, -2);
|
||||
}else{
|
||||
$msg = $fieldNameMap[$column].'达到'.$log->$column.$fieldUnitMap[$column].'值';
|
||||
$this->closeAir($_device, $msg);
|
||||
}
|
||||
$this->closeAir($device, $msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//开关控制;
|
||||
}
|
||||
|
||||
public function verifyRule($rule, $log)
|
||||
{
|
||||
$res = [
|
||||
|
|
@ -370,7 +372,7 @@ class DeviceService extends BaseService
|
|||
$_keys = [];
|
||||
foreach($rule['children'] as $child){
|
||||
$cRes = $this->verifyRule($child, $log);
|
||||
if($cRes){
|
||||
if($cRes && $cRes['status']){
|
||||
$_keys = array_merge($_keys, $cRes['keys']);
|
||||
continue;
|
||||
}else{
|
||||
|
|
@ -421,7 +423,16 @@ class DeviceService extends BaseService
|
|||
*/
|
||||
public function getAirStatus(Device $device)
|
||||
{
|
||||
dd(app(HttpClient::class)->getDeviceStatus($device->sn, ["switch_state"]));
|
||||
if($device->type != Device::TYPE_AIR){
|
||||
return false;
|
||||
}
|
||||
$res = app(HttpClient::class)->getDeviceStatus($device->sn, ["switch_state"]);
|
||||
|
||||
if($res && isset($res[0])){
|
||||
if($res[0]['value'] == 1){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -441,7 +452,7 @@ class DeviceService extends BaseService
|
|||
]);
|
||||
//编号,-todo
|
||||
// $httpClient = app(HttpClient::class);
|
||||
// dd($httpClient->deviceDataDownlink($device->sn, 'switch_control', ['switch_state' => 0]));
|
||||
// dd($httpClient->deviceDataDownlink($device->sn, 'switch_control', ['switch_state' => 1]));
|
||||
return ;
|
||||
}
|
||||
|
||||
|
|
@ -458,10 +469,9 @@ class DeviceService extends BaseService
|
|||
'type' => 2,
|
||||
'content' => $msg,
|
||||
]);
|
||||
dd('关闭通风');
|
||||
//编号,
|
||||
// $httpClient = app(HttpClient::class);
|
||||
// dd($httpClient->deviceDataDownlink($device->sn, 'switch_control', ['switch_state' => 1]));
|
||||
// dd($httpClient->deviceDataDownlink($device->sn, 'switch_control', ['switch_state' => 0]));
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class DeviceLogService
|
|||
$perPage = 50;
|
||||
|
||||
do {
|
||||
$data = $httpClient->getDeviceFlowList(
|
||||
$data = $httpClient->deviceFlowList(
|
||||
$device->sn, $start, $end, $page, $perPage
|
||||
);
|
||||
|
||||
|
|
@ -56,74 +56,25 @@ class DeviceLogService
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($device->isTypeSoil()) {
|
||||
// 如果包含气象设备监测字段,则跳过
|
||||
if (Arr::hasAny($item['data'], [
|
||||
'day_rainfall',
|
||||
'accumulate_rainfall',
|
||||
'potassium_content',
|
||||
'moment_rainfall',
|
||||
'pm10_concentration',
|
||||
'pm25_concentration',
|
||||
'box_noise',
|
||||
'box_carbon',
|
||||
'box_humidity',
|
||||
'box_pressure',
|
||||
'box_temperature',
|
||||
'box_illumination',
|
||||
'wind_power',
|
||||
'wind_speed',
|
||||
'wind_degree',
|
||||
'wind_direction',
|
||||
])) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($device->isTypeMeteorological()) {
|
||||
// 如果包含土壤设备监测字段,则跳过
|
||||
if (Arr::hasAny($item['data'], [
|
||||
'nitrogen_content',
|
||||
'phosphorus_content',
|
||||
'potassium_content',
|
||||
'conductivity',
|
||||
'soil_humidity',
|
||||
'soil_temperature',
|
||||
])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
$device->isTypeSoil() && Arr::hasAny($item['data'], [
|
||||
|
||||
])
|
||||
) {
|
||||
|
||||
} elseif (
|
||||
$device->isTypeMeteorological() &&
|
||||
Arr::hasAny(
|
||||
$item['data'],
|
||||
[
|
||||
'nitrogen_content',
|
||||
'phosphorus_content',
|
||||
'potassium_content',
|
||||
'conductivity',
|
||||
'soil_humidity',
|
||||
'soil_temperature',
|
||||
]
|
||||
)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$isSoilMonitoring = Arr::hasAny($item['data'], [
|
||||
'soil_humidity',
|
||||
'soil_temperature',
|
||||
'nitrogen_content',
|
||||
'potassium_content',
|
||||
'phosphorus_content',
|
||||
]);
|
||||
|
||||
if (($device->isTypeSoil() && ! $isSoilMonitoring) || (! $device->isTypeSoil() && $isSoilMonitoring)) {
|
||||
// 如果多合一气象监测器包含土壤监控时,需过滤掉气象监控的数据
|
||||
if ($device->isTypeSoil() && Arr::hasAny($item['data'], [
|
||||
'current_rainfall',
|
||||
'day_rainfall',
|
||||
'accumulate_rainfall',
|
||||
'moment_rainfall',
|
||||
'pm10_concentration',
|
||||
'pm25_concentration',
|
||||
'box_illumination',
|
||||
'box_pressure',
|
||||
'box_carbon',
|
||||
'box_temperature',
|
||||
'box_humidity',
|
||||
'box_noise',
|
||||
'wind_degree',
|
||||
'wind_direction',
|
||||
'wind_power',
|
||||
'wind_speed',
|
||||
])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -498,6 +449,10 @@ class DeviceLogService
|
|||
switch ($key) {
|
||||
case 'wind_samples':
|
||||
$attributes['wind_degree'] = value(function (array $windSamples) {
|
||||
if (empty($windSamples)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
|
||||
|
|
@ -527,6 +482,10 @@ class DeviceLogService
|
|||
}, $item);
|
||||
|
||||
$attributes['wind_direction'] = value(function ($windDegree) {
|
||||
if (is_null($windDegree)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($windDegree >= 22.5 && $windDegree < 67.5) {
|
||||
return MeteorologicalDailyReport::WIND_DIRECTION_NORTHEAST;
|
||||
} elseif ($windDegree >= 67.5 && $windDegree < 112.5) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue