-
Notifications
You must be signed in to change notification settings - Fork 2
Webserver nano_AJAX_streaming_Example_Guide
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://[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.