Beam.io

Wamda MIT Media Lab Workshop – The Recap.

We boarded that plane and started the mysterious journey on a Sunday night. I was lucky to join some friends from my hometown and others from Lamba Labs – Beirut First Hackerspace. We Joined forces and few hours later, we landed at Abu Dhabi’s airport and got our brain scanned then made it to the hotel safe and sound.

The next day, things started to gradually make sense. Snap back to reality, I knew I had a new quest to complete but I wasn’t really sure of what exactly that is. In fact, I wasn’t sure at all; the agenda of the workshop was clear and it’s definitely not a typical entrepreneurship event. I had a feeling we’re going to build something! The clock tics… and it’s time to begin.

Mr. Joi Ito - Director of the MIT Media Lab

Mr. Joi Ito – Director of the MIT Media Lab

The workshop kick started with a jolt of energy given by Mr. Joi Ito -Director of the Media Lab- his talk was really interesting, as inspiring as any of his TED talks! I looked around and started to take tiny baby steps out of introversion, my attempt to socialise was nearly hopeless, just until the ice breaker Bilal (@bilalghalib) fired things up with his games; these looked ridiculous at first, but turned out to be key to a magical output. He connected people together by stimulating the audience and pushing them to interact in a finite paradigm; How’s that? Bilal understands the human chemistry, he’s the Heisenberg in that field. The chaotic fun ended with us getting divided into our ‘tracks’. I was luckily placed in the sensors and networks track, my favorite. We gathered in the hallway, right outside the workshop, where a circle of introduction was formed in order to really wire this board by sharing each member’s favorite sensor penchant.

Jammin' with the locals

Jammin’ with the locals

Later at night, natural selection played its role, some members of the team called it a night and the others went for a few drinks, but I was personally seeking new random fun! Went with the flow and ended up with Bilal , Qarly (@QarlyQ) and Pragun!

Pragun, QQ and Bilal were re-inventing the wheel!

Pragun, QQ and Bilal were re-inventing the wheel!

The next morning, my alarms betrayed me and I missed the field trip. Luckily I was able to catch up with Spencer (@ssfrr), one of the track’s instructors, who showed me some of the electronics and the sensors they brought from the Media Lab, it was quite fascinating. The track regrouped and shared thoughts on this cool visit. Apparently, they went to Masdar City, a futuristic eco-friendly city, a pretty good place to get inspired.

Nan and the Tidmarsh Sensor Node

Nan and the Tidmarsh Sensor Node

Next, we gathered in the cinema room, where Nan talked to us about the different kinds of sensors and Arduinos that are to our disposal during this workshop. Spencer shared his interesting API to browse the sensors data in a RESTful way. The most interesting mother of all sensors was the Tidmarsh Sensor Node. It can sense the following:

  • Low-power Accelerometer
  • Barometric Pressure Sensor
  • High-Resolution Temperature/Humidity Sensor
  • High Dynamic Range Ambient Light Sensor

Then we’ve been asked to sketch few ideas and present them and consequently mapping them into 4 categories; it was up to each member to join the desired category and form a team. I was always fascinated with omnipresence and so do these people: Dr. Ramy (@RamyElTarras), Simon (@ConversionPoint) both programers and engineers and Sherif (@SherifMaktabi) our product designer. We all teamed up and came up with Beam.io.

Beam.io

Beam.io

Beam.io (@beamiobot) is a sensor network that interacts on social media. That’s right, you send a tweet with a bunch of parameters (hashtags), and based on your location (optional) the closest Beam network will reply to you with the requested data. Each node is modular so you can plug and play sensors based on your needs. Sensor nodes can be private or public; for each private node we sell, we’re going to donate a public node to communities all over the world! This will fasten the process of having more and more public sensors all over the world. I would leave you to imagine the different use cases where BeamBot comes in…

…and when your prototype works, things get rockin’!

… then you test some more

…and then you get to demo it to Pr. Paradiso!

Here’s how our prototype looked like:

Hardware Stack:

  • Raspberry Pi Model B (512MB Ram)
  • Raspberry Pi Camera Module (2MP)
  • MIT Tidmarsh Sensor Node
  • Rechargeable batteries
  • Edimax WiFi dongle
  • 4GB SD Card with Raspbian OS
  • Serial to USB converter

Software Stack:

  • Node.js
  • Python
  • Twitter API
  • Shell Scripts

We’re open source! Fork us on Github: https://github.com/DonaldDerek/beam.io

It was a hell of a ride my friends. Thanks to Wamda and to the MIT Media Lab who made this happen.

flattr this!

Startup Weekend Byblos: The Aftermath.

Startup Weekend Byblos - LAU

Startup Weekend Byblos 2013, happened on Nov 15-17 at the Lebanese American University – Byblos campus. It was part of The Global Entrepreneurship week!

Personal Opinion.

After organising, facilitating, mentoring and winning previous local Startup Weekend events, I came with the following insights regarding this experience:

It’s not about the idea, it’s about finding the right people. The world is full of ideas that lacks a good implementation, and that’s precisely what Startup Weekend aims to do. Get these ideas from a conceptual stage to an actual product in 54 hours! Nobody ever said, that Startup Weekend events are meant to be easy. This competition is not for newbies, although we welcome them. It is a chance for them to learn and experiment with the Startup life.

A big chunk of those who attended Startup Weekend events in Lebanon in the past 2 years forgot what the word product mean, thus they end up creating fake products that they call prototypes, and dedicate their time to create smooth graphics and a killing business models to impress the judges and make some money in the weekend. Can you really win a Startup Weekend without writing a single line of code ? Unfortunately in Lebanon, the answer in some situations was YES!

As an organiser, I could have changed that by disqualifying people here and there, but in that case, we won’t need to throw a ceremony at the end, and perhaps we don’t need judges to judge. Sad but true, we lack builders.

In Lebanon we lack implementers, for instance whenever we threw a show & tell event at Lamba Labs, the Hackerspace would get pact with people! Whenever there’s a build night, or any other type of non-networking events, few people showed up. Perhaps they were busy networking elsewhere. Talking is what we do best in this country.

Startup Weekend’s motto is: No Talk, All Action. It’s the other way around here: All Talk, No Action. It remains ear friendly if that’s what you care about.

Respect.

I respect every single team in Startup Weekend Byblos or Beirut who fought by the rules.

I respect every single individual, who met a co-founder, a friend, or anyone who completes him from a mental and/or a business perspective.

I respect developers who wrote hundred lines of code in these weekends.

I respect designers who joined teams.

I respect those who threw away their ideas, just to join a team.

I respect business oriented people who managed well their teams and who were ethical in these weekends.

The Aftermath.

This year at Startup Weekend Byblos, we had an exceptional situation. Saily Team represented by Jihad Kawas got disqualified. It was a great idea, but unfortunately it wasn’t cooked during this weekend. After consulting the main Startup Weekend board, they made it clear for us that team escalation is prohibited, thus this year at Startup Weekend Byblos we don’t have a 1st winner.

The other teams who won the 2nd and 3d position respectively are:

Baladi Min Baladi
Baladi Min Baladi is a platform that uses e-commerce to buy and sell local homemade goods of the Lebanese villages.
Team:

  • Cosette Saliba – Designer
  • Firas Darwiche – UX Expert

Clapp

Phone Control App through whistling and clapping*

Team:

  • Mario Achkar – Programmer & System Engineer
  • Oussama Al Jamal – Electrical Engineer
  • Kifah Daher – Electrical Engineer

Check all the teams on the official Startup Weekend’s site. Find below the event metrics:

14 ideas where pitched on Friday, 10 where selected to present the final pitch on Sunday. The other teams who had cool ideas were:

  • BLOODY: A team of four first year computer science students at LAU developing a socio-medical aimed application named “Blood Needed” that links hospitals requests for blood type to every user registered in the android application.
  • Antarchitect: This startup is about giving students the ability to evaluate themselves by connecting, sharing and comparing portfolios of students in the same field around the world. By Comparing with others we can learn, adjust and improve. Power to the students!
  • InkLink: Is an online directory to help people at startup weekend to create more innovation by reviewing previous pitches and ideas that are filled by startup weekend organizers or community .
  • YalaImages: A project that provides live high quality photos about instantly occurring events from professional photographers to users.
  • tyoun.in: tryoun.in is a musicians hub that uses a smart engine to allows musicians to match together to form bands or simply socialize. It also has many features that link the music industry together.
  • Smart Outlets: Easy way to control devices in your home. just a simple outlet without any wires or wireless signals or any modification with the existing wires installed… it works via a signal sent through the house electrical wires, and this signal is received back into another desired socket in your home to control the device by turning it on or off. it can be also integrated to be controlled through the internet using a micro controller or raspberry Pi. or it can be also just a simple way to turn on or off desired devices when it is on generator ups or regular E.D.L.
  • uWallet: uWallet is an Online Money Based Application, easing money transactions on campus. uWallet cover all sorts of university services from buying books to cafeteria meals. Filling your account with money will be in the university business office.
  • Saily: Saily is a mobile Social Network for Garage Sale, making the buy/sell used stuff experience, more simple, quick, and efficient.

 Videos, pics and the fun stuff can be found on our Facebook Page: https://www.facebook.com/swbyblos

Tips to become the next Arabnet Devtour Champion

Donald Derek - Code Master Badge

Arabnet Devtour Lebanon 2012 was a life changing event. I’m writing this blogpost because I want to share with you some essential tips to win the next Arabnet Devtour. Who knows perhaps the next Code Master will be you.

If you’re reading this post I’m pretty sure that you know what the Arabnet Devtour is all about, if not please refer to this official link.

This year the competition is divided into 3 rounds:

  1. Speed: You’re most likely going to be asked to implement an easy task but you will be very short on time .
    Duration: 30min to 45min max

    Ex: Implement a todo list app with a set of functionalities. Extra points will be given for those who implement the bonus features
  2. Creativity: This round is really challenging, participants have a lower rate of survival than the previous round. Here you will be asked to use/combine known APIs (Twitter, Instagram, Facebook, Youtube…) in order to build a creative and useful app.
    Duration: 1h 30min to 2h max

    Ex: Build a Tweetogram app where you need to combine both Twitter and Instagram’s APIs and come up with something useful and creative.
  3. Competency: Unleash all your powers, anything is possible in this level. Leave no room for panic and never surrender.
    Duration: 30min to 2h max
    Ex: Build a Media Player using Jamendo’s API (Github Repo, demo)

Miscellaneous Tips:

  • Have a Github account! Winners will be asked to upload their final code
  • Prepare your APIs Libraries SDKs (Facebook, Twitter…)
  • Be familiar with any REST API
  • Use Apigee’s console as my friend Jad Joubran suggested
  • Use local storage instead of a Database
  • JavaScript #FTW: use JS all the way.
  • Use Twitter Bootstrap or any similar UI Library for quick and decent prototyping

4 Winners will be given the chance to participate in the Arabnet DevChampionship and represent their counties.

Good luck to all and May the source be with you,

flattr this!

[Workshop] The JavaScript Revolution I

Powered By Lamba Labs - Beirut First Hacker Space

Powered By Lamba Labs – Beirut First Hacker Space

Talks:

  1. Theoretical JavaScript and OO Concepts by Jad Jabbour
  2. JavaScript in the mobile world: Code structure and optimisation by Jad Joubran 
  3. An intro to Backbone.js by Piotr Yordanov
  4. The JavaScript ecosystem: Node.js & MongoDB by Donald Derek
  5. Experimental JavaScript: Arduino & Node.js by Marc Farra

 

Theoretical JavaScript and OO Concepts

By Jad Jabbour: A software developer that just loves experimenting with codes and has an unconditional love-hate relationship with JavaScript!

Code Example on Github

 

JavaScript in the mobile world: Code structure, optimisation and Phonegap

By Jad Joubran: Co-Founder and CTO of eTobb and coding is his ultimate passion. He won 4th place at the ArabNet Developers Tournament 2012 and was part of the Lebanese winning team of the Arabnet Championship in Dubai

Code Example on Github

 

An intro to Backbone.js

By Piotr Yordanov: Ex-Co-founder of the first Map-based, real-estate website in the Middle-East BaytBaytak.com. Now a Hero at Draper University

Find his campaign on Indiegogo

 

The JavaScript ecosystem: Node.js & MongoDB

by Donald Derek: A Hipster Geek from Lamba Labs – Beirut First Hackerspace, RaspberryPi Tinkerer and a JavaScript Freak. He snatched the first place in the ArabNet Developers Tournament 2012 and was part of the Lebanese winning team of the Arabnet Championship in Dubai

Code Example on Github

 

Experimental JavaScript: Arduino & Node.js

By Marc Farra: Founding member of Lamba Labs – Beirut First Hackerspace! Computer Engineer interested in human computer interaction and new media.

Code Example on Github

 

Sponsors:

This event was powered by:

logo_ll

Special Thanks to everyone who attended the workshop powered by Lamba Labs – Beirut First Hackerspace

logo_mena

The awesome videos were shot and edited by Menaveristy

coworking

Thanks to CoWorking+961 for hosting this event

flattr this!

[CF-I] Configure your staging machine with Node.js and NGINX

nodejs

If you're one of those critical readers, you might be asking yourself: what the   hell is [CF-I]. Well, I'm a Control Freak and I'm trying to compile a series of blogposts where I can keep track and explain to myself how I solved problems that weface daily in the backend world.

If you want to cut the crap and skip the brief explanation you can find my NGINX Config files on this Github repository.

 PaaS & SaaS

Telling a control freak to use Heroku for instance will kinda limit and demotivate him. That’s why I hate using any Platform or Software as a Service. My friends tried to convince me otherwise using the following args:

” Dude, it’s really fast to setup, you’ll start coding your app in no time… ”
” …Ah I love NodeJitsu, I won’t worry about scaling my app”

You might agree with them, anyways the dominating variable in our matrix nowadays is speed
I remember a Goblin from World of Warcraft saying “Time is money friend…”

But I believe in building my own backend system without relying on any third party entities ( Except for Analytics and so ) that will not only save you time and money but it will boost your knowledge in understanding and dealing with complex systems. At the end of the day, that’s what really matters. The currency of the Universe is Knowledge.
Ah! Take me back to programming!

Node.JS & NGINX

NGINX is way faster at serving static content than Node.JS, combine them and you’ll minimise the traffic that hit your Node process therefore you’ll get a decent and scalable web application that can really scale beyond the good ol’ Web Servers like Apache and let’s not forget that both Node.JS and NGINX are event driven.

Setting up the Production Environment

My Linode VPS is running on an Ubuntu 12.04 LTS (Long Term Support) distribution I’ve also tried it on my Digital Ocean Debian 7 droplet with a slightly different setup.

After adding your domain zone inside the Linode DNS Manager and going through some basic Linux and security configurations you’re ready to install both Node.JS and NGINX.
After installing NGINX and building your Node app with Express for example you need to create your NGINX config file

sudo nano /etc/nginx/sites-available/example.com

Add the config file bellow assuming that your domain name is example.com


# Node Express on Port 8080
upstream example{
    server 127.0.0.1:8080;
}

# NGINX Server Instance
server {
    listen 0.0.0.0:80;
    server_name example.com www.example.com;
    access_log /var/log/nginx/example.log;

    # Gzip Compression
    gzip on;
    gzip_comp_level 6;
    gzip_vary on;
    gzip_min_length  1000;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_buffers 16 8k;

    # Proxy to the Node instance
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;
      proxy_pass http://example.com;
      proxy_redirect off;
    }
 }

Then you need to create a symbolic link to your config file inside your sites-enabled directory

cd /etc/nginx/sites-enabled/  
sudo ln -s /etc/nginx/sites-enabled/example.com example.com

reload nginx

service nginx reload

 

Setting up the Staging Environment

If you need to create a staging env using a subdomain like staging.example.com you need to go back to your Linode DNS Manager go into the example.com zone and add an A/AAAA Record with the hostname “staging”

Once done you need to create another configuration file inside /etc/nginx/sites-enabled

call it staging.example.com and follow the previous procedure to create a symbolic link.

The configuration file will be slightly different. Don’t forget to run Express on a different port.


# Node Express Staging on Port 3000
upstream staging{
    server 127.0.0.1:3000;
}

# NGINX Server Instance
server {
    listen 0.0.0.0:80;
    server_name staging.example.com;
    access_log /var/log/nginx/staging.example.log;

    # Gzip Compression
    gzip on;
    gzip_comp_level 6;
    gzip_vary on;
    gzip_min_length  1000;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_buffers 16 8k;

    # Proxy to the Node instance
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;
      proxy_pass http://staging.example.com;
      proxy_redirect off;
    }
 }

Use PM2 to launch your Node Apps as a Daemon

Pm2 is really awesome and simple to use. In the past I tried Forever but I’m glad that there’s a better tool now. I use nodemon just for development.

Start a Node App with Pm2

pm2 start app.js -i max

Reload all apps

pm2 reload all

flattr this!

EyeEm API + CSS3 Filters

1

Before the Arabnet Championship, my friend and I were brainstorming about potential ideas that might be hot topics for the competition, we failed at guessing, but it was a good warm-up and I felt like I should re-factor and continue this tiny project on a weekend.

The Idea:

Fetching images from EyeEm’s public API, then applying some CSS3 filters. This small project showed, and once again, the power of CSS3 and HTML5. Unfortunately it only works on modern WebKit Browsers (Chromium/Google Chrome, Safari) but who’s know even IE is evolving faster than ever now. *Sarcasm

The Implementation:

EyeEm’s API is pretty decent and easy to use. Check it out on Github and register your app here I’ve also found a pretty cool CSS3 Filters demo page which saved some time. Not to forget the awesome FLAT-UI that prettifies things.

The code is on Github, if you have any cool ideas to add to it, fork-it :)

The Results:

2

3

Check out a live demo

flattr this!

Jedis from Lebanon in the Arabnet Final Championship 2013

jedies

Representing Lebanon in the Arabnet Final Championship 2013

Four geeks from Lebanon, from left to right we have Jad Joubran, Georges Frewat, Donald Derek Haddad and Roy Naufal landed in Dubai for a united purpose, winning. We fought with our laptops and music till the end, and got the title back to our country. It was a hell of an experience my friends.

Continue reading

Build your own Google TV Using RaspberryPi, NodeJS and Socket.io

Image By http://korben.info/

Image By http://korben.info/



If you’d like to support this project please flattr this!

Please note that this project is not intended to replicate an actual GoogleTV, but it’s simply a proof of concept using modern web technologies.
Watch the full workshop here hosted by Menaversity
This workshop was given at Lamba Labs Beirut First Hackerspace 
after a series of lightning talks check out the presentation here
If you'd like to bypass the tutorial and jump into the fun stuff, you can always  fork the code on Github

Google-tv-logo3-l

What’s Google TV ?

Turned out that Google is also doing its own thing for the 10-foot screen. Google announced 2 versions of their famous new TV, the first is called the Buddy Box which is currently an expensive box manufactured by Sony and the second is an Integrated TV built right into the TV set that will be announced soon.

The Google TV looks something like that:

google_tv_preview

Google TV preview

Developers: you can start building your own Web Apps for the Google TV or renovate any android app to fit the 10′ experience, all the resources can be found at Google’s Developers Site

Build your own Google TV

In this tutorial you’re going to build your own version of the Google TV using the following open source technologies:

Hardware:

Software Stack:

  • Raspbian OS – a Debian distro specially made for the rPi
  • NodeJs
    • Socket.io – to handle the connection between our remote and our TV via websockets
    • Express – to handle some basic http requests
    • Omxcontrol – a simple module to control the OMXPlayer which is the best video player on the rPi
  • Chromium Browser
  • OMXPlayer
  • Youtube-dl – a script that let you download youtube videos
  • QuoJS – to handle swipe gestures on the mobile web app
  • HTML5, CSS3 transitions, Javascript, and Moustache as a template engine
  • Youtube API

The end result

raspberrypi_tv_google_tv

Raspberry Pi TV with its special remote controller

 

Walkthrough

The project is divided into 4 main categories:

  1. Installing the software stack
  2. Basic shell commands & scripts
  3. Building the back-end: NodeJS + Express + Socket.io
  4. Building the front-end: Dashboard and Remote App

1.Installing the software stack:

Install Raspbian & NodeJS

Follow this tutorial to install Raspbian and Node Js on your Raspberry Pi

Install Chromium & Youtube-dl

Install Chromium Browser for the Raspberry Pi Source

sudo apt-get install chromium-browser

In order to have a better display you can also install MC core fonts using

sudo apt-get install ttf-mscorefonts-installer

Install and Update Youtube Downloader

sudo apt-get install youtube-dl 

sudo youtube-dl -U
Note-1: There’s a problem when you want to stream videos on the RaspberryPi from youtube in Chromium, they’re extremely slow because the videos are not being rendered on the GPU. Youtube-dl comes as a quick alternative, the video is downloaded instead then played by the OMXPlayer which will render our videos on the GPU giving us a good quality of HD videos.
Note-2: The OMXPlayer is installed by default on the Raspbian.

2.Basic shell commands & scripts

If you’re using SSH to connect to your RaspberryPi you should first add “DISPLAY=:0.0″ to your env variables, by simply executing

export DISPLAY=:0.0

To check all your environment variables

env

Test Chromium in Kiosk Mode:

chromium --kiosk http://www.google.com

Test Youtube-dl

youtube-dl youtube_video_url

I’ve added few arguments to the youtube-dl command to change the name of the downloaded file to be just the “-o youtube ID [dot] the extension” and with the “-f /22/18 ” I can force this script to download for me a 720p version of the video. Check out the full list of supported youtube formats here

youtube-dl  -o "%(id)s.%(ext)s" -f /22/18 youtube_video_url

After downloading the video, try playing it using OMXPLayer

omxplayer youtube_video_file

Have fun trying the keyboard shortcuts to pause/resume your video and a lot more

Fancy! Let’s automate this process using Node JS

Building the backend: NodeJS + Express + Socket.io

The source code is intended to be simple for the sake of the workshop. Here’s the project’s hierarchy:

  • public
    • js
    • css
    • images
    • fonts
    • index.html
    • remote.html
  • app.js
  • package.json

Package.json – A JSON file needed by npm to auto-install dependencies and save some basic info about your project

{
    "name": "RasPi.TV",
    "version": "0.0.1",
    "private": false,
    "scripts": {
        "start": "node app.js"
    },
    "dependencies": {
    "express": "3.1.1",
    "socket.io":"0.9.14",
    "omxcontrol":"*"
    }
}

after creating this file, go to your app directory and run the following to install the dependencies.

npm install
Note-3: Notice that a folder called node_modules will be created prior to this action, if you like to use git, don’t forget to create a .gitignore file and simply write into it “node_modules” this will ignore the folder node_modules from being added to your git project

Create the app.js file and lets start by creating our basic HTTP Express Server

var express = require('express')
  , app = express()  
  , server = require('http').createServer(app)
  , path = require('path')

// all environments
app.set('port', process.env.TEST_PORT || 8080);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));

//Routes
app.get('/', function (req, res) {
  res.sendfile(__dirname + '/public/index.html');
});

app.get('/remote', function (req, res) {
  res.sendfile(__dirname + '/public/remote.html');
});

server.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

This is our basic Express HTTP server configuration with our routes. To test what’ve done so far, you should first create the index.html and remote.html files inside the public/ directory, write your favorite “Hello, World” messages into them, then go back to your terminal and execute

node app.js

or

npm start
Note-4: That will only work if you have added the following piece of code to your package.json
...
"scripts": {
        "start": "node app.js"
    },
...

Once your server starts it will output that Express server listening on port 8080
To test your “Hello, World” pages you should run this application in the background by simply doing

node app.js &

Now this is the most primitive way to launch a Node application in the background, while learning node you might bump into some modules that automates this simple task, just like Forever.js

Now we have our Node Application up and running in the background, let’s open chromium in kiosk mode and test our Hello, World pages.

chromium --kiosk http://localhost:8080

Adding the Socket.io Magic

I strongly believe that WebSockets are the foundation of the modern web, I always like to point out the following analogy that helped me understand Socket.io

When AJAX first popped out, old skool developers felt its magic, but they’ve encountered many problems due to how different browsers handle Asynchronous JavaScript and XML requests. jQuery came with the solution by providing a nice and minimal set of functions to deal with the browsers nightmare. Socket.io did the same but for WebSockets and even more!

In order to provide realtime connectivity on every browser, Socket.IO selects the most capable transport at runtime, without it affecting the API.

  1. WebSocket
  2. Adobe® Flash® Socket
  3. AJAX long polling
  4. AJAX multipart streaming
  5. Forever Iframe
  6. JSONP Polling

In order to integrate Socket.io we should add the following to our app.js file:

var express = require('express')
  , app = express()  
  , server = require('http').createServer(app)
  , path = require('path')
  , io = require('socket.io').listen(server)
  , spawn = require('child_process').spawn

and to minify the logs add this:

//Socket.io Config
io.set('log level', 1);

When developing with Socket.io always think like you’re creating a Hello, World Chat Application. I’ve added a simple Chat Application done with Node & Socket.io on a github repo for the sake of this tutorial!

Our Socket.io Server is ready, but it doesn’t do anything, we should implement how we process messages and events sent from the client to the server.

Here’s how you implement this on the server’s side, note that you should also implement how you handle messages on the client’s side, we will see that as we progress throughout this tutorial.

io.sockets.on('connection', function (socket) {
    socket.emit('message', { message: 'welcome to the chat' });
    socket.on('send', function (data) {
        //Emit to all
        io.sockets.emit('message', data);
    });
});

Now our server Emits the message “message” whenever a new client is connected, and waits for an event name “send” to process the data and emit it back to all connected clients

In our case We have two types of clients: The RaspberryPi Display (Screen) and the Mobile Web Application (Remote)

var ss;
//Socket.io Server
io.sockets.on('connection', function (socket) {

 socket.on("screen", function(data){
   socket.type = "screen";
   //Save the screen socket
   ss = socket;
   console.log("Screen ready...");
 });

 socket.on("remote", function(data){
   socket.type = "remote";
   console.log("Remote ready...");
   if(ss != undefined){
      console.log("Synced...");
   }
 });
)};

Client Side Sockets Handeling

inside remote.html we should have the following:


	<script src="/socket.io/socket.io.js"> </script>
	<script>
	  //use http://raspberryPi.local if your using Avahi Service 
          //or use your RasperryPi IP instead
          var socket = io.connect('http://raspberrypi.local:8080');
	  socket.on('connect', function(data){
		socket.emit('screen');
	  });
	</script>

On our index.html


	<script src="/socket.io/socket.io.js"> </script>
	<script>
	  //use http://raspberryPi.local if your using Avahi Service 
          //or use your RasperryPi IP instead
          var socket = io.connect('http://raspberrypi.local:8080');
	  socket.on('connect', function(data){
		socket.emit('screen');
	  });
	</script>

Execute Shell Commands from Node Server

Node enables us to run a system command within a new child process, and listen in on its input/output. This includes being able to pass arguments to the command, and even pipe the results of one command to another. 

The basic way of executing shell commands from NodeJS is very simple

spawn('echo',['foobar']);

But if you want to pipe in the output, you should add the following function to your app.js file:

//Run and pipe shell script output 
function run_shell(cmd, args, cb, end) {
    var spawn = require('child_process').spawn,
        child = spawn(cmd, args),
        me = this;
    child.stdout.on('data', function (buffer) { cb(me, buffer) });
    child.stdout.on('end', end);
}

Adding OMXControl – the OMXPlayer controller Node Module

Luckily I found a node module on npmjs.org that let you control your OMXPlayer using Express!
just add the following to your app.js file to use it.

var omx = require('omxcontrol');

//use it with express
app.use(omx());

This will create for us the following routes, that we can use to control and play our videos:

http://localhost:8080/omx/start/:filename

http://localhost:8080/omx/pause


http://localhost:8080/omx/quit

Pretty Awesome!

Putting it all together

Our evolved app.js file


/**
 * Module dependencies.
 */

var express = require('express')
  , app = express()  
  , server = require('http').createServer(app)
  , path = require('path')
  , io = require('socket.io').listen(server)
  , spawn = require('child_process').spawn
  , omx = require('omxcontrol');

// all environments
app.set('port', process.env.TEST_PORT || 8080);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(omx());

//Routes
app.get('/', function (req, res) {
  res.sendfile(__dirname + '/public/index.html');
});

app.get('/remote', function (req, res) {
  res.sendfile(__dirname + '/public/remote.html');
});

//Socket.io Congfig
io.set('log level', 1);

server.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

//Run and pipe shell script output 
function run_shell(cmd, args, cb, end) {
    var spawn = require('child_process').spawn,
        child = spawn(cmd, args),
        me = this;
    child.stdout.on('data', function (buffer) { cb(me, buffer) });
    child.stdout.on('end', end);
}

//Save the Screen Socket in this variable
var ss;
//Socket.io Server
io.sockets.on('connection', function (socket) {

 socket.on("screen", function(data){
   socket.type = "screen";
   ss = socket;
   console.log("Screen ready...");
 });
 socket.on("remote", function(data){
   socket.type = "remote";
   console.log("Remote ready...");
 });

 socket.on("controll", function(data){
	console.log(data);
   if(socket.type === "remote"){

     if(data.action === "tap"){
         if(ss != undefined){
            ss.emit("controlling", {action:"enter"}); 
            }
     }
     else if(data.action === "swipeLeft"){
      if(ss != undefined){
          ss.emit("controlling", {action:"goLeft"}); 
          }
     }
     else if(data.action === "swipeRight"){
       if(ss != undefined){
           ss.emit("controlling", {action:"goRight"}); 
           }
     }
   }
 });

 socket.on("video", function(data){

    if( data.action === "play"){
    var id = data.video_id,
         url = "http://www.youtube.com/watch?v="+id;

    var runShell = new run_shell('youtube-dl',['-o','%(id)s.%(ext)s','-f','/18/22',url],
        function (me, buffer) { 
            me.stdout += buffer.toString();
            socket.emit("loading",{output: me.stdout});
            console.log(me.stdout)
         },
        function () { 
            //child = spawn('omxplayer',[id+'.mp4']);
            omx.start(id+'.mp4');
        });
    }    

 });
});

Building the front-end

Raspberry Pi TV Screen Front-end

Raspberry Pi TV Screen Front-end

Describing in details how I built the front-end is outside the scope of this tutorial, however I would like to point out few tips that I discovered while doing this project over the weekend.

When designing for the 10′ Screen there’s some design considerations that you should follow, Google assembled a nice set of these standards on their Developers Site

Raspberry Pi TV Remote

Raspberry Pi TV Remote

Instead of creating a typical remote, full of fake buttons, I decided to give QuoJS a try, it’s really fantastic and easy to use!

$$(".r-container").swipeLeft(function(){
socket.emit('control',{action:"swipeLeft"}); 
});

Here’s an example of how I send the message “Control” back to the server with the data action:”swipeLeft”
the server will handle that message by sending it to the screen, the screen client will handle this message by moving the selected square to the next app (Watch, Listen, Play)

I’ve also stumbled upon few trick that will let your iPhone mobile web app look like a native one with a nice icon and a splash screen.
Just add the following to your HTML <head></head> blocks

<link rel="apple-touch-icon" href="images/custom_icon.png"/>
<link rel="apple-touch-startup-image" href="images/startup.png">
<meta name="viewport" content="width=device-width initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-title" content="Remote">
<meta name="apple-mobile-web-app-capable" content="yes">

Wrap-up

This project is still a work in progress, updates coming soon. If you liked this tutorial please don’t forget to check the source code on Github and show some love by starring it .

logo_ll

Special Thanks to everyone who attended the workshop at Lamba Labs Beirut Hackerspace we hack and make pretty cool things there, come and join us if you can!

gdg_beirut

This workshop is also powered by GDG Beirut and the idea was baked during my lightning talk at the Google IO Extend Beirut 2013

t3_log_en

This tutorial is sponsored by T3 Middle East

logo_mena

And it was fully recorded by Menaveristy, the video is out! Watch it here.