I used a "mean" steack (mongodb, express.js, angular js and node js) to implement everything in software.

You can find the current (really, really alpha) source code on github

There're several reasons why I tried this combination:

I wanted to try it in a real projetc

It's the same language in frontend/backend/db

Javascript is pretty good at rapid prototyping

Concepts:

On an embedded project like this we have the problem of shared resources (sound and light in our case). So only one process can access the resource at any given time, as we have multiple operation modes (light, mood light, alarm, audiobook mode), those services could block each other. So to keep everything simple I decided for a very easy strategy: when a process wants to access a resource, another possibly currently running process is stopped, so that the resource can be used again by the new process. In our case, this is possibly also one of the best solutions: none of the processes does really need a resource + the only time triggered process is the alarm: the alarm should always get the resource when it starts, also when something else is running. All other processes are user triggered (and we only have one user), so we probably want the process to claim the resource.

Interfacing the LEDs: pwm with Pi-blaster

Usually the raspberry Pi does only have 1 or 2 pwm ports. For this project however, I needed at least 4 of them so I used the pi-blaster project to drive multiple ports with pwm. I had the problem of flicker while dimming the LEDs, so I had to switch to an earlier version which does not have the problem. Furthermore I had to change the sources to use pcm-mode by default, otherwhise pi-blaster uses the sound module to produce pwm which results in really disgusting noise on the speakers. Furthermore I had to adjust the ports: Port 21 was renamed to 27 in the latest raspberry Pi version.

Logging

As explained in the intro I decided to log all the sensor values in mongodb to view them later on and analyse them. There's a great library for interfacing with the mcp3008 chip for node. The log entries can be queried with a REST api. On the frontend I used flot, a jquery library for plotting charts.

Logging the accelerometers was a bit more difficult, because I basically wanted to log "Is there motion" not "what is the direction of the motion". Therefore I continuously logged the absolute difference between 2 measurements and built a sliding average over 100 samples (1 sample every millisecond) leading to 10 measurements per second. When the average exceeds a certain threashold (empirically determined) an event is fired, so that the alarm-scheduler and other modules can take according actions. As the sample frequency for movement is pretty high, I only log values when they change a certain amount from the last saved value. otherwhise it would be too much I/O for the raspberry slowing everything down (plus it would take forever to display the data).

Alarms

Alarms are also stored in mongodb and the node-cron library is used to start them. They can be edited via a REST api. On the front-end I used a gradient picker and a sound-picker to configure the sunrise-light and the mood sounds.

To have a preview of the currently selected color without too much delay, I added socket support to guarantee a fast communication when picking color values. when editing the light gradient, the selected color is always previewed on the weggup. The sound/light gradient can also be completely previewed and all sounds can be played seperately. The volume of every sound can be adjusted seperately, as well if it should be repeated or not.

The sound files are read from a certain directory on the raspberry Pi, which is also shared via samba.

To realise the sleep cycle functionality the alarm scheduler listens to the movement event from the logger and checks if the next light sleeping phase lies within a certain timeframe between wake up time and a defined time prior to this to reschedule the alarm. The main problem is to forecast the next light sleeping phase. At the moment I use a constant duration of 3 hours per sleep cycle. When I will have gathered more movement data I will adjust this accordingly or find another method of predicting the next light sleep phase (depending on the collected data).

Playing sound

To play sound mplayer processes are spawned in the background in slave mode, so that they can be easily controlled from node. I will possibly change to another player, as hardware requirements, and therefore delays are quite high with mplayer.

The single button interface

When pressing the top of the housing, the internal button gets pressed. This event causes the weggup to turn on bright light, acting as a lamp. When pressing the button, while anything is running, this process is stopped immediately. I.e. the button acts as a "shut off anything that is running" switch, and when nothing is running, it acts as a "lights on" switch.

Other modules:

All the modules can be started and stopped from a web interface. The configuration of all parameters can also be controlled there. I've implemented a simple common settings manager for all the modules, so I can add new ones easily (when i find some time, I will create custom settings pages for all the modules, which are more comfortable to use).