RasPi does the Home Automation (Part V): Just around the corner

Looking for a lightweight Java-based solution to run REST services on embedded systems I already had an eye on the Vert.x project. I was excited to see there is a talk about it on the agenda of the Herbstcampus in Nuremberg last week (I talked about my RasPi projects).

It was a pleasure to attend the talk with Eberhard Wolff about Vert.x!

Inspired by Eberhards presentation I was thrilled to give it a try and I created my first “Vertical” as a REST service for my little home automation project (as an alternative to my custom HttpServer).
Clearly I will only need a very small fraction of the provided power!

Setup Vert.x on RasPi

  • Download and Install Vert.x
    e.g. extract the package to /opt
  • put ‘vert.x-2.0.1-final/bin‘ on path:
    e.g. add 'export PATH=/opt/vert.x-2.0.1-final/bin:$PATH' at the and of ~/.bashrc.

Check installation

vertx-version

Implementing the service

I added vertx-core & vertx-platform as maven dependency to my Sweethome project.
Note the ‘provided’ scope: the dependencies are just used at compile time. At runtime the needed libs will be provided by the vertx environment.

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>2.0.1-final</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-platform</artifactId>
    <version>2.0.1-final</version>
    <scope>provided</scope>
</dependency>

Now I am prepared to give it a try with a very simple so called ‘Verticle‘ implementing a request handler which is called in case the REST call signature is matching.

Basically the URL contains the parameter for my Send-command mentioned in a previous post:

http://IP:PORT/intertechno/send/HOUSE_CODE/GROUP/DEVICE>/COMMAND

public class IntertechnoVerticle extends Verticle {

    @Override
    public void start() {
        RouteMatcher routeMatcher = new RouteMatcher();
        routeMatcher.get("/intertechno/send/:houseCode/:group/:device/:command", new Handler<HttpServerRequest>() {
            @Override
            public void handle(HttpServerRequest req) {
                container.logger().info("received request from: " + req.remoteAddress());
                
                String deviceCode = String.format("%s %s %s", req.params().get("houseCode"), req.params().get("group"), req.params().get("device"));
                String commandParam = (String) req.params().get("command");
                Send.Command command = "0".equals(commandParam) ? Send.Command.TURN_OFF : Send.Command.TURN_ON;
                
                container.logger().info("Send: " + deviceCode + " " + command.name());
                new Send().send(deviceCode, command);
                container.logger().info("OK");
                
                req.response().setStatusCode(200);
                req.response().end("<b>Send: " + deviceCode + " " + command.name() + "</b>");
            }
        });

        int port = 14880;
        HttpServer server = vertx.createHttpServer();
        server.requestHandler(routeMatcher)
                .listen(port);

        container.logger().info("---------------------------------------");
        container.logger().info("-                                     -");
        container.logger().info("-      S W E E T H O M E  SERVER      -");
        container.logger().info("-                                     -");
        container.logger().info("---------------------------------------");
        container.logger().info("Server started.");
        container.logger().info("Listening on port " + port);
        container.logger().info("Waiting for incoming requests...");
    }
}

Deploy and run vertx

Start the server…

vertx run de.jensd.sweethome.server.vertx.IntertechnoVerticle -cp /opt/lib/sweethome-1.0.4-SNAPSHOT.jar

vertx-intertechno-verticle

… and call the service:

vertx-intertechno-url

You can get the code here.

[EOM]