Back- and front-end web developer at Q42. Usually works with C# and Javascript but occasionally wanders off... Follow me at @lukasvan3l
Don't wanna be here? Send us removal request.
Link
Last week the annual O’Reilly Solid conference was held at Fort Mason in San Francisco. Two days packed with “software, hardware, everywhere”.
Main takeaway / TL;DR
15 years ago the entry level to creating software was lowered far enough for people to easily step in. The number of software...
1 note
·
View note
Text
Connected lighting is jump-starting home automation
I've been working on the Philips hue lightbulbs for more than a year now, specifically on the internet connectivity part. And I've found that hue is the start of a much bigger movement. Let me whow you.
Remote control The hue kit that you can buy at the Apple store has a few built-in remote features. First, there's the basic "remote control" from outside of your house. Secondly there's geofencing. By setting a perimeter around your house, you can let your app turn the lights on before you even open the front door. And thirdly, there's IFTTT, which lets you create triggers on internet events to control your lights. For example, you can have the lamp in your hallway turn blue if it's going to rain and you should bring your umbrella when you go out.
Build your own apps Philips also opened up the internal API of the hue bridge to the public, allowing you to build your own apps. This of course resulted in loads of different interfaces on various devices.
But it also sparked more creative minds, like the hue disco app, that reacts to sounds via the microphone, and you can create your own in-home disco lighting. Or the goldee app that uses dynamic scenes, where the light gradually and slightly changes color over time, to mimic a more natural lighting.
Combining with other devices But that internal API also enables your lights to talk to other devices in your house. The goldee box is a wall switch that can control your hue (or lifx, or ilumi) lighting, and improves your interaction with lighting without the need of a smartphone.
Take it a step further and you arrive at the revolv. It's a box that you install somewhere in your house, and it can talk multiple channels. Not just lighting, but also your wemo outlet, yale lock, sonos sound system and others. And this thing is already in production, I have one sitting next to me on my desk at Q42.
The future These things all exist today. Look how far we've gotten. But there's still a bright future ahead for home automation. The nest thermostat and nest secure are doing a pretty good job at presence awareness and more importantly, presence prediction. If your house knows you're going to need a warmed-up house, it can arrange that for you. Same goes for lights, music, etc. And it's not just your house that's connected to this ecosystem. The Tesla Model S for instance, also has an API.
So hue is really at the start of a bigger ecosystem of connected products. By being an open system, it's using that ecosystem to make itself more useful. And I'm excited to be a part of that.
2 notes
·
View notes
Text
Hosting static files on Google App Engine (GAE)
I'm currently working on an app for the new FirefoxOS phone's hitting the market. A small html/js/css only app that you can run offline and controls your Philips Hue lightbulbs. Who wouldn't want a $60 dollar phone to control your $200 lightbulbs? My point exactly.
So I have a really lightweight app, that I want hosted. And as I'm doing nearly everything with Google App Engine hosting these days, I want the html/js/css files hosted there.
The easiest way, I found, was to create a Python project. You'll only need one extra file on top of the static files you have, and put all your files in a subdirectory of the project (say "static_files"). The file is called app.yaml and has something like the following content:
application: firefoxos-hue version: 1-0 #no . characters allowed :( runtime: python27 api_version: 1 threadsafe: true
handlers: - url: / # redirect the homepage to index.html static_files: static_files/index.html upload: static_files/index.html - url: /(.*) # serve all other files as if they were in the root static_files: static_files/\1 upload: static_files/(.*)
The top block is some metadata about the project, below that the URL handlers. One handler serves index.html when users access the homepage. The second serves all static files from the static_files directory directly to users.
Now you can use the Google App Engine Launcher to import this directory, run it locally, or deploy it as an appengine project.
1 note
·
View note
Text
Open Data Anthology
I was at the The Hague Open Data Meetup this evening. It was held at the Dutch National Library (KB), and I recognized a scenario they'd encountered during their first Hackathon: the developers didn't know what to do with the data the KB offered, and nothing came out of it.
The problem is that the data of the KB wasn't appealing to the attendees of the hackathon. The data was OCR-scanned 18th century books. Who attends hackathons? Developers. What do they know of 18th century literature? Nothing.
To get meaningful information out of the dataset, you need other people than just developers. Researchers and people that have insight into the content itself, they are the people that come up with interesting concepts, so you have to get them aboard!
Let's start with giving the event a different name. "Hackathon" is a really nerdie term, and going to scare away others.
How about "Jam", "Anthology", "Assembly", "Poem night"...
0 notes
Text
Single Page Interface using Backbone
Here's a little snippet that contains the bare basics of a single page interface built in backbone.
var AppRouter = this.Backbone.Router.extend({ routes: { "*actions": "defaultRoute" } });
var app_router = new AppRouter();
This creates a Backbone Router. When this router receives a "navigate" command, it in turn triggers the "route:defaultRoute" event.
app_router.on('route:defaultRoute', function (actions) { var contentcontainer = $('#body .main-content'); contentcontainer.html('Loading...'); $.get('/' + actions).then(function (data) { contentcontainer.html('<div>ajax loaded:</div>' + data); }, function (data) { contentcontainer.html('An error occurred: ' + data); }); });
Now, when the defaultRoute is triggered, the url it is navigating towards is retrieved via ajax and then inserted in the contentcontainer.
this.Backbone.history.start({ pushState: true, root: "/", silent: true });
To keep the history and url's working, we initiate the Backbone history, with pushState.
$(function () { $('body').on('click', 'a', function (evt) { evt.preventDefault(); app_router.navigate($(this).attr('href'), { trigger: true }); }); });
And then to tie things together: on each link in the page, prevent the default action and trigger the routing.
On the server you can see if the request is AJAX or not. If it is, don't return the header and footer, just the contents of the main-content element. If it's not and AJAX call, then serve the entire page. This way the entire site works like a single page interface, but when you reload the page it'll work too.
This is especially neat because search engines often don't use javascript the same way your typical user does. Using the above approach makes the website navigable without javascript.
Best of all, it's extensible! Want a specific pagetransition to animate? No problem, create a route for it and handle that specific transition.
Enjoy!
0 notes
Text
OkCupid put a smile on my face
A colleague encouraged me to try out OkCupid. For educational purposes of course: they had a very addictive way of getting users to answer a bunch of questions about themselves. He had himself answered hundreds (!!) of questions.
But what I liked most about my 5 minutes on OkCupid was the feedback on the registration flow. Check out the city box, when I fill in that I'm from Leiden:
I really liked the feedback and it's tone of voice. But it got me wondering what it would do with more difficult input. So I typed "haag":
Awesome, so it had a good location search. Now let's just pick one and move on:
Whow! Didn't see that coming :) The password feedback also put a smile on my face:
After this experience I was looking forward to the questions that I was actually here for. But I didn't even get beyond the first question: "What are you looking for? A: Sex or B: True love". How am I going to explain either answer to my wife?
0 notes
Photo

Look at that! Using the mobile interface we built, we can control the lights from outside the building! Hueray!
0 notes
Video
It's w00tcamp time!!! And I'm creating awesome stuff with the Philips Hue lamps! George from Philips brought about 50 lamps this way and we're lighting up the entire office :)

0 notes
Text
Social responsibility
Today I held a presentation at Q42, about Q42. The listeners were four entrepreneurs from developing countries (kosovo, pastina) who are in the process of building or running a technical enterprise. The BiD Network helps these people by getting them in contact with companies that can aid them in their development process.
When they asked me, I couldn't say no to an oppertunity to tell people how awesome Q42 is. And if I could help these entrepreneurs by doing so, all the more reason.
So I told them about our developer-centric working environment, with project- and company management as facilitators to the all-mighty developers. About our 48 employees of which 45 are developers. Each one motivated by the cool projects they do, the cutting-edge technology they're using, weekly passion-time, yearly w00tcamp, company outings, and so on.
The entrepreneurs were quite amazed when they learned that our founder Kars at some point hired a CEO so he could spend more time developing again. The people I told the story to were at this point founders of small companies, but they hadn't foreseen this possible future for themselves yet ;-)
For me personally it was a good exercise in explaining outsiders what Q42 is and what it stands for. The devil is in the details, and it's quite a challenge to put your finger on the sweet spot. And of course, a little CSR (that's what google translate makes of it...) never hurts!
2 notes
·
View notes
Text
marketing.css
Small tip: don't name your static files like "marketing.css", because some ad blockers might think it's untrustworthy and block the download of it :-$
Just found out the hard way...
0 notes
Text
Class not enhanced correctly - Siena
When calling my EnhancedModel.findById(Object) function, I get this error:
UnsupportedOperationException occured : Class not enhanced correctly
Turns out this is because inside the EnhancedModel I created an overload of the findById function with two parameters: findById(String, String).
This is also the case with getByKey(Object) function; if you create an overload with other parameters; class not enhanced correctly.
0 notes
Text
PlayFramework & GAE localization editor
Play Framework includes the messages-file way of handling the translation of values. Unfortunately, this won't do for the site I'm creating: it has 7 different languages and editors need to be able to translate on-the-fly.
So I thought I'd share the solution that's now implemented: translations via the BigTable datastore.
Datastore First of all, there's a model:
@Entity public class Translation extends EnhancedModel {
@Id(Generator.AUTO_INCREMENT) public Long id;
public String locale; public String name; public String translation;
@Index("qidx") public List<String> q;
@PreSave @PreInsert @PreUpdate public void updateSearchFields() { if (this.translation != null && this.translation.isEmpty()) this.translation = null; this.q = Utils.splitSearchWords(String.format("%s %s", name, translation)); } }
I'm using Siena 2.0.7, that's where the annotations are coming from. The "q" field gets indexed and the editors can search on that field when they're looking for a translation. OnSave of a record this field also gets updated.
PlayPlugin Next up is the code that actually translates the &{'translatable message'} that the views are asking for. This is going to be a PlayPlugin overriding the getMessage function:
public class MessagesDbPlugin extends PlayPlugin { @Override public String getMessage(String locale, Object key, Object... args) { return String.format(getTranslation(locale, key.toString()), args); } }
Now we're set up to get the actual translations from the database. Of course we need to also cache them using the gae memcached client, as it's much faster then the actual datastore.
private static String getTranslation(String locale, String key) { if (Utils.isNullOrEmpty(key)) return "";
// look up in cache String value = Cache.get(Translation.generateCacheKey(locale, key), String.class); if (!Utils.isNullOrEmpty(value)) return value;
// look up in database Translation t = Translation.all().filter("locale", locale).filter("name", key).get(); if (t != null) { cache(t); return Utils.isNullOrEmpty(t.translation) ? t.name : t.translation; }
// validate the locale: is it possible? if (!Play.langs.contains(locale)) { Logger.error("Invalid language: %s", locale); return ""; }
// not found: insert into the database and the cache for each language for (String lang : Play.langs) { Translation newT = new Translation(); newT.locale = lang; newT.name = key; newT.translation = null; newT.save(); cache(newT); }
// now return the key, as the value is empty
return key; }
That's it, you're set! Each time a translation is requested that doesn't yet exist in the database, it gets inserted. So if you accidentally skip one and don't enter it in the database, is pops up in the cms anyway.
CMS
I'm not going to display all the javascript, html and css involved in making the translations editable, but it's fairly easy. Getting the translations you searched for is plain and simple:
Translation.all().filter("locale", locale).filter("q", q.toLowerCase().trim()).fetch();
And don't forget to invalidate the cache entry after you saved a new translation!
That's it! I might make a Play Module out of it some day, if enough people ask me to :)
0 notes
Text
Set play framework id for gae:deploy
We're working on setting up our playframework / google appengine project with a full DTAP roadmap. The way we did that at Q42 is first to integrate our project in Teamcity; teamcity now even does automatic deploys to google appengine!
One problem I encountered was that I wanted to set a specific Framework ID when executing the gae:deploy command. Turns out, you can just append the id just as you would on a run command. So:
play gae:deploy - -%gae-dev
or
play gae:deploy - -%gae-prod
Now you can have different values in your application.conf for different appengine environments, for instance
%gae-dev.application.baseUrl=http://project-dev.appspot.com/
or
%gae-prod.application.baseUrl=http://project.appspot.com/
0 notes
Link
For the Museums and the Web 2012 Hackathon that I participated in, I created Museumify. You input a picture of yourself, and your face will be inserted on top of the face of a piece of art. Here's obama:
The technique behind it is fairly simple: it uses face.com where you input the URL to an image and it returns JSON containing the location of the eyes, nose, mouse, etc. Here's a sample:
{"width":140, "height":140, "tags":[{"recognizable":false, "width":77.86, "height":77.86, "center":{"x":48.93,"y":53.93}, "eye_left":{"x":29.65,"y":37.36}, "eye_right":{"x":67.52,"y":38.95}, "mouth_left":{"x":30.09,"y":73.59}, "mouth_center":{"x":46.26,"y":78.64}, "mouth_right":{"x":65.45,"y":75.99}, "nose":{"x":44.89,"y":61.78}, "ear_left":null, "ear_right":null, "chin":null, "yaw":4.43, "roll":3.56, "pitch":-5.05, "attributes":{"face":{"value":"true","confidence":96}, "gender":{"value":"male","confidence":37}, "glasses":{"value":"true","confidence":96}, "smiling":{"value":"true","confidence":95}}}]}
With the eye, mouth and nose information, you can find out what direction the face is looking at, if it's en profile etc. The museumify site only crops the picture and overlays it, but a lot more is possible this way. Think of overlaying your picture on an art object that's looking the same direction.
Maybe in the future I'll pick up the project again to include this. But for now, it was a nice experiment and will just be sitting there :)
4 notes
·
View notes
Text
PlayFramework + GAE OnApplicationStart code
Google App Engine works in mysterious ways! The default @OnApplicationStart doJob of play framework apparantly doesn't work. But there's a workaround if you want to have code executed when your application is booted. For instance, to inject bootstrap data in your database.
The solution I found makes use of the Plugins functionality of play. A plugin can execute code on application start, exactly what we need!
So here's my code to create a one-class-plugin:
package plugins;
import play.*; import play.Play.Mode; import play.test.Fixtures;
public class Bootstrap extends PlayPlugin {
@Override public void onApplicationStart() { if (Play.mode == Mode.DEV) { Logger.info("Loading data............."); Fixtures.deleteAllModels(); Fixtures.loadModels("data.yml"); } Logger.info("App loaded!"); }
}
And then one little extra: put a "play.plugins" file in your /app directory with the following contents:
4242:plugins.Bootstrap
This registers the plugin with a priority of 4242 with Play. SpringPlugin, for instance, has a priority of 1000.
That's it! No ugly url's to call after a deploy, this code gets executed automagically.
4 notes
·
View notes
Text
Addthis bug!
Addthis updated its code somewhere in the past days. At two specific places in their code they set "d = document". Because there's no "var" in front of this, window.d gets set to document. This code conflicts with a library we use (spiffy) that also binds to window.d.
The symptoms are javascript breaking, and when you open the console you get js errors on every mouse move.
0 notes
Text
ISingletonDependency is tenant specific!
I don't know if it's positive or negative, but certainly worth knowing if you're working with the OrchardCMS Multitenancy module:
A different instance of the ISingletonDependency is created for each tenant.
15 notes
·
View notes