/moorescloud-holiday

Some simple stuff messing around with a Holiday by Moorescloud.

Primary LanguageJavaScriptMIT LicenseMIT

Coding with the Moorescloud Holiday

This repo shows a few different ways to get a Holiday by Moorescloud to do some simple things in a few different languages. Starting with turning the 50 lights on and off; and then moving on to chase, comet and gradient effects.

I’ve tried to write this readme without assuming too much knowledge, as I know some people use their Moorescloud Holiday to try out coding with their kids. If you know things like bash and colour formats, just skip the Tips section.

Contents

Tips

  • Start with the on/off examples. They are written about as simply as possible. Also, from experience, you really want to be able to turn them off when you get something wrong ;)
  • It’s a good idea to note the Holiday’s original name, something like holiday-ab123c even if you change it on the Device Name tab.
  • My Holiday is named enlightenment, so anywhere you need to update some code to point to your Holiday you can look for that string. If you’re curious, all my hardware gets names from Red Dwarf; and Enlightenment is a holoship – a ship made of light :)
  • I should also note this code isn’t particularly neat or tidy. It works but use it at your own risk ;)

Bash shell

I’m assuming you’re using a bash shell to run this code. That means:

  • OSX Terminal on Mac
  • Windows Subsystem for Linux (WSL) on Windows 10; or Cygwin for older windows. Note the default Command Prompt does not work for this!
  • It’s usually just called ‘Terminal’ on Linux

Any time I say ‘in bash’ or ‘in the CLI’ I mean running a command in the bash shell.

You will need to download or clone this repo, then run commands from the code sample subdirectories. If you are unfamiliar with bash, a simple trick to find the right location is to start your bash shell then run one of…

  • OSX: open .
  • WSL: explorer.exe .
  • Cygwin: cygstart .

…which will open the bash shell’s location in your GUI file explorer. Then you can match up the locations to understand where to put the files. You move between directories with the cd (change directory) command.

For example, to run the bash commands:

  • cd bash
  • ./holiday.sh on
  • ./holiday.sh off

If you get a permission error, instead of using ./ syntax, use the bash command instead bash holiday.sh on etc. Or you can run chmod u+x *.sh and try again.

To move out of the bash directory, run cd .. to move back ‘up’ one level, then you can move into other directories eg. cd node-udp.

Colour formats

If you aren’t familiar with Hex and RGB

Hex colours are the #123456 format, where the numbers map to RRGGBB in a 00 to ff range. Examples:

  • #ffffff – white
  • #000000 – black
  • #ff0000 – red

RGB colours are three numbers in an array [1,2,3] where 1 is red, 2 is green and 3 is blue. Each number can be a value from 0 (off) to 255 (full brightness). Examples:

  • [255,255,255] – white
  • [0,0,0] – black
  • [255,0,0] – red

If you need to quickly pick some Hex or RGB colours, Google provides a handy colour picker if you search for hex colour

Holiday maintenance tips

This is not exhaustive, just some tips noted down over the years:

  • If you use the Holiday a lot (some people use it every day, all year!) you should periodically SSH in to the Holiday and clear /var/log (tip from Mark)
  • Don’t try to upgrade Linux on the Holiday, it’ll stop working. If you know what you are doing you could rebuild it with Froosh’s updated ARM build but note the code samples here may not work with that build (they might, I just don’t know!).
  • If you want to fix your Holiday’s timer so it doesn’t jitter, have a look at this PR which was sadly too late to ship with the units.

Holiday documentation

Since the official docs aren’t online any more, this readme collects what I could find; has some basic info on setting things up; and a copy of the PDF in case you lost your instruction book.

Elsewhere:

Hardware docs:

  • Holiday manual covers finding and connecting to your Holiday. Note you can also find via MAC address in your router, the MAC’s printed on the Holiday unit.
  • Holiday hardware architecture has deeper hardware info that you probably don’t really need.

Enabling SSH:

  1. In your browser
    1. Open the Holiday application (http://yourholidaysname/)
    2. Go to Settings – Developer Mode
    3. Toggle dev mode ON.
  2. In bash check the name ping yourholidaysname (ctrl+c to stop)
  3. Then you can connect. With the default settings:
    1. ssh holiday@yourholidaysname
    2. Default password is holiday
    3. Once you’ve logged in you should see something like [holiday@yourholidaysname ~]$
  4. You can change the default password by running the command passwd on the Holiday; but be sure to put that new password into your password safe for future reference. I’ve no idea how you’d recover SSH access if you forget the password.

There are two Holiday APIs:

  1. UDP ‘Secret API
  2. IOTAS (Internet Of Things Access Server) API

The UDP API is used in the /node-dup code samples; all others are using the IOTAS API.

UDP API

See the UDP ‘Secret API’ github repo for full details

Holiday by MooresCloud provides a very fast UDP-based API to control its globes. Port 9988 is opened and is advertised through mDNS – the avahi service record for secretapi.udp is included in this repo.

The packet format is very simple, 160 (0xa0) bytes composed of:

  • 10 bytes of header (ignored)
  • 150 bytes of data, the RGB values for each of the 50 globes.

Packets not of exactly 160 bytes will be rejected.

IOTAS API

The official docs for this are gone, so what follows is an incomplete and unofficial bit of API documentation, reverse-engineered by reading consumer code I wrote three years ago. So be nice if you find an error ;)

There are two endpoints:

  • /iotas/0.1/device/moorescloud.holiday/localhost/setlights – sends a frame of colours to set the lights, allowing you to change the individual globes to different colours.
  • /iotas/0.1/device/moorescloud.holiday/localhost/gradient – starts a gradient transition for the lights, setting the whole string to the same colour.
  • Both endpoints take a JSON payload and return {"value": true} or {"value": false}

Setlights takes a JSON object with a lights property, which takes an array of 50 hex colours for the globes. For example to set all lights on to full white:

{ "lights": [ 
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff",
"#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff"
] }

…and just in case you’re now sitting with your Holiday going at full bore on your desk, blinding you, here’s how to set them all off:

{ "lights": [ 
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000",
"#000000", "#000000", "#000000", "#000000", "#000000"
] }

Gradient takes a JSON object with begin, end and steps defining the start and end colours in RGB arrays; and the number of steps to take in the transition. For example to start from black and work up to full white in 128 steps:

{ 
  "begin": [0, 0, 0], 
  "end": [255, 255, 255], 
  "steps": 128 
}

…and back down:

{ 
  "begin": [255, 255, 255], 
  "end": [0, 0, 0], 
  "steps": 128 
}

Note gradients take some time and don’t cancel previous gradients when they start. So if one gradient hasn’t had time to complete before you set another one, you will get a nasty stuttering effect.

You don’t have to match the existing colour displayed on the Holiday, if you set a different starting colour it will immediately change to that colour before beginning the gradient. That does mean you can change the colour of the whole string by setting both begin and end to the same colour; and setting steps to 1. That has the same effect as using setlights with all 50 colours set to the same value.

To finish a gradient with the lights entirely off, steps must be set to at least half the highest starting value; and the end value must be [0,0,0]. When calculating steps remember to count zero in th 0-255 range, so there are 256 steps; which means to go from full brightness to black, you must use at least 128 steps (which is why the example above uses 128 steps).

Trying the IOTAS API in bash

A simple way to try out the endpoints is to send them to your Holiday in bash using curl.

First, export your Holiday’s name to a variable (this has to be done once every bash session):

export HOLIDAYNAME=yourholidaysname

This means you can copy and paste the rest of the commands, which use the $HOLIDAYNAME environmental variable you just set.

The gradient API is actually short enough to write the JSON directly, just be sure to enclose the whole JSON object in single quotes. Run these commands on one line.

Gradient from off/black to red:

curl -X PUT -d '{"begin":[0,0,0],"end":[255,0,0],"steps":128}' http://$HOLIDAYNAME/iotas/0.1/device/moorescloud.holiday/localhost/gradient

Gradient from green to off/black:

curl -X PUT -d '{"begin":[0,255,0],"end":[0,0,0],"steps":128}' http://$HOLIDAYNAME/iotas/0.1/device/moorescloud.holiday/localhost/gradient

The setlights API can be set this way as well, but it’s very long so it’s easier to write files. Create…

  1. setlights-on.json with the first hex example above (setting all lights to #ffffff)
  2. setlights-off.json with the first hex example above (setting all lights to #000000)

Then from the same directory in bash, run:

curl -X PUT -d @setlights-on.json http://$HOLIDAYNAME/iotas/0.1/device/moorescloud.holiday/localhost/setlights
curl -X PUT -d @setlights-off.json http://$HOLIDAYNAME/iotas/0.1/device/moorescloud.holiday/localhost/setlights

You can do the same with gradient JSON:

curl -X PUT -d @gradient-on.json http://$HOLIDAYNAME/iotas/0.1/device/moorescloud.holiday/localhost/gradient

I’m sure you can figure out what to put into the files at this point :) From here on, setting the lights is just a matter of creating your JSON payload in whatever language you like, then sending it to the Holiday. Have fun!

Code samples

/bash

If you’re feeling impatient, just run holiday.sh for a set of options including the nice simple “on” and “off”.

Setup:

  • Edit the HOLIDAYURL variable in the .sh files so they point to your Holiday (IP or hostname)
  • Ensure you have curl by running type curl in your bash shell. You may need to install Xcode on OSX to enable this.

Scripts:

  • holiday-setlights-with-json-files.sh just does setlights taking its JSON objects from .json files. Very simple, easy starting point.
  • nrl.sh adds the critically important maroon and blue options not present in the standard NRL app ;)
  • holiday.sh has more options including sending JSON directly from the script. Uses setlights and gradient API points.

/javascript

Sets the lights and also does a simple visualisation of the lights and API calls:

It’s effectively a simulator and bare-bones alternative interface to control the Holiday. It wasn’t really what I intended to do but that’s how it turned out :)

If you view it locally (by opening javascript/index.html in a browser) it still does the visualisation but it won’t actually affect the lights. This does mean you can try things out before uploading your code to the Holiday.

Setup:

This one’s a little different as you have to put the code onto the holiday to actually control the lights (due to the Holiday’s CORS/cross-origin security settings).

  1. Enable SSH on your holiday as noted earlier
  2. Then copy the files to your holiday…
  3. Method one:
    1. Use an sFTP client like FileZilla to connect to yourholidaysname (port 22)
    2. Copy the files in /javascript/ to /home/holiday/holideck/iotas/www/apps/test/
  4. Method two:
    1. Using bash, starting in the root of this repo
    2. cd /javascript/
    3. scp * holiday@yourholidaysname:/home/holiday/holideck/iotas/www/apps/test/

Note that you can name /test/ whatever you want.

Usage:

  • Browse to http://yourholidaysname/apps/test/
  • Or, open javascript/index.html in a browser to view locally and see any changes you’ve made to the code. This won’t control your lights, just the visualiser.

/node-udp

This is an alternative way to drive your Holiday with Javascript, using the UDP ‘Secret API’ (named for the people who created it, not because it’s a secret).

Requirements:

Setup:

  • Run npm install in the /node-udp/ directory to install @garthk’s holiday-udp library
    • If the NPM install fails for some reason, there is a backup copy – rename /node-udp/backup_node_modules/ to /node-udp/node_modules/ and try running the code. A proper NPM install is still recommended, this is just an all-else-fails option.
  • (optional) Edit the “holiday” variable in the .js files so they point to your Holiday (IP or hostname). You can skip editing the files and pass your holiday’s name to the script as an argument: node script holidayname

Usage:

  • node on.js <holidayname> and node off.js <holidayname>
    • node on.js sets all lights to white.
    • node off.js sets all lights to black (off).
  • node chase.js <brightness> <interval> <holidayname> does a simple coloured chase.
    • node chase.js
    • node chase.js 50 2000 – brightness 50, 2 second interval
  • node holiday.js does on and off; plus a runner/comet effect:
    • node holiday.js on – fill with RGB 255,255,255
    • node holiday.js off – fill with RGB 0,0,0
    • node holiday.js on [10,20,30] – fill with RGB 10,20,30
    • node holiday.js runner – comet effect

/python

Dependencies:

Setup:

  • Edit the URL in requests.put to point to your holiday.

Usage:

  • python holiday.py on
  • python holiday.py off
  • python holiday.py hash 123456 (where 123456 is any valid colour hash)

Note that most of the original Moorescloud code was done in Python, so if you want more advanced examples have a dig around https://github.com/moorescloud