Validate your HTML, continued

Following up my post about validating your HTML, here comes some alternatives to the tools that I suggested in the first post!

Alternative validator: vnu.jar

There’s another validator called vnu.jar. Check out the vnu.jar web service, vnu.jar website and source code. It’s very easy to install.

There’s a Grunt plugin to use vnu.jar as validator: grunt-html.

Alternative build system: Gulp

gulp-w3cjs works with W3C.js under the hood just like grunt-html-validate. It does not yet have an option to use a locally installed validator. Any takers? :)

HTML, what’s the point?

Finally, I’ve heard from a reader that doesn’t see the point in validating HTML was missing reasons for why we should validate HTML:

I do miss a discussion about the *value* of validating HTML. You seem to simply assert that it is valuable, but without some kind of justification for why you should do it, validating HTML is IMO just cargo culting.

Or to put it in another way: You should reflect on the question of why many (most?) don’t bother validating their HTML. Is it because the ROI is too insignificant?

Here’s a great answer provided by Anders Ringqvist:

HTML validation is *not* cargo culting. If I got a dollar for every time I fixed/answered someones problem/question about a layout problem that was only bad nesting of tags I would be richer than Mark Zuckerberg. Not validated HTML is a time vampire for your dev team. Of course if you only do open source and have all the time in the world or do solo dev then by all means.

Validate HTML templates with your task runner

Most frontend developers nowadays automatically validate their JavaScript and CSS, but it’s easy to forget to validate the HTML.

Many of us use a task runner to keep our JavaScript lint-free using JSLint or JSHint (some people probably even started using ESLint). Many of us automatically validate our LESS, SASS, Stylus or CSS. But can you say that you are automatically validating your HTML?

At the last CopenhagenJS, the main talk of the evening was “Grunt vs. Gulp – a JavaScript Task runner showdown” by Vanja Ćosić. More than half of the audience had experience with Grunt, and perhaps 10% had experience with Gulp. 40 people is a very small sample but it proves that most of us started automating some of the tasks in our everyday workflow.

W3C validator

Validator S.A.C., a native Mac application around W3C’s validator

I love the W3C validator. To me, this is the best validator, but if you know of any other good validators, please let me know. What bothered me though, was the fact that I always had to visit the website to check my page. Was there a way to check it using Grunt or Gulp?


The grunt-html-validation takes you a long way. You can set up the grunt task to run after your filesystem watcher, to automatically check every time you save any HTML file in your project. However, with several files and iterations, you are going to end up “spamming” the server. They will block you after a few requests! To me it happened after a thousand or a little more requests. The unblocking happens after an hour or so. But don’t worry, there’s a simple solution to this problem!

Install W3C validator locally

Installing the W3C validator will not only let you do as many validations as your heart desires, it could also be slightly faster because you eliminate the roundtrip over the Internet to the W3C server and back. The process of installation used to require sorting out dependencies and building the source code, but is now a piece of cake using one of the pre-made builds. For Mac, there’s a standalone application called Validator S.A.C.

Direct link to download it here or the check web page for most recent version. Run the installer and you’re done!

Running a web service

This step is intended for the Mac application Validator S.A.C. It could look different for the other platforms, however I haven’t tried them yet.

Install the configuration file and restart Apache:

cd /Applications/
% sudo cp validator/httpd/conf/validator-SAC.conf /etc/apache2/other
% sudo apachectl graceful

You might get an error during the installation, like I did (on OS X 10.9). For some reason, the last line in the validator-SAC.conf caused the error. You can just put a # at the start of the whole line to disable it – it’s not needed. What it’s supposed to do is to register as a Bonjour service. This way “anyone on your local network can access the service from a Bonjour enabled browser (for example, Safari’s Bonjour bookmark menu).” (quote from the website).

Configure your plugin to use localhost

For grunt-html-validate, just set options.serverUrl to “http://localhost/w3c-validator/check”. Now you’re all set!

Now spend the rest of your day checking and fixing all the problems that have snuck in to your HTML! The better part are probably completely harmless, but dare I bet you have a bigger number of warnings than you think? :))

3D modelling with Sketchup (basics)

Notes from newbeginner’s 3D workshop by Marie Dahlén at Fabriken

Date: 2014-03-08
Location: Fabriken / Stapeln
Tutor: Marie Dáhlen



Two kinds of 3D: Polygon or Nurbs


  • Vertex points that are combined to make a polygon


  • More formulas for shapes – become rendered into polygons
  • If you want to do a vase you can keep a smooth curve – “high tesselation of the polygons”
  • For asymmetrical things, polygons are easier because you can extrude the surfaces you want to alter.
  • Rhinoceros is a good tool for modelling nurbs


Sketchup does polygon modelling. Unfortunately it’s hard to see the topology – how the polygons are built up.

In 3D printing, topology is very important. Weird “twisted” polygons are bad.

Programs to show the topology

  • K-3D – free 3D modelling and animation software. Easy to see topology.

25 (Free) 3D Modeling Applications You Should Not Miss


It’s possible to export shapes from Illustrator and get them into some 3D editors.

Photoshop CC

Now it’s possible to create 3D shapes and even print them, all inside Photoshop CC.

Sketchup walkthrough

  • You can create a new project with millimeters
  • View – Tool palettes – Large toolsets
  • The pallet instructor is a good help for newbies
  • Good resource: > Learn > Video Tutorials
  • The left palette is similar to the palette in Photoshop – but for rectangles
  • Click and drag to create a polygon, then click again to finish.

Now we have a rectangle.

  • Push / pull, drag up to create a cube
  • Scroll to zoom in/out
  • Push the middle button to pan around

Now we have a cube.

  • Use the line tool to split into multiple polygons
  • Move mouse slowly – when it snaps it’s in the middle
  • Move tool – select vertices and move them around
  • You can also combine multiple objects using this tool
  • Create a circle – make it a cylinder
  • Select an object, use the move tool, move it into the cube
  • Select both, Edit > Intersect Faces > With selection

Now we have a combined shape.

  • View > Hidden geometry – shows the vertices of the shapes
  • In Sketchup, you can’t edit the vertices
  • View > Face style > X-ray / Wireframe, different ways to see the model
  • Vertices inside shapes are bad – select vertices inside of the joined shape to remove them

Other tools

Follow me

  • Make an edge, for example using Arc tool
  • Select the Follow Me tool
  • Push the edge away from the geometry – to nicely create a “chamfer”
  • If you need to clean up afterwards, use the eraser tool

Freehand tool

Draw a freehand shape and extrude it into a solid object.

Offset tool

  • Select the Offset tool
  • Drag out a surface inside another surface
  • Use push/pull tool to push the surface down (or up)
  • You have created a solid inside!

Tips about workflow

File handling

  • 3D programs tend to crash
  • Files tend to be corrupted
  • Save your files often
  • Save different versions of files – for instance append a number at the end of the filename
  • Sketchup auto-saves by default every 5 mins, also creates backup file

Do alterations of same object, keep them all in same scene

  • Show / hide geometries
  • Edit > Hide (Apple+E) to hide object

Prepare for 3D printing

  • You must have solid objects (both an outside and inside / a “thickness”)
  • You can preview your model in Slic3r to see if it will work
  • When something is sticking out to the side, you need support structure (work against gravity)
  • Cura, Slic3r, Mesh Mixer can create support structure
  • You might want to rotate the object to get a better structure
  • Sometimes you might want to slice your object into multiple pieces (for instance a globus) and then glue them together after they are printed

File format


Most 3D programs print from .STL, but in Sketchup you need to download the extension to export to STL.

File > Export STL…

Working with other 3D programs

It’s common to do quick sketches in Sketchup and then keep working on details in other programs.

FBX, OBJ are the most common formats shared by other 3D modelling software.

Your own £29 e-paper browser kiosk

I’ve been tinkering around with the Nook Simple Touch to see if I can make it into a browser kiosk. It’s an e-reader from Barnes & Noble similar to the Kindle, but it’s very cheap; on offer now in the US for $59 and in the UK for £29! It runs Android and you can pretty easily jailbreak it.
Turns out it’s very easy to turn it into your own browser kiosk!

Phonegap running on Nook Simple Touch

Phonegap running on Nook Simple Touch

What can I do with it?

The first thing that pops to my mind is single-purpose, fixed home gadgets.

  • Wall clock: Show the time, weather and what our calendars show for today.
  • Home Automation Remote: Put it on the wall next to the light switches. Show controls for wireless lights, music and volume etc.


  • Everything in one device: Touch display, web browser, WiFi
  • Thin product that easily can be mounted to a wall
  • Low power consumption because of E-ink display (however WiFi does drain it over a day or so)
  • Good exercise in UI constraints – monochrome display with slow refresh rate

Let’s do it!

Root the Nook

Follow the instructions here:

Install the browser kiosk

On your computer:
Install Phonegap: npm install -g phonegap
Make a Phonegap app:
phonegap create nook-kiosk
Add your web page to the www/ folder or point the project to your website
Build with Android as target platform: phonegap run android
After a short while, your app is ready.
Open the URL to your APK file in your Nook browser. You will be asked if you want to install it. Do it!

Disable sleep

adb shell
sqlite3 /data/data/
update system set value=’-1′ where name=’screen_off_timeout’;

Now you can have an awesome touch-based remote for your home automation system – have it always display the menu and put it up on the wall together with the light switches :-)

Questions I still haven’t solved

  • Can we use the physical side buttons? (There’s two on the left side and two on the right)
  • Can we disable the home button?
  • How to make the kiosk app autostart? As of now, I’ve used an app from the Kindle App Store to do it for me.


Does this give you ideas? Let me know in the comments!

New appliances for Second Screen Apps

Aside from TV and gaming consoles, I have yet to see many suggested appliances for Second Screen Apps. I believe that the potential is huge and I decided I’d share some of my ideas.

So what is Second Screen Apps anyways?

In a way, Second Screen Apps are similar to the web interfaces that we have in headless appliances such as wireless routers. You control the device by loading up an interface in your smartphone (or tablet or computer…)
The difference is that your main device already has a screen.

What you can do obviously differs, but there’s many advantages to being able to shift the control to your smartphone. For one thing, its precise touchscreen trumps most other input devices you meet in your everyday life. You also don’t have to stand in line to get access to a machine. But there’s also models where the First Screen helps your smartphone – mainly with having a much larger display surface for the content. I could keep listing reasons but I feel like it’s much more real with some examples.

Here are three of my ideas to tickle your imagination:

ATM: While you’re standing in line, why not already use your smartphone to choose the amount you’d like to withdraw and whether you’d like a reciept?
Might not save you a lot of time, but if many people do it then the line will be faster.

Interactive mall map: in many malls there’s a big touchscreen display acting as an interactive map of the mall to help visitors find their way around. When you’ve found out where to go, save the map and the coords to your smartphone. Or if there is a queue to the map screen, open the app directly in your phone.

Train station: If you’re awaiting a friend’s arrival, go to the time table screen and subscribe to delays and the arrival of their train.

Some more ideas in my previous post My side project queue.

Connecting Second Screen Apps

Second screen, sometimes also referred to as “companion device” (or “companion apps” when referring to software applications), is a term that refers to an additional electronic device (e.g. tablet, smartphone) that allows a content consumer to interact with the content they are consuming, such as TV shows, movies, music, or video games. Extra data is displayed on a portable device synchronized with the content being viewed on television.


I believe that Second Screen Apps can be amazing. They will in deed tap into your TV, game console and car but also many more situations. They will largely be implemented in native apps but HTML5 will be essential for a good user experience. In this post I will list different methods of connecting your users to your Second Screen App.

The critical steps

The most critical steps for a user in their experience of a Second Screen App is figuring out how get started. Where do I get the app? Should I scan a QR-code? Should I scan it with my Second Screen App or a QR reader app? Do I connect to a WiFi SSID?

The hurdle can be quite high and the best thing we can do is to reduce the number of steps required to get started:


  1. Scan QR-code to get link to app store
    (If you don’t have a QR-app, also get that)
  2. Click to download
  3. Enter app store credentials
  4. Wait for DL
  5. Find the app and launch it


  1. Open web browser
  2. Type in URL

HTML5 + Captive Portal:

  1. Connect to SSID

The right URL opens automatically in web browser

Clearly HTML5 and a Captive Portal provides the best user experience for connecting your Second Screen App.

Then again, please note that users are different, so different paths might feel natural to them. It might be a good strategy to offer more than one way to connect to the app.
Also note that apps offer more features than HTML5 such as notifications and background running.

Cheap wireless hacking with OpenWRT

Since I bought my WiFi-router in 2006, a Linksys WRT54G, I’ve been interested in open source router firmwares and network hacking. At the time, the features seemed quite amazing. You could do all kinds of super features, for instance QoS, formerly only available in professional equipment.

The firmware that stuck with me is OpenWRT but there is more to choose from, for instance Tomato and DD-WRT.

Quite recently I’ve started poking around with embedded, using node.js on a Raspberry Pi. When I needed WiFi that was not always easy:

You might not be surprised that I started looking back to my dear OpenWRT. And since I last used it, lots of cheap hardware has come out which makes it ideal for low budget embedded hacking.

The TP-Link MR-3020 is about $30 / €20 and has a nice hardware despite its small size:

  • Powered via its USB micro connector
  • Can power the Raspberry Pi via its USB connector
  • One RJ-45 Ethernet port
  • WiFi chip can deliver up to 150MBps
  • Pushbutton that you can configure to do something useful
  • Flashable out of the box, no need to open up and connect to a serial console

Watch out for TP-Link’s over-promising marketing lingo though: “Portable 3G/4G Wireless N Router” does not mean a SIM card reader and 3G chip on the board. It simply means that they added software support for some 3G USB dongles. When you run OpenWRT you still have the option to add a 3G USB dongle, just like with any other OpenWRT compatible hardware that has USB.

So, you ask, why should I buy something like this and what can I do with OpenWRT? Well, here are some of my ideas:

  • Make a Captive Portal for your embedded web server. (Ask me if you want to know more about this)
  • Make a router for your Device Lab that automatically logs all traffic in HAR format
  • Convert all bypassing images to black and white for the hell of it.

There are obviously many cool hacks for the OpenWRT out there, for instance:

So check it out and get started hacking! As a frontend developer I admit that the learning curve can sometimes seem steep, but getting started is very easy and you can get help in the OpenWRT forums. The reward for learning about network hacking is two-fold; First of all it’s fun to add network support to your hobby projects. Secondly, you get to know more about network stuff. Having insight in the “plumbing” of the Internet is something you will have lots of use for even as a frontend developer. For one thing, it can have a huge affect on page load speeds.

My favorite communities of the Öresund region

My favorite communities

These are my favorite communities of the Öresund (Copenhagen-Malmö) region.


A big usergroup centered around JavaScript and related technologies. Talks are in English.

When: Meetings are monthly, every third Thursday of the month.

Location: In and around Copenhagen (also Malmö and Lund).

Website: CopenhagenJS


A usergroup centered around web technologies. Talks are in Swedish and sometimes English.

When: Every first Thursday of the month (which is not a holiday)

Location: Scania region (normally Malmö and Lund).

Website: Lat55

Demo Dag

Demo dag is an occasional Demo show in Copenhagen. It’s hosted around town by friends of the event.

When: Meetings are normally 3-4 times per year.

Location: Copenhagen and soon premiering in Malmö (see below)

Demos are:

  • 7 minutes of anything that works.
  • Anything goes, as long as you actually built it.
  • No slideshows, just show us your thing.

It’s often software – but it doesn’t have to be! We like wood, plastic, electronics, software. As long as you made it.

Website: Demo Dag


Fabriken is a workshop for all things do-it-yourself, like digital production, wood works and electronics. There is a laser cutter, 3D-printers and much more available. If you ever wanted to build your own robot army in order to take over the world do housecleaning, this is the place to start.

When: Meetings are every Thursday.

Where: Stapeln, Malmö

Website: Fabriken

Three awesome places to be

Foo Café

It’s like a conference, all year around. Hosting a huge list of usergroups and seminars, there is at least one event almost every night.

Where: Media Evolution, Malmö

When: Almost every night

Website: Foo Café


Aside from hosting the awesome Fabriken, Stapeln also has many other cool communities under its roof, so check it out.

Website: Stapeln

Malmö Open Device Lab

When you build web sites, how do you make sure they work on all devices? By testing on lots of devices! Malmö Open Device Lab has a big collection of devices so that you don’t have to.

Where: InUse, Gustav Adolfs Torg, Malmö

When: Business hours, book through the website

Website: Malmö Open Device Lab

Upcoming events

There is so much awesomeness going on that I won’t be able to attend it all. Just check out some of the things going on now:
(As of 2013-08-18)

August 22 #instaglass – or what you get when hacking iPhone, Instagram, and Google glass

August 23-24 Foo Hack – Foo Café Hackathon

August 29 Fabriken reopens at Stapeln, Malmö

August 31 Build your own 3D-printer workshop at Fabriken, Stapeln, Malmö

September 19 CopenhagenJS September Meetup

October 1 Demo Dag Malmö at Foo Café

My side project queue

Inspired by Matt Swanson’s post “My Side Project Queue” I decided to write down my own.

I have been on parental leave for the last 10 months which has given me many opportunities to think and few opportunities to code. It gives an advantage when it comes to implementation as you frequently force yourself to throw away bad ideas even before you started working on them.

Never the less, I’ve come to collect more ideas than I have time to work on. Just for fun I thought I would share with you, reader of the Interwebs, and maybe someone would find it interesting / useful. If you believe in one of these ideas, feel free to take it and run with it. Also feel free to talk to me about it if you’d like to.

Working title: Cap5, a captive portal

Quick Pitch: Second Screen interaction should be web based because you shouldn’t have to download an app. And why should you scan a QR code? Captive Portal makes it easier to get started: Just connect with your smartphone to the SSID and the web app opens by itself.

User: Anyone is a bypassing user who wants to interact with a public display or system that should have a web gui: TV:s, cars, train station monitors, public city guide screens.

Stack: OpenWRT, IPTables, NAT

Working title: Digital graffiti

Quick Pitch: A public Second Screen app for Collaborative Interactive Art. Projector is beaming on a big wall for instance in a mall. By-passers connect and draw and add photos using their smartphones.


Server: Raspberry Pi, NodeJS, Socket.IO

WiFi Router: Runs Cap5

Projector: HTML5, canvas, JavaScript

Client: HTML5, canvas, JavaScript

Working title: Real Estate Broker Interactive Window

Quick Pitch: Real Estate brokers often have a display in their windows showing their latest objects. But if you don’t read fast enough, it will scroll to the next object. Using a captive portal we can make them interactive, using smartphone as a remote. The user will have time to read everything and can also interact in other ways like leaving their phone number and saving the object to their phone.


Server: Raspberry Pi, NodeJS, Socket.IO

WiFi Router: Runs Cap5

Store Window TV: HTML5, CSS3, JavaScript

Client: HTML5, CSS3, canvas, JavaScript, connects with WiFi

Working title: Devices help games

Quick Pitch: What if you could use your tablet and smartphones as external displays for your games? For instance, move the instruments of a flight simulator to external devices to free up space on the main display and make use of the devices you already have.

Server: NodeJS, Socket.IO, some way to interface with the games

WiFi Router: Runs Cap5

Client: HTML5, canvas, JavaScript, connects with WiFi

Game: Would need an API for external displays

Working title: Whiteboard IO

Quick Pitch: A digital whiteboard for meetings. Same whiteboard can be visible on several locations at once. Users connect and interface with the whiteboard with their smartphones. Add meeting notes, mind maps, photos, URLs. The result is e-mailed to the participants in a nice format.

Server: NodeJS, Socket.IO

WiFi Router: Runs Cap5

Client: HTML5, canvas, JavaScript, connects with WiFi

Working title: Wood IO

Quick Pitch: Internet of Things for kids: Hand-crafted wooden toys with cool circuitry inside. Equally or more immerse than other interactive toys for the kid. More fun for the geeky mom or dad. Healthier than plastics (which sometimes contain heavy metals).

Stack: Embedded platform like Spark! Core or Electric Imp. Backend would be Node.JS with Socket.IO.

Make an interactive graffiti wall

Illustration of an interactive graffiti wall

Make an interactive graffiti wall using Raspberry Pi and Node.JS

In this tutorial we will enable a projector or display to be painted on using connected smartphones. With the setup described, it’s easy to implement your own multi-device applications.

This is awesome

A personal note: As a frontend developer, I think it’s amazing to be able to leverage such a humble hardware setup. Just using a Raspberry Pi and some accessories, I get a web server that users can connect to with Wi-Fi and the rendering of HTML5 and CSS3 to a display. The software is all open source and all open web standards.

There are however limitations to how much you can do on the rendering side. Most importantly, CSS3 is not hardware accelerated on the Raspberry Pi yet. I’ve published some performance tweaks if you want to delve into that.

Table of contents

  1. Hardware setup / Shopping list
  2. Software setup
  3. Frontend setup
  4. Let’s get cracking!
  5. Software installation
  6. Browser in kiosk mode
  7. Reboot your Pi

Hardware setup / Shopping list

hardware setup

Raspberry Pi, SD card, Wi-Fi router, USB cables, network cable, charger, HDMI cable

  • Raspberry Pi
  • Raspberry Pi basics: Case, SD card (4GB is probably sufficient for this project), USB power adapter, USB micro cable (for power)
  • network cable and WiFi router (your home router is also fine)
  • optional: CopenhagenJS sticker

Software setup

Software: Debian, NodeJS, Socket.IO, Chromium

Software: Debian, NodeJS, Socket.IO, Chromium

  • OS: Raspbian Node.JS
  • Browser: Chromium in kiosk mode
  • Server: Node.JS
  • Socket library: Socket.IO

Frontend setup

  • Module library: Require.JS
  • Event capturing library: capture-smartphone
  • Absolutely no jQuery what so ever!

There’s more to be said about this setup. I will go through the details in a blog post coming up.

Let’s get cracking!

First acquire all the hardware in the list above. You probably have most of the things already. If you don’t have a case for the Raspberry Pi, don’t despair. You can make one in Lego or out of any box of the right size. Download the official Raspbian image and copy it to the SD card. Connect your Pi to your network and power it up. Establish a connection from your working machine via SSH. User pi, default password raspberry.


Add your local machine’s public SSH key if you don’t want to type your password every time you connect:

# from localhost, add ssh-key to your Raspberry Pi 
# to avoid having to type password all the time
ssh-copy-id -i .ssh/ pi@raspberrypi

Software installation

Raspberry pi utility

raspi-config is a useful utility for getting started with your Raspberry Pi. It has an easy-to-use graphical (well, ncurses) interface. I recommend doing these things now:

  • Expand the disk
  • Choose a locale
  • Enable Turbo mode for greater speed Beware: Only class 10 SD cards seem to be able to take a high overclocking! If too high, it will cause corruption of the data on the SD card.
sudo raspi-config

Update all APT packages

sudo apt-get update
sudo apt-get upgrade

Install GIT

sudo apt-get install git-core

Update firmware

sudo wget -O /usr/bin/rpi-update 
sudo chmod +x /usr/bin/rpi-update
sudo rpi-update

Install NVM and the latest stable Node.JS

Because of the certification process in Debian Stable, current NodeJS in APT is 0.6. We want to run a more recent version so we have to install it manually.

Update: The official NodeJS site now provides binaries for Raspberry Pi! Simply download the binary at (switch the number to whatever is considered latest stable by the NodeJS site.) The filename of your download should be called something like node-v0.10.5-linux-arm-pi.tar.gz.

If you want to be able to easily jump between NodeJS versions and don’t mind building it locally (takes hours!) then I still recommend using NVM which is a handy version manager for Node itself.

git clone git:// ~/.nvm
. ~/.nvm/
echo . ~/.nvm/ >> .bashrc
nvm install v0.10.5
nvm alias default 0.10.5

Add the boilerplate website

Get the source code for this project and install its dependencies

git clone 
cd capture-smartphone
npm install

Start your site up as a daemon

We want our server to start automatically. For NodeJS, we can use the following script to use a node.js app as a daemon:

Create /etc/init.d/node-app

#This script is copied from


# REDHAT chkconfig header

# chkconfig: - 58 74
# description: node-app is the script for starting a node app on boot.
# Provides: node
# Required-Start:    $network $remote_fs $local_fs 
# Required-Stop:     $network $remote_fs $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: start and stop node
# Description: Node process for app

case "$1" in
        if [ -f $PID_FILE ]
                echo "$PID_FILE exists, process is already running or crashed"
                echo "Starting node app..."
		echo $! > $PID_FILE;
        if [ ! -f $PID_FILE ]
                echo "$PID_FILE does not exist, process is not running"
                echo "Stopping $APP_DIR/$NODE_APP ..."
		echo "Killing `cat $PID_FILE`"
		kill `cat $PID_FILE`;
		rm $PID_FILE;
                echo "Node stopped"

		if [ ! -f $PID_FILE ]
			echo "$PID_FILE does not exist, process is not running"

			echo "Restarting $APP_DIR/$NODE_APP ..."
			echo "Killing `cat $PID_FILE`"
			kill `cat $PID_FILE`;
			rm $PID_FILE;
			echo $! > $PID_FILE;
			echo "Node restarted"

		echo "Usage: /etc/init.d/node-app {start|stop|restart}"

Now it needs to have a Run flag and we need to start the service:

sudo chmod +x /etc/init.d/node-app
#start it!
sudo /etc/init.d/node-app start
#if it seems to work, make it start upon boot
sudo update-rc.d node-app defaults

Browser in kiosk mode

Install Chromium

The main display is rendered by the Raspberry Pi. We want it to hide the mouse cursor, disabling the screensaver and to run in full screen mode. The package unclutter hides the mouse cursor and x11-server-utils enables us to disable the screensaver.

sudo apt-get install chromium x11-xserver-utils unclutter

Enable Kiosk mode

For this kind of a device, I’d like the browser to start automatically and in full screen. Create the file /etc/xdg/lxsession/LXDE/autostart

@lxpanel --profile LXDE
@pcmanfm --desktop --profile LXDE
#@xscreensaver -no-splash
@xset s off
@xset -dpms
@xset s noblank
@chromium --kiosk --incognito http://localhost:3000/examples/graffiti.html

Reboot your Pi

You’re done! By now you should have your own interactive graffiti wall. Simply connect the Pi to your router, then connect smartphones to your SSID and fire up the web page!

If you’re inspired and want to make something of your own, be my guest to fork the code of this project. It should be fairly easy if you know JavaScript! Stay tuned for a blog post describing the web technologies used for this example.