独立封装的 PLC 监控类(支持 JSON 配置 + 实时读取 + 界面显示 + GetValue 方法

张开发
2026/4/13 10:14:23 15 分钟阅读

分享文章

独立封装的 PLC 监控类(支持 JSON 配置 + 实时读取 + 界面显示 + GetValue 方法
✅ 最终完整解决方案独立封装的 PLC 监控类支持 JSON 配置 实时读取 界面显示 GetValue 方法根据你提供的JSON 配置和界面图片我为你封装了一个完全独立、可复用的PlcMonitorManager类。核心特性自动加载config.json支持你提供的完整 JSON动态生成与图片完全一致的界面分组 GroupBox 复选框 数值显示后台定时循环读取所有 PLC 地址内部存储当前所有 PLC 状态Dictionarystring, object提供GetValue(string key)方法可通过名称或地址快速获取最新值完全独立可直接嵌入 WinForms / WPF 项目中使用1. 模型类PlcModels.cspublicclassPlcItem{publicstringGroup{get;set;}string.Empty;publicstringName{get;set;}string.Empty;// 用于 GetValue 的 keypublicstringAddress{get;set;}string.Empty;publicstringDataType{get;set;}int16;publicstringType{get;set;}checkbox;// checkbox / valuepublicobject?CurrentValue{get;set;}// 实时存储的值publicControl?TagControl{get;set;}// 界面控件引用用于刷新}publicclassPlcGroup{publicstringName{get;set;}string.Empty;publicListPlcItemItems{get;set;}new();}publicclassPlcConfig{publicListPlcGroupGroups{get;set;}new();}2. 独立 PLC 监控管理类PlcMonitorManager.cspublicclassPlcMonitorManager:IDisposable{privatereadonlyDriver_plcDriver;privatereadonlyPlcConfig_config;privatereadonlyDictionarystring,PlcItem_allItemsnew();// Name - ItemprivatereadonlyDictionarystring,PlcItem_addressMapnew();// Address - ItemprivatereadonlySystem.Windows.Forms.Timer_updateTimer;privatereadonlyFlowLayoutPanel?_mainPanel;// 如果需要传入主容器// 当前所有 PLC 状态供外部快速读取publicIReadOnlyDictionarystring,objectCurrentValues_currentValues;privatereadonlyDictionarystring,object_currentValuesnew();publicPlcMonitorManager(DriverplcDriver,stringconfigJsonPath,FlowLayoutPanel?mainPanelnull){_plcDriverplcDriver;_mainPanelmainPanel;// 加载 JSON 配置stringjsonFile.ReadAllText(configJsonPath);_configJsonSerializer.DeserializePlcConfig(json,newJsonSerializerOptions{PropertyNameCaseInsensitivetrue})??newPlcConfig();// 构建快速查找表foreach(vargroupin_config.Groups){foreach(varitemingroup.Items){item.Groupgroup.Name;_allItems[item.Name]item;_addressMap[item.Address]item;}}_updateTimernewSystem.Windows.Forms.Timer{Interval300};// 300ms 刷新一次_updateTimer.Tickasync(s,e)awaitUpdateAllPlcDataAsync();}/// summary/// 构建完整监控界面与你图片完全一致/// /summarypublicvoidBuildUI(){if(_mainPanelnull)return;_mainPanel.Controls.Clear();_mainPanel.FlowDirectionFlowDirection.LeftToRight;_mainPanel.WrapContentsfalse;_mainPanel.AutoScrolltrue;foreach(vargroupin_config.Groups){vargroupBoxnewGroupBox{Textgroup.Name,Width380,Height620,PaddingnewPadding(10),FontnewFont(Microsoft YaHei,10.5F,FontStyle.Bold)};varflpnewFlowLayoutPanel{DockDockStyle.Fill,FlowDirectionFlowDirection.TopDown,WrapContentsfalse,AutoScrolltrue};foreach(varitemingroup.Items){varctrlCreateItemControl(item);if(ctrl!null)flp.Controls.Add(ctrl);}groupBox.Controls.Add(flp);_mainPanel.Controls.Add(groupBox);}}privateControlCreateItemControl(PlcItemitem){if(item.Typecheckbox){varrownewFlowLayoutPanel{FlowDirectionFlowDirection.LeftToRight,AutoSizetrue,MarginnewPadding(3,6,3,6)};varindicatornewLabel{Text■,FontnewFont(Microsoft YaHei,18F,FontStyle.Bold),ForeColorColor.Gray,AutoSizetrue,MarginnewPadding(5,0,12,0)};varnameLabelnewLabel{Textitem.Name,AutoSizetrue,MarginnewPadding(0,8,0,0),FontnewFont(Microsoft YaHei,9.5F)};row.Controls.Add(indicator);row.Controls.Add(nameLabel);item.TagControlindicator;returnrow;}elseif(item.Typevalue){varrownewFlowLayoutPanel{FlowDirectionFlowDirection.LeftToRight,AutoSizetrue,MarginnewPadding(3,6,3,6)};varnameLabelnewLabel{Textitem.Name,AutoSizetrue,Width220,MarginnewPadding(8,5,12,0)};varvalueBoxnewTextBox{Text—,ReadOnlytrue,Width130,BackColorColor.White,TextAlignHorizontalAlignment.Right};row.Controls.Add(nameLabel);row.Controls.Add(valueBox);item.TagControlvalueBox;returnrow;}returnnull!;}/// summary/// 核心循环读取所有地址并更新状态/// /summaryprivateasyncTaskUpdateAllPlcDataAsync(){foreach(varitemin_allItems.Values){if(item.TagControlnull)continue;object?valuenull;if(item.Typecheckbox)valueReadPlcBool(item.Address,item.DataType);elseif(item.Typevalue)valueReadPlcValue(item.Address,item.DataType);if(value!null){item.CurrentValuevalue;_currentValues[item.Name]value;// 存入全局状态_currentValues[item.Address]value;// 同时支持地址查询// 刷新界面if(item.TagControlisLabelindicatoritem.Typecheckbox)indicator.ForeColor(bool)value?Color.LimeGreen:Color.Gray;elseif(item.TagControlisTextBoxtb)tb.Textvalueisfloatf?f.ToString(F2):value.ToString();}}}// PLC 读取方法复用你原来的 Driver privateboolReadPlcBool(stringaddress,stringdataType){try{varsignalnewSignalObject{Addressaddress,SignalDataTypedataType};varresult_plcDriver.Read(signal);returnresult?.Dataisboolbb;}catch{returnfalse;}}privateobject?ReadPlcValue(stringaddress,stringdataType){try{varsignalnewSignalObject{Addressaddress,SignalDataTypedataType};varresult_plcDriver.Read(signal);returnresult?.Data;}catch{returnnull;}}/// summary/// 公开方法根据名称或地址获取最新 PLC 值/// /summarypublicobject?GetValue(stringkey){if(_currentValues.TryGetValue(key,outvarvalue))returnvalue;// 支持通过 Address 查询if(_addressMap.TryGetValue(key,outvaritem)item.CurrentValue!null)returnitem.CurrentValue;returnnull;}publicvoidStart(){_updateTimer.Start();}publicvoidStop(){_updateTimer.Stop();}publicvoidDispose(){Stop();_plcDriver?.UnInitialize(null);}}3. 使用示例Form 中调用publicpartialclassPlcMonitorForm:Form{privatePlcMonitorManager?_manager;publicPlcMonitorForm(){InitializeComponent();// 你的原有初始化// 使用方法 vardrivernewDriver();// 你原来的 Driver// ... 初始化 driverIP、Port 等_managernewPlcMonitorManager(driver,config.json,mainFlowPanel);// mainFlowPanel 是你主容器_manager.BuildUI();// 自动生成界面_manager.Start();// 开始循环读取}// 示例外部随时获取任意 PLC 值privatevoidButton_Click(objectsender,EventArgse){bool?initFlag_manager?.GetValue(初始化完成标志位)asbool?;double?pressure_manager?.GetValue(密封压力)asdouble?;MessageBox.Show($初始化完成标志位 {initFlag}\n密封压力 {pressure});}protectedoverridevoidOnFormClosing(FormClosingEventArgse){_manager?.Dispose();base.OnFormClosing(e);}}4. 优点总结完全独立PlcMonitorManager一个类搞定所有逻辑。高效批量读取 字典缓存性能极高。易用外部只需调用GetValue(名称)或GetValue(地址)即可。界面一致与你提供的图片完全一致。可扩展新增标签只需改 JSON无需改代码。需要我继续提供完整config.json已按你图片补全所有条目WPF 版本的PlcMonitorManager带报警颜色高亮 语音提示的增强版请告诉我下一步需求我马上补充

更多文章