====== Shell Script Widget Control API ====== This is a method of controlling widgets using URI requests only, and as such is amenable to being placed into Unix-like shell scripts. ===== URI Method summary ===== There is a two-step procedure to talk to a widget. You will need to know * the current time (in milliseconds from epoch; use the command "date +%s" from a GNU date or the result from the C function time() to get this time in seconds). * your widgetID. See [[api:JavaScript Widget Control API]] for how to obtain a widgetID. The procedure is as follows. - Get a sessionID for your widget. - Send a message to your widget using the sessionID. === Getting a sessionID === Make a request for some JavaScript code using this URI: https://www.iobridge.com/interface/?actionID=RM_Widget&widgetID=XXXXXXXX&dt=NNNNNNNNN Substitute XXXXXXXX with your widgetID and NNNNNNNN with the time in base 10. The server responds with a block of JavaScript which contains the sessionID. The code is somewhat tricky, and may change, but the data we need is in the first argument to the JavaScript function DI(). This argument is a URI enclosed by URL-encoded quotes. This URI contains the sessionID, but the whole URI can be used as as stem for sending an action to the widget, and will be called AAAAAAAA. === Using the action base URI to activate a widget === This is fairly simple. Suppose your widget takes a value (e.g., serial send widget, or servo variable position); then make a request with this URI: AAAAAAAA&setValue=MMMMMMMM&dt=NNNNNNNN Substitute AAAAAAAA with the action base URI found above (it has the sessionID and widgetID encoded into it). Substitute MMMMMMMM with the value to send to the widget in text. (It's a good idea to URL-encode it if you're not sanitizing the inputs.) Again, NNNNNNNN is the current time. ===== Example bash script ===== There is some sample code. Replace the widgetIDs marked in the function parsewidget() with your own. This script has been tested with a [[function boards:serial LCD]] and [[smart boards:servo controller smart board]]. modules. This script requires the external commands "date", "wget" and "hexdump". They are fairly common on most Unix/Linux/BSD systems. * [[http://en.wikipedia.org/wiki/Date_(Unix)]] * [[http://en.wikipedia.org/wiki/Wget]] * [[http://en.wikipedia.org/wiki/Hexdump]] #!/bin/bash # Daniel F. Smith, iobridge@dfsmith.net # # Usage: # iobridge.sh message [message...] # # The argument can be the widgetID or a friendly name # (see the parsewidget function). If the friendly name starts # with "lcd", then some convenient substitutions will be made # to the message (see the parsemessage function). # # E.g., # ./iobridge.sh lcd '%clear%Hello world!' # ./iobridge.sh servo 400 2000 400 # ./iobridge.sh wuQRD6ENmrDq 1000 WGET=/usr/bin/wget HEXDUMP=/usr/bin/hexdump DATE=/bin/date function gethttp { $WGET -qO- "$1" } function urlencode { r=`echo -n "$1" | $HEXDUMP -ve '/1 " %02X"'` echo "${r// /%}" } function stripquote { x="$1" x=${x/#\&\#39;/} x=${x/%\&\#39;/} echo $x } function getTime { echo $(( $SECONDS * 1000 )) } function getactionbaseurl { widget="$1" rmbaseurl="https://www.iobridge.com/interface/?actionID=RM_Widget" rmurl="${rmbaseurl}&widgetID=${widget}&dt=`getTime`" rmdata=`gethttp "$rmurl"` diargs="${rmdata/*DI\(/}" diargs="${diargs/\)*/}" diarg1=`stripquote "${diargs/,*/}"` echo "$diarg1" } function parsewidget { case "$1" in lcd) echo "Aj4OEj3OSzDw" # dfsmith's personal LCD widget ;; servo | servo1) echo "wuQRD6ENmrDq" # dfsmith's personal servo ;; *) echo "$1" ;; esac } function parsemessage { message="$2" case "$1" in lcd*) lcdesc=$'\xFE' message="${message//%escape%/${lcdesc}}" message="${message//%bright%/${lcdesc}B}" # "X" (0-9) message="${message//%delaybright%/${lcdesc}T}" # "XD" (0-9,binary delay) message="${message//%reset%/${lcdesc}Z}" message="${message//%clear%/${lcdesc}C}" message="${message//%home%/${lcdesc}H}" message="${message//%move%/${lcdesc}L}" # "RRCC" (row column) message="${message//%cursoroff%/${lcdesc}K}" message="${message//%cursoron%/${lcdesc}J}" message="${message//%cursorblink%/${lcdesc}P}" message="${message//%cursorsteady%/${lcdesc}Q}" message="${message//%scroll%/${lcdesc}S}" # "RS...\xFE" (row,speed) message="${message//%hbar%/${lcdesc}G}" # "RLLHHX" (row,L-label,R-label,a-k) message="${message//%vbar%/${lcdesc}V}" # "X" (0-8) ;; esac echo `urlencode "$message"` } SECONDS=`$DATE +%s` logicalwidget="$1"; shift widget=`parsewidget "$logicalwidget"` actionbaseurl="`getactionbaseurl "$widget"`" while [ "$1" != "" ]; do message="$1"; shift encodedmessage=`parsemessage "$logicalwidget" "$message"` actionurl="${actionbaseurl}&setValue=${encodedmessage}&dt=`getTime`" gethttp "$actionurl" >/dev/null done