Skip to content

Webserver nano_AJAX_streaming_Example_Guide

Benoît Thébaudeau edited this page Sep 23, 2019 · 7 revisions

AJAX is a group of methods for TCP communication between server and client, whereby the browser client can be updated over time as new data is sent from the server. The TCP connection remains open because the server never sends a FIN to indicate that the page is complete. Coupled with javascript processing this can give live displays and logging of sensor data over a long period of time.

The AJAX page in webserver-nano was copied from the sky-websense example, with the addition of a text box that accumulates the data in a standard comma-separated format for importing into spreadsheets. The box continues to be updated when the browser is minimized, thus it functions as a background data collection routine.

The data is sent by a never-ending cgi script, which has conditional compilations for the various platforms and their sensor data. The script output consists of a TCP segment every few seconds containing javascript function calls with the sensor values as arguments, e.g. b(3042);ener(42,5,10);adc(30,32,31,32,40); sends battery voltage in millivolts, ENERGEST on percentages (x100) for cpu,tx, and rx, and five adc channels.

On the browser side the javascript is parsed using eval() which then calls each function to handle the data as desired. Large plotting libraries such as flot and jQuery can be used. Obviously hundreds of kilobytes can not be stored on each mote so these would have to be loaded from another server. Google and MS host such js libraries. This example uses a rudimentary 2.5 kB ajax.js file that can be served by the mote. For example the above data is handled with

 //Displays a line of text
 function ener(cp,tx,rx) {e('ener').innerHTML='<em>ENERGEST :</em> CPU= '+dc(cp/100,2)+'%  Tx= '+dc(tx/100,2)+'%  Rx= '+dc(rx/100,2)+'%';}
 
 //Adds to comma-separated text box
 function adc(a0,a1,a2,a3,a4,a5,a6,a7){
   var el=e('csv'),sv=el.scrollTop;
   el.innerHTML+=dc(((new Date()).getTime()-sts.getTime())/1000,1)+','+a0+','+a1+','+a2+','+a3+','+a4+','+a5+','+a6+','+a7+'\r';
   if((sv+el.clientHeight+30)<el.scrollHeight)el.scrollTop=sv;else el.scrollTop=sv+42;
 }

Changing the display is then just a matter of javascript programming. During development the .js file can be loaded from the host, then ultimately minified and stored on each mote.

The minimal net platform is useful for simulating a mote output. Copy the ajax.shtml, ajaxdata.shtml, and ajax.js files from the /apps/webserver-nano/httpd-fs/makefsdata.ignore folder up to the httpd-fs directory and touch or edit the .js file to force a new httpd-fs.c build (this requires PERL). Then cd to /examples/webserver-ipv6 and $make clean the first time (to flush possible object modules from webserver6).

 $make TARGET=minimal-net clean (always make clean when changing webservers!)
 $make TARGET=minimal-net WITH_WEBSERVER=webserver-nano
 ../../tools/makefsdata -A HTTPD_STRING_ATTR -d ../../apps/webserver-nano/httpd-fs -o ../../apps/webserver-nano/httpd-fsdata.c
 Processing directory ../../apps/webserver-nano/httpd-fs as root of packed httpd-fs file system
 Writing to /home/dak/contiki/apps/webserver-nano/httpd-fsdata.c
 Adding /404.html
 Adding /ajax.js
 Adding /ajax.shtml
 Adding /ajaxdata.shtml
 Adding /files.shtml
 Adding /index.shtml
 Adding /status.shtml
 Adding /tcp.shtml
 All done, files occupy 3745 bytes
 touch ../../apps/webserver-nano/httpd-fs.c
 gcc ...
 cp webserver6.minimal-net webserver-nano.minimal-net

Then run the binary, on windows/cygwin you pass the ip4 address of the adapter to share, the default being 10.10.10.10:

 $./webserver-nano.minimal-net
 usage: <program> <ip addr of ethernet card to share>
 -->I'll try guessing 10.10.10.10
 init_pcap: found interface: MS LoopBack Driver
 init_pcap:    with ipv6 address: [fe80::e5b0:4547:ef64:2ff7]
 init_pcap:    with address: 10.10.10.10
 set_ethaddr: found adapter: Microsoft Loopback Adapter
 set_ethaddr:  with address: 10.10.10.10
 set_ethaddr:  ethernetaddr: 02-00-4C-4F-4F-50
 IPV6 Addresss: [aaaa::206:98ff:fe00:232]
 IPV6 Addresss: [fe80::206:98ff:fe00:232]
 *******Contiki-2.5-release-40-ga547b22 online*******

on linux,

 sudo webserver-nano.minimal-net
 todo

Now point the browser to http:https://[aaaa::206:98ff:fe00:232]

and click on the ajax link

Edit the ajax cgi source and javascript until satisfied with the result, then build for a physical mote:

 $make TARGET=redbee-econotag clean
 $make TARGET=redbee-econotag WITH_WEBSERVER=webserver-nano

Note the Firefox Web Developer addon, very useful for debugging javascript.

Run wireshark on the interface to see the TCP traffic.

Bugs and gotchas:

  • Works in Firefox. View page source will not show the text box content unless the stop button is pushed. However saving the page will save all the data.
  • Probably works similarly in Safari.
  • IE9 does not repeatedly call the onreadystatechange function, however it will call it once when the stop button is pushed. All the data will then be rendered (hence identical times in the first csv field). Because the stop button does an r.abort(), saving the page will not save the data. You must copy and paste from the text buffer.
  • Chrome behaves as IE9 except the buffer is flushed on abort(). No data :(
  • Opera - ?
  • Removing READONLY from the text box would allow editing, but Firefox (at least) stops updating it after the first edit.
Clone this wiki locally