代码拉取完成,页面将自动刷新
编码 | 中文注释 | 单位 |
---|---|---|
w01010 | 水温 | ℃ |
w01001 | pH 值 | 无量纲 |
w01009 | 溶解氧 | mg/L |
w01003 | 浑浊度 | NTU |
w01014 | 电导率 | uS/cm |
w01019 | 高锰酸盐指数 | mg/L |
w21003 | 氨氮(NH3-N) | mg/L |
w21011 | 总磷(以 P 计) | mg/L |
w21001 | 总氮(湖、库.以 N 计) | mg/L |
├─src
├─GWSTHJJ.STD
├─GWSTHJJ.STD
├─bin(编译文件)
│CEquip.cs(插件入口类)
│MessageAnalysis.cs(消息协议解析类)
│SocketFilter.cs(Socket过滤器,用于解析byte[]流)
│SocketServer.cs(Socket服务端帮助类)
(1)SocketHelp类:负责监听一个供下层设备TCP连接的端口和接收来自下层设备发送的原始数据。关键代码:
var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);//端口复用
// 绑定
serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
// 监听
serverSocket.Listen(20);
serverSocket.BeginAccept(AcceptCallback, serverSocket);//获取连接
(2)MessageAnalysis类:负责将下层设备发送的原始数据根据协议解析成具体的环境监测指标量。关键代码:
var temLen = Convert.ToInt32(dataStr.Substring(2, 4));//数据段长度
var crcStr = dataStr.Substring(6, temLen);
var crcResult = CalculateCrc(crcStr);//CRC校验结果
var crcExcept = dataStr.Substring(dataStr.LastIndexOf("&&", StringComparison.OrdinalIgnoreCase) + 2);
if (crcResult != crcExcept)
{
// crc校验不成功
return false;
}
var parseModel = FInterpreterInternal(crcStr);
if (parseModel == null || string.IsNullOrEmpty(parseModel.Cn))
{
return false;
}
// 将解析出的数据模型加入到缓存
AddAnalysisModelToDic(parseModel);
var cmdStr = parseModel.Cn switch
{
"1013" => SendCmdStr("9013", parseModel),
"2011" => SendCmdStr("9014", parseModel),
"2021" => SendCmdStr("9014", parseModel),
_ => ""
};
// 响应下层设备的字节数组
cmdArray = Encoding.UTF8.GetBytes(cmdStr);
(3)LogProvider类:提供日志记录的接口函数。 (4)CEquip类:将MessageAnalysis类解析出的指标量根据协议插件的遥测、遥信配置响应给各点位。响应指标量的状态关键代码:
public override bool GetYX(YxpTableRow r)
{
var analysisCollection = MessageAnalysis.AnalysisModelDic[_terminalNo].OrderBy(m => m.ReportDataTime).ToList();
if (analysisCollection.Any())
{
var analysis = analysisCollection[^1];
var dataItem = analysis.DataItems.FirstOrDefault(d => d.Pairs.Any(p => p.Key.Contains(r.main_instruction)));
if (dataItem != null)
{
var state = dataItem.Pairs.FirstOrDefault(p => p.Key.Contains(r.main_instruction + "-Flag"));
if (state.Value == Flag.正常)
{
SetYXData(r, false);//不报警
}
else
{
SetYXData(r, state.Value);
}
}
}
return true;
}
响应指标量的实时值关键代码:
public override bool GetYC(YcpTableRow r)
{
var analysisCollection = MessageAnalysis.AnalysisModelDic[_terminalNo].OrderBy(m => m.ReportDataTime).ToList();
if (analysisCollection.Any())
{
var analysis = analysisCollection[^1]; //获取最后一项的数据包
var dataItem = analysis.DataItems.FirstOrDefault(d => d.Pairs.Any(p => p.Key.Contains(r.main_instruction)));
if (dataItem != null)
{
var key = r.minor_instruction.EndsWith("-") ? r.main_instruction : r.main_instruction + "-" + r.minor_instruction;
var state = dataItem.Pairs.FirstOrDefault(p => p.Key.Contains(key));
var parseDouble = double.TryParse(state.Value, out var stateDouble);
if (parseDouble)
{
SetYCData(r, stateDouble);
}
else
{
SetYCData(r, state.Value);
}
}
}
return true;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。