|
|
|
@ -25,7 +25,11 @@
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Linq.Expressions;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using Dm.util;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Sln.Iot.Business.@base;
|
|
|
|
@ -35,6 +39,7 @@ using Sln.Iot.Model.dao;
|
|
|
|
|
using Sln.Iot.Model.dto;
|
|
|
|
|
using Sln.Iot.Repository.service;
|
|
|
|
|
using Sln.Iot.Serilog;
|
|
|
|
|
using Sln.Iot.Socket;
|
|
|
|
|
using Sln.Iot.Socket.Adapter;
|
|
|
|
|
using TouchSocket.Core;
|
|
|
|
|
using TouchSocket.Sockets;
|
|
|
|
@ -48,9 +53,25 @@ namespace Sln.Iot.Business
|
|
|
|
|
{
|
|
|
|
|
private readonly IRecordIotEnvInstantService? _service;
|
|
|
|
|
|
|
|
|
|
public IotEnvBusiness(SerilogHelper logger, AppConfig appConfig, StringChange stringChange, IRecordIotEnvInstantService? service) : base(logger, appConfig, stringChange)
|
|
|
|
|
private readonly IBaseAlarmRuleService _alarmRuleService;
|
|
|
|
|
|
|
|
|
|
private readonly WebSocketBusiness _webSocket;
|
|
|
|
|
|
|
|
|
|
private readonly TcpServer _tcpServer;
|
|
|
|
|
|
|
|
|
|
private readonly IBaseMonitorInfoService _monitorInfoService;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public IotEnvBusiness(SerilogHelper logger, AppConfig appConfig, StringChange stringChange, IRecordIotEnvInstantService? service,
|
|
|
|
|
IBaseAlarmRuleService alarmRuleService, WebSocketBusiness webSocket, TcpServer tcpServer
|
|
|
|
|
, IBaseMonitorInfoService monitorInfoService) : base(logger, appConfig, stringChange)
|
|
|
|
|
{
|
|
|
|
|
_service = service;
|
|
|
|
|
_alarmRuleService = alarmRuleService;
|
|
|
|
|
_webSocket = webSocket;
|
|
|
|
|
|
|
|
|
|
_tcpServer = tcpServer;
|
|
|
|
|
_monitorInfoService = monitorInfoService;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override FilterResult BufferAnalysis(ISocketClient client, BufferRequestInfo requestInfo, int bodyLength)
|
|
|
|
@ -139,17 +160,16 @@ namespace Sln.Iot.Business
|
|
|
|
|
|
|
|
|
|
ValueIsNan(ref f_vibrationSpeed);
|
|
|
|
|
|
|
|
|
|
iotEnvInstant.VibrationSpeed = (decimal) f_vibrationSpeed;
|
|
|
|
|
iotEnvInstant.vibrationSpeed = (decimal) f_vibrationSpeed;
|
|
|
|
|
break;
|
|
|
|
|
case CommParams.VibrationDisplacement: //振动-位移
|
|
|
|
|
bodyLength = 58;
|
|
|
|
|
byteBlock.Read(out byte[] vibrationDisplacement, 4);
|
|
|
|
|
base._stringChange.SwapBytes(ref vibrationDisplacement);
|
|
|
|
|
float f_vibrationDisplacement = BitConverter.ToSingle(vibrationDisplacement, 0);
|
|
|
|
|
|
|
|
|
|
ValueIsNan(ref f_vibrationDisplacement);
|
|
|
|
|
|
|
|
|
|
iotEnvInstant.VibrationDisplacement = (decimal)f_vibrationDisplacement;
|
|
|
|
|
iotEnvInstant.vibrationDisplacement = (decimal)f_vibrationDisplacement;
|
|
|
|
|
break;
|
|
|
|
|
case CommParams.VibrationAcceleration: //振动-加速度
|
|
|
|
|
byteBlock.Read(out byte[] vibrationAcceleration, 4);
|
|
|
|
@ -158,7 +178,7 @@ namespace Sln.Iot.Business
|
|
|
|
|
|
|
|
|
|
ValueIsNan(ref f_vibrationAcceleration);
|
|
|
|
|
|
|
|
|
|
iotEnvInstant.VibrationAcceleration = (decimal)f_vibrationAcceleration;
|
|
|
|
|
iotEnvInstant.vibrationAcceleration = (decimal)f_vibrationAcceleration;
|
|
|
|
|
break;
|
|
|
|
|
case CommParams.VibrationTemp: //振动-温度
|
|
|
|
|
byteBlock.Read(out byte[] vibrationTemp, 4);
|
|
|
|
@ -167,7 +187,7 @@ namespace Sln.Iot.Business
|
|
|
|
|
|
|
|
|
|
ValueIsNan(ref f_vibrationTemp);
|
|
|
|
|
|
|
|
|
|
iotEnvInstant.VibrationTemp = (decimal)f_vibrationTemp;
|
|
|
|
|
iotEnvInstant.vibrationTemp = (decimal)f_vibrationTemp;
|
|
|
|
|
break;
|
|
|
|
|
case CommParams.CJSJ:
|
|
|
|
|
byteBlock.Read(out byte[] b_CJSJ, 6);
|
|
|
|
@ -204,9 +224,13 @@ namespace Sln.Iot.Business
|
|
|
|
|
ParamVerification(ref result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SendData(result);
|
|
|
|
|
|
|
|
|
|
var inRes = _service.SplitInsert(result,out List<long> insertIds);
|
|
|
|
|
|
|
|
|
|
_logger.Info($"{amount}个物联网数据解析处理完成,保存{result.Count}个物联网数据,保存{(inRes ? "成功" : "失败")}");
|
|
|
|
|
|
|
|
|
|
ParamAlarmFilter(result);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -276,28 +300,28 @@ namespace Sln.Iot.Business
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.VibrationSpeed == _appConfig.virtualValue)
|
|
|
|
|
if (item.vibrationSpeed == _appConfig.virtualValue)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"MonitorId:{item.monitorId},振动速度值为 FF FF FF FF,已启用过滤不保存该表数据");
|
|
|
|
|
iotEnvInstants.RemoveAt(i);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.VibrationDisplacement == _appConfig.virtualValue)
|
|
|
|
|
if (item.vibrationDisplacement == _appConfig.virtualValue)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"MonitorId:{item.monitorId},振动位移值为 FF FF FF FF,已启用过滤不保存该表数据");
|
|
|
|
|
iotEnvInstants.RemoveAt(i);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.VibrationAcceleration == _appConfig.virtualValue)
|
|
|
|
|
if (item.vibrationAcceleration == _appConfig.virtualValue)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"MonitorId:{item.monitorId},振动加速度值为 FF FF FF FF,已启用过滤不保存该表数据");
|
|
|
|
|
iotEnvInstants.RemoveAt(i);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.VibrationTemp == _appConfig.virtualValue)
|
|
|
|
|
if (item.vibrationTemp == _appConfig.virtualValue)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"MonitorId:{item.monitorId},振动温度值为 FF FF FF FF,已启用过滤不保存该表数据");
|
|
|
|
|
iotEnvInstants.RemoveAt(i);
|
|
|
|
@ -305,5 +329,150 @@ namespace Sln.Iot.Business
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="iotEnvInstants"></param>
|
|
|
|
|
public void SendData(List<RecordIotEnvInstant> iotEnvInstants)
|
|
|
|
|
{
|
|
|
|
|
lock (string.Empty)
|
|
|
|
|
{
|
|
|
|
|
foreach (var iotEnvInstant in iotEnvInstants)
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(200);
|
|
|
|
|
var monitorInfo = _monitorInfoService.Query(x => x.monitorId == iotEnvInstant.monitorId).FirstOrDefault();
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
if (monitorInfo != null)
|
|
|
|
|
{
|
|
|
|
|
sb.Append(iotEnvInstant.monitorId);
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(monitorInfo.monitorType);
|
|
|
|
|
if (monitorInfo.monitorType == 5 || monitorInfo.monitorType == 6)
|
|
|
|
|
{
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.temperature);
|
|
|
|
|
}
|
|
|
|
|
if (monitorInfo.monitorType == 6)
|
|
|
|
|
{
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.humidity);
|
|
|
|
|
}
|
|
|
|
|
if (monitorInfo.monitorType == 7)
|
|
|
|
|
{
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.noise);
|
|
|
|
|
}
|
|
|
|
|
if (monitorInfo.monitorType == 8)
|
|
|
|
|
{
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.illuminance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (monitorInfo.monitorType == 10)
|
|
|
|
|
{
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.vibrationSpeed);
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.vibrationAcceleration);
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.vibrationDisplacement);
|
|
|
|
|
sb.Append("-");
|
|
|
|
|
sb.Append(iotEnvInstant.vibrationTemp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sb.Append(";");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//string str = $"{iotEnvInstant.monitorId}-{iotEnvInstant.temperature}-{iotEnvInstant.humidity}-{iotEnvInstant.noise}-{iotEnvInstant.illuminance}-{iotEnvInstant.vibrationSpeed}-{iotEnvInstant.vibrationAcceleration}-{iotEnvInstant.vibrationDisplacement}-{iotEnvInstant.vibrationTemp}";
|
|
|
|
|
string str = sb.ToString();
|
|
|
|
|
byte[] bytes = StringToBytesUsingASCII(str);
|
|
|
|
|
|
|
|
|
|
_tcpServer.SendDataToRecevieDevice(bytes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static byte[] StringToBytesUsingASCII(string input)
|
|
|
|
|
{
|
|
|
|
|
if (input == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException(nameof(input), "输入字符串不能为 null。");
|
|
|
|
|
}
|
|
|
|
|
// 使用 ASCII 编码将字符串转换为字节数组
|
|
|
|
|
return Encoding.ASCII.GetBytes(input);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 报警参数过滤
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="iotEnvInstants"></param>
|
|
|
|
|
private void ParamAlarmFilter(List<RecordIotEnvInstant> iotEnvInstants)
|
|
|
|
|
{
|
|
|
|
|
if (iotEnvInstants == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException(nameof(iotEnvInstants), "报警参数过滤异常,传入参数为空");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 预编译比较委托(避免循环内重复编译)
|
|
|
|
|
static Func<decimal, decimal, bool> CreateComparer(int triggerRule)
|
|
|
|
|
{
|
|
|
|
|
ParameterExpression x = Expression.Parameter(typeof(decimal), "x");
|
|
|
|
|
ParameterExpression y = Expression.Parameter(typeof(decimal), "y");
|
|
|
|
|
BinaryExpression comparison = triggerRule == 0
|
|
|
|
|
? Expression.GreaterThan(x, y)
|
|
|
|
|
: Expression.LessThan(x, y);
|
|
|
|
|
return Expression.Lambda<Func<decimal, decimal, bool>>(comparison, x, y).Compile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var fieldAccessors = new Dictionary<int, Func<RecordIotEnvInstant, decimal>>
|
|
|
|
|
{
|
|
|
|
|
{ 0, item => item.temperature },
|
|
|
|
|
{ 1, item => item.humidity },
|
|
|
|
|
{ 2, item => item.vibrationSpeed },
|
|
|
|
|
{ 3, item => item.vibrationDisplacement },
|
|
|
|
|
{ 4, item => item.vibrationAcceleration },
|
|
|
|
|
{ 5, item => item.vibrationTemp },
|
|
|
|
|
{ 6, item => item.noise },
|
|
|
|
|
{ 7, item => item.illuminance }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach (var item in iotEnvInstants)
|
|
|
|
|
{
|
|
|
|
|
var alarmRules = _alarmRuleService.Query(x => x.monitorId == item.monitorId);
|
|
|
|
|
|
|
|
|
|
List<BaseAlarmRule> ruleRes = new List<BaseAlarmRule>();
|
|
|
|
|
List<string> alarmContents = new List<string>();
|
|
|
|
|
foreach (var rule in alarmRules)
|
|
|
|
|
{
|
|
|
|
|
decimal paramValue = fieldAccessors.TryGetValue(rule.monitorField, out var accessor)
|
|
|
|
|
? accessor(item)
|
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
|
|
var comparer = CreateComparer(rule.triggerRule);
|
|
|
|
|
|
|
|
|
|
if (comparer(paramValue, rule.triggerValue))
|
|
|
|
|
{
|
|
|
|
|
ruleRes.Add(rule);
|
|
|
|
|
alarmContents.Add($"{item.monitorId}传感器数据在{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}触发{rule.ruleName}异常告警,告警规则:{(rule.triggerRule == 0 ? "大于" : "小于") },阈值:{rule.triggerValue},详细信息:{rule.cause}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MonitorAlarmDto monitorAlarmDto = new MonitorAlarmDto()
|
|
|
|
|
{
|
|
|
|
|
monitorId = item.monitorId,
|
|
|
|
|
isFlag = ruleRes.Count() > 0 ? 1 : 0,
|
|
|
|
|
deviceParam = item,
|
|
|
|
|
alarmRules = ruleRes,
|
|
|
|
|
alarmContents = alarmContents,
|
|
|
|
|
recordTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
|
|
|
|
};
|
|
|
|
|
string str = JsonConvert.SerializeObject(monitorAlarmDto);
|
|
|
|
|
_logger.Alarm($"传感器数据推送:{str}");
|
|
|
|
|
|
|
|
|
|
_webSocket.PushMsg(str);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|