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

Friday, September 19, 2014

Guaranteed minimum income?

Seeing this MetaFilter post, I wonder if we're starting to approach Gandhicon 3 ("then they fight you") on the idea of a guaranteed minimum income.

I sincerely hope so. I honestly don't know if it's a good idea or not, but it would be great to see it discussed seriously. (And seeing it brought up in The Atlantic and actually kicked around in Switzerland seems like a good step in that direction.)

Intuitively, it seems... unwise.  Wouldn't everyone just stop working, letting the world grind to a halt?  But there are indications that when it was tried in Canada, that wasn't the case, with hours worked dropping only about 1% for men and between 3-5% for women, while hospitalizations decreased and school attendance increased.

(On the gripping hand, I may have been heavily influenced by being raised Orthodox Trekkie.)

I suspect this will become more and more of an issue as jobs continue to be lost to automation.  When self-driving cars are common, will we still have truckers?  That's 3.5 million jobs in the US alone.  And then there are the taxi drivers, bus drivers, etc.  And that's just one industry.

Something to think about.

Sunday, July 20, 2014

Using Netflix in XBMC with Ubuntu 14.04

I use XBMC to run my home theater system.  It's a great piece of software that can be configured to look and act in a huge variety of ways while remaining straightforward to use and set up.  One of its great features is an add-on system with a rich set of third-party multimedia tools.

Until recently, it was pretty straightforward to have a nice experience in XBMC under Linux using a combination of XBMCFlix and Pipelight.  Pipelight provides a way to run the Silverlight video streaming libraries under Linux and XBMCFlix launches the Netflix player in a full-screen Chrome window.  Installing these add-ons meant that Netflix worked well[1] and integrated right into XBMC.

Recently, however, Google has dropped support for the Netscape Plugin API (NPAPI) which Pipelight relies on to make Silverlight work.  Since XBMCFlix launches Chrome and can't be configured to use Firefox, this means that upgrading to a recent version of Chrome breaks Netflix support in XBMC on Linux.

Fortunately it's easy to work around this and trick the Chrome launcher used by XBMC to use Firefox instead.  It's a dirty hack and isn't a great solution for a general purpose desktop (especially as it involves uninstalling Chrome, which you might want to keep) but it does the trick on my entertainment system.

Here's how to do it:

  1. Uninstall Chrome or Chromium.  (On Ubuntu or other Debian-based distribution, you can do this in the Software Center or by typing "sudo apt-get remove google-chrome" (or "sudo apt-get remove chromium-browser" in a terminal.)
  2. Launch Firefox, put it in full-screen mode by pressing F11, and exit it with Alt-F4.  This will make it default to full-screen next time it's launched.
  3. Using your favorite text editor, create a script in your home directory called "google-chrome".  (It's important to make it all lower case and include the hyphen.  It needs to be named exactly "google-chrome", nothing else.)
  4. Copy and paste the following into the text file:

    #!/bin/bash

    for i in $@; do
        if [[ $i =~ ^http ]]
        then
          urls="$urls $i"
        fi
    done

    firefox $urls
  5. Save the file.
  6. Make your script executable so it can be launched by XBMC by opening a terminal and typing "chmod a+x google-chrome".
  7. Put your script where the launcher for Chrome would normally live by typing "sudo mv google-chrome /usr/bin".
Once this is done, you can install Pipelight and XBMCFlix in XBMC as you normally would.  When XBMCFlix goes to launch Chrome, it will launch Firefox instead.

Again, this is a bit of an ugly hack, but if you have a PC that does nothing but run XBMC this will get you up and working quickly.  There are ways that a script like this could be exploited, but the odds of Netflix including one in a URL to target Linux users of XBMC are pretty low, and if you have a single-purpose home theater system there's probably not much damage that could be done anyway.

Now go enjoy some movies!


1: Well, after you lie to Netflix about what operating system you're running. It's 2014 and they are still doing browser user-agent sniffing as if it were useful or effective.

Monday, July 7, 2014

Hiring? Vet your application process! And please don't use Taleo.

I've written a bit before on this topic from my experiences in trying to hire people.  But now I want to say something from the point of view of a job seeker.

Your application system is part of your culture


When hiring, remember that the job listings on your website are an indication of your values and culture.  If your application process is hostile and bureaucratic, applicants will assume working there will be soul-crushing and awful.

In some areas, you can get away with this.  The job market is tight in many sectors right now.  But in others, companies are desperate for talent but are turning it away at the gate.[1]  If you make it difficult for the people you want to hire to apply, they will go somewhere else!  It's like opening a store and putting barbed wire across the door; why would I go somewhere that I'm obviously not wanted?

When designing your application process, walk through it and ask yourself "would I apply for a job here with this process?".

If you're looking to hire people, please don't use Taleo.


(Warning: this section is a bit ranty.  But it's true and a great example of how bad things can be when nobody pays attention to the applicant side of a process.)

Taleo is a "talent management" system, meaning that it's supposed to handle all the easily automatable things around posting a position and tracking applicants.  I don't know how well it performs these functions from the HR/business side, but I have experienced it from the job seeker side several times.  And that experience is universally awful.

Let me give a real-world example of what a job seeker sees when they use your Taleo application system.  First of all, they get absolute state-of-the-1990s web design.  Ugly "hold CONTROL (or the clover key on a Mac)" instructions in tiny boxes that require painful scrolling and careful clicking.  One mistake and the 12 selections you've made in the 4-line high box with 60 options goes poof!

Maybe they want to search instead.  Searching is a thing that people like, right?  Especially if you treat each word as its own search term, so "sales engineer" gets anything with the word "sales" or the word "engineer" anywhere in the posting.  How convenient!

If they've made it this far though, your job seeker has a long (and unsortable) list of possible matches.  But they can't open each match in a new tab or window to compare them, as the links get built with Javascript.  Even better, the real URL to the job is never written to the URL bar in the browser, so you can't open the job in the same window and copy the URL to a new one.  One job at a time is all you get, and when you go back to the list the page jumps to the top, losing your place.  (This one in particular got me when I intended to apply to a large company.  I opened about 10 promising titles from a list of several hundred in new tabs, only to find they were all a generic error page once I was done paging through the available jobs.  Guess where I didn't end up applying to any jobs?[2])

There's much more; Taleo asks that a resume be uploaded but then forces the applicant to put the same data into multiple small ugly boxes, forces a slow process with seemingly infinite page loads, and eventually acts as a black hole where applicants can't check their status or follow up on their applications in any meaningful way.  In short, whether intentionally or not, it's a system designed to prevent people from applying for jobs and to leave them feeling dispirited and angry once they've done so.

Fixing things


What's the ultimate goal of a hiring process?  It's not to build reports on demographics or to create a database of skills and salary requirements for HR; it's to get people into your company.

When you design your hiring process, design the applicant side first!  Think about how someone will search for a job, how they will apply, and how they will follow up afterwards.  You can collect the data HR needs to track while still ensuring that the process is pleasant from the applicant's side.  It's not difficult, but it does require forethought and focus.

And please, don't use Taleo.



1: An example is for basically anyone with technical knowledge of OpenStack. At the last OpenStack Developer Summit in Atlanta, nearly every company there was desperate to hire anyone with OpenStack experience. (See, for example, the last section of the wrapup from day 2.) Companies had HR representatives at their booths on the trade show floor just to negotiate with prospective hires on the spot! It was cutthroat, but these same companies are making it painful to apply to those same jobs now.

2: The big company I was applying to is one of the folks desperate to hire OpenStack talent. I was applying for an OpenStack-related job...