You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
8.5 KiB
C#
199 lines
8.5 KiB
C#
using Dm.util;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Newtonsoft.Json;
|
|
using RJCP.IO.Ports;
|
|
using Sln.Iot.Business;
|
|
using Sln.Iot.Common;
|
|
using Sln.Iot.Config;
|
|
using Sln.Iot.Model.dao;
|
|
using Sln.Iot.Model.dto;
|
|
using Sln.Iot.Repository.service;
|
|
using Sln.Iot.Serilog;
|
|
using SqlSugar;
|
|
using System;
|
|
using System.Linq.Expressions;
|
|
using System.Net.WebSockets;
|
|
using System.Text;
|
|
using TouchSocket.Core;
|
|
using TouchSocket.Sockets;
|
|
|
|
namespace Sln.Iot.Serial
|
|
{
|
|
public static class SerialExtensions
|
|
{
|
|
|
|
public static void UseSerialPortExtensions(this IServiceProvider service)
|
|
{
|
|
IRecordIotEnvInstantService instantService = service.GetService<IRecordIotEnvInstantService>();
|
|
|
|
IBaseAlarmRuleService _alarmRuleService = service.GetService<IBaseAlarmRuleService>();
|
|
|
|
WebSocketBusiness webSocket = service.GetService<WebSocketBusiness>();
|
|
|
|
var logger = service.GetService<SerilogHelper>();
|
|
try
|
|
{
|
|
var appConfig = service.GetService<AppConfig>();
|
|
var tcpClient = service.GetService<TcpClient>();
|
|
var stringChange = service.GetService<StringChange>();
|
|
|
|
SerialPortStream serialPort = new SerialPortStream(appConfig.serialPortConfig.PortName);
|
|
serialPort.BaudRate = appConfig.serialPortConfig.BaudRate;
|
|
serialPort.Parity = Parity.None;
|
|
serialPort.StopBits = StopBits.One;
|
|
serialPort.DataBits = appConfig.serialPortConfig.DataBits;
|
|
serialPort.Handshake = Handshake.None;
|
|
|
|
serialPort.DataReceived += (sender, e) =>
|
|
{
|
|
lock (string.Empty)
|
|
{
|
|
try
|
|
{
|
|
byte[] receivedData = new byte[serialPort.BytesToRead];
|
|
serialPort.Read(receivedData, 0, receivedData.Length);
|
|
|
|
string str = Encoding.ASCII.GetString(receivedData);
|
|
logger.Info($"串口服务接收到数据:{str}");
|
|
|
|
List< RecordIotEnvInstant > iotEnvInstants = new List< RecordIotEnvInstant >();
|
|
string[] monitorInfos = str.Split(';');
|
|
|
|
foreach ( string monitorInfo in monitorInfos )
|
|
{
|
|
|
|
if (monitorInfo.Length < 12)
|
|
{
|
|
continue;
|
|
}
|
|
logger.Info($"解析串口数据:{monitorInfo}");
|
|
RecordIotEnvInstant iotEnvInstant = new RecordIotEnvInstant();
|
|
string[] strs = monitorInfo.Replace(";","").Split('-');
|
|
|
|
iotEnvInstant.monitorId = strs[0];
|
|
|
|
if (strs[1] == "5" || strs[1] == "6")
|
|
{
|
|
iotEnvInstant.temperature = decimal.Parse(strs[2].Trim());
|
|
}
|
|
if (strs[1] == "6")
|
|
{
|
|
iotEnvInstant.humidity = decimal.Parse(strs[3].Trim());
|
|
}
|
|
if (strs[1] == "7")
|
|
{
|
|
iotEnvInstant.noise = decimal.Parse(strs[2].Trim());
|
|
}
|
|
if (strs[1] == "8")
|
|
{
|
|
iotEnvInstant.illuminance = decimal.Parse(strs[2].Trim());
|
|
}
|
|
|
|
if (strs[1] == "10")
|
|
{
|
|
iotEnvInstant.vibrationSpeed = decimal.Parse(strs[2].Trim());
|
|
iotEnvInstant.vibrationAcceleration = decimal.Parse(strs[3].Trim());
|
|
iotEnvInstant.vibrationDisplacement = decimal.Parse(strs[4].Trim());
|
|
iotEnvInstant.vibrationTemp = decimal.Parse(strs[5].Trim());
|
|
}
|
|
iotEnvInstant.collectTime = DateTime.Now;
|
|
iotEnvInstant.recordTime = DateTime.Now;
|
|
iotEnvInstants.Add(iotEnvInstant);
|
|
|
|
Thread.Sleep(200);
|
|
}
|
|
|
|
|
|
var inRes = instantService.SplitInsert(iotEnvInstants, out List<long> insertIds);
|
|
|
|
logger.Info($"物联网数据保存{(inRes ? "成功" : "失败")}");
|
|
|
|
ParamAlarmFilter(iotEnvInstants,_alarmRuleService,logger, webSocket);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Info($"串口接收数据异常:{ex.Message}");
|
|
}
|
|
}
|
|
};
|
|
|
|
serialPort.Open();
|
|
|
|
logger.Info($"串口服务加载启动成功");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"串口服务加载异常:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
private static void ParamAlarmFilter(List<RecordIotEnvInstant> iotEnvInstants, IBaseAlarmRuleService _alarmRuleService, SerilogHelper _logger, WebSocketBusiness _webSocket)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|