CHAPTER 7 ■ CONTROL HUBS 258 You can use the same mechanism to invoke software-only devices, such as media players and Festival, allowing music to be streamed into locations where physical speaker cabling is not possible. The system is bidirectional, so you can also get a remote machine to send any commands it gets to the main server for processing. Marple was introduced in version 2.2.0 of Minerva and is now supported by all the current Bearskin commands and used transparently to the user. The Workings There are two files necessary to enable Marple’s full range of functionality, both are called devlist and exist for each of the Bearskin commands that have been enabled. They are formatted thusly: localhost dev /dev/dsp - - default dev /dev/dsp - - bedroom soap 192.168.1.123 19781 localhost The columns are as follows, in order: The device name: This is always the first argument to any of the Bearskin commands, such as the bedroom in cdplayer bedroom play 1. Protocol type: This currently may be dev or soap. If the protocol is dev, then the protocol device represents a Linux-style device on the local machine. If it’s soap, then the device specifies the IP address of the machine to talk to. Protocol device: This indicates which address is to be used for the device. It’s usually a device or IP address (see the previous item). Protocol parameter: This is used in conjuncture with the protocol device. This is mostly unused, but in the example earlier it represents the port number associated with the IP address. The remote device name: When the command is being executed on the remote device, this name is used instead of the original one given. This parameter is unused for dev protocols. Handling Protocols When the user invokes the cdplayer command for example (from either the Web, command line, or Cosmic), the script will examine the local devlist file located at $MINBASE/etc/devices/cdplayer/devlist for a matching device name in the first column. If no matching device name can be found, it then reads the global devlist file (in the same format but located at $MINBASE/house/marple/cdplayer/devlist) and tries again. If a match still can’t be found, then the original device name is used by cdplayer in the hope that it is application-specific and the cdplayer application can understand it. Once a matching device name is found (regardless of which file contained it), the device is evaluated. In the case of dev protocols, the protocol parameter (such as /dev/dsp) is passed back to the application for immediate use. CHAPTER 7 ■ CONTROL HUBS 259 All other protocols, such as soap, are handled by external commands located in $MINBASE/bin/xmit/[protocol_name]/cmd. This combines the new protocol information (IP address and port) with all the parameters from the original command, with the remote device name (column 4) in place of the original one, and passes it to the appropriate cmd script. Here it is in geek parlance: $MARPLEPROTOCOL/cmd ${DEVARRAY[2]} ${DEVARRAY[3]} $COMMAND ${DEVARRAY[4]} $ALLARGS This command can then issue an appropriate network packet to the server listed. In the case of SOAP, a call is made to minerva/marple/cmd.php where the arguments are extracted, and a brand new Bearskin command is formulated like this: <?php function getCommand($cmd, $args) { # in case someone tries exec'ing other programs, in different directories # we'll try and stop them. $cmd = str_replace("/", "", $cmd); $cmd = str_replace(" ", "", $cmd); $minervaPath = "/usr/local/minerva"; $fullCommand ="$minervaPath/bin/$cmd $args"; return $fullCommand; } function marple($cmd, $args) { $fullCommand = getCommand($cmd, $args); $result = array(); exec($fullCommand, $result); $rts = ""; foreach ( $result as $v ) { $rts .= "$v\n"; } return $rts; } $server = new SoapServer(null, array('uri' => "urn://www.minervahome.net/marple")); $server->addFunction("marple"); $server->handle(); ?> Note that the only commands available are under the /usr/local/minerva hierarchy, with all instances of pruned out to stop malicious code from being run. CHAPTER 7 ■ CONTROL HUBS 260 ■ Note If you add your own protocols but they’re not addressed by an IP/port pair, then you can reappropriate the two columns to your desires, provided your $MARPLEPROTOCOL/cmd script can understand them. Using the cdplayer example again, the remote machine processes a command that now looks like this, if it were to be processed locally: cdplayer localhost play 1 Bearskin Compatibility To make your own commands compatible with Marple, you need to begin your scripts with a few extra lines of code. Here’s an example: DEVICE=`$MINBIN/finddev mixer $*` if [ $? == 0 ]; then echo $DEVICE exit 0; fi This rather strange-looking piece of code makes use of both the finddev output and its exit code. It returns a 0 in those cases where the device name was found but wasn’t intended for this machine. In other words, it has dispatched a SOAP request or similar and 1 when a genuine device was found. The latter is more usual and ends up being /dev/dsp or similar. As far as the command scripts go, this is all that’s necessary. The extra work comes from creating a local devlist. But each is generally a carbon copy of the others. Namely, a file called $MINBASE/etc/devices/new_app_name/devlist should be created and appear like this, replacing /dev/dvd with a suitable device for your app: localhost dev /dev/dvd - - default dev /dev/dvd - - Note that the local devlist file should always include a default and localhost reference. This ensures that every query can terminate and stops recursive loops from happening. ■ Note Some low-level software, such as the CD player program cdcd, requires $HOME to be set up before the program can be run. This requires the machine charged with processing SOAP requests to add this extra line of code and sometimes prepare a .cdcdrc file in the home directory of the www-data user. CHAPTER 7 ■ CONTROL HUBS 261 Utility Scripts A quick perusal of the $MINBASE/bin directory will reveal a number of commands that haven’t yet been covered. These divide into status and user tools. Status These are the simplest to consider and are basic scripts that perform read-only tasks to report on the various elements of the system. Because of the architecture, this is usually nothing more complex than reading text files in the /var/log/minerva directory or querying the existing commands. Every status command, except vstatus, issues its report to the standard output stream. In this way, it can be incorporated directly into a web page output or piped into announce: netstatus: Calls the user tool $MINBASE/bin/ipcheck to determine whether the external network is available, in addition to your local web server. Because ipcheck is synchronous, this can take a short while to happen, particularly if there’s no available Internet. lstatus: Life status, reporting what should generally happen today. For example, “empty the bins tonight.” This is a housewide message and so appears on everyone’s status reports. weatherstatus: A simple echo of the weather forecast that has been downloaded and processed previously with ~minerva/update/weather. mstatus: Reports on the media currently playing, including both MP3 and CDs, detailing the artist and album when they’re known. status: All of the earlier reports are combined into one, along with the time and date, making it an informative alarm call. tvonnow: Provides a list of the TV programs currently showing. The list is downloaded every night and stored locally, where this code rips out only those programs in the current time slot. vstatus: A wrapper to status, presenting all the information in a spoken form with announce, meaning there’s a single chime at the beginning and end of the whole phrase, and not one between each individual report. User Tools As I’ve mentioned several times, the differences between an automated house and a smart home are the subtleties and extras and make people go “Wow!” These tools generally fall into this category: hdate: This reports the date in a natural, humanistic manner such as Tuesday the 15th of December 2009 instead of Tue Dec 15 10:40:03 GMT 2009. This not only makes it user-friendly but machine friendly too, since the output can be sent to a speech processor where you’ll get a better-sounding voice because it understands how to vocalize words and sentences better than the computerized form. CHAPTER 7 ■ CONTROL HUBS 262 housenight: This is a simple shutdown script for putting the house to sleep. The default script says “Goodnight” and switches off a predetermined set of lights. You may want to extend this to send shutdown messages to secondary PCs (as shown in Chapter 4) or initiate overnight download scripts. htime: This reports the time in a natural, humanistic manner in the same way that hdate does for the date. vtime: This produces a vocal version of the time using piecemeal samples, as covered in Chapter 5. ipcheck: This pings each web site listed in $MINBASE/etc/ipcheck.conf to determine whether the Internet, as a whole, is currently available. pmedia: This is a utility script to pause any, and every, media device that is currently playing such as MP3 and CD. If the media is already paused, then it resumes it. This is a useful emergency cutoff command, especially when issued remotely through Cosmic, when you’re trying to listen to what someone else in the house is saying. 6 timedscale: This blocking script repeatedly calls a given command, scaling the input parameters over time. So, a call like timedscale 0 100 60 x10control default dim e3 will vary the light output from 0 to 100 over the next 60 seconds by appending the scaled numbered to the end of the command. When the program does not take the value as its final parameter, you will need to create a small wrapper script to rearrange the arguments. Topology Ideas Every house is different. And for the most part, so are the network and wiring configurations necessary to run it. Here, I present a couple of standard configurations as inspiration. Networking Figure 7-7 shows the simplest of networks. It uses an off-the-shelf router to hide your Node0 server and your other machines on a local address range (such as 192.168.1.x). The router is then configured to open specific ports, redirecting those requests to the main server or other machines on the network as appropriate. The additional machines can be laptops, media head units, or secondary administrative machines such as file servers. 6 Having music available in every room increases the ambient noise, making it more difficult to hear others calling you, so some of these commands exist to solve the problems that we have created. . created and appear like this, replacing /dev/dvd with a suitable device for your app: localhost dev /dev/dvd - - default dev /dev/dvd - - Note that the local devlist file should always. "urn://www.minervahome.net/marple")); $server->addFunction("marple"); $server->handle(); ?> Note that the only commands available are under the /usr/local/minerva hierarchy, with. commands that have been enabled. They are formatted thusly: localhost dev /dev/dsp - - default dev /dev/dsp - - bedroom soap 192.168.1.123 19781 localhost The columns are as follows, in order: