Download PuTTY free
 
 
 
 
 
 

 

 

 

BACnet Web Services, AJAX and Internet Explorer

Overview

In my previous article called "BACnet Web Services In Action" I demonstrated how Real Time Data can be integrated into a .Net application using Visual Studio 2005. I mentioned that it was very easy to do exactly the same with Internet Explorer and I will demonstrate this using Ajax (Asynchronous JavaScript and XML).

Ajax is used to make a web page feel more responsive by exchanging small amounts of data with the BACnet Web Server behind the scenes, so that the entire web page does not have to be reloaded each time the Real Time Data is refreshed. This increases the web page's interactivity, speed, and usability. Many large Web sites such as Google Maps already use this technique and you have probably already visited them without realising that Ajax is working behind the scenes.

Communicating with the Web Service

In order to commumnicate with the Web Service we need to send it an XML request and get an XML response back using the HTTP protocol. This is similar to getting a standard web page, but we need to POST an XML message to a URL rather than using a GET request for a URL. To demonstrate this we will assume that the getValue request for the path /.sysinfo/.vendor-name returned the response SCADA Engine giving us the following XML request and response messages.

Request

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope

 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xmlns:xsd="http://www.w3.org/2001/XMLSchema"

 xmlns:ns="urn:bacnet_ws">

 <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

  <ns:getValue>

   <ns:options></ns:options>

   <ns:path>/.sysinfo/.vendor-name</ns:path>

  </ns:getValue>

 </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

 

Response

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope

 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xmlns:xsd="http://www.w3.org/2001/XMLSchema"

 xmlns:ns="urn:bacnet_ws">

 <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

  <ns:getValueResponse>

   <ns:result>SCADA Engine</ns:result>

  </ns:getValueResponse>

 </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

 

 

XMLHTTP Object

Internet Explorer 5.0 onwards comes complete with the XMLHTTP object which is required by Microsoft Applications that use .Net and SOAP. This object can be called from Javascript by both Internet Explorer and Firefox. The following javascript code would take the the XML request string and URL as an input and return the XML response as a string. It uses a synchronous request which means the function waits until a response, or timeout occurs.


function doPOST(strURL, strRequest)
{
  objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP');
  objXMLHTTP.open('POST',strURL,false);
  objXMLHTTP.setRequestHeader('SOAPAction','http://tempuri.org/getXML');
  objXMLHTTP.setRequestHeader('Content-Type','text/xml');
  objXMLHTTP.send(strRequest);
  return(objXMLHTTP.responseText);
}

There is an option to make calls Asyncronous with the third parameter to the open method and this is what makes Ajax tick. An Asyncronous command is one that returns immediately without waiting. This means the Web Browser can send a request to the BACnet Web Service behind the scenes and when a response comes back it will swing back into action and handle the response.

Communicating with the Web Service using AJAX

When the page loads a message is Posted to the BACnet Web Service using an asynchronous HTTP request, the onLoad event will return imediately and the page will load as quickly as possible. Then later on when the Response is returned from the web service a callback function will be executed which will update the innerHTML of a Div within the web page. The HTML and Javascript code for this page is shown below.

<html>

<head>

<title>BACnet Web Services - getValue</title>

 

<script language="javascript">

//This script can be used to return a Value from the BACnet Web Service Asyncronously

//Asynchronous Operation is what the 'A' stands for in AJAX !!

 

//Variables

//XMLHTTP object for communication to the Web Server

var objXMLHTTP;

var strDivID;

 

//Issue a getValue request from the web server.

//The First Parameter is the URL of the Web Service

//The Second Parameter is the ID Name of the DIV element which will be updated on the Page

//The Third Parameter is the Path Name used in the getValue Request

function getValue(strURL, sDivID, sPath)

{

  strDivID = sDivID;

  doPOST(strURL, sPath);

}

 

//Use the XMLHttpRequest to communicate with a web service.

function doPOST(strURL, sPath)

{

  objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP');

  objXMLHTTP.open('POST',strURL,true);

  objXMLHTTP.setRequestHeader('SOAPAction','http://tempuri.org/getXML');

  objXMLHTTP.setRequestHeader('Content-Type','text/xml');

  objXMLHTTP.onreadystatechange = stateChangeHandler;

 

  try

  {

    objXMLHTTP.send(buildGetValueRequest(sPath));

  }

  catch(e)

  {

    updateDiv('* error * - ' + e.description);

  }

}

 

//Construct a SOAP envelope.

function buildGetValueRequest(sPath)

{

  //The SOAP request must be built as an XML String, the only variable in this string

  //is the Path used in the getValue request command.

 

  var strSOAP = '<?xml version="1.0" encoding="UTF-8"?>';

  strSOAP += '<SOAP-ENV:Envelope \n';

  strSOAP += ' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" \n';

  strSOAP += ' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" \n';

  strSOAP += ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \n';

  strSOAP += ' xmlns:xsd="http://www.w3.org/2001/XMLSchema" \n';

  strSOAP += ' xmlns:ns="urn:bacnet_ws"> \n';

  strSOAP += ' <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> \n';

  strSOAP += ' <ns:getValue> \n';

  strSOAP += ' <ns:options></ns:options> \n';

  strSOAP += ' <ns:path>' + sPath + '</ns:path> \n';

  strSOAP += ' </ns:getValue> \n';

  strSOAP += ' </SOAP-ENV:Body> \n';

  strSOAP += '</SOAP-ENV:Envelope> \n';

 

  return(strSOAP);

}

 

 

//Handle server response to XMLHTTP requests.

function stateChangeHandler()

{

  if(objXMLHTTP.readyState == 4)

  {

    try

    {

      var work = new ActiveXObject('MSXML2.FreeThreadedDOMDocument.3.0');

      work.loadXML(objXMLHTTP.responseText);

      updateDiv(work.selectSingleNode('//ns:getValueResponse').firstChild.text);

    }

    catch(e)

    {

      updateDiv('* error *');

    }

  }

}

 

function updateDiv(sText)

{

  try

  {

    document.getElementById(strDivID).innerHTML=sText;

  }

  catch(e) {}

}

</script>

 

</head>

 

<body onload="getValue('http://localhost:8080', 'idVendorName', '/.sysinfo/.vendor-name');">

 

<h1>BACnet Web Services - getValue</h1>

 

<b>Vendor Name</b>

<div id="idVendorName">* waiting *</div>

 

</body>

 

</html>

 

Conclusion

The SCADA Engine BACnet Web Service comes complete with this and other HTML sample pages which is all you need to create a Web Page for displaying Real Time Data from your building management system. Additional samples are included for the getValues request, as well as periodic refreshes of Real Time Data within a Web page.