Livepage Generator

The live pages seem to update magically as you look at the web page, but in fact most of the work is done by a single script on ares (now read fourier for ares?) , and some AJAX magic by the web browser. This page explains how it all happens. If you are looking for information on how to get the live page information working for the LBA monitor, that is found here

There is a script on ares called /var/www/html/live/livepage_query_lba_gfx_webcam_cedunanet.cgi. This is a Perl script that queries the live page databases on ares as the livepage user to get the latest data, then generates:

  • an XML file that your web browser loads to fill the live page with data
  • the PGPLOT GIF plots of where the telescope is pointing
  • more PGPLOT GIF plots showing the last 24 hours of weather data at each telescope
  • a symbolic link to the latest webcam image of the Mt Pleasant 26m telescope
  • a file that is incorporated into the LBA Live monitor page

If the livepages for both Hobart and Ceduna are not updating then it is probably this script that isn't running. To check this logon to ares and ps -ef | grep livepage if there are no processes listed (apart from the grep itself) then (as root) issue the following two commands

  1. export LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib
  2. /etc/init.d/livepages

If Ares has suffered power failures or the like, the SQL tables may be crashed and need to be repaired. This can be done fairly easily

  • Log in as root to the mysql database: mysql -u root -p , using the ares root password.
  • Find the database that is corrupt. The error listing from /etc/init.d/livepages will list the problem but it's worth checking the other databases too. For example the following query:
    use mt_pleasant_26;
    select * from drives order by id desc limit 1;
    should give you data from the drives database. if it comes back as "... is marked as crashed and should be repaired", then you simply give the mysql command:
    repair table drives;

XML file

The XML file that it creates is saved in /var/www/html/live/mt_pleasant_26.xml or /var/www/html/live/ceduna_30.xml. These are very simple XML files with the following format:

  • the parent element is <data>
  • there is only one level of child elements below the parent element; these elements are
    • <network>: information about the status of the Ceduna wireless network
    • <telescope>: specifies the name of the telescope
    • <weather>: information about the weather
    • <drives>: information about the drives
    • <time>: information about the time
    • <safety>: information about limit switches, panic buttons etc.
    • <coord>: information about where the telescope is pointing
    • <focus>: information about the focus position
    • <antenna>: information about what the antenna is doing
    • <img>: the name of the pointing image that the script made for this data
  • for each element, there is an associated id attribute which specifies which database field this element is associated with. The rule is very simple: if the database field is called weather_wind_speed_long (for example), then the XML file will have an element <weather> with an id attribute of wind_speed_long.
  • for any element it is possible to associate a class of error to it. This is usually associated only with wind speed errors, panic switches etc.
  • the between the opening tag of the element and its closing tag, there should be a value for the data. For example, for the wind speed, the full element would look like <weather id="wind_speed_long">18.2</weather>. If the wind was too high you might expect to see the element <weather class="error" id="wind_state">WIND_BAD</weather>.

PGPLOT Pointing GIFs

The pointing image the script creates is put in the same directory as the XML file (ie. /var/www/html/live) and is called mt_pleasant_26_julian_date.gif (or similar for ceduna_30). The Julian date is put into the filename so that there is always a unique name for the new image. It was found that if the same name was used for the image, then the browser never bothered to reload the image and so updating it did nothing. The script automatically deletes images that are more than 2 updates old (about 10 seconds).

PGPLOT history GIFs

The "last 24 hours" GIF plots are updated every minute by the script, since the SQL queries needed for this take a bit longer to run than the one used every 5 seconds. Specifically, to get the weather data for the last 24 hours in a reasonable amount of time, we only gather every 50th point, and we let mySQL filter out the rest, with the query:
SELECT time_ut_day_number,time_utc,weather_temperature,weather_air_pressure,weather_humidity,weather_wind_speed_long,weather_wind_direction from telescope where right(id,2)=00 or right(id,2)=50 order by id desc limit 346
Note that there is no time specified here, we only gather the last 346 points separated by 50 elements = 346*50*5 = 86500 seconds. However if there are periods when data was not being collected, then the data returned may span more than a single day. The PGPLOT routine in the script handles this properly, so that the time is always correctly displayed.

Webcam images

The latest webcam image is always linked to the file /var/www/html/live/latest_webcam_mt_pleasant_26.jpg. Which of the 8640 images in the directory /home/observer/public_html/live_pictures is the latest is determined by the script with the command ls -t | head -n 1.

Tick phases and LBA Live information

The latest tick phase from the Mt Pleasant observatory can be found in the file /home/jstevens/public_html/hotick.html, while that of Ceduna is in the file /home/jstevens/public_html/cdtick.html. The script takes these files, and information from the telescope tables and outputs a file at /var/www/html/live/mt_pleasant_26_lba.txt (similar

for ceduna_30) which looks like:
time 2008 261/01:59:24
coords 05:25:31.4 -45:57:55.4
pointing 231.845 27.98
feed S/X
tickphase 11.4004
windspeed 17
temperature 13.2
state TRACKING

This file goes directly to the LBA Live monitor page that Chris Phillips maintains. A slight kludge to the system was made on 30/11/09 to include correct wrapping of the tickphase and to stop the feed for Ceduna being reported as the same as Hobart. The original script is available as /var/www/html/live/livepage_query_lba_gfx_webcam_cedunanet.old.cgi

AJAX magic

The live page itself is quite simple. Standard xhtml is used to form the page, and a Javascript program has been written so that the webpage can be quickly changed and still function as a live page.

An example of this is given here. The Javascript at the top of the live page is as follows:

<script language="javascript">

function getData(){
  var XMLHttpRequestObject = false;
  var activex = false;
  if (window.ActiveXObject){
    XMLHttpRequestObject = new
      ActiveXObject("Microsoft.XMLHTTP");
    activex=true;
  } else if (window.XMLHttpRequest){
    XMLHttpRequestObject = new XMLHttpRequest();
    XMLHttpRequestObject.overrideMimeType("text/xml");
  }

  if(XMLHttpRequestObject){
    XMLHttpRequestObject.open("GET","http://www-ra.phys.utas.edu.au/live/mt_pleasant_26.xml",true);

    XMLHttpRequestObject.onreadystatechange = function(){
      if (XMLHttpRequestObject.readyState == 4){
        if (XMLHttpRequestObject.status == 200) {
	  if (activex == false){
	    xmlDocument = XMLHttpRequestObject.responseXML;
	  } else {
	    xmlDocument = new ActiveXObject("Microsoft.XMLDOM");
	    xmlDocument.loadXML(XMLHttpRequestObject.responseText);
	  }
	  displayData(xmlDocument);
        } else {
          alert("There was a problem retrieving the XML data:\n"+XMLHttpRequestObject.statusText);
        }
      }
    }

    XMLHttpRequestObject.send(null);
    setTimeout('getData()',5000);
  } else {
    alert("Your browser doesn't support XMLHttpRequest - upgrade NOW!");
  }
}

function displayData(xmldoc){
  var displayParams = new Array();
  displayParams[0]="time";
  displayParams[1]="coord";
  displayParams[2]="drives";
  displayParams[3]="antenna";
  displayParams[4]="safety";
  displayParams[5]="weather";
  displayParams[6]="focus";
  displayParams[7]="encoder";

  telescopenode = xmldoc.getElementsByTagName("telescope");
  document.getElementById("telescope").innerHTML=telescopenode[0].firstChild.nodeValue;

  for (var x in displayParams){
    newNode = xmldoc.getElementsByTagName(displayParams[x]);
    for (var y = 0; y < newNode.length; y++){
      yAttr = newNode[y].attributes;
      if (yAttr){
        yID = yAttr.getNamedItem("id");
        yText = yID.nodeValue;
	yClass = yAttr.getNamedItem("class");
	if (yClass){
	  yError=" <img src='live_warning.png' />";
	} else {
	  yError="";
	}
        target = document.getElementById(displayParams[x]+"_"+yText);
        if (target){
          target.innerHTML=newNode[y].firstChild.nodeValue+yError;
        }
      }
    }
  }
  telescopenode = xmldoc.getElementsByTagName("img");
  document.gfx_position.src=telescopenode[0].firstChild.nodeValue;
}

</script>

This script should not need to be changed, and can be included on any page that you want to give live page functionality to. The only thing to note is that the script above will try to find the Mt Pleasant 26m data. To get Ceduna data, change the line
XMLHttpRequestObject.open("GET","http://www-ra.phys.utas.edu.au/live/mt_pleasant_26.xml",true);
to
XMLHttpRequestObject.open("GET","http://www-ra.phys.utas.edu.au/live/ceduna_30.xml",true);

The web page can then be made however you like. You should include span tags in the xhtml code that the Javascript will substitute for the data in the XML file. For example, to include the telescope state in your page, simply put the following in your xhtml:
<span id="antenna_antenna_state"></span>

The basic rule is that in the XML file, you will have an element tag and an id attribute. The Javascript will combine the tag and the id like element_id, so the temperature would be weather_temperature for instance. Whenever the Javascript finds a span with an id attribute that it knows, it will replace it with the XML data.

To get the Javascript to run when the page is loaded, you must also put the <body onload="getData()"> tag into your page.