Saturday, December 19, 2015

Exploring the Onion Omega

Some backstory (or the importance of being engaged)

I'll be honest, I felt a bit burned out on new small Internet of Things devices after my previous experience with the Belleds Q.  The Q shipped, but was immediately abandoned by the development team and left to die.  I even tried to help keep things moving by creating some projects that I documented here and setting up a forum called IoTTalk to bring the folks hacking on the Q together, but it wasn't enough without the support of the project's founders who moved with no forwarding address.

But a few months back, I joined in on the Kickstarter for the Onion Omega, a platform for prototyping and building Internet of Things devices.  I'm happy to say that my experience with Onion couldn't be more different!  The founders have been incredibly involved and responsive, interacting with the community on a daily basis.  Seeing what people are already doing with this new platform and being part of the community is truly exciting!

Now onto the Onion Omega

The Omega is a tiny development platform based on an ARM System On a Chip (SOC).  It includes a 400MHz processor, 64MB of RAM, 16MB of onboard flash storage, WiFi, and a number of expansion pins that can be used for a multitude of purposes, all costing about $19.  It barely sips power, being able to run for several days off of a common cell phone external battery via its USB power input.  Some existing expansions provide USB ports, Ethernet networking, relays, and even a tiny OLED display!

The Omega itself is about 44mm/1.75" along its longest axis, or about 12mm longer than a standard SD card. 


The best part for me is that it runs Linux natively.  I've been hacking on Linux for a couple of decades at this point and am usually more comfortable with a command line than a soldering iron, so having a platform that I can start using from a familiar environment is huge for me.

The Omega provides a WiFi access point out of the box and if docked to an expansion with a USB port also provides a serial console and provides both ssh/console access and a web interface.  This makes it easy to start using with no special tools or setup required.  It runs OpenWRT, a Linux distribution commonly used in wireless routers, meaning it has access to a wide array of software already packaged.  (At the moment, there's still some ongoing effort to recompile all those packages for the Omega, but even lacking existing ones the Onion team has great instructions and support for cross-compiling and pushing files over to the Omega.)

So what can it do?

Toy projects

I've done a couple of toy projects with the Omega already.  To play with the platform, the first thing I did was set up a script to poll the wireless networks within its range every 5 seconds and write them to a file.  I then plugged the Omega into an external cell phone battery and took a brief walk around my neighborhood to see what I would see.  The code for that and the simple (and ugly!) parser is in a repository on Github.  (It can even display the current summary status on the OLED expansion!)

I've written up a few more tutorials (mostly aimed at people with limited Linux experience) over at the Onion Community site.  For example, by installing a single package and using simple shell commands, you can blink the onboard LED in a Morse code message.

Save some money

Slightly more usefully, I used some shell scripts and an Omega to act as a WiFi-enabled remote control for the serial port in my home projector.  This is hundreds of dollars cheaper than any existing wireless serial system I could find and will allow me to connect my projector to a home automation system.

An Onion Omega and USB to serial adapter plugged into my video projector allowed me to duplicate a wireless serial adapter that sells for hundreds of dollars.


The real beauty of this is that I didn't have to do any hardware hacking.  All of the functionality is exposed through Linux, meaning a few shell scripts or a Python program is all I need to use the functionality of these real-world devices.

What's next?

After I mount my projector on the ceiling and have a single button to dim the lights, turn on the stereo receiver and projector, and load up Netflix, I'll need a new project.  I wonder if anyone is looking at porting Snappy Ubuntu to the Omega...

(There were over 500 unique unsecured access points in range during my 20 minute walk, and an even larger number still using the long-deprecated WEP security system that would be basically effortless to break.  Upgrade your routers, people!)

Sunday, February 22, 2015

A bit more on the Q

I poked at the Q Station and my light bulbs a bit more today, and ended up with a couple of Bash scripts that might be fun or amusing. One of them is a very simple GUI for changing bulb colors, and the other sends Morse code messages by blinking the light on and off. (Thanks to my partner Andi for thinking of that one!)

Bulb names are configurable but I'm lazy.

Yes, it's just the Zenity color selection dialog.

These are quick and dirty scripts using Zenity, but they work (at least under a default Ubuntu install) and make playing with the bulbs a lot easier.   I haven't tested this on any other Linux distributions but as long as Zenity and netcat are available they should work.

What I hope is slightly more interesting is that I've tried to separate out some simple but useful functions for working with the Q.  I hope these will be useful to other people in playing with the hardware.  There are Bash functions for changing the color of the bulbs, turning them on and off, and building the JSON string that the Q expects via its UDP interface.  (It's painful and error-prone to do this by hand.)

The code is up on github and can be cloned with 'git clone https://github.com/mccollam/belleds.git'.  If anyone uses this or has any suggestions I'd love to hear about it!

Saturday, February 7, 2015

The Q API

I wrote about the Q and my thoughts about it at a general level recently.  I've also been tinkering with making it actually do interesting things via the API that it exposes.

The API is part of a beta firmware update, and it shows.  For example, right now the command to get a list of connected light bulbs locks up the device and requires a reboot.  I'm sure that will get fixed, and fortunately I can just read the serial numbers off of the physical bulbs themselves in the meantime.  But it does mean that it's basically impossible to write a consumer application to the API right now.

The API


The API that the Q exposes is pretty simple: it listens on a UDP port for messages in JSON.  It then returns nothing, a string, or JSON data.  It's a bit warty; anything communicating with it needs to expect different formatted data depending on the action.  I'd prefer to see it always return JSON, including when it doesn't understand the request.  Unfortunately, it never returns anything if there is an error and some commands don't get a success confirmation or even acknowledgement.  So it's possible that you think something has failed when it has succeeded or vice-versa.   I really hope that changes.

It's also not as well documented yet as I'd like.  There are fields that are entirely explained right now.  For example, the API to control the lights themselves contains fields like "effect", "matchValue", and "iswitch" which are undocumented.  So far I've determined that setting effect to "9" makes the bulb do what you say, a few other values (e.g. "8") makes it turn white no matter what color is specified, and anything else seems to have no effect at all but receives an "ok cmd!" response from the Q station.

Tinkering quickly


While it's possible to write a C, Python, Perl, etc. program as a harness to play with the Q, that's more work than I wanted to go through to just poke at it.  Plus I'm lazy and want to just do things from Bash wherever I can.

Since the Q just expects JSON messages on a given UDP port, it's possible to use netcat to do this without writing anything extra.  As an example, this will simply ping the unit and determine if it is working:

$ echo '{ ping" }' | nc -u 10.1.10.182 11600 -q 1
belled,MQ1AC43700000669,172.16.0.1,1

(This is using my Q's IP address.  You'll want to replace 10.1.10.182 with your unit's IP address.)

The "-q 1" parameter to nc tells it to disconnect after nothing is sent for one second.  Once I had this in my command history, it was a bit more convenient than hitting ^C to end the connection.

I've also used this to change a bulb's color:

$ echo '{ "cmd":"light_ctrl", "r":"155", "g":"20", "b":"255", "bright":"100", "sn_list":[ { "sn":"MD1AC44200001127" } ], "iswitch":"1", "matchValue":"0", "effect":"9"}' | nc -u 10.1.10.182 11600 -q 1
ok cmd!

(Again, my Q's IP address and my light bulb's serial number won't work for you, so be sure to change those.)

netcat allows simple interaction with the Q to interactively play with the API without having to bother with writing a full script and deal with sockets yourself.

Light bulbs with computers inside: a review of the Q

Having a weekend where I'm neither traveling for work nor booked solid socially means that I have some time to play with my nifty Belleds lighting system, the Q.  There's a beta firmware update available that exposes a JSON API, so I can actually make it do things without using the (frankly awful) mobile app they provide.  This means that for the first time, my Internet-accessible light bulbs are actually usable!

... Well, they'll be more usable when the firmware and API have the bugs shaken out (a bit more about which here).  Right now there are a few issues with it that prevent any real development against it.  But I'm confident that will come.  In the meantime, I've got some thoughts about the device itself.

The Q hardware


The Q itself is pretty straightforward.  It's basically a tiny wifi router running OpenWRT.  It exposes a very simple web interface that seems designed for the iPhone browser that really basically just allows you to turn the wireless functionality on or off and to play music, which will make the connected light bulbs play a light show.  Mine came with three bulbs and the various connectors, etc. needed to plug it all up.

And all packed in squishy foam.

The Q station itself is pretty small, and has an ethernet port, a USB port (presumably for connecting media players or USB drives full of music), and a headphone port (for connecting speakers).  The unit itself is powered by a micro USB cable, which is a nice touch.



It has an open unpassworded telnet server that logs directly into the root account.  While this can be disabled and passworded, nothing in the documentation mentions it.  So, kudos for being open, but a huge slap on the wrist for being insecure by default and not even telling anyone.  (Another thing I hope will be addressed in the future.)

The box itself is unsurprisingly light and running busybox.

Root out of the box.

overlayfs so losing power won't break anything

It is, in fact, configured for Alljoyn.

Default software


As I mentioned, the default interface it exposes is almost featureless.






Interestingly, there are some files and additional web pages on the device that aren't directly exposed.  I think some of them are leftovers from earlier devices -- the firmware seems to be made by a Chinese company that has been making embedded devices with web interfaces for a while.  A few of the more interesting ones are below:

This seems to be a much more comprehensive and configurable music service page.

MAC address cloning for weirdly restrictive networks?

Firmware updates.  There are lots of non-localized Chinese files floating around in the web directory on this device.

This seems to be some sort of testing tool, but I'm not quite sure for what.

More interesting software


As I mentioned before, the Q is running OpenWRT.  This is running locally on port 80 and seems to have all of its functionality present.
This would make a decent home router.

There's also some real weirdness in a few daemons running on the box.  For example, it pings a Chinese site (baidu.com) to determine if it's connected to the network.  Unfortunately, the script that does this restarts the networking service on the router if it can't reach Baidu, meaning that if you are blocking that for any reason or are on a network without outbound connections or DNS, the box will disconnect and reconnect repeatedly.  Yet another thing that I hope to see fixed.

Repeat after me: pinging a website outside of your control is not the same thing as a connection monitor.

Summing up


The Q is definitely not quite ready for prime time, but I think it could definitely get there with a bit more time and polish.  I'm personally excited about its potential, and especially the fact that it speaks Alljoyn.  I think this is the future of connected devices, and we're seeing only the barest fraction of what is to come.  (And also I like light bulbs that make pretty colors that I can change with a remote control.)

Ooh, violet.  Also, my partner made this lamp with a forge, a hammer, and a MIG welder.

Friday, January 23, 2015

Building and running the Alljoyn 'About' sample application

I got some nifty color-changing networked light bulbs via a Kickstarter campaign recently.  Hopefully I'll have more to say about those later when I have a bit more time (as I took some unboxing shots and poked around in the router they shipped with it and found some curious things).  But in the meantime, I've been poking around at the Allseen Alliance's Alljoyn framework.

Alljoyn is a framework that allows all sorts of nifty communication and collaboration between devices.  Imagine getting a new window-mounted air conditioner and having it and your thermostat immediately start talking to each other and getting your house to the right temperature, or your lights dimming in response to you starting a movie on your television.  There are all sorts of cool things this sort of communication could allow.

But for now I'm just trying to get it built and working with my light bulbs.  Tonight I spent a little bit of time getting it built and running the simple 'About' sample application that ships with it.  I thought the notes I took might be useful if anyone else starts playing with it. And unfortunately some of the docs about running the 'About' samples are a bit wrong, so maybe this will help someone out.

And if you do play with Alljoyn, please let me know!  Double bonus points if you can point me at some tutorials that don't start with the assumption that you've read the whole codebase and every document ever produced.  I just want to make some light bulbs blink!

Set up the environment

I used the following:

  • Virtual machine (VirtualBox) with 2x x86_64 CPUs, 1GB RAM, 16 GB disk, bridged network
  • Ubuntu 14.04 Server
  • Default packageset plus OpenSSH server
  • Applied full updates (apt-get update ; apt-get upgrade) as of 23 Jan 2015 and reboot

I initially started with libvirt but after a few minutes of trying to convince it to bridge the network device, I decided to just go with VirtualBox rather than spend all night tinkering with that.

Install prerequisites

git:

sudo apt-get install git
git config --global user.email "email@server.tld"
git config --global user.name "User Name"

Repo:

(per http://source.android.com/source/downloading.html#installing-repo)

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

Build tools:

(per https://allseenalliance.org/developers/develop/building/linux)
[NB: ia32-libs was not available in the package archives but didn't seem to be necessary]

sudo apt-get install build-essential libgtk2.0-dev libssl-dev xsltproc libxml2-dev scons libssl-dev #ia32-libs

Grab sources

Per https://wiki.allseenalliance.org/develop/downloading_the_source

mkdir -p src/alljoyn
cd src/alljoyn

# Uncomment other versions below if you want something other than 14.06
#repo init -u https://git.allseenalliance.org/gerrit/devtools/manifest
#repo init -u https://git.allseenalliance.org/gerrit/devtools/manifest -b refs/tags/v14.06 -m versioned.xml
repo init -u https://git.allseenalliance.org/gerrit/devtools/manifest -b RB14.06
repo sync

Build samples

export AJ_ROOT=`pwd`
cd core/alljoyn
scons BINDINGS=cpp WS=off BT=off ICE=off SERVICES="about,notification,controlpanel,config,onboarding,sample_apps"

Run 'about' sample

(per https://allseenalliance.org/developers/develop/run-sample-apps/about/linux)

cd $AJ_ROOT
export TARGET_CPU=x86_64

# NB: The following are in the docs but are wrong.  Corrections below.
#export LD_LIBRARY_PATH=$AJ_ROOT/core/alljoyn/build/linux/$TARGET_CPU/debug/dist/cpp/lib:$LD_LIBRARY_PATH
#$AJ_ROOT/core/alljoyn/build/linux/$TARGET_CPU/debug/dist/cpp/bin/samples/AboutService

export LD_LIBRARY_PATH=$AJ_ROOT/core/alljoyn/build/linux/$TARGET_CPU/debug/dist/cpp/lib:$AJ_ROOT/core/alljoyn/build/linux/$TARGET_CPU/debug/dist/about/lib:$LD_LIBRARY_PATH
$AJ_ROOT/core/alljoyn/build/linux/$TARGET_CPU/debug/dist/about/bin/AboutClient