Home

Code

Below you find all posts tagged with "Code". You can always go back to the home page if you want to read more.

Reverse Engineering Elgato Eve Energy HomeKit Characteristics

Code
Elgato Eve Energy

I got myself an Elgato Eve Energy power sensor and switch to get a feeling for HomeKit in general and how I can make use of it.

The hardware itself looks clean and stylish and the installation is a breeze: You simply plug it in, fire up the Eve app and pair it. After about a minute of setting things up I was able to switch the outlet on and off and get statistics about the current power consumption in W and total power consumption in kWh.

After another minute of playing around I was also able to talk to the outlet using Siri, how cool is that? Asking Siri "Is the living room outlet turned on?" resulted in her answer "Your outlet is turned on", telling her “Turn off the oulet in the laundry room” switched the outlet off. Awesome.

Talking to my outlets and getting statistics is nice and all but what I really want is setting up triggers and do stuff depending on each other like sending notifications once the washing machine is done. I knew that the whole HomeKit framework is not yet where I want it to be (e.g. apps working with your accessories need to be running in the foreground) and the Eve accessories aren’t there es well (e.g. no triggers) but as already said, first of all I want to get a feeling for it.

To dive in deeper I fired up Xcode and played around with the HomeKit API, looking at what the outlet exposes to see where it takes me… Oh my, what a letdown! HomeKit has the concept of characteristics that tell you about the different aspects of an accessory. This is supposed to be standardized so all HomeKit apps can communicate with all kind of HomeKit hardware but Elgato does not seem to be interested in playing along: Yes, the characteristics are available but there is not the slightest bit of information about what the individual characteristics are representing and neither about their format.

Asking the Elgato support about a documentation of characteristics resulted in a short "Nope, documentation is not available". Thank you!

After being annoyed for a couple of hours I decided doing some reverse engineering to see what characteristics Eve Energy exposes and to make some sense of it. To do that I tried several test scenarios and dumped the value of all characteristics as well as the output of the Eve app in these.

Now it was simply a task of comparing characteristics, guessing formats and some calculations. To cut a long story short I summarized what I learned about Eve Energy in a Gist on GitHub. I haven’t made sense of everything up to now but it should be a good start. I try updating the Gist as I learn more and am open for comments and additions.

DipInit Mobile

Diplomacy, Code

DipInit Mobile is the solution for the rare occasions where you don't have your Mac with you but still need to allocate powers for a game of Diplomacy. It is a web application running in a browser, allowing you to do exactly what you already know from the desktop version of DipInit: Allocating countries for a game of Diplomacy based on the players' priorities.

To use DipInit Mobile, open it in your favorite browser and prioritize away. The web app was designed to work on mobile phones and was successfully tested on iPhone 5+ and large screen Android devices. For even quicker access, add DipInit to your smartphone's home screen.

Click here to open DipInit Mobile and get your game on!

node-mailchimp 0.8.2 - Bugfixes and Mandrill API

node.js, Code

node-mailchimp has finally been updated to version 0.8.2 with some long overdue bugfixes and is available via npm and GitHub. Good things come to those who wait.

In addition to the bugfixes I added support for the Mandrill API which should be working fine but was not properly tested up to now. I would not mind if you play around with it. Mandrill is a new product from the MailChimp team that provides email as a service running on the MailChimp infrastructure. Mandrill support in node-mailchimp is not yet available via npm but only directly from the GitHub repository.

If you want to give it a try, have a look at the following example. Further information can be found on the GitHub project page.

First of all you need an instance of the Mandrill API wrapper:

var MandrillAPI = require('mailchimp').MandrillAPI;

try { 
    var mandrill = new MandrillAPI('Your API Key');
} catch (error) {
    console.log('Error: ' + error);
}

With the wrapper instantiated you can now use all methods described in the Mandrill API documentation. The method names in this wrapper reflect the method names of the API and are named category_method with dashes (-) in method names being replaced by underscores (_).

The API method send-template from the API category messages would thus be available as messages_send_template in this wrapper. The parameters of the methods are passed as an object, omitting the API key which was already set earlier.

var params = {
	template_name: 'Name of the template to send',
	template_content: 'An array of template content to send',
	message: 'Information on the message to send'
};

mandrill.messages_send_template(params, function (data) {
    if (data.error)
        console.log('Error: '+data.error+' ('+data.code+')');
    else
        console.log(data); // Do something with your data!
});

A second way to use the Mandrill API is by using the call method instead of the wrapped methods directly. The call method differentiates between the categories and methods of the Mandrill API more clearly and automatically converts dashes to underscores. The example above using the call method looks like the this:

var params = {
	template_name: 'Name of the template to send',
	template_content: 'An array of template content to send',
	message: 'Information on the message to send'
};

mandrill.call('messages', 'send-template', params, function (data) {
    if (data.error)
        console.log('Error: '+data.error+' ('+data.code+')');
    else
        console.log(data); // Do something with your data!
});

Any feedback on the Mandrill functionality as well as node-mailchimp in general is much appreciated. Just contact me via the GitHub project page or Twitter.

logo.js

Code, JavaScript
logo.js

Officially announced at JSConf EU 2011, but used for almost a year and half prior by the community, we are just going to offer this logo for use with JS projects. If you like it use it, if you don’t that’s cool too. Just don’t complain unless you want to offer a different one, post your alternative to twitter with the tag #jslogo. We are releasing this under a WTFPL license so you can print it on anything, use it anywhere, and never have to worry about royalties, licenses, and other such things.

This is a gift from JSConf to you, with love!

Enjoy.

voodootikigod

node-mailchimp 0.8.0 - Now with OAuth2 goodness

node.js, Code

The latest version of node-mailchimp is now available from npm and GitHub. Be sure to update to have fun with the brand new OAuth2 functionality. Yay!

Below you find a rundown on how the OAuth2 process is handled by node-mailchimp along with an example on how to use it.

First of all you have to require and instantiate the module with a couple of parameters. The parameters clientId and clientSecret are required parameters available from MailChimp, a detailed explanation on how to get these can be found in the MailChimp OAuth2 documentation.

var MailChimpOAuth = require('mailchimp').MailChimpOAuth;

var options = {
    clientId: 'Your MailChimp client id',
    clientSecret: 'Your MailChimp client secret',
    serverUri: 'http://www.example.com',
    redirectUri: 'http://www.example.com/successfulLogin.html'
};

var oauth = new MailChimpOAuth(options);

When instantiating the module a server is automatically set up that listens on HTTP requests from MailChimp. This server needs to be available from the internet at the URI specified by serverUri, more on that later.

We're using OAuth2 as we want the user to allow access to MailChimp without giving his credentials to us so we need to send him to the MailChimp server to authorize there. Using the following method of MailChimpOAuth we receive a special URI to the MailChimp login form the user needs to be redirected to in a browser.

oauth.getAuthorizeUri();

That URI also includes the serverUri specified as a parameter and exactly that’s the URI the user will be redirected to upon successful authorization. The answer from MailChimp to that URI includes a code we need later on. If you additionally specified the parameter redirectUri the user is redirected to that page in the browser so he doesn't see a blank page.

The code received is now used to request an access token from MailChimp which in turn is used to get some additional metadata for our connection. All of that happens automagically, though, you don't have to do anything except listening for an authed event issued by MailChimpOAuth once everything is finished.

oauth.on('authed', function (apiKey) {
});

As you can see the event receives the parameter apiKey which you can pass on to other API functionality. That API key isn't really an API key to be quite honest, MailChimp is treating the access token similar to an API key, as explained in their API docs, though.

That's it! Having the API key you can now do whatever you want with the API, for example reading a list of the last 25 campaigns like follows.

var MailChimpAPI = require('mailchimp').MailChimpAPI;

oauth.on('authed', function (apiKey) {

    try { 
        var api = new MailChimpAPI(apiKey, { version : '1.3', secure : false });
    } catch (error) {
        console.log('Error: ' + error);
    }

    api.campaigns({ start: 0, limit: 25 }, function (data) {
        if (data.error)
            console.log('Error: '+data.error+' ('+data.code+')');
        else
            console.log(JSON.stringify(data)); // Do something with your data!
    });

});

One more thing: It makes sense listening on the error event of MailChimpOAuth as well so you're hopefully able to tell what went wrong, if something goes wrong.

oauth.on('error', function (message) {
    console.log('Error: '+message);
});

Any feedback is much appreciated as version 1.0 is getting closer and I want a solid wrapper by then that not only implements all functionality available in the MailChimp API (it does that already) but is also a breeze to work with.

Navigating the Makernote hell

node.js, Code

Trying to enhance node-exif, my Exif library for node.js, I came across Makernotes which really do annoy me right now.

Makernotes are part of the Exif specification, a standard for storing information about an image inside the image file, especially used in JPEGs. Where Exif itself is well specified and documented, the Makernote part is everything but. The specification describes the Makernote as "a tag for manufacturers of Exif writers to record any desired information. The contents are up to the manufacturer, but this tag should not be used for any other than its intended purpose".

As you can imagine the part the contents are up to the manufacturer led to a lot of different specifications with most of them being proprietary. Hurray! Luckily most of the specifications have been reverse engineered by now, for example by Evan Hunter, and are available around the internet, no one seems to claim completeness, though.

As if the proprietary nature with missing specifications isn't enough the Makernotes bring a couple of other problems which I’m not going to elaborate on here. If you’re interested you can check the Exiv2 Makernote page for a start.

Anyway, after digging for information and writing some code to extract the Makernote data I now need to test if everything works and iron out some bugs. This is why I'm looking for pictures taken with cameras by the following manufacturers and hope you can help me out:

Agfa, Asahi, Canon, Casio, Contax, Epson, Fujifilm, Foveon, Kodak, Konica, Kyocera, Leica, Mamiya, Minolta, Nikon, Olympus, Panasonic, Pentax, Ricoh, Samsung, Sigma, Sony.

If you own a camera by one of the manufacturers, know someone who does or simply have a picture taken with one of these cameras around I’d really appreciate if you can drop me a line and/or the picture on Twitter or GitHub. Thanks!