PanelAPI

Hier habe ich beschrieben, wie man ein eigenes Panel für die Hausautomation erstellt, welches nun zufriedenstellend funktioniert. Um gewisse Funktionen auf dem Panel automatisiert ausführen zu können, habe ich ja auch bereits xdotool mit installiert. Dies möchte ich nun aktiv nutzen:

Use-Case

  • Wenn jemand an der Haustüre Klingelt, soll die Kamera das Klingelevent verwenden, um das Panel automatisch einzuschalten und die entsprechende Kamera-Sicht auf dem Panel zu aktivieren.
  • Da ich vom Sofa aus direkte Sicht zum Hausautomations-Panel habe, wird mir dies erlauben zukünftig zu entscheiden, ob es sich lohnt aufzustehen ;))

Umsetzung

Hier habe ich bereits beschrieben, wie man xdotool nutzen kann um bestimmte Mausklicks auf dem Panel automatisch ausführen zu können. Das Ziel ist es nun, dass die Kamera dieses Script bei einem Klingelevent aufrufen kann. Die Kamera kann sich nicht per SSH auf das Panel einloggen und ein Script aufrufen. Was sie aber kann, ist ein HTTP-GET Call ausführen. Deswegen habe ich ein sehr simples REST-API geschrieben, welches auf dem Panel HTTP-Calls entgegennehmen kann. Das REST-API nimmt damit HTTP Get Calls entgegen und führt dann das xdotool Script aus.

Sparkjava

Ich bin ein ehemaliger Java-Entwickler. Deswegen fällt die Wahl wieder auf Java. Um sowas umzusetzten, musste man früher einige Handstände vollziehen und insbesondere einen Application-Server/Container wie z.B. Tomcat betreiben.

Heute ist das zum Glück einiges einfacher. Ich nutze dafür Sparkjava. Spark ist ein leichtgewichtiges Framework, welches es erlaubt rasch WebApplikationen bzw. REST-APIs zu schreiben.

Für einen ersten Start siehe die Spark-Doku.

Ich beschreibe hier kurz, wie ich die Umsetzung gemacht habe. Achtung: Das ist nicht Best-Practice sondern ein straight-forward Ansatz, ohne spezielles exception-handling…

Maven POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ch.paket</groupId>
    <artifactId>PanelAPI</artifactId>
    <version>1.0</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.sparkjava</groupId>
            <artifactId>spark-core</artifactId>
            <version>2.9.3</version>
        </dependency>
    </dependencies>

</project>

Die Main-Methode

Die Main Methode macht folgendes

  • Starten Web-Server auf Port 8011, er hört auf get URL “/selectMobotixCamera”
  • Wenn die URL aufgerufen wird, wird das Bash-Script ausgeführt. Die return-messages des Scripts werden anschliessend gelesen und zurückgegeben:
package ch.intelli;

import spark.Request;
import spark.Response;
import spark.Route;
import spark.Spark;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args){
        spark.Spark.port(8011);
        Spark.get("/selectMobotixCamera", new Route() {
            public Object handle(final Request request, final Response response){

                String message = "";
                BufferedReader in;
                String[] cmd = new String[]{"/bin/sh", "/home/xxx/xdotool_script.sh", "parameter1"};
                Process pr = null;
                try {
                    pr = Runtime.getRuntime().exec(cmd);

                    in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
                    String line = null;
                    line = in.readLine();

                    while(line != null)
                    {
                        message = message.concat(line);
                        System.out.println(line);
                        line = in.readLine();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }

                return message;
            }
        });
    }
}

Jar als Service einbinden

Nachdem wir nun einen Spark-Webservice erstellt haben (jar), kann dieses als Service auf dem Raspberry Pi eingebunden werden:

Struktur und Service-File erstellen

cd ~
mkdir PanelAPI
cd PanelAPI
vi panelAPI.service

Inhalt panelAPI.service

[Unit]
Description=Java Service for PanelAPI
After=network.target

[Service]
ExecStart=java -jar /home/xxx/PanelAPI/PanelAPI.jar
Restart=always
User=ralwet

[Install]
WantedBy=multi-user.target

Service registrieren

sudo cp panelAPI.service /etc/systemd/system/panelAPI.service
sudo systemctl enable panelAPI.service

Nach einem Reboot ist das REST-API aktiv.

Links

https://codetober.com/how-to-start-jar-file-as-service-raspberry-pi-4/