Max Cube Rest Webservice

Hallo Zusammen,

ich habe hier auf der Basis von MaxBuddy und der eQ-3 Standardklassen einen kleinen Java Rest (JSON) Webservice gebaut.

Folgende Funktionen werden aktuell unterstützt:

  1. Alle Räume mit allen Devices werden zurückgeliefert (Settings, Temperaturen, Ventilstellung, …)

http://{host}:{port}/max-ws/rest/rooms

  1. Ein einzelner Raum mit allen Devices werden zurückgeliefert

http://{host}:{port}/max-ws/rest/rooms/{roomId}

  1. Auto Mode setzen (mit roomId = 0 werden alle Räume angesprochen :slight_smile:

http://{host}:{port}/max-ws/rest/rooms/{roomId}/mode/AUTO

  1. Manueller Mode setzen mit Temperatur

http://{host}:{port}/max-ws/rest/rooms/{roomId}/mode/MANUAL?temp={temp}

  1. Auto Mode mit Temperatur setzen

http://{host}:{port}/max-ws/rest/rooms/{roomId}/mode/AUTO_TEMPERATURE?temp={temp}

  1. Temporärer Modus mit Temperatur und Dauer (Party Modus)

http://{host}:{port}/max-ws/rest/rooms/{roomId}/mode/TEMPORARY?temp={temp}&hours={hours}

Installation:

  1. Download aller benötiger Dateien:

https://dl.dropbox.com/u/179978/max.zip

  1. JDK 1.7 installieren

  2. Tomcat7 als Windows Service (oder unter Linux) installieren

  3. Den Tomcat 7 Windows Service mit einen User Account starten (kein Systemaccount)

  4. In die max.properties die eigene Cube IP und Port eintragen und in das Homeverzeichnis des Tomcat Benutzers kopieren.

  5. max-ws.zip in das Tomcat webapp Verzeichnis entpackagen. (C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\max-ws)

  6. Da ich nicht die eQ-3 und die maxBuddy Klassen hier hochladen wollte, müssen die noch nachträglich in das WAR File kopiert werden. Wenn man maxBuddy installiert hat findet man die 4 Jar Dateien hier:

  7. C:\Program Files (x86)\MAX!Buddy\app\buddy.jar

  8. C:\Program Files (x86)\MAX!Buddy\launcher.jar

  9. C:\Users$HOME\AppData\Roaming\MAXBuddy\ext-libs\maxupdate\lib\MaxEssentialsBackend-1.3.6.jar

  10. C:\Users$HOME\AppData\Roaming\MAXBuddy\ext-libs\maxupdate\lib\MaxLocalBackend-1.3.6.jar

Alle Jars müssen nach

C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\max-ws\WEB-INF\lib

kopiert werden.

  1. Tomcat starten und Logfile auf Fehler überprüfen: C:\Program Files\Apache Software Foundation\Tomcat 7.0\logs omcat7-stdout.*.log

  2. Wenn alles geklappt hat kann man im Browser zum testen die Räume ausgeben lassen:
    http://localhost:8080/max-ws/rest/rooms

Wie es aussehen sollte hab ich im Anhang in der JSON Beispieldatei (rooms-json.txt) hinterlegt.

Für IPS habe ich einen kleinen PHP Webservice Client (MaxWsClient.php) geschrieben, der die oben genannten Funktionen implementiert:

Mit


$max = new MaxWsClient('192.168.0.61', '8080');
$max->install();

werden alle Räume und Devices (aktuell nur die Thermostaten) in IPS angelegt.

Mit dem Client kann man dann auch sehr einfach die Werte periodisch aktualisieren und Temperaturen oder den ControlMode setzen.

Bisher funktioniert das ganze bei mir äußerst zuverlässig und viel besser als die Lösung direkt über den Socket.

Hi Nixda,

danke für Deine Erläuterungen, als Newbie habe ich es bis zu Punkt 9 Deiner Installationsanleitung geschafft, allerdings scheitere ich an der IPS Implementierung, sprich mit Deinen Skript für den Webservice Client. Kannst Du mir hierzu ähnlich wie im ersten Teils mit einer Schritt für Schritt Anleitung weiterhelfen.

Vielen Dank
Spechtl

Hallo Spechtl,

Du musst zuerst die Klasse MaxWsClient.php in IPS importieren. Dann kannst Du mit einem Skript folgendes aufrufen:


include_once('MaxWsClient.php');

$maxClient = new MaxWsClient('192.168.0.61', '8080'); // eigene ip und port deines Tomcats
$maxClient->install();

Danach hast Du alle Max Komponenten in IPS. Das updaten der einzelnen Werte musst Du selber scripten, z.B. so


include_once('MaxWsClient.php');

$maxClient= new MaxWsClient('192.168.0.61', '8080'); // eigene ip und port deines Tomcats
$room = $maxClient->getRoom(1);

SetValue(12345, $room->setPointTemperature);
SetValue(12346, $room->temperatureMode);
SetValue(12347, $room->devices[0]->state->valvePosition);

Viele Grüße

Danke nixda,

es hilft wenn man die Klasse inkludiert und anstatt die Cube IP die des Tomcats verwendet :slight_smile:

Anyhow das install gibt mir ein paar Fehler zurück, wenngleich auch alle Variablen angelegt werden,

Warning: Ident darf nur aus Buchstaben und Zahlen bestehen in C:\IP-Symcon\scripts\MaxWsClient.php on line 90

Notice: Undefined property: stdClass::$lastMeasurementUpdate in C:\IP-Symcon\scripts\MaxWsClient.php on line 76

Warning: Ident darf nur aus Buchstaben und Zahlen bestehen in C:\IP-Symcon\scripts\MaxWsClient.php on line 90

Notice: Undefined property: stdClass::$measuredTemperature in C:\IP-Symcon\scripts\MaxWsClient.php on line 75

Warning: Cannot auto-convert to Float from Variant. Error: Could not convert variant of type (Null) into type (Double) in C:\IP-Symcon\scripts\MaxWsClient.php on line 107

Notice: Undefined property: stdClass::$lastMeasurementUpdate in C:\IP-Symcon\scripts\MaxWsClient.php on line 76

Notice: Undefined property: stdClass::$valvePosition in C:\IP-Symcon\scripts\MaxWsClient.php on line 78

Warning: Cannot auto-convert to Integer from Variant. Error: Could not convert variant of type (Null) into type (Integer) in C:\IP-Symcon\scripts\MaxWsClient.php on line 107

Warning: Ident darf nur aus Buchstaben und Zahlen bestehen in C:\IP-Symcon\scripts\MaxWsClient.php on line 90

Notice: Undefined property: stdClass::$lastMeasurementUpdate in C:\IP-Symcon\scripts\MaxWsClient.php on line 76
Abort Processing during exceed of maximal ErrorCount: Ident darf nur aus Buchstaben und Zahlen bestehen Error in Script C:\IP-Symcon\scripts\MaxWsClient.php on Line 90 

Und selbst mit Deinen klaren Anweisungen habe ich ein Problem zu verstehen wie ich z.B. die Temperatur abfragen kann, sorry mit all meinen Newbie Fragen, aber so wie es mir scheint verstehe ich nicht wie Du mit Deinen Ansatz vorgehst. Danke für Deine weitere Unterstützung.

 include_once('MaxWsClient.php');

$maxClient= new MaxWsClient('192.168.123.30', '8080'); // eigene ip und port deines Tomcats
$room = $maxClient->getRoom(1);

SetValue(52461  /*[Hardware\Max\Haus\Wohnzimmer\Thermostat 1 links\MeasuredTemperature]*/, $room->devices[0]->state->measuredTemperature);
SetValue(14392  /*[Hardware\Max\Haus\Wohnzimmer\Wandthermostat 1\MeasuredTemperature]*/, $room->devices[2]->state->measuredTemperature);

Grüße
Spechtl

Hallo nixda,

kannste mal ein Screenshot von der Webseite hier reinstellen?
Danke

Hi Nixda,

kurzes Update, läuft nun alles, hatte in wenig Probleme mich in Deine Arbeit rein zu denken, und nicht das ich jetzt alles verstanden hätte was Du da gezaubert hast… aber es funzt :slight_smile:

Nochmals Danke, jetzt muss sich das System beweisen und dann wird erweitert.

Viele Grüße
Spechtl

Wenn man bei MaxBudyy auf Beta klickt in den Einstellungen, dann zieht die Software auch die IST-Temperatur aus den Thermostaten. Kannst du deine Scripte um diese Funktion erweitern?

Nach deinen Screenshots sieht es nämlich nicht danach aus als würden diese Daten abgefragt werden können. Zum testen der Scripte bin ich allerdings noch nicht gekommen.

Ansonsten schonmal Respekt und vielen Dank für diese Arbeit. :slight_smile:

die Temperaturen von den einzelnen Thermostaten werden ebenfalls abgefragt, allerdings übermitteln sie im Gegensatz zum Wandthermostat nicht ständig, sondern nur wenn der Stellantrieb aktiviert wurde, danach ist wieder Ruhe, daher auch die wertvolle Abfrage wann das letzte Mal die Daten übermittelt wurden. IMHO keine Einschränkung der IPS Integration, sondern vielmehr des Produkts, das bereits über die Max Buddy SW um diese Info erweitert wurde.

Wie gesagt absoluter Newbie und vielleicht kann Nixda mehr dazu sagen.

Grüße
Spechtl

Welche Webseite meinst Du? Das IPS Webfront?

Ja so wie die Oberfläche dann aussieht

Na ja, das Skript erstellt ja nur die Variablen für die vorhandenen MAX Devices. Die Webfront Konfiguration muss man selber anlegen.

So siehts bei mir aus:

Hallo Spechtl,

sorry das ich nicht gleich geantwortet habe, ich habe aktuell nicht so viel Zeit für mein IPS Projekt …

Du hast recht, die Temperatur wird nur unregelmäßig von den Thermostaten zum Cube geschickt und ist deshalb nicht immer aktuell, bzw. vorhanden.

Ich habe jetzt alle Räume mit Wandthermostaten ausgerüstet, mit denen kommt die Temperatur korrekt und immer verfügbar.

Bezüglich der Stabilität der Cube Connection vom Webservice zum Cube gibt es bei mir noch Probleme. Ab und zu bricht die Connection weg und baut sich nicht wieder auf, dann hilft bei mir nur das Durchstarten des Tomcats. Ich habe dazu in IPS einen Watchdog geschrieben, der beim Ausfall, den Tomcat durchstartet.

Tritt das Problem bei Dir auch auf?

Wenn ich dazu komme werde ich am Wochenende eine neue Version des Webservice bereitstellen. Die enthält ein paar Bugfixes und das Logging ist korrekt konfiguriert.

Viele Grüße
Holger

Hi Holger,

NP, kann verstehen, dass IPS nicht immer an #1 gesetzt ist.

Gerne würde ich Deinen neuen Webservice testen, habe Dank der positiven Erfahrung mit Deinen Script das System nun um etliche Thermostate und auch Wandthermostate erweitert, so wie es aussieht werde ich aber für den Keller wohl einen zusätzlichen Cube benötigen.

Wie könnte das dann mit dem Tomcat laufen?

Apropo Tomcat, hatte jetzt mal 4-5 Tage nicht gespielt und über die Zeit ist das System stabil gelaufen. Wenn Du mit mir Dein Watchdog teilen könntest, würde ich den aber sicherheitshalber auch gerne eingebaut haben.

Wie programierst Du eigentlich Deine Profile, über IPS oder über die Original Steuerung bzw. Max Buddy?

Finde auch Deine Visualisierung sehr gelungen, wie hast Du die aufgebaut?

Danke und viele Grüße
Spechtl

sodala, kurzes Update, um weitere 10 Thermostate und 3 Wandthermostate erweitert, und siehe da ähnliche Probleme wie bei Dir mit Tomcat, denn er ist nunmehr sehr instabil und bricht sehr häufig zusammen…

Grüße
Spechtl

Hallo Nixda,

ich finde Dein Projekt sehr interessant, inzwischen habe ich auch das MAX! System im Einsatz, verteilt auf 3 Räume sind 4 Thermostate, 2 Wandthermostate, 2 Fensterkontakte und 1 Cube.
Nun wollte ich mich nach Deiner Anleitung an die Einbindung an IPS wagen.
Bis zum Punkt 8 Deiner Anleitung habe ich es wohl geschafft.
Bei der Kontrolle des Tomcat Logs wir aber ein Fehler gemeldet, als absoluter Javaleie interpretiere ich es so, das die Classe „BuddyConnection“ fehlt. Hier das complette Log


2013-02-15 16:29:26 Commons Daemon procrun stdout initialized
16:29:56.286 [localhost-startStop-1] ERROR o.s.web.context.ContextLoader - Context initialization failed
java.lang.NoClassDefFoundError: org/fenwulf/maxbuddy/connection/BuddyConnection
	at java.lang.Class.getDeclaredConstructors0(Native Method) ~[na:1.7.0_13]
	at java.lang.Class.privateGetDeclaredConstructors(Unknown Source) ~[na:1.7.0_13]
	at java.lang.Class.getDeclaredConstructors(Unknown Source) ~[na:1.7.0_13]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:230) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:976) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:949) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:589) ~[spring-beans-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) ~[spring-context-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383) ~[spring-web-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283) ~[spring-web-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) [spring-web-3.2.0.RELEASE.jar:3.2.0.RELEASE]
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797) [catalina.jar:7.0.35]
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5291) [catalina.jar:7.0.35]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.35]
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) [catalina.jar:7.0.35]
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) [catalina.jar:7.0.35]
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633) [catalina.jar:7.0.35]
	at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1114) [catalina.jar:7.0.35]
	at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1673) [catalina.jar:7.0.35]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [na:1.7.0_13]
	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) [na:1.7.0_13]
	at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.7.0_13]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.7.0_13]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.7.0_13]
	at java.lang.Thread.run(Unknown Source) [na:1.7.0_13]
Caused by: java.lang.ClassNotFoundException: org.fenwulf.maxbuddy.connection.BuddyConnection
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714) ~[catalina.jar:7.0.35]
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559) ~[catalina.jar:7.0.35]
	... 32 common frames omitted

Was mache ich falsch, bzw. von wo bekomme ich die Classe BuddyConnection.

Gruß
Helmut

Hi,

habe heute mal das Skript eingebunden und es funktioniert super. Gibt es zu dem Skript schon einige Updates? Z.B. zum Auslesen oder Einstellen der Zeitzonen.

Grüße

Thommy

Hi,

@Thommy

Hast Du das Script mit der aktuellen Maxbuddy Version in Gebrauch. Am 22.10. ist wohl eine neue Version erschienen. Meine bisherigen Versuche schlugen leider alle fehl.

VG

Tobi

Mit maxbudy hab ich es auch nie zum fliegen gebracht.
Allerdings bin ich hier auf eine brauchbare Grundlage direkt in PHP gestossen:

http://www.mega-nas.de/max/readerscript

Für meine Zwecke völlig ausreichend und anpassbar. Und keine andere Zusatzsoftware notwendig.
Und läuft auch mit aktueller max Firmware.

Gruss
Chris

Moin,

ich habe das ganze genauso gemacht wie hier in der Anleitung mit der aktuellen Version von MayBuddy. Nur die Bezeichung für die Ist Temperatur muss man ändern damit diese auch importiert wird. Und was soll ich sagen … es klappt ! Wenn du also Hilfe brauchst einfach kurz sagen wo du hängst.

VG

Andreas

Klingt perfekt. Da ich das PHP-mäßig nicht überblicke: Kannst Du damit steuern oder nur auslesen?

Grüße
galleto