此篇文章主要在分享如果用Advantech ADAM WISE 4012-E 提供的restful API來達到資料蒐集的目的。
- 簡介
Advantech ADAM WISE 4012-E主要是由研華所提供的無線資料蒐集器Solution , 通訊協定則是非常普遍的IEEE 802.11。無論是家用、工業用、商用,如智慧工廠、智慧家庭與植物工廠等應用,只要你想要蒐集的數據,是可以透過Sensor或是高低位電壓、電流等等的訊號透過DI(Digital Input) , AI(Anolog Input)來蒐集的,都可利用這個RTU(Remote Terminal Unit)的裝置來蒐集資料。如果不想自己呼叫restful API取得資料的話,研華也有販售SCADA的產品WebAccess可以取得ADAM WISE的蒐集值。雖然研華有介紹到可以蒐集PLC的資料,但因為成本和寫入企業資料庫的考量,所以目前我在使用PLC的資料蒐集並不是用他們家的Solution,如果再更高階的話,可能就要考慮SECS/GEM的架構了。研華官方範例影片連結 : https://www.youtube.com/watch?v=FsLpCABStG0
- 韌體設定
剛買到ADAM WISE,背面會有模式(AP Mode , Initial Mode)的說明和一個調整模式用的藍色指撥,在Initial Mode的模式下,找到該裝置的SSID,並連上該裝置。
因為我們期望這台裝置能夠蒐集資料並透過AP回傳,所以要利用Default的Web Setting URL : http://192.168.1.1/config 去設定AP Mode的Information,Account : root , PW : 00000000 ,這些在背面的標籤上都有註明。
並在Configuration -> Wireless的設定中設定AP的SSID 以及密碼,Submit儲存,將藍色指撥調整模式為AP Mode並重新送電給ADAM WISE 4012-E。
重啟後就會看到該裝置前面的WiFi訊號的強弱,代表你已經正確連上該AP了。這個時候就可以連進你的AP取得DHCP給ADAM的IP Address。
- Restful API
多數的參考文章或影片都沒有提到這個部分,但其實實作也滿簡單的,以下用Visual Studio 2017 C# 來說明一個簡單的範例,API的URL可以參考http://advdownload.advantech.com/productfile/Downloadfile2/1-14JNLJL/UM-WISE-4000-Ed.4-EN.pdf,研華的使用者手冊都都有提到Restful API以及上面述說的那些設定。要比較注意的是.net 在3.5之後的版本,WebRequest的Proxy是預設開啟的,要先把他關閉,不然會有Performance issue。
// Create a request for the URL.
WebRequest request = WebRequest.Create("http://10.248.72.201/di_value/slot_0");
//Set Account and Password for Advantech ADAM WISE
request.Proxy = null;
String username = "root";
String password = "00000000";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + encoded);
request.PreAuthenticate = true;
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
textBox1.Text = responseFromServer;
//Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
reader.Close();
response.Close();
程式基本上就是簡單的Http Get,得到的就會是一串輕量化的JSON格式資料,你可以用Json.NET去解析並處理得到的資料,解析完後塞進資料庫,就能利用報表或是其他表示方式來Monitor你想要監控的訊號源。
JSON.NET 是 紐西蘭的一位老兄James所開發的 JSON 程式庫。 JSON.NET 是 Visual Studio 中最受歡迎的 NuGet 套件之一, 已經有510萬個下載數 ,自2006年發表以來也有11年的歷史了,請各位安心服用。Visual Studio 2010之後的版本都可以使用NuGet(簡化程式庫安裝程序延伸套件)來安裝Json.net,詳情步驟請見https://docs.microsoft.com/zh-tw/nuget/tools/package-manager-ui
我的做法是先分別建立DI和DO的Class,用以存放Json解析後得到的資料
public class DI
{
public string IP { get; set; }
public string Ch { get; set; }
public string Md { get; set; }
public string Val { get; set; }
public string Stat { get; set; }
public string Cnting { get; set; }
public string OvLch { get; set; }
}
public class DO
{
public string IP { get; set; }
public string Ch { get; set; }
public string Md { get; set; }
public string Val { get; set; }
public string Stat { get; set; }
public string PsCtn { get; set; }
public string PsStop { get; set; }
public string PsIV { get; set; }
}
然後再使用Json.net的 DeserializeObjec function來解析Json並放進DI或DO的Class物件myData
DI myData = JsonConvert.DeserializeObject<DI>(sJson);
下指令給Digital Out的方式跟Get DI的方式差不多,簡單來說就是對某個URL位址下PUT指令,資料的內容就是要讓Channel的Value變為0或1,就可以控制DO的開和關了
public string SendJsonStringToWISE(int iDOInput , string sSlot , string Channel)
{
string sResult=string.Empty;
try
{
// Create a request using a URL that can receive a post.
string sURL = string.Empty;
string sIPAddress = "http://10.248.72.201/";
sURL = sIPAddress + "do_value/" + sSlot + "/ch_" + Channel;
//WebRequest request = WebRequest.Create("http://10.248.72.201/do_value/slot_0/ch_1");
WebRequest request = WebRequest.Create(sURL);
// Set the Method property of the request to POST.
request.Method = "PUT";
// Create POST data and convert it to a byte array.
//string postData = @"{""Ch"":1,""Md"":3,""Stat"":1,""Val"":0,""PsCtn"":0,""PsStop"":0,""PsIV"": 0}";
string postData = @"{""Ch"": " + Channel + @" ,""Md"":3,""Stat"":1,""Val"":" + iDOInput + @",""PsCtn"":0,""PsStop"":0,""PsIV"": 0}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
//Set Account and Password for Advantech ADAM WISE
request.Proxy = null;
//String username = "root";
//String password = "00000000";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + encoded);
request.PreAuthenticate = true;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
}
catch (Exception ex)
{
throw ex;
}
return sResult;
}