基於HslCommunication實現 基於WebApi, javascript來讀寫PLC數據,包括三菱,西門子,歐姆龍,modbus,ab plc,台達,橫河,信捷,松下,匯川,基恩士,富士,LS等等PLC


本文介紹在一些特殊的場景和需求下,使用HslCommunication的可以實現一些比較有意思的功能。例行介紹HSL的安裝

github地址:https://github.com/dathlin/HslCommunication 如果喜歡可以star或是fork,還可以打賞支持,打賞請認准源代碼項目。

聯系作者及加群方式:http://www.hslcommunication.cn/

 

在Visual Studio 中的NuGet管理器中可以下載安裝,也可以直接在NuGet控制台輸入下面的指令安裝:

Install-Package HslCommunication

  

如果需要教程:Nuget安裝教程:http://www.cnblogs.com/dathlin/p/7705014.html

組件的完整信息和API介紹參照: http://api.hslcommunication.cn  組件的使用限制,更新日志,都在該頁面里面。

 

我們來看看這種系統的架構設計模式。

 

我們有一個主的后台服務器來連接現場的各種PLC設備,然后進行數據交互。這個沒有問題,很好實現,但是現在有需求,我們在遠程客戶端界面,或是手機端界面,瀏覽器界面,等等,需要對遠程的PLC進行讀寫一些數據操作,這時候怎么實現是最簡單方便的?

 

在HSL里,提供了兩種簡單的可能性。可以輔助你快速實現需要的操作信息。

1. 基於MRPC實現,詳細見文章:https://www.cnblogs.com/dathlin/p/14094128.html

  優點:對客戶端的控制更強,權限控制也更加強,可以細化到每個API的權限控制,和MQTT深度結合,支持訪問TOPIC信息,傳輸數據有進度報告。

       缺點:MRPC為定制協議,需要定制開發,目前實現了C#,java,python版本,其他平台或是語言都需要定制實現。

2.基於WebApi實現,下文詳細說明。

       優點:客戶端標准化,使用postman即可測試,絕大多數語言和平台都支持webapi接口,已經有相關的輪子,可以直接調用。

       缺點:MRPC的優點就是缺點。

 

我們開始寫代碼,我們先假設有1個PLC需要不停的采集,分析數據,做處理。我們新建一個控制台程序,安裝HslCommunication組件。為了方便起見,我們假設這個PLC是西門子PLC,實際上無論什么牌子的都是一樣的。

namespace ConsoleServer
{
	class Program
	{
		static void Main( string[] args )
		{
			SiemensS7Net plc = new SiemensS7Net( SiemensPLCS.S1200, "127.0.0.1" ); // 此處拿了本地虛擬的PLC測試
			plc.SetPersistentConnection( ); // 設置了長連接

			while (true)
			{
				Thread.Sleep( 1000 ); // 每秒讀取一次
				OperateResult<short> read = plc.ReadInt16( "M100" );
				if (read.IsSuccess)
				{
					// 讀取成功后,進行業務處理,存入數據庫,或是其他的分析
					Console.WriteLine( "讀取成功,M100:" + read.Content );
				}
				else
				{
					// 讀取失敗之后,顯示下狀態
					Console.WriteLine( "讀取PLC失敗,原因:" + read.Message );
				}

			}
		}
	}
}

  

此處就簡化了一些操作信息,反正是要執行一些業務操作的。現在我們需要在客戶端的程序里,增加一個按鈕,比如功能是鎖定機台。這個功能的實現是寫入M300.1為True。如果解鎖,就是寫false

 

 

因為我們的客戶端是部署在其他電腦的,當然是需要新建一個winform的項目了,如果是WPF也是一樣的。也是弄兩個按鈕出來,然后寫事件。

 

 有了事件之后,我們怎么來寫代碼呢?

如果想實現基於webapi來讀寫,代碼非常精簡。我們改造下服務器端的實現:

namespace ConsoleServer
{
	class Program
	{
		static void Main( string[] args )
		{
			SiemensS7Net plc = new SiemensS7Net( SiemensPLCS.S1200, "127.0.0.1" ); // 此處拿了本地虛擬的PLC測試
			plc.SetPersistentConnection( ); // 設置了長連接

			HttpServer httpServer = new HttpServer( );
			httpServer.RegisterHttpRpcApi( "MainPlc", plc );
			httpServer.Start( 8000 );    // 需要管理員啟動

			while (true)
			{
				Thread.Sleep( 1000 ); // 每秒讀取一次
				OperateResult<short> read = plc.ReadInt16( "M100" );
				if (read.IsSuccess)
				{
					// 讀取成功后,進行業務處理,存入數據庫,或是其他的分析
					Console.WriteLine( "讀取成功,M100:" + read.Content );
				}
				else
				{
					// 讀取失敗之后,顯示下狀態
					Console.WriteLine( "讀取PLC失敗,原因:" + read.Message );
				}

			}
		}
	}
}

  

增加了三段話,實例化服務,注冊PLC,啟動。

當前的服務器提供了什么RPC的接口呢?,我們運行起來。然后用HslCommunication的DEMO程序打開瞧瞧就可以了。

服務器端啟動之后,就是一直在打印讀取成功了。沒有其他的內容

 

 

 

好了,到這里我們的程序寫完了,我們的PLC已經提供了遠程讀寫的WebApi的接口了,可能我們會問,在哪里呢?我們打開demo看看。

 

 

上面的操作之后我們看到了所有的接口列表。

 

 

我們點擊其中的一個接口,例如  ReadOrderNumber 接口,我們想讀取PLC的訂貨號。點擊之后,界面變化了。

 

 

不管他,我們直接點擊讀取。

 

 

我們看到有數據返回了。我們成功讀取到了一個json字符串,是不是很熟悉,獲取規則如下:

因為讀取是可能會失敗的,也就是Content屬性可能為空,那么我們就需要先判斷 IsSuccess 為 True ,我們再去拿Content的數據。

如果為 False, 那么代表讀取失敗了,失敗原因就在 Message 里面。這時候,你可以顯示出來。或是記錄日志,寫入寫入數據庫都是可以的。

 

我們再來嘗試讀取M100的short數據,在PLC里就是 MW100的值。

 

 結果如下:

 

 

當我們重新選擇ReadInt16接口的方法時,

 

 這時候已經顯示當前的接口已經有一次調用的信息了。

我們再測試一個寫入的操作。

 

 我們可以讀取驗證一下、

 

 

OK,我們現在用POSTMAIN測試一下。

 

 

需要注意的是,當前的方法是POST的。

 

既然支持webapi,最后我們來嘗試在網頁上的操作,我們先做一個網頁,放一個按鈕,然后搞一個點擊事件。去請求數據,然后顯示讀取結果。我們用到了 jquery,頁面如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HslCommunication教程</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <h1>測試Webapi的內容</h1>
    <p>點擊下方的按鈕即可
    </p>
    <button onclick="GetPlcValue()">測試</button>
    <p>結果如下:</p>
    <p id="test1"></p>
    <script type="text/javascript">
        function GetPlcValue(){
            $.ajax({
                type:'post',
                async: false,
                url:'http://127.0.0.1:8000/MainPlc/ReadInt16',
                dataType:'JSON',
                data:JSON.stringify({
                    'address': 'M100'
                }), 
                success:function(result){
                    console.log(result);
                    if(result.IsSuccess){
                        $("#test1").text("Read Success, value is : " + result.Content);
                    }
                    else{
                        $("#test1").text("Read Failed, Message: " + result.Message);
                    }
                }
            });
        }
    </script> 
</body>
</html>

  

  

很簡單沒啥內容,我們運行下。

 

 

emmm,好像遇到跨域問題了,沒關系,我們在服務器上稍微更改一下。

 

 

然后我們在頁面上再次進行操作一下:

 

 

同理,寫入都是類似的。

 

最后我們來聊聊,如何實現你自己的API接口到 webapi上。例如我們要增加一個算法的接口,傳入兩個數,返回方法之和。

我們定義一個類。

		public class Algorithms
		{
			[HslCommunication.Reflection.HslMqttApi(HttpMethod = "POST", Description = "這是一個計算兩個數相加的方法。")]
			public int Add(int a, int b )
			{
				return a + b;
			}
		}

我們看這個方法,定義了POST,當然了,GET也可以的,這樣客戶端的方式只要匹配就好了。

然后我們注冊下服務

 

 

完事,我們看看客戶端的界面。

 

 我們更改下傳入的值

 

 

 

當然,HttpServer進行用戶名驗證也是可以的。具體可以查看另一篇博客:https://www.cnblogs.com/dathlin/p/12335933.html

這時候的POSTMAN就是要攜帶基本的驗證了,我們來看看加一個權限控制的api的使用方法

 

		public class Algorithms
		{
			[HslCommunication.Reflection.HslMqttApi(HttpMethod = "POST", Description = "這是一個計算兩個數相加的方法。")]
			public int Add(int a, int b )
			{
				return a + b;
			}

			[HslCommunication.Reflection.HslMqttPermission(UserName = "admin")]
			[HslCommunication.Reflection.HslMqttApi( HttpMethod = "POST", Description = "這是一個計算兩個數相乘的方法。" )]
			public int Multipy( int a = 10, int b = 20 )
			{
				// 當前方法只能用戶名為admin的調用
				return a * b;
			}
		}

  我們增加的第二個方法就是增加權限的控制,這樣的話,客戶端再請求的話,就是需要增加權限頭

我們先看POSTMAN

 

 

 

 我們看到了返回了數據,然后我們再看看發送的header里都有什么

 

 這個內容就校驗的內容之一了,好了,我們在js里可以這么寫代碼了

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HslCommunication教程</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <h1>測試Webapi的內容</h1>
    <p>點擊下方的按鈕即可
    </p>
    <button onclick="GetPlcValue()">測試</button>
    <p>結果如下:</p>
    <p id="test1"></p>
    <script type="text/javascript">
        function GetPlcValue(){
            $.ajax({
                headers:{
                    'Authorization': 'Basic YWRtaW46MTIzNDU2'
                },
                type:'post',
                async: false,
                url:'http://127.0.0.1:8000/Algorithms/Multipy',
                dataType:'JSON',
                data:JSON.stringify({
                    'a': 10,
                    'b': 20
                }), 
                success:function(result){
                    console.log(result);
                    $("#test1").text("Read Success, value is : " + result);
                    //if(result.IsSuccess){
                        //$("#test1").text("Read Success, value is : " + result.Content);
                    //}
                    //else{
                        //$("#test1").text("Read Failed, Message: " + result.Message);
                    //}
                }
            });
        }
    </script> 
</body>
</html>

  然后再運行,就是返回了正確的結果了

 

 

 

 

如果有什么其他的問題,歡迎留言。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM