162 lines
6.1 KiB
PHP
162 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Carbon\Carbon;
|
|
use App\Models\{Device,MonitorMode,WarningNotice,SoilReport,MeteorologicalReport,WaterQualityReport};
|
|
|
|
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://气象监测
|
|
$slug .= Device::TYPE_METEOROLOGICAL;
|
|
break;
|
|
case WaterQualityReport::class://水质监测
|
|
$slug .= Device::TYPE_SOIL;
|
|
break;
|
|
}
|
|
|
|
$rule = settings()->get($slug);
|
|
|
|
if($rule){
|
|
foreach($rule as $lv => $rule){
|
|
$res = $this->verifyRule($rule, $log);
|
|
if($res && $res['status']){
|
|
$this->inLog($device, $reportedAt, $log, $lv, $res['keys']);
|
|
}
|
|
}
|
|
}
|
|
return ;
|
|
}
|
|
|
|
private 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']){
|
|
if($log->wasChanged($cRes['keys'])){
|
|
$res['status'] = true;
|
|
$res['keys'] = array_merge($res['keys'], $cRes['keys']);
|
|
}elseif(WarningNotice::where([
|
|
'loggable_type' => $log::class,
|
|
'loggable_id' => $log->id,
|
|
])->count() == 0){
|
|
$res['status'] = true;
|
|
$res['keys'] = array_merge($res['keys'], $cRes['keys']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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{
|
|
break;
|
|
}
|
|
}
|
|
if($log->wasChanged($_keys)){
|
|
$res['status'] = true;
|
|
$res['keys'][] = implode(',', $_keys);
|
|
}elseif(WarningNotice::where([
|
|
'loggable_type' => $log::class,
|
|
'loggable_id' => $log->id,
|
|
])->count() == 0){
|
|
$res['status'] = true;
|
|
$res['keys'][] = implode(',', $_keys);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}else{//单条件
|
|
$key = $rule['left']['field'] ?? '';
|
|
$value = $log->$key ?? null;
|
|
$min = $rule['right']['0'] ?? null;
|
|
$max = $rule['right']['1'] ?? null;
|
|
if($min !== null && $max === null){//设置了最小值,未设置最大值
|
|
if($value >= $min ){
|
|
$res['status'] = true;
|
|
$res['keys'][] = $key;
|
|
}
|
|
}elseif($min === null && $max !== null){//设置最大值,未设置最小值
|
|
if($value <= $max ){
|
|
$res['status'] = true;
|
|
$res['keys'][] = $key;
|
|
}
|
|
}elseif($min !== null && $max !== null){//最大值,最小值都有设置
|
|
if($value >= $min && $value <= $max){
|
|
$res['status'] = true;
|
|
$res['keys'][] = $key;
|
|
}
|
|
}
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
|
|
private function inLog(Device $device, Carbon $reportedAt, Model $log, $lv, $columns){
|
|
|
|
if(!is_array($columns)){
|
|
$columns = array($columns);
|
|
}
|
|
switch($device->type){
|
|
case Device::TYPE_METEOROLOGICAL:
|
|
$fieldNameMap = MonitorMode::fieldMap(Device::TYPE_METEOROLOGICAL);
|
|
$fieldUnitMap = MonitorMode::fieldUnitMap(Device::TYPE_METEOROLOGICAL);
|
|
break;
|
|
case Device::TYPE_SOIL:
|
|
$fieldNameMap = MonitorMode::fieldMap(Device::TYPE_SOIL);
|
|
$fieldUnitMap = MonitorMode::fieldUnitMap(Device::TYPE_SOIL);
|
|
break;
|
|
}
|
|
|
|
$notices = array();
|
|
foreach($columns as $column){
|
|
$msg = '';
|
|
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].'值';
|
|
}
|
|
|
|
$notices[] = [
|
|
'device_id' => $device->id,
|
|
'lv' => $lv,
|
|
'content' => '【'.$device->name.'】【'.WarningNotice::lvMap()[$lv].'】'.$msg,
|
|
'reported_at' => $reportedAt,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
'loggable_type' => $log::class,
|
|
'loggable_id' => $log->id,
|
|
];
|
|
}
|
|
count($notices) > 0 && WarningNotice::insert($notices);
|
|
|
|
}
|
|
}
|