diff --git a/app/Admin/Controllers/AirLogController.php b/app/Admin/Controllers/AirLogController.php
new file mode 100644
index 0000000..c60b267
--- /dev/null
+++ b/app/Admin/Controllers/AirLogController.php
@@ -0,0 +1,12 @@
+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'
]
],
@@ -302,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'
]
],
@@ -325,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"=>"未知",
+ "1"=>"开启",
+ "2"=>"关闭",
+ "*"=> '其他:${type}'
+ ])->label('动作'),
+ amisMake()->TableColumn()->name('created_at')->type('datetime')->label('执行时间'),
+ ])
])
]),
]);
@@ -401,7 +422,7 @@ 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}'
@@ -453,9 +474,10 @@ 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;
-
+ unset($config['type']);
$res = $monitorMode->devices()->update([
'extends' => $config,
]);
diff --git a/app/Admin/Controllers/HomeController.php b/app/Admin/Controllers/HomeController.php
index 4b0a059..c68c5ba 100644
--- a/app/Admin/Controllers/HomeController.php
+++ b/app/Admin/Controllers/HomeController.php
@@ -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),
diff --git a/app/Admin/routes.php b/app/Admin/routes.php
index a148d18..3daa5f5 100644
--- a/app/Admin/routes.php
+++ b/app/Admin/routes.php
@@ -103,4 +103,6 @@ Route::group([
//喷雾自动开启/关闭日志
$router->resource('atomizing-logs', \App\Admin\Controllers\AtomizingLogController::class)->only(['index']);
+ //通风自动开启/关闭日志
+ $router->resource('air-logs', \App\Admin\Controllers\AirLogController::class)->only(['index']);
});
diff --git a/app/Filters/Admin/AirLogFilter.php b/app/Filters/Admin/AirLogFilter.php
new file mode 100644
index 0000000..6a49de9
--- /dev/null
+++ b/app/Filters/Admin/AirLogFilter.php
@@ -0,0 +1,16 @@
+where('device_id', $deviceId);
+ }
+}
diff --git a/app/Models/AirLog.php b/app/Models/AirLog.php
new file mode 100644
index 0000000..20a5915
--- /dev/null
+++ b/app/Models/AirLog.php
@@ -0,0 +1,14 @@
+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()->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'] && !$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].'值,且';
+ }
+
+ $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'] && !$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].'值,且';
+ }
+
+ $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){
+ $_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)
+ {
+ dd(app(HttpClient::class)->getDeviceStatus($device->sn, ["switch_state"]));
+ 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' => 0]));
+ 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,
+ ]);
+ dd('关闭通风');
+ //编号,
+ // $httpClient = app(HttpClient::class);
+ // dd($httpClient->deviceDataDownlink($device->sn, 'switch_control', ['switch_state' => 1]));
+ return ;
+ }
}
diff --git a/app/Services/DeviceLogService.php b/app/Services/DeviceLogService.php
index 478f7cd..876eb92 100644
--- a/app/Services/DeviceLogService.php
+++ b/app/Services/DeviceLogService.php
@@ -295,7 +295,8 @@ class DeviceLogService
}
$meteorologicalReport->fill($attributes)->save();
-
+
+ (new \App\Services\Admin\DeviceService())->meteorologicalControAir($device, $meteorologicalReport, $time);
(new DeviceWarningService())->judgeLog($device, $meteorologicalReport, $time);
}
diff --git a/app/Services/DeviceWarningService.php b/app/Services/DeviceWarningService.php
index 1f962dc..454f8b6 100644
--- a/app/Services/DeviceWarningService.php
+++ b/app/Services/DeviceWarningService.php
@@ -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://水质监测
diff --git a/database/migrations/2023_07_24_101436_create_air_logs_table.php b/database/migrations/2023_07_24_101436_create_air_logs_table.php
new file mode 100644
index 0000000..4b2406f
--- /dev/null
+++ b/database/migrations/2023_07_24_101436_create_air_logs_table.php
@@ -0,0 +1,34 @@
+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');
+ }
+};