Developing widgets for chumby

From Chumby Wiki
Revision as of 17:38, 9 September 2007 by Chumby (Talk | contribs)

Jump to: navigation, search

Summary

This page describes the development of widget for the "Ironforge" production chumby hardware.

If you're developing widgets for alpha prototype hardware, please see Developing Widgets for Foo/Katamari instead.

Widgets for the Chumby are developed for Adobe Flash Lite 3.0. Flash Lite 3.0 has a feature-set based on desktop Flash Player 8.

Supported Features:

  • Flash video (FLV) encoded with ON2 and Sorenson Spark codecs
  • Video, NetStream and NetConnection classes
  • External MP3 files
  • External PNG, GIF, non-progressive JPEGs

Not supported:

  • Bitmap caching, bitmap effects or enhancments
  • Focal gradients
  • Progressive JPEGs

Also important for developers to note is that the device's current input system is a touchscreen, meaning that mouseMove events will only occur while mouseDown (equivalent on current computers of only being able to move the mouse while holding a mouse button), which may/will have some effect on how your programs operate.

For efficiency's sake, Flash Lite downsamples images and embedded fonts, so avoid resizing images and small serif fonts, as detail will be lost.

Developer environment

While the chumby runs Flash Lite, it's actually a fairly normal Flash Player, and will run content most created for Flash 8 and earlier. It's not necessary to specifically publish for Flash Lite 2 or Flash Lite 3 in the Flash development tools unless you plan on using the features specific to Flash Lite. Most of these features are designed more for mobile phones and thus don't apply to chumby devices.

The most common and complete development tools for Flash are those available from Adobe, however, there are several other third-party programs that will generate Flash movies. Any version of Adobe's Flash products is capable of producing widgets for chumby, not just the latest version (currently Flash CS 3 Professional)

Performance and optimizations

The protoype chumby has a 350Mhz ARM9 processor - similar in performance to a low-end Pentium desktop. There are certain tricks and techniques that can make the difference between a sluggish movie and one that works smoothly.

  • Change property values only when necessary. The very act of changing a property can result in a redraw of that object, even if the value itself hasn't changed. Be sure to check to see if changing the property is necessary before changing it - for instance, don't change the _rotation value of the hour hand of a clock if it hasn't actually moved.
  • Change dynamic text only when necessary. If the text isn't actually different, don't change it.
  • Reduce the size of images by playing with compression settings. Make the images as small as possible with acceptable quality.
  • Reduce the size of audio by playing with compression settings. As with images, try for small size with acceptable quality.
  • Simplify vector graphics. See if you can use Flash's curve simplification to reduce the number of points and curves. For static graphics, you might even be better off creating bitmaps and using them instead.
  • Avoid layered translucent areas. Piling on a lot of translucency is expensive. You may be better off using PNGs with these effects already composited. If you can use masks, use them.
  • Avoid gradients. Gradient fills, particularly radial gradients and gradients with translucency, are expensive. Use them sparingly.
  • Avoid full-frame animation. Animation that changes large areas of the display can slow down the animation - try to keep the percentage of the screen being updated as small as possible for any given frame.
  • Use tweening sparingly. Try to keep tweening to one or two small objects at a time. Don't use shape tweens unless absolutely necessary - they're extremely expensive to compute.
  • Avoid processing a lot of data in a single frame. Try queuing data in an array and process one item per frame. It complicates things a little bit, but will result in smoother operation and will avoid Actionscript timeouts.
  • Avoid lots of text. Lots of small text can be expensive to render. The chumby is meant to be read from a few feet away, so you really should be using large text anyway.
  • Don't do too many network fetches at the same time - Flash Lite limits the number of fetches intiated on the same frame, and the total number of fetches in progress at the same time. Considering queuing fetches and intiating new fetches when the previous ones complete.


Widget Environment

Widgets are given a set of parameters about the environment of the chumby: For example:

this['_chumby_chumby_name']='TestChumby'
this['_chumby_widget_instance_id']='12121212-1212-1212-1212-121212121212'

The _chumby_chumby_name field contains the name of the chumby as assigned by the user. The _chumby_widget_instance_id is the unique GUID assigned that that particular instance of the widget in that particular channel for that particular user.

A widget that has a configuration dialog may create additional values - for instance, a horoscope widget might create:

this['sign'] = 'Scorpio'

Security

The widget has a security sandbox similar to a movie running in a browser plugin - an external source of content should have an appropriate crossdomain.xml file to expose content to the widget. For more information, please see the following Flash Player Technotes and Articles:

If you wish you widget to be compatible with "Virtual Chumby", in addition to funntioning on the device itself, then you should build widgets so they can be loadMovie()'d into another movie at some level other than _level0 - this means you should try to avoid adding random properties to _level0, _global, or the built-in objects. If you wish to use _root, then you shold set _lockroot = true on the main timeline of your widget movie.

In general, widgets should be under 100K in size in order to reduce download time and use the minimum of storage in the device itself.

Testing a widget locally

The chumby itself has no substantial local storage, so you should not expect to store widgets on the chumby. If you want to run Flash movies on the device itself without uploading to the chumby servers, you'll need to do it from a USB mass storage device plugged into the back of the chumby.

Here's how to do it without bringing up a console:

  • Get a USB dongle, formatted as VFAT, and put your Flash movie on the top level.
  • Create a script file on the dongle called "debugchumby" with the contents
#!/bin/sh
chumbyflashplayer.x -i /mnt/usb/<name of flash file>.swf

The file must use UNIX-style line terminations, and the last line must be terminated.

  • Plug the dongle into the USB port on the back of your chumby
  • Power it up - after the opening animation, your widget should run

Notes for OS X users (and those less in the know)

  • Most USB thumb drives come out-of-the-box fat16 or fat32 formatted (same thing as VFAT) and work just fine on OS X
  • The script file can be created in Textwrangler, a free text editor. Files can be saved with UNIX line encodings from it.
  • The script file should have NO extension (like .txt etc.)

Uploading a widget

You can upload a widget to our service which you can then use on your chumby. You will need to have the SWF for your widget, and a 80x60 pixel JPEG thumbnail image which represents your widget.

  • Create an account with chumby.com, if you haven't already
  • Log in - you will probably be redirected to a page that offers to let you register a chumby, or a list of your current physical chumbys
  • Select the "upload a widget" item from the "widgets" menu
  • Fill in the information

Widgets should be under 100K in size in order to reduce download time and use the minimum of storage in the device itself.

A widget uploaded using this mechanism will show up in the widget mix configuration, and can be selected just like any other widget, however, these uploaded widgets will only be accessible from your account. If you'd like your widget to be visible to everyone, turn on the "Public" radio button on the upload page - your widget will be reviewed by a Chumby employee.

Widget durations

As an author, you're limited in the duration your widget can run, a maximum of 999 seconds (around 15 minutes). It it not possible (without special permission from Chumby) to author a widget that will run an indeterminate amount of time, or forever. The user, however, does have a few simple options to choose to make a widget run "forever" - select "Forever" from the "customize" menu when they add a widget, put the widget alone in a channel, or press the "stay" button in the Control Panel.

It it possible, however, to indicate that a widget has completed its operation before it would naturally time out. Simply set the variable "_chumby_widget_done" to "true" on the main timeline of your widget movie - the Control Panel will detect that and immediately expire the widget's timer.

Several developers have argued that their widgets are so important to users that they must be allowed to run forever. As policy, we've decided to have the user make that determination, not the author.

Example widgets

Here are some Flash source (.fla) files for various types of widgets:

Using a secure shell (SSH) console to test widgets

To bring up an SSH console, you need to turn on the secure shell daemon (sshd) on the chumby. There area couple of ways of doing this:

From the Control Panel:

  • Bring up the Control Panel suing the squeeze sensor on the top of the chumby
  • Select the "Settings" button
  • Select the "Chumby Info" button
  • Select the "pi" symbol hidden in the upper right corner of the screen
  • Select the "SSHD button

From a USB flash drive:

  • On the USB flash drive, create a file called debugchumby, with the following contents:
#!/bin/sh
/sbin/sshd
  • Boot the chumby with that installed in one of the external USB ports

You shoud probably also put the widget you wish to test on your USB flash drive.

At this point, the chumby should allow you to log in using an ssh client. Under Windows, we recomment PuTTY, and both MacOS X and Linux typically have ssh clients builtin.

Using your ssh client, log in to the IP of the chumby, with the username "root". You should see some ASCII art of the chumby logo.

Now you need to stop the currently playing Flash player, whcih is running the Control Panel and widgets - at a prompt, type:

stop_control_panel

The touchscreen and other sensors should stop responding.

At this point, you should be able to launch your widget. For instance, if your widget is called "widget.swf" on the flash drive mounted at /mnt/usb, then you'd type:

chumbyflashplayer.x -i /mnt/usb/widget.swf

You can use ctrl-C to exit the player.


Flash Access to Sensors

The Chumby Flash Player has some ASnative calls to access the various sensors

NOTE: These are very likely to change in future releases - use at your own peril.

NOTE: If you are compiling your widgets in AS2, you will have to change the syntax of the ASnative calls in order to compile without errors:

_bend = ["ASnative"](5,14)();         // this will return a value
_accelerometer = ["ASnative"](5,60);  // this will return a function object


Touchscreen

Normally, the touchscreen is calibrated by the user using the Control Panel, however, raw coordinates are available.

_rawX = ASnative(5,10); // get the last raw touchscreen X coordinate
_rawY = ASnative(5,11); // get the last raw touchscreen Y coordinate
trace('x:'+_rawX()+', y:'+_rawY());

Display

This allows you to dim or turn off the display, perhaps for power reasons.

_getLCDMute = ASnative(5,19); // get the value of the LCD "mute"
_setLCDMute = ASnative(5,20); // set the value of the LCD "mute"
trace(_getLCDMute());
_setLCDMute(1);

There are three possible values:

_setLCDMute(0); // full on
_setLCDMute(1); // dim
_setLCDMute(2); // full off

Speaker

This cuts off audio to the built in speakers, but still allows audio through the headphone jack.

_getSpeakerMute = ASnative(5,17);
_setSpeakerMute = ASnative(5,18);
trace(_getSpeakerMute());
_setSpeakerMute(1);

There is a system daemon that does this automatically, so you'd have to kill that in you want to control this yourself.

Mic

A Mic has been added instead of the light sensor.

Code to come.

DC Power

This tells you whether the device is connected to the DC power adaptor, or if it's running on the 9V battery. Currently, the Control Panel will turn off the display if the device is running on battery.

_dcPower = ASnative(5,16);
trace(_dcPower());

Accelerometer

The accelerometer can be found in the "Katamari" model of the chumby. The force values are read-only, and range 0-4095, with zero point (no force) at 2048, and a range of approximately -5 to +5 G. The "current" values are the instantaneous value of the sensor, the "avg" values are a running average of the last couple of readings (which will be somewhat smoother), and the "impact" values represent a change in force above a certain threshold. The "impactTime" can be use to detect when the impact occured. The "impactHints" value is used internally by the driver for housekeeping and is currently undocumented. A "Foo" chumby should return 0 for all values. Make sure you have:

 _accelerometer = ['ASnative'](5,60);

Somewhere in your code.

 version = _accelerometer(0);
 timestamp = _accelerometer(1);
 currentX = _accelerometer(2);
 currentY = _accelerometer(3);
 currentZ = _accelerometer(4);
 avgX = _accelerometer(5);
 avgY = _accelerometer(6);
 avgZ = _accelerometer(7);
 impactX = _accelerometer(8);
 impactY = _accelerometer(9);
 impactZ = _accelerometer(10);
 impactTime = _accelerometer(11);
 impactHints = _accelerometer(12);

A quick way to convert a component to a multiple of G would be:

gValue = rawValue*0.0024489559928062587-5;

Note that the value of G varies depending upon your location - the above equation represents an average.

Bend Sensor

This is the switch sensor on the top of the chumby device

_bent = ASnative(5,25); // get the "bent" flag (0/1)
trace(_bent());


Video

The optimal video settings for the production chumbys using FlashLite 3 are:

  • Frame rate: 12fps
  • Video data rate: 220
  • Audio data rate: 32kbps (mono) or less
  • Width: must be less than or equal to 320
  • Height: must be less than or equal to 240


Most Common Problems

The most common problems with widgets that seem to fail on the chumby are:

  • The movie is the wrong version - FlashLite 3 will not play Flash 9 movies.
  • The movie does not have sufficient security privileges - crossdomain files may not exist on the external content servers
  • The movie has the wrong dimensions - the widgets should be 320x240