Using the tsctl server from HTML/Javascript

From embeddedTS Manuals

The tsctl server (tsctl --server) has built in support for HTML/Javascript access by acting in a very limited capacity as a web server on port 8000 on the board the server is started on. It does so by accepting (and ignoring) any and all HTTP headers sent, which are terminated by two empty new-lines. Then follows the actual data, which it interprets in the same manner as from the tsctl command line or from a file. The main difference between the tsctl web server and the command-line client is that the former defaults to "Mode JSON" while the latter defaults to "Mode Assign" or (for the tsctl shell) to "Mode NoAssign".

Note: The tsctl web server returns the header "Access-Control-Allow-Origin: *". This allows you to create a single HTML page that can control multiple devices.

The first step to using the tsctl with HTML and Javascript is to create the interface in HTML. This can consist of form elements or any other interface mechanism available to the web browser(s) you are creating your page for. As a simple example, suppose you want to create a web page to display the current A/D value on the board. You might create the following markup in your HTML page:

ADC value = <span id='adc1'></span>V

The creates an empty span with an id we can use to fill in the value later. Next, you will need to write some javascript code to talk to the tsctl server to fetch the A/D value.

First, here is a Javascript function that will create an XMLHttpRequest for talking to the server, then make the request, and when the reply has been received it will call the callback passed.

function AJaXRequest(url,parms,success,failure) {
    var ob;

    var callback = function() {
        if (this.readyState == 4) {
            if (typeof success == 'function') success(this.responseText)
        }
    }
    if (window.XMLHttpRequest) {
        ob=new XMLHttpRequest()
    } else if (window.ActiveXObject) {
        ob=new ActiveXObject("Microsoft.XMLHTTP")
    }
    if (ob) {
        ob.onreadystatechange=callback;
        ob.open("POST",url,(callback != null));
        ob.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
        try {
            ob.send(parms)
        } catch (e) {
            if (typeof failure == 'function') failure(e)
        }
    }
    return ob;
}

If you are already using your own javascript library such as jQuery, you may already have such a function available to you.

Next, here is another function using the above definition that will send the tsctl command to get ADC channel 1 and then put the results in the 'adc1' span created above, assuming a 10-bit A/D with a 0-10V range:

function getADC1(server) {
   AJaXRequest(server,"AIO Get 1\nend\n", function(reply) {
       var ret = JSON.parse(reply)
       document.getElementById('adc1').innerHTML = Math.round(ret["AIO_Get_0"] * 10000 / 32768)/1000
   })
}

The server parameter is the URL of the tsctl server, such as "http://192.168.0.50:8000". Note that the actual command to be sent has newlines quoted ("\n"), and ends with the "end" command. This is a special command that causes the tsctl server to immediately terminate the connection. Without this command the browser may hang until a timeout occurs to close the connection.

The data returned by the server uses the same name/value pairing that the command line does. Therefore if, for example, a second "AIO Get" command was issued in the above request, the reply would be in the ret["AIO_Get_1"] field of the reply.