研華(Advantech) ADAM WISE 4012-E restful API example

  • 2411
  • 0
  • IOT
  • 2017-10-12

此篇文章主要在分享如果用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

「advantech adam wise」的圖片搜尋結果

  • 韌體設定

剛買到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;
        }