• Aucun résultat trouvé

Laddie Front Panel UI

Dans le document LINUX APPLIANCE DESIGN (Page 188-193)

In earlier sections of this chapter we reviewed the requirements, operations, and hardware for the Laddie front panel. In this section we’ll look at the software that implements the front panel UI. We’ll break our discussion into three areas: the software for the front panel, the various front panel emu-lators, and the software architecture common to both. Let’s start with the common architecture.

UI Software Architecture

The front panel software uses an event-driven state machine. Events include button presses, the expiration of a timer, and arriving log messages that indicate a possible change of state in the alarm system. Output from the program includes SQL commands sent to the Laddie daemon, a flag to flash (or not flash) the LED, and the text displayed on the LCD.

Figure 10-10: Laddie front panel architecture

Several state variables are used. The primary state variable, unimagi-natively called State, indicates the type of information displayed on the LCD: status, log, or menu. There are also states for the brief Command Sent message and for an indication that the program could not open an SQL connection to the ladd daemon. Another state variable, Curcmd, contains an integer that indicates which command to show when the user is in the menu.

The Command button cycles Curcmd through the five possible front panel commands. The Zone state variable holds the zone number to use for the current command. The Zone button cycles Zone through the five possible zone numbers.

Figure 10-11: Events and states in the front panel menu system

The code to handle the state and event processing is fairly easy to read once you’ve reviewed the operation of the front panel. The state machine

logmuxd

code is implemented twice—once in C for the hardware and several emulators, including a web-based emulator written in JavaScript and PHP.

lad216

The C code to generate the proper escape sequences is in the lad216 program. The program uses standard in and out, so if you build the hard-ware described above and install our /dev/lad_pad driver, you could tie the lad216 program to the hardware with the command:

lad216 </dev/lad_pad >/dev/lad_pad

The code is in three files: main.c which has the select loop, menu.c which has the state machine, and lad216.c which encodes the output for display on the lad_pad hardware. Using standard input and output makes it easy to connect lad216 to the various front panel emulators described below.

Front Panel Emulators

A front panel emulator is a great way to test a front panel design without actually building it. Front panel emulators that ship with the finished product are particularly nice for end users who do not want to be burdened with learning different UIs.

We went a little overboard building front panel emulators for Laddie, building one that uses C and curses, one that uses Tcl/Tk and the X Window system, and one that uses JavaScript and HTML. You can choose which emu-lator to examine based on your preferred programming language.

The curses version replaces lad216.c with cur216.c, but still uses the main.c and menu.c files. You can try the curses front panel emulator by booting the Laddie CD and telnetting into the appliance. The cur216 executable is in the default path.2

The Tcl/Tk version, x216.tcl, is based on the lad216 executable, using Tcl/Tk to replace the lad_pad hardware with a Tcl equivalent. The Laddie CD does not include the X Window system so you can not run x216.tcl on a booted Laddie appliance.

You can try the web-based front panel emulator by booting Laddie and pointing your browser to http://192.168.1.11/front_panel. The index.html file should open a window with a photograph of our actual front panel hard-ware. The buttons are tied to an image map and operate the same way the buttons do on the real system. The LED is either a static image of the LED in the off state, or is an animated GIF image of the flashing LED. The HTML of the LCD uses CSS to specify a fairly large monospaced font.

The techniques used in the web emulator are simple, and you may find them of use if you ever build a web emulator of your own front panel. To illustrate these techniques, let’s look at how the LED image is controlled. In the HTML we specify the exact location of the image and give it a name, led.

2 You may need to set the terminal type, since telnet does not set it for you. I use xterm on my desktop, so when I telnet to the Laddie appliance, I set the terminal type with the command export TERM=xterm.

<div id="led" style="position:absolute; left:27; top:20;"></div>

The JavaScript code uses XMLHttpRequest() to request the alarm status from a PHP script tied to the webserver running on the appliance. The value returned is zero if there are no alarms. The JavaScript to control the LED image is straightforward.

if (alarms > 0) {

document.getElementById("led").innerHTML="<img src=led_flash.gif>";

} else {

document.getElementById("led").innerHTML="<img src=led_off1.gif>";

The JavaScript program uses the exact same architecture and state machine as described above, and it uses XMLHttpRequest() instead of select() to asynchronously wait for log messages. After the arrival of any log message, the code queries ladd for the latest status and redraws the web page based on the new status information.

Improving Our Design

The Laddie front panel could be improved in several ways. The lad_pad driver could have been simplified had we separated the LCD data lines from the two output lines used for keypad scanning. Separating them would have allowed the convenient use of a second timer just for LCD output characters, which would have made the LCD more responsive to output. Another improvement in the driver would have been to pull more than one character from the queue if the characters were not sent to the LCD. For example, there is no reason to wait 20 milliseconds between characters if the character is an escape code or an LED command.

The photograph in the web front panel is of the hardware we built.

This is a little backward. Normally, you would build and test the emulated web-based version before building the actual hardware.

The web-based front panel has a more subtle problem. It uses XMLHttpRequest() to wait for arriving log messages, and after receiving one, it sets a timer to make the next request.

setTimeout("GetLogMsg()", 100);

This arrangement, no matter how short the timer, will miss log messages that arrive close together. You can see this in action by setting three alarms and clearing them all at once. The log display will capture the log of the first alarm being cleared, but it will miss one or both of the logs for the next two.

The main web interface has the same problem, but solves it by numbering the log messages. After updating the web page, the JavaScript code in the main web UI reads the ID of the last message received from logmuxd. If the ID of the log in the web page does not include the most recent log message, the page is redrawn using the most recent log messages.

Summary

In this chapter we’ve looked at how you can build an effective front panel using buttons, LEDs, and small, text-only LCDs. We saw that scanning a keypad or LED array can reduce the number of I/O lines you need, and that movement, such as a blinking LED, can draw the eye and let the user know that the appliance is running. We also noted that how well your appliance is accepted may depend on how quickly you make user interaction possible and how easily users can navigate your menu system.

We reviewed Laddie’s front panel design, including its menu system, hardware, UI software, and various front panel emulators. Our hardware design includes an HD44780 display and a 2-by-2 keypad. The source for our 2.6 character device driver, lad_pad, is on the CD and might be a nice introduction to kernel modules.

The UI menu system is implemented as a state machine, and is imple-mented twice. The first implementation, using C, uses standard in and out so that it can be tied to either a Tcl/Tk emulator or to the real front panel. The second implementation uses JavaScript and image maps for the front panel buttons and uses XMLHttpRequest() to receive the asynchronous log messages.

11

D E S I G N I N G A F R A M E B U F F E R

Dans le document LINUX APPLIANCE DESIGN (Page 188-193)