{"id":1639,"date":"2022-07-06T21:34:04","date_gmt":"2022-07-06T21:34:04","guid":{"rendered":"https:\/\/www.dev-metal.ch\/?p=1639"},"modified":"2022-07-07T11:21:12","modified_gmt":"2022-07-07T11:21:12","slug":"panelapi","status":"publish","type":"post","link":"https:\/\/www.dev-metal.ch\/?p=1639","title":{"rendered":"PanelAPI"},"content":{"rendered":"<p><a href=\"https:\/\/www.dev-metal.ch\/?p=1602\" target=\"_blank\" rel=\"noopener\">Hier<\/a> habe ich beschrieben, wie man ein eigenes Panel f\u00fcr die Hausautomation erstellt, welches nun zufriedenstellend funktioniert. Um gewisse Funktionen auf dem Panel automatisiert ausf\u00fchren zu k\u00f6nnen, habe ich ja auch bereits <a href=\"https:\/\/www.dev-metal.ch\/?p=1602#xdotool\" target=\"_blank\" rel=\"noopener\">xdotool mit installiert<\/a>. Dies m\u00f6chte ich nun aktiv nutzen:<\/p>\n<h2>Use-Case<\/h2>\n<ul>\n<li>Wenn jemand an der Haust\u00fcre Klingelt, soll die Kamera das Klingelevent verwenden, um das Panel automatisch einzuschalten und die entsprechende Kamera-Sicht auf dem Panel zu aktivieren.<\/li>\n<li>Da ich vom Sofa aus direkte Sicht zum Hausautomations-Panel habe, wird mir dies erlauben zuk\u00fcnftig zu entscheiden, ob es sich lohnt aufzustehen ;))<\/li>\n<\/ul>\n<h2>Umsetzung<\/h2>\n<p><a href=\"https:\/\/www.dev-metal.ch\/?p=1602#Mausklicks_fuer_Kamera-Auswahl\" target=\"_blank\" rel=\"noopener\">Hier<\/a> habe ich bereits beschrieben, wie man xdotool nutzen kann um bestimmte Mausklicks auf dem Panel automatisch ausf\u00fchren zu k\u00f6nnen. 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\u00fchren. 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\u00fchrt dann das xdotool Script aus.<\/p>\n<h3>Sparkjava<\/h3>\n<p>Ich bin ein ehemaliger Java-Entwickler. Deswegen f\u00e4llt die Wahl wieder auf Java. Um sowas umzusetzten, musste man fr\u00fcher einige Handst\u00e4nde vollziehen und insbesondere einen Application-Server\/Container wie z.B. Tomcat betreiben.<\/p>\n<p>Heute ist das zum Gl\u00fcck einiges einfacher. Ich nutze daf\u00fcr <a href=\"https:\/\/sparkjava.com\" target=\"_blank\" rel=\"noopener\">Sparkjava<\/a>. Spark ist ein leichtgewichtiges Framework, welches es erlaubt rasch WebApplikationen bzw. REST-APIs zu schreiben.<\/p>\n<p>F\u00fcr einen ersten Start siehe die <a href=\"https:\/\/sparkjava.com\/documentation#getting-started\" target=\"_blank\" rel=\"noopener\">Spark-Doku<\/a>.<\/p>\n<p>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&#8230;<\/p>\n<h4>Maven POM<\/h4>\n<pre>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"\r\n         xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\r\n    &lt;groupId&gt;ch.paket&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;PanelAPI&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.0&lt;\/version&gt;\r\n\r\n    &lt;properties&gt;\r\n        &lt;maven.compiler.source&gt;1.8&lt;\/maven.compiler.source&gt;\r\n        &lt;maven.compiler.target&gt;1.8&lt;\/maven.compiler.target&gt;\r\n    &lt;\/properties&gt;\r\n\r\n    &lt;dependencies&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;com.sparkjava&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;spark-core&lt;\/artifactId&gt;\r\n            &lt;version&gt;2.9.3&lt;\/version&gt;\r\n        &lt;\/dependency&gt;\r\n    &lt;\/dependencies&gt;\r\n\r\n&lt;\/project&gt;<\/pre>\n<h4>Die Main-Methode<\/h4>\n<p>Die Main Methode macht folgendes<\/p>\n<ul>\n<li>Starten Web-Server auf Port 8011, er h\u00f6rt auf get URL &#8222;\/selectMobotixCamera&#8220;<\/li>\n<li>Wenn die URL aufgerufen wird, wird das Bash-Script ausgef\u00fchrt. Die return-messages des Scripts werden anschliessend gelesen und zur\u00fcckgegeben:<\/li>\n<\/ul>\n<pre>package ch.intelli;\r\n\r\nimport spark.Request;\r\nimport spark.Response;\r\nimport spark.Route;\r\nimport spark.Spark;\r\n\r\nimport java.io.BufferedReader;\r\nimport java.io.IOException;\r\nimport java.io.InputStreamReader;\r\n\r\npublic class Main {\r\n    public static void main(String[] args){\r\n        spark.Spark.port(8011);\r\n        Spark.get(\"\/selectMobotixCamera\", new Route() {\r\n            public Object handle(final Request request, final Response response){\r\n\r\n                String message = \"\";\r\n                BufferedReader in;\r\n                String[] cmd = new String[]{\"\/bin\/sh\", \"\/home\/xxx\/xdotool_script.sh\", \"parameter1\"};\r\n                Process pr = null;\r\n                try {\r\n                    pr = Runtime.getRuntime().exec(cmd);\r\n\r\n                    in = new BufferedReader(new InputStreamReader(pr.getInputStream()));\r\n                    String line = null;\r\n                    line = in.readLine();\r\n\r\n                    while(line != null)\r\n                    {\r\n                        message = message.concat(line);\r\n                        System.out.println(line);\r\n                        line = in.readLine();\r\n                    }\r\n\r\n                } catch (IOException e) {\r\n                    e.printStackTrace();\r\n                }\r\n\r\n                return message;\r\n            }\r\n        });\r\n    }\r\n}<\/pre>\n<h3>Jar als Service einbinden<\/h3>\n<p>Nachdem wir nun einen Spark-Webservice erstellt haben (jar), kann dieses als Service auf dem Raspberry Pi eingebunden werden:<\/p>\n<p>Struktur und Service-File erstellen<\/p>\n<pre>cd ~\r\nmkdir PanelAPI\r\ncd PanelAPI\r\nvi panelAPI.service<\/pre>\n<p>Inhalt panelAPI.service<\/p>\n<pre>[Unit]\r\nDescription=Java Service for PanelAPI\r\nAfter=network.target\r\n\r\n[Service]\r\nExecStart=java -jar \/home\/xxx\/PanelAPI\/PanelAPI.jar\r\nRestart=always\r\nUser=ralwet\r\n\r\n[Install]\r\nWantedBy=multi-user.target<\/pre>\n<p>Service registrieren<\/p>\n<pre>sudo cp panelAPI.service \/etc\/systemd\/system\/panelAPI.service\r\nsudo systemctl enable panelAPI.service<\/pre>\n<p>Nach einem Reboot ist das REST-API aktiv.<\/p>\n<h1>Links<\/h1>\n<ul>\n<li><a href=\"https:\/\/sparkjava.com\/\" target=\"_blank\" rel=\"noopener\">Spark<\/a><\/li>\n<\/ul>\n<p>https:\/\/codetober.com\/how-to-start-jar-file-as-service-raspberry-pi-4\/<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hier habe ich beschrieben, wie man ein eigenes Panel f\u00fcr die Hausautomation erstellt, welches nun zufriedenstellend funktioniert. Um gewisse Funktionen auf dem Panel automatisiert ausf\u00fchren zu k\u00f6nnen, habe ich ja auch bereits xdotool mit installiert. Dies m\u00f6chte ich nun aktiv nutzen: Use-Case Wenn jemand an der Haust\u00fcre Klingelt, soll die Kamera das Klingelevent verwenden, um [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"no","_lmt_disable":"","footnotes":""},"categories":[10],"tags":[],"class_list":["post-1639","post","type-post","status-publish","format-standard","hentry","category-techdocs"],"modified_by":"ralph","_links":{"self":[{"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=\/wp\/v2\/posts\/1639","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1639"}],"version-history":[{"count":16,"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=\/wp\/v2\/posts\/1639\/revisions"}],"predecessor-version":[{"id":1655,"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=\/wp\/v2\/posts\/1639\/revisions\/1655"}],"wp:attachment":[{"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1639"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1639"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dev-metal.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}