目 錄
1. 概述... 2
2. 平臺演示... 2
3. 控制端與iNeuKernel的互動協議... 3
4. 設備驅動實作控制業務... 4
5. 應用效果... 9
5.1 CS客戶端... 9
5.2 BS瀏覽器... 9
5.3 Linux環境測驗... 10
5.4 視頻應用效果... 10
>>iNeuKernel v2.3版本下載:https://pan.baidu.com/s/1nxpnC7FazBBVyK9zUFgjyg
1. 概述
2019年6月,iNeuOS發布第一個版本以來,實際合作的客戶和在談合作的客戶,對于云端控制或云端修改引數的需求比較多,基本上是共識,將來5G的發展和應用,云端控制將是一個常態,在iNeuOS的規劃中已經作為一項重要作業,之所以沒有早期開發云端控制部分,是因為我們所在的工業領域(煤炭、鋼鐵、化工、電力等)是重工業,與互聯網傳輸資料都有嚴格的限制,更不可能讓云端控制,另外涉及到安全問題,
大部分云端控制的需求涉及行業一般為環保、農業、電工裝備等,業務需求一般是遠程修改引數和控制一些開關狀態,但是這些操作不會帶來致命事故,更多的是從遠程運維角度考慮的需求,
現在iNeuKernel(設備容器)物聯網核心組件,已經具備了遠程控制服務功能,支持終端設備或軟體以Socket或WebSocket通道協議,通過標準的文本協議與硬體或傳感進行互動,實作遠程修改引數和控制的目的,后續會把這項功能集成到iNeuView(Web組態)視圖建模,可以通過組態頁面操作實作遠程控制,
參見以前的文章:
《終端控制傳感器或設備,形成回路控制》
《4種通訊模式機制》
2. 平臺演示
在線演示:http://demo.ineuos.net (注:服務器比較慢,請耐心等待,自已注冊用戶,體驗系統功能)
視頻演示:http://www.ineuos.net/video/iNeuOS%20and%20app.mp4
驅動開發:http://www.ineuos.net/index.php/products/ineukernel-15.html (v2.1版本)
手機APP:http://demo.ineuos.net/app/ineuos_app.apk
3. 控制端與iNeuKernel的互動協議
控制端可以理解為iNeuView組態,控制操作通過互動協議與后臺的iNeuKernel進行互動,進一步與設備驅動互動,對設備進行控制操作,當然其他終端的操作鏈路也是這樣的,示意,如下圖:

互動協議充分考慮了系統命令和設備命令兩種情況,一個是對后臺服務進行遠程控制,一個是對設備進行控制,綜合完成遠程運維業務需求,示意,如下圖:

4. 設備驅動實作控制業務
以Modbus RTU通訊協議為例,實作遠程控制業務需求,IRunDevice介面有一個RunServiceConnector函式介面接收控制端發來的互動資訊,互動資訊是一個DevicePacket協議包,
注:具體代碼事例,可以加物聯網&大資料技術群:54256083,找群主,
(1)DevicePacket設備協議包轉換成JSON格式
"DevicePacket": { "OperationCode": "20200206202127025", "DeviceId": "92b2306385f749d494a9b24f469cac87", "DeviceName": "Modbus", "Desc": "", "DeviceFrames": [ { "TagId": "79be2b1e790f4c06873a8446bca755ea", "TagName": "tag1", "DataType": "int", "Value": "true", "FrameId": "20200206202127032", "OperationType": "setack", "Code": "200", "Desc": "淇敼鎴愬姛", "Time": "2020-02-06T20:21:27.0322772+08:00" } ] }
(2)RunServiceConnector函式介面接收設備協議包
/// <summary> /// 與服務(Service)互動使用的介面,與service.OnServiceConnector配合使用, /// </summary> /// <param name="fromService"></param> /// <param name="toDevice"></param> /// <param name="asyncService"></param> /// <returns></returns> public override IServiceConnectorCallbackResult RunServiceConnector(IFromService fromService, IServiceToDevice toDevice, AsyncServiceConnectorCallback asyncService) { if(!(toDevice.Object is DevicePacket)) { OnDeviceRuningLog("RunServiceConnector 接收到的為非 DevicePacket 物件"); return null; } //設定優先呼叫此設備驅動 this.DevicePriority = DevicePriority.Priority; //接收過來的設備協議包 this._devicePacket = (DevicePacket)toDevice.Object; //異步回傳操作結果,把操作最終的結果反饋給代理服務,最終通知操作端 this._asyncServiceConnectorCallback = asyncService; //設定為當前為接收狀態 this._sendCommandState = SendCommandState.Received; OnDeviceRuningLog("已經接收到命令交換資訊,正在準備下發命令......"); return new ServiceConnectorCallbackResult(true, null); }
(3)GetConstantCommand()函式介面獲得下發控制命令
if (_sendCommandState == SendCommandState.Received) //發送命令 { #region 構建發送命令 if (_devicePacket != null) { #region _sendCommandState = SendCommandState.ReadySending; foreach (DeviceFrame df in _devicePacket.DeviceFrames) { ITag tag = tags.Where(t => t.TagId == df.TagId && t.TagName == df.TagName).FirstOrDefault(); if (tag != null) { IModbusMessage requestMsg = null; byte[] reqeustBytes = null; switch (tag.Function) { case 0x01: //線圈,bool值 reqeustBytes = _modbusRtuMaster.BuildWriteSingleCoilCommand(byte.Parse(tag.SlaveId), ushort.Parse(tag.Address), bool.Parse(df.Value), out requestMsg); break; case 0x03: //保持暫存器,數值 reqeustBytes = _modbusRtuMaster.BuildWriteSingleRegisterCommand(byte.Parse(tag.SlaveId), ushort.Parse(tag.Address), ushort.Parse(df.Value), out requestMsg); break; default: OnDeviceRuningLog("沒有找到可寫入命令的標簽配置"); break; } if (reqeustBytes != null) { requestList.Add(new RequestInfo(reqeustBytes, new SendObject(requestMsg, tag))); } } } _sendCommandState = SendCommandState.Sending; #endregion } else { _sendCommandState = SendCommandState.None; } #endregion }
(4)Communicate接收控制命令回傳結果
byte[] revData =https://www.cnblogs.com/augustuss/p/ info.Data; IModbusMessage requestMessage = _sendObject.ModbusMessage; ITag tag = _sendObject.Tag; //用于驗證修改值回傳資料 bool modiftyData = https://www.cnblogs.com/augustuss/p/false; //是否修改回傳資料 bool validate = true; //驗證是否通過 if(requestMessage.FunctionCode == Modbus.Modbus.WriteSingleCoil) { modiftyData = true; try { _modbusRtuMaster.ValidateWriteSingleCoilResponse(revData, requestMessage); } catch(Exception ex) { validate = false; OnDeviceRuningLog(ex.Message); } } else if(requestMessage.FunctionCode==Modbus.Modbus.WriteSingleRegister) { modiftyData = true; try { _modbusRtuMaster.ValidateWriteSingleRegisterResponse(revData, requestMessage); } catch (Exception ex) { validate = false; OnDeviceRuningLog(ex.Message); } } if(modiftyData) { if (_devicePacket != null) { DeviceFrame df = _devicePacket.DeviceFrames.Where(t => t.TagId == tag.TagId).FirstOrDefault(); if (df != null) { if (validate) //正常 { df.OperationType = "setack"; df.Code = "200"; df.Desc = "修改成功"; _modifyConfirm.Add(df.TagId, true); } else { df.OperationType = "setack"; df.Code = "-1"; df.Desc = "修改失敗"; } OnDeviceRuningLog(String.Format("{0},{1}!!!", tag.TagName, df.Desc)); if (_asyncServiceConnectorCallback != null) { _asyncServiceConnectorCallback.Invoke(_devicePacket); } } else { OnDeviceRuningLog("獲得修改設備幀資料為空"); } bool modifyComplete = true; foreach(DeviceFrame d in _devicePacket.DeviceFrames) { modifyComplete=_modifyConfirm.ContainsKey(d.TagId); if(!modifyComplete) { break; } } if(modifyComplete) { _devicePacket = null; _asyncServiceConnectorCallback = null; _modifyConfirm.Clear(); _sendCommandState = SendCommandState.Complete; OnDeviceRuningLog("修改引數已全部完成!!!"); } } }
5. 應用效果
5.1 CS客戶端

5.2 BS瀏覽器

5.3 Linux環境測驗

5.4 視頻應用效果
文章:
《.NET Core開發的iNeuOS工業互聯網平臺,發布 iNeuDA 資料分析展示組件,快捷開發圖形報表和資料大屏》
《[視頻演示].NET Core開發的iNeuOS物聯網平臺,實作從設備&PLC、云平臺、移動APP資料鏈路倍訓 》
《.NET Core開發的iNeuOS物聯網平臺部署樹霉派(raspbian),從網關到云端整體解決方案》
《.NET Core開發的iNeuOS物聯網平臺部署在Ubuntu作業系統,無縫跨平臺》
《iNeuOS 物聯網云作業系統2.0發布,集成設備容器、視圖建模、機器學習三大模塊 》
《iNeuOS云作業系統,.NET Core全系打造 》
物聯網&大資料技術 QQ群:54256083
物聯網&大資料合作 QQ群:727664080
網站:http://www.ineuos.net
聯系QQ:504547114
合作微信:wxzz0151
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/62051.html
標籤:其他
