Compare commits
5 Commits
09a24aaa83
...
909eee158c
| Author | SHA1 | Date |
|---|---|---|
|
|
909eee158c | |
|
|
f719f38677 | |
|
|
de943fda5a | |
|
|
eab2a29438 | |
|
|
101bb2c632 |
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
use App\Services\Admin\AirLogService;
|
||||
|
||||
class AirLogController extends AdminController
|
||||
{
|
||||
protected string $serviceName = AirLogService::class;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||
use App\Services\Admin\AtomizingLogService;
|
||||
|
||||
class AtomizingLogController extends AdminController
|
||||
{
|
||||
protected string $serviceName = AtomizingLogService::class;
|
||||
}
|
||||
|
|
@ -8,9 +8,8 @@ use App\Services\Admin\DeviceService;
|
|||
use App\Admin\Components;
|
||||
use App\Models\Device;
|
||||
use App\Models\Keyword;
|
||||
use App\Models\MeteorologicalDailyReport;
|
||||
use App\Models\MeteorologicalReport;
|
||||
use App\Models\MonitorMode;
|
||||
use App\Models\RegionMonitor;
|
||||
use App\Models\Region;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\MqttService;
|
||||
|
|
@ -276,26 +275,49 @@ class DeviceController extends AdminController
|
|||
* 空气条件设置
|
||||
*/
|
||||
public function airDetail(){
|
||||
$regionId = request()->input('region_id', 0);
|
||||
$config = null;
|
||||
$device = null;
|
||||
if($regionId){
|
||||
$region = Region::find($regionId);
|
||||
if($region){
|
||||
$monitorMode = $region->monitorModes()->where('type', MonitorMode::TYPE_AIR)->first();
|
||||
$device = $monitorMode->devices()->first();
|
||||
$config = $device?->extends ?? null;
|
||||
}
|
||||
}
|
||||
return amisMake()->Grid()->columns([
|
||||
amisMake()->Wrapper()->sm(6)->body([
|
||||
amisMake()->Panel()->title('智能开关设置')
|
||||
->labelWidth(100)
|
||||
->body([
|
||||
\amisMake()->Form()->title('')->mode('horizontal')->body([
|
||||
\amisMake()->Form()->title('')->mode('horizontal')
|
||||
->api([
|
||||
'method'=>'post',
|
||||
'url'=>admin_url('save-region-config').'/'.$regionId.'?type='.MonitorMode::TYPE_AIR,
|
||||
'data'=>[
|
||||
'open_is_enable' => '${open_is_enable}',
|
||||
'open_config' => '${open_config}',
|
||||
'close_is_enable' => '${close_is_enable}',
|
||||
'close_config' => '${close_config}',
|
||||
]
|
||||
])
|
||||
->data($config ? $config : [])
|
||||
->body([
|
||||
amisMake()->FieldSetControl()->title('智能开启')->body([
|
||||
\amisMake()->SwitchControl()->name('open_is_enable')->label('开关'),
|
||||
\amisMake()->ConditionBuilderControl()->label('条件')->fields([
|
||||
\amisMake()->ConditionBuilderControl()->name('open_config')->label('条件')->fields([
|
||||
[
|
||||
'label' => '温度', 'type'=>'number','step'=>'0.01','name'=>'q',
|
||||
'label' => '温度', 'type'=>'number','step'=>'0.01','name'=>'box_temperature',
|
||||
'operators'=> [
|
||||
'equal', 'not_equal', 'less', 'less_or_equal', 'greater', 'greater_or_equal', 'between', 'not_between',
|
||||
'less', 'less_or_equal', 'greater', 'greater_or_equal'
|
||||
// 'is_empty', 'is_not_empty'
|
||||
]
|
||||
],
|
||||
[
|
||||
'label' => '湿度', 'type'=>'number','step'=>'0.01','name'=>'x',
|
||||
'label' => '湿度', 'type'=>'number','step'=>'0.01','name'=>'box_humidity',
|
||||
'operators'=> [
|
||||
'equal', 'not_equal', 'less', 'less_or_equal', 'greater', 'greater_or_equal', 'between', 'not_between',
|
||||
'less', 'less_or_equal', 'greater', 'greater_or_equal'
|
||||
// 'is_empty', 'is_not_empty'
|
||||
]
|
||||
],
|
||||
|
|
@ -303,18 +325,18 @@ class DeviceController extends AdminController
|
|||
]),
|
||||
amisMake()->FieldSetControl()->title('智能关闭')->body([
|
||||
\amisMake()->SwitchControl()->name('close_is_enable')->label('开关'),
|
||||
\amisMake()->ConditionBuilderControl()->label('条件')->fields([
|
||||
\amisMake()->ConditionBuilderControl()->name('close_config')->label('条件')->fields([
|
||||
[
|
||||
'label' => '温度', 'type'=>'number','step'=>'0.01','name'=>'q',
|
||||
'label' => '温度', 'type'=>'number','step'=>'0.01','name'=>'box_temperature',
|
||||
'operators'=> [
|
||||
'equal', 'not_equal', 'less', 'less_or_equal', 'greater', 'greater_or_equal', 'between', 'not_between',
|
||||
'less', 'less_or_equal', 'greater', 'greater_or_equal',
|
||||
// 'is_empty', 'is_not_empty'
|
||||
]
|
||||
],
|
||||
[
|
||||
'label' => '湿度', 'type'=>'number','step'=>'0.01','name'=>'x',
|
||||
'label' => '湿度', 'type'=>'number','step'=>'0.01','name'=>'box_humidity',
|
||||
'operators'=> [
|
||||
'equal', 'not_equal', 'less', 'less_or_equal', 'greater', 'greater_or_equal', 'between', 'not_between',
|
||||
'less', 'less_or_equal', 'greater', 'greater_or_equal'
|
||||
// 'is_empty', 'is_not_empty'
|
||||
]
|
||||
],
|
||||
|
|
@ -326,21 +348,19 @@ class DeviceController extends AdminController
|
|||
amisMake()->Wrapper()->sm(6)->body([
|
||||
amisMake()->Panel()->title('开关记录')
|
||||
->body([
|
||||
\amisMake()->Table()->title('')
|
||||
->data([
|
||||
'items' => [
|
||||
[
|
||||
'name'=> '温度>10℃',
|
||||
'name1'=> '关闭',
|
||||
'time1'=> '2023-03-21 10:00:00',
|
||||
]
|
||||
]
|
||||
])
|
||||
->columns([
|
||||
amisMake()->TableColumn()->name('name')->label('触发条件'),
|
||||
amisMake()->TableColumn()->name('name1')->label('状态'),
|
||||
amisMake()->TableColumn()->name('time1')->label('执行时间'),
|
||||
])
|
||||
\amisMake()->CRUDTable()
|
||||
->api(admin_url('air-logs').'?_action=getData&device_id='.($device?->id ?? 0))
|
||||
->title('')
|
||||
->columns([
|
||||
amisMake()->TableColumn()->name('content')->label('触发条件'),
|
||||
amisMake()->TableColumn()->name('type')->type('mapping')->map([
|
||||
"0"=>"<span class='label label-info'>未知</span>",
|
||||
"1"=>"<span class='label label-success'>开启</span>",
|
||||
"2"=>"<span class='label label-danger'>关闭</span>",
|
||||
"*"=> '其他:${type}'
|
||||
])->label('动作'),
|
||||
amisMake()->TableColumn()->name('created_at')->type('datetime')->label('执行时间'),
|
||||
])
|
||||
])
|
||||
]),
|
||||
]);
|
||||
|
|
@ -353,11 +373,13 @@ class DeviceController extends AdminController
|
|||
$regionId = request()->input('region_id', 0);
|
||||
$config = null;
|
||||
$statusStr = '未知';
|
||||
$device = null;
|
||||
if($regionId){
|
||||
$region = Region::find($regionId);
|
||||
if($region){
|
||||
$monitorMode = $region->monitorModes()->where('type', MonitorMode::TYPE_ATOMIZING)->first();
|
||||
$config = $monitorMode?->pivot->config ?? null;
|
||||
$device = $monitorMode->devices()->first();
|
||||
$config = $device?->extends ?? null;
|
||||
|
||||
if($monitorMode){
|
||||
//判断设备状态是否离线;
|
||||
|
|
@ -400,13 +422,13 @@ class DeviceController extends AdminController
|
|||
\amisMake()->Form()->title('')->mode('horizontal')
|
||||
->api([
|
||||
'method'=>'post',
|
||||
'url'=>admin_url('save-region-config').'/'.$regionId,
|
||||
'url'=>admin_url('save-region-config').'/'.$regionId.'?type='.MonitorMode::TYPE_ATOMIZING,
|
||||
'data'=>[
|
||||
'is_enable' => '${is_enable}',
|
||||
'config' => '${config}'
|
||||
]
|
||||
])
|
||||
->data($config ? json_decode($config) : [])
|
||||
->data($config ? $config : [])
|
||||
->body([
|
||||
amisMake()->FieldSetControl()->title('当前状态')->body([
|
||||
amisMake()->TextControl('status', '状态')->value($statusStr),
|
||||
|
|
@ -429,21 +451,19 @@ class DeviceController extends AdminController
|
|||
amisMake()->Wrapper()->sm(6)->body([
|
||||
amisMake()->Panel()->title('开关记录')
|
||||
->body([
|
||||
\amisMake()->Table()->title('')
|
||||
->data([
|
||||
'items' => [
|
||||
[
|
||||
'name'=> '定时喷灌',
|
||||
'name1'=> '关闭',
|
||||
'time1'=> '2023-03-21 10:00:00',
|
||||
]
|
||||
]
|
||||
])
|
||||
->columns([
|
||||
amisMake()->TableColumn()->name('name')->label('触发条件'),
|
||||
amisMake()->TableColumn()->name('name1')->label('状态'),
|
||||
amisMake()->TableColumn()->name('time1')->label('执行时间'),
|
||||
])
|
||||
\amisMake()->CRUDTable()
|
||||
->api(admin_url('atomizing-logs').'?_action=getData&device_id='.($device?->id ?? 0))
|
||||
->title('')
|
||||
->columns([
|
||||
amisMake()->TableColumn()->name('type')->type('mapping')->map([
|
||||
"0"=>"<span class='label label-info'>未知</span>",
|
||||
"1"=>"<span class='label label-success'>开启</span>",
|
||||
"2"=>"<span class='label label-danger'>关闭</span>",
|
||||
"*"=> '其他:${type}'
|
||||
])->label('动作'),
|
||||
amisMake()->TableColumn()->name('content')->label('描述内容'),
|
||||
amisMake()->TableColumn()->name('created_at')->type('datetime')->label('操作时间'),
|
||||
])
|
||||
])
|
||||
]),
|
||||
]);
|
||||
|
|
@ -454,10 +474,12 @@ class DeviceController extends AdminController
|
|||
if($id){
|
||||
$region = Region::find($id);
|
||||
if($region){
|
||||
$monitorMode = $region->monitorModes()->where('type', MonitorMode::TYPE_ATOMIZING)->first();
|
||||
$type = $request->input('type', 0);
|
||||
$monitorMode = $region->monitorModes()->where('type', $type)->first();
|
||||
$config = $request->input() ?? null;
|
||||
$res = $region->monitorModes()->updateExistingPivot($monitorMode->id, [
|
||||
'config' => $config,
|
||||
unset($config['type']);
|
||||
$res = $monitorMode->devices()->update([
|
||||
'extends' => $config,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Models\Device;
|
||||
use App\Models\MeteorologicalReport;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Slowlyo\OwlAdmin\Renderers\Card;
|
||||
use Slowlyo\OwlAdmin\Renderers\Flex;
|
||||
|
|
@ -21,6 +23,7 @@ class HomeController extends AdminController
|
|||
|
||||
public function index(): JsonResponse|JsonResource
|
||||
{
|
||||
(new \App\Services\Admin\DeviceService())->meteorologicalControAir(Device::find(3), MeteorologicalReport::find(217), now());
|
||||
$page = $this->basePage()->css($this->css())->body([
|
||||
Grid::make()->columns([
|
||||
$this->frameworkInfo()->md(8),
|
||||
|
|
|
|||
|
|
@ -100,4 +100,9 @@ Route::group([
|
|||
$router->post('crop-plant-detail', '\App\Admin\Controllers\CropPlantController@plantDetail');
|
||||
|
||||
$router->resource('system/settings', \App\Admin\Controllers\SettingController::class);
|
||||
|
||||
//喷雾自动开启/关闭日志
|
||||
$router->resource('atomizing-logs', \App\Admin\Controllers\AtomizingLogController::class)->only(['index']);
|
||||
//通风自动开启/关闭日志
|
||||
$router->resource('air-logs', \App\Admin\Controllers\AirLogController::class)->only(['index']);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Device;
|
||||
use App\Models\AtomizingLog;
|
||||
use App\Services\MqttService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class MqttPenwuPlan extends Command
|
||||
|
|
@ -18,7 +21,7 @@ class MqttPenwuPlan extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'MQTT 喷雾控制';//-todo
|
||||
protected $description = 'MQTT 喷雾控制';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
|
|
@ -27,11 +30,56 @@ class MqttPenwuPlan extends Command
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
//获取所有喷雾监控点,对应的自动喷雾配置
|
||||
//获取当前时间(时,分)
|
||||
//判断该配置是否开启
|
||||
//判断当前该情况,并判断时间,决定开启,关闭,不作为;
|
||||
|
||||
//首先获取当前状态
|
||||
$service = new MqttService();
|
||||
$status = $service->getStatus();
|
||||
//判断是否离线,或者状态异常;
|
||||
if($status && $status['error'] == 0 && $status['status'] == 1){
|
||||
//获取所有喷雾监控点,对应的自动喷雾配置
|
||||
$deviceList = Device::where('type', Device::TYPE_ATOMIZING)->get();
|
||||
$time = now()->format('H:i');//获取当前时间(时,分)
|
||||
$time = '01:00';
|
||||
foreach($deviceList as $device){
|
||||
$_config = $device->extends ?? [];
|
||||
if($_config && $_config['is_enable']){//判断该配置是否开启
|
||||
foreach($_config['config'] as $item){
|
||||
list($start, $end) = explode(',', $item['time_zone']);
|
||||
//决定开启,关闭,
|
||||
if($time == $start){//相等
|
||||
// 如果当前对应位置已开启,则不作为
|
||||
if(
|
||||
($item['value'] == 'a' && $status['yv1'] == 0)
|
||||
||($item['value'] == 'b' && $status['yv2'] == 0)
|
||||
){
|
||||
$service->open($item['value'], $item['input']);
|
||||
//记录触发日志
|
||||
AtomizingLog::create([
|
||||
'device_id' => $device->id,
|
||||
'type' => 1,
|
||||
'content' => '自动开启【区域'.strtoupper($item['value']).'】,喷雾量'.$item['input'].'%',
|
||||
]);
|
||||
}
|
||||
}elseif($time == $end){
|
||||
if($status['is_running']){
|
||||
if(
|
||||
($item['value'] == 'a' && $status['yv1'] == 1)
|
||||
||($item['value'] == 'b' && $status['yv2'] == 1)
|
||||
){
|
||||
$service->close();
|
||||
//记录触发日志
|
||||
AtomizingLog::create([
|
||||
'device_id' => $device->id,
|
||||
'type' => 2,
|
||||
'content' => '自动关闭【区域'.strtoupper($item['value']).'】',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class Kernel extends ConsoleKernel
|
|||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
$schedule->command('mqtt:penwu-plan')->everyMinute();//每分钟执行
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Filters\Admin;
|
||||
|
||||
use EloquentFilter\ModelFilter;
|
||||
|
||||
class AirLogFilter extends ModelFilter
|
||||
{
|
||||
/**
|
||||
* 所属种植计划
|
||||
*/
|
||||
public function device($deviceId)
|
||||
{
|
||||
return $this->where('device_id', $deviceId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Filters\Admin;
|
||||
|
||||
use EloquentFilter\ModelFilter;
|
||||
|
||||
class AtomizingLogFilter extends ModelFilter
|
||||
{
|
||||
/**
|
||||
* 所属种植计划
|
||||
*/
|
||||
public function device($deviceId)
|
||||
{
|
||||
return $this->where('device_id', $deviceId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use EloquentFilter\Filterable;
|
||||
|
||||
class AirLog extends Model
|
||||
{
|
||||
use Filterable;
|
||||
|
||||
protected $fillable = ['device_id', 'type', 'content', 'created_at', 'updated_at'];
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use EloquentFilter\Filterable;
|
||||
|
||||
class AtomizingLog extends Model
|
||||
{
|
||||
use Filterable;
|
||||
|
||||
protected $fillable = ['device_id', 'type', 'content', 'created_at', 'updated_at'];
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Admin;
|
||||
|
||||
use App\Models\AirLog;
|
||||
use App\Filters\Admin\AirLogFilter;
|
||||
|
||||
|
||||
/**
|
||||
* @method AirLog getModel()
|
||||
* @method AigLog|\Illuminate\Database\Query\Builder query()
|
||||
*/
|
||||
class AirLogService extends BaseService
|
||||
{
|
||||
protected string $modelName = AirLog::class;
|
||||
|
||||
protected string $modelFilterName = AirLogFilter::class;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Admin;
|
||||
|
||||
use App\Models\AtomizingLog;
|
||||
use App\Filters\Admin\AtomizingLogFilter;
|
||||
|
||||
|
||||
/**
|
||||
* @method AtomizingLog getModel()
|
||||
* @method AtomizingLog|\Illuminate\Database\Query\Builder query()
|
||||
*/
|
||||
class AtomizingLogService extends BaseService
|
||||
{
|
||||
protected string $modelName = AtomizingLog::class;
|
||||
|
||||
protected string $modelFilterName = AtomizingLogFilter::class;
|
||||
|
||||
}
|
||||
|
|
@ -4,10 +4,11 @@ namespace App\Services\Admin;
|
|||
|
||||
use App\Models\Device;
|
||||
use App\Models\MonitorMode;
|
||||
use App\Models\{MeteorologicalDailyReport, MeteorologicalReport, SoilDailyReport, SoilReport};
|
||||
use App\Models\{MeteorologicalDailyReport, MeteorologicalReport, SoilDailyReport, SoilReport, AirLog, MonitorDevice, RegionMonitor, Region};
|
||||
use App\Filters\Admin\DeviceFilter;
|
||||
use Carbon\Carbon;
|
||||
use App\Admin\Components;
|
||||
use App\Iot\Linkos\HttpClient;
|
||||
/**
|
||||
* @method Device getModel()
|
||||
* @method Device|\Illuminate\Database\Query\Builder query()
|
||||
|
|
@ -274,4 +275,203 @@ class DeviceService extends BaseService
|
|||
}
|
||||
return $fieldMap;
|
||||
}
|
||||
|
||||
public function meteorologicalControAir(Device $device, MeteorologicalReport $log, Carbon $reportedAt)
|
||||
{
|
||||
//如果温度或者湿度发生变化;
|
||||
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();
|
||||
|
||||
$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();
|
||||
|
||||
$config = $_device?->extends ?? [];
|
||||
|
||||
$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'] && !$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].'值';
|
||||
}
|
||||
$this->openAir($_device, $msg);
|
||||
}
|
||||
}
|
||||
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].'值';
|
||||
}
|
||||
$this->closeAir($_device, $msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function verifyRule($rule, $log)
|
||||
{
|
||||
$res = [
|
||||
'status' => false,
|
||||
'keys' => []
|
||||
];
|
||||
if(isset($rule['conjunction'])){//多条件
|
||||
switch($rule['conjunction']){
|
||||
case 'or':
|
||||
if(isset($rule['children'])){
|
||||
foreach($rule['children'] as $child){
|
||||
$cRes = $this->verifyRule($child, $log);
|
||||
if($cRes && $cRes['status']){
|
||||
$res['status'] = true;
|
||||
$res['keys'] = array_merge($res['keys'], $cRes['keys']);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'and':
|
||||
if(isset($rule['children'])){
|
||||
$_keys = [];
|
||||
foreach($rule['children'] as $child){
|
||||
$cRes = $this->verifyRule($child, $log);
|
||||
if($cRes && $cRes['status']){
|
||||
$_keys = array_merge($_keys, $cRes['keys']);
|
||||
continue;
|
||||
}else{
|
||||
$res['status'] = false;
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
$res['status'] = true;
|
||||
$res['keys'][] = implode(',', $_keys);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else{//单条件
|
||||
$key = $rule['left']['field'] ?? '';
|
||||
$value = $log->$key ?? null;
|
||||
switch($rule['op']){
|
||||
case 'less':
|
||||
break;
|
||||
if($value < $rule['right']){
|
||||
$res['status'] = true;
|
||||
$res['keys'][] = $key;
|
||||
}
|
||||
case 'less_or_equal':
|
||||
if($value <= $rule['right']){
|
||||
$res['status'] = true;
|
||||
$res['keys'][] = $key;
|
||||
}
|
||||
break;
|
||||
case 'greater':
|
||||
if($value > $rule['right']){
|
||||
$res['status'] = true;
|
||||
$res['keys'][] = $key;
|
||||
}
|
||||
break;
|
||||
case 'greater_or_equal':
|
||||
if($value >= $rule['right']){
|
||||
$res['status'] = true;
|
||||
$res['keys'][] = $key;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通风设备当前状态
|
||||
*/
|
||||
public function getAirStatus(Device $device)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启通风设备
|
||||
*/
|
||||
public function openAir(Device $device, string $msg)
|
||||
{
|
||||
if($device->type != Device::TYPE_AIR){
|
||||
return ;
|
||||
}
|
||||
//记录触发日志
|
||||
AirLog::create([
|
||||
'device_id' => $device->id,
|
||||
'type' => 1,
|
||||
'content' => $msg,
|
||||
]);
|
||||
//编号,-todo
|
||||
// $httpClient = app(HttpClient::class);
|
||||
// dd($httpClient->deviceDataDownlink($device->sn, 'switch_control', ['switch_state' => 1]));
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭通风设备
|
||||
*/
|
||||
public function closeAir(Device $device, string $msg)
|
||||
{
|
||||
if($device->type != Device::TYPE_AIR){
|
||||
return ;
|
||||
}
|
||||
AirLog::create([
|
||||
'device_id' => $device->id,
|
||||
'type' => 2,
|
||||
'content' => $msg,
|
||||
]);
|
||||
//编号,
|
||||
// $httpClient = app(HttpClient::class);
|
||||
// dd($httpClient->deviceDataDownlink($device->sn, 'switch_control', ['switch_state' => 0]));
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,7 +246,8 @@ class DeviceLogService
|
|||
}
|
||||
|
||||
$meteorologicalReport->fill($attributes)->save();
|
||||
|
||||
|
||||
(new \App\Services\Admin\DeviceService())->meteorologicalControAir($device, $meteorologicalReport, $time);
|
||||
(new DeviceWarningService())->judgeLog($device, $meteorologicalReport, $time);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@ use App\Models\{Device,MonitorMode,WarningNotice,SoilReport,MeteorologicalReport
|
|||
class DeviceWarningService
|
||||
{
|
||||
public function judgeLog(Device $device, Model $log, Carbon $reportedAt){
|
||||
//设备预警
|
||||
$slug = 'mode_warning_';
|
||||
switch ($log::class) {
|
||||
case SoilReport::class://土壤监测
|
||||
$slug .= Device::TYPE_SOIL;
|
||||
break;
|
||||
case MeteorologicalReport::class://水质监测
|
||||
case MeteorologicalReport::class://气象监测
|
||||
$slug .= Device::TYPE_METEOROLOGICAL;
|
||||
break;
|
||||
case WaterQualityReport::class://水质监测
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('atomizing_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('device_id');
|
||||
$table->unsignedTinyInteger('type')->default(0)->comment('0未知;1开启,2关闭');
|
||||
$table->string('content');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('atomizing_logs');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('air_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('device_id');
|
||||
$table->unsignedTinyInteger('type')->default(0)->comment('0未知;1开启,2关闭');
|
||||
$table->string('content');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('air_logs');
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue