|
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.
|