Difference between revisions of "Developing widgets for chumby"
(→Security) |
(→Testing a widget locally) |
||
Line 78: | Line 78: | ||
=Testing a widget locally= | =Testing a widget locally= | ||
− | The chumby itself has no substantial local storage, so you should not expect to store widgets on the chumby. | + | 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. | * 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 | * Create a script file on the dongle called "'''debugchumby'''" with the contents | ||
#!/bin/sh | #!/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. | 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 | * Plug the dongle into the USB port on the back of your chumby |
Revision as of 10:06, 1 August 2007
Contents
- 1 Summary
- 2 Developer environment
- 3 Performance and optimizations
- 4 Widget Environment
- 5 Security
- 6 Testing a widget locally
- 7 Uploading a widget
- 8 Using "virtual chumby"
- 9 Example widgets
- 10 Using SCP to Test Applications
- 11 Iterating With chumbyflashplayer.x
- 12 Flash Access to Sensors
- 13 Most Common Problems
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 contrian 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:
- External data not accessible outside a Macromedia Flash movie's domain
- Security Changes in Macromedia Flash Player 7
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 "my widgets" from the "my chumby" menu
- Click the "upload a widget" link
- 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. In the future, you'll be able to share these widgets with your friends, and even submit them to chumby for public access.
Using "virtual chumby"
The website has a mechanism for testing widgets in a Flash-based simulation of the widget playback of a real chumby. You do not need a physical chumby to utilize this functionality.
- 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 "my widget mixes" from the "my chumby" menu.
- Click the "virtual chumby for this widget mix" link for one of the widget mixes - you should have at least one called "Default".
You can add widgets to any given widget mix. Both the real and virtual chumbys will check in for updated widget mixes every five minutes or so, or you can simply restart the Flash movie by reloading the virtual chumby's page.
Example widgets
Here are some Flash source (.fla) files for various types of widgets:
- Sample Clock Widget
- Sample Binary Clock Widget
- Sample RSS Widget
- Sample Webcam Widget
- Sample Banner Widget
- Sample Accelerometer Widget
Using SCP to Test Applications
Do you know the joke about the how to avoid getting lost and stranded on a forest trek? Bring some vermouth and gin with you, and if you get lost, sit on a tree stump and mix 3/4 cup gin with a 1/4 vermouth and from all around the forest, people will jump at you and say, "that's no way to mix a martini"... and you're saved!
In a similar vein, I'm putting up how I was able to get a edit/compile/debug cycle going for the Chumby in the hopes someone who can improve it, "jumps out".
I was able to develop and test a few FlashLite apps using the method of placing a file on the USB key and moving and back and forth to the Chumby. This got old quickly, so I found this (somewhat) better workflow. Although SSH is available using the method above, so you can remotely open a shell from your development workstation, scp is not on the chumby.
- Create a VFAT formatted usb key as described above.
- Create a executable file on the dongle called "debugchumby" with the contents
#!/bin/sh /sbin/sshd
- Test that this is working by restarting the Chumby and ensure you can ssh into this as root from your development box. Since root doesn't have a password, it's a good idea to remove the key and reboot after you finish development.
ssh -l root chumby
You should get a root prompt at this point. Note, I've got dnsmasq running so my chumby has a 'name', it might just be an IP address for you (e.g. ssh -l root 192.168.0.XXX)
- Note where your usb key is mounted on the chumby - it's /mnt/usb for me (and likely for you)
- Put usb key back in your development box.
- Get a copy of scp either by compiling it for ARM-linux, or find a precompiled ARM version. For instance, for Zaurus, there an scp in the OpenSSH package: http://www.killefiz.de/zaurus/showdetail.php?app=1035. The files can be unzipped & untarred, eventually locating scp.
- place scp in the usb key root directory.
- place usb key back in the chumby, and then reboot the chumby again
- cd to /usr/bin on the chumby and create a symlink to the scp on /mnt/usb/. You could also just copy scp to /usr/bin, and I'm sure there's some clever way to set the path to have the /mnt/usb/scp, but I didn't bother (can be done with
PATH=$PATH:/mnt/usb
)
(on Chumby)
cd /usr/bin ln -s /mnt/usb/scp /usr/bin cd /mnt/usb chmod +x scp
- from your development box terminal window, as sudo (or root), you should now be able to copy a file
sudo scp <filename> chumby:
- from your chumby terminal window, you should now see the file you've just uploaded in /mnt/usb/<filename>
Good luck! This is much easier than moving the usb key back and forth!
- Notes: sftp_server can be done similarly. This would be nicer because there's some nice GUI front-ends for it. however, I'm not able to get it working with the few minutes I've spent on it. I believe it has something to do with the sextopus ascii logo that is creating a problem for the sftp initiation, according to some googling on sftp_server failure modes. I'd like to temporarily remove this ascii art and see if it helps (where is it being called from?). Or maybe not...
- Clearly you can save a step above by putting the scp on the key first. I thought it was worth getting ssh running first...
- Samba would be very nice, you could save the flash swf on the chumby right from Flash Professional.
- File Access Monitor to detect newly dropped SWF file, and automatically reinvoke Chumbyplayer.x
-hbchumby
- The ascii art is at: /usr/local/etc/sshd_banner
To remove: SSH the Chumby, and use vi: (vi /usr/local/etc/sshd_banner)
Iterating With chumbyflashplayer.x
Now that you can move files to the Chumby easily, how can you iterate?
What I did is create a similar script on the Chumby (in /mnt/usb
) that kills the current Chumby player and restarts it with my test application:
#!/bin/sh rm /tmp/flashplayer_started killall chumbyflashplayer.x /usr/bin/chumbyflashplayer.x -i mytestapp.swf
The chumby has a watchdog timer that looks for lockups in the FlashLite Player or Control Panel - deleting /tmp/flashplayer_started
prevents it from relaunching the player.
-hbchumby
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 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);
The "brightness" values are used by the Linux kernel to automatically dim the display. There are 16 subranges, each with its own threshold and associated brightness values.
_getBrightnessForRange = ASnative(5,21); // get the display brightness for the indexed light level range _setBrightnessForRange = ASnative(5,22); // set the display brightness for the indexed light level range for (i=0;i<16;i++) trace(_getBrightnessForRange(i)); _setBrightnessForRange(5,255);
_getBrightnessThresholdForRange = ASnative(5,23); // get the threshold for the indexed light level range _setBrightnessThresholdForRange = ASnative(5,24); // set the threshold for the indexed light level range trace(_getBrightnessThresholdForRange(5)); _setBrightnessThresholdForRange(5,24);
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);
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
Not include in the Production Units
From Forum Post [1]: "...the bend sensor has been replaced by a switch. The bend sensor was too imprecise, tended to be damaged by overethusiatic squeezing, and was available from only a single source."
The bend sensor is currently used by the Control Panel to bring up the controls.
_bend = ASnative(5,14); // get the "last" bend sensor reading trace(_bend());
_bent = ASnative(5,25); // get the "bent" flag (0/1) trace(_bent());
_bendAverage = ASnative(5,28); // get the 10-second running average of the bend sensor
Light Sensor
Not included in Production Unit
See [2]
_light = ASnative(5,15); // get the ambient light sensor reading trace(_light());
Most Common Problems
The most common problems with widgets that seem to fail on the chumby are:
- The movie is the wrong version - FlashLite 2 will not play Flash 8 or Flash 9 movies.
- The movie does not have sufficient security privileges - crossdomain files may not exist on the external content servers
- The movie is not written to be loaded into another movie - this is often the case with movies with preloaders that reference _root or _level0 - if you need something globally accessible, consider making it a property of Object, MovieClip or some other built-in object. For Flash 7 movies, you can also do "this._lockroot=true" on your main timeline to treat it as _root.
- The movie uses device fonts - be sure all the required fonts are embedded
- The movie has the wrong frame rate - the chumby wants widgets to be 12fps
- The movie has the wrong dimensions - the widgets should be 320x240
- The movie contains Flash Video - FlashLite 2 does not support Flash Video