JUDO iSoft Plus: Unterschied zwischen den Versionen
K (→Einbindung in FHEM: - Standard-Abfrage geändert) |
K (Timer ergänzt) |
||
Zeile 188: | Zeile 188: | ||
attr JUDO_iSoft saltRangeInWeeks { int( (ReadingsVal("JUDO_iSoft","salt-range",0)/7))} , saltQuantityInPercent { int( (ReadingsVal("JUDO_iSoft","salt-quantity",0)/50000)*100)} | attr JUDO_iSoft saltRangeInWeeks { int( (ReadingsVal("JUDO_iSoft","salt-range",0)/7))} , saltQuantityInPercent { int( (ReadingsVal("JUDO_iSoft","salt-quantity",0)/50000)*100)} | ||
</pre> | |||
== Readings auslesen == | |||
Da die Art der Anbindung nur angepasste Readings liefert, wenn man sie regelmäßig abfragt, habe ich dazu einen Timer aufgesetzt, der 1x am Tag die relevanten Werte abfragt. Das ist eigentlich nur wichtig, falls man ab und an doch noch über einen anderen Weg z.B. die Apps des Herstellers auf die JUDO zugreift und Wert verändert. Bei mir sieht das dann so aus: | |||
<pre> | |||
Internals: | |||
COMMAND get JUDO_iSoft SaltQuantity; | |||
get JUDO_iSoft SaltRange; | |||
get JUDO_iSoft WaterDaily; | |||
get JUDO_iSoft WaterTotal; | |||
get JUDO_iSoft WaterAverage; | |||
get JUDO_iSoft FlowRate; | |||
get JUDO_iSoft ResidualHardness; | |||
DEF *23:55:00 | |||
get JUDO_iSoft SaltQuantity; | |||
get JUDO_iSoft SaltRange; | |||
get JUDO_iSoft WaterDaily; | |||
get JUDO_iSoft WaterTotal; | |||
get JUDO_iSoft WaterAverage; | |||
get JUDO_iSoft FlowRate; | |||
get JUDO_iSoft ResidualHardness; | |||
</pre> | |||
Um 1x pro Stunde gegen Ende der vollen Stunde den Wasserbrauch der aktuellen Stunde abzugreifen setze ich einen weiteren Timer auf. Bei mir jewils um :58 der aktuellen STunde. Das ist natürlich nicht ganz exakt. Wenn sich die Uhr der Judo und von fhem auseinander driften bekommt man ggf. schon wieder den Wert der nächsten Stunde. | |||
<pre> | |||
Internals: | |||
CFGFN | |||
COMMAND get JUDO_iSoft WaterCurrent | |||
DEF +*01:00:00 get JUDO_iSoft WaterCurrent | |||
NAME at_Judo_HourlyStats | |||
NR 34559 | |||
NTM 06:58:00 | |||
PERIODIC yes | |||
RELATIVE yes | |||
REP -1 | |||
STATE Next: 06:58:00 | |||
TIMESPEC 01:00:00 | |||
TRIGGERTIME 1538801880 | |||
TRIGGERTIME_FMT 2018-10-06 06:58:00 | |||
TYPE at | |||
READINGS: | |||
2018-10-06 06:20:53 state Next: 06:58:00 | |||
Attributes: | |||
alignTime 00:58 | |||
room ,00_Masterswitches,10_Räume->UG->Keller | |||
</pre> | </pre> | ||
Zeile 206: | Zeile 252: | ||
<div class="hbox"> | <div class="hbox"> | ||
<div class="vbox phone-width"> | |||
<div class="card lift"> | <div class="card lift"> | ||
<header>Zustand Salz</header> | <header>Zustand Salz</header> |
Version vom 6. Oktober 2018, 05:24 Uhr
JUDO iSoft Plus | |
---|---|
Allgemein | |
Protokoll | IP |
Typ | Wasserenthärter |
Kategorie | IP |
Technische Details | |
Kommunikation | n/a |
Kanäle | n/a |
Betriebsspannung | 230 V |
Leistungsaufnahme | ? |
Versorgung | AC |
Abmessungen | 39x67x45 cm (BxHxT) |
Sonstiges | |
Modulname | HTTPMOD |
Hersteller | Judo GmbH |
Die JUDO i-soft plus Enthärtungsanlage [1] ist eine Wasserenthärtungsanlage mit IP-Konnektivität. Sie verfügt über LAN und WLAN-Anschluss und ist auf die Steuerung via App des Herstellers ausgelegt.
Für eine erfolgreiche Integration in FHEM muss die Anlage über das Menü beim Hersteller registriert werden. Die folgenden Informationen sind erforderlich:
- Benutzername: Selbst gewählter Login-Name auf der iSoft plus (vgl. Gerätehandbuch)
- Kennwort: Selbst gewähltes Kennwort
- Seriennummer: Seriennummer des Geräts. Diese ist entweder über das Menü auslesbar oder alternativ auch über die APP des Herstellers.
- IP-Adresse: Die IP-Adresse des Geräts im Heimnetz.
Einbindung in FHEM
Das Gerät wird mittels des Moduls HTTPMOD eingebunden. Dazu gilt zunächst die folgende Konfiguration als Basis. Zunächst legen wir die Standardanfrage an das Modul fest. Die Portnummer 8124 ist vom Hersteller vorgegeben. Wir vergeben gleich ein paar Platzhalter, die später in den Aufrufen und den Antworten ersetzt werden, damit wir die Werte nur an einer zentralen Stelle konfigurieren müssen.
define JUDO_iSoft HTTPMOD https://%JUDO_ipaddress%:8124/?group=waterstop&command=valve&msgnumber=4&token=%token% 300
Mit dieser Definition wird als Standard-Anfrage die Statusabfrage nach dem Wasserstop gesendet. Diese wird zyklisch alle 300 Sekunden wiederholt. Wem das nicht reicht, der kann den Zyklus herunter setzen oder auch nach anderen Standard-Werten abfragen. Wer das kontinuierliche Pollen vermeiden will, setzt den Wert auf 0.
Nach erfolgreicher Authentifizierung wird von der iSoft ein Token generiert und muss bei jedem Aufruf übergeben werden:
attr JUDO_iSoft replacement01Mode reading attr JUDO_iSoft replacement01Regex %token% attr JUDO_iSoft replacement01Value token
Anschließend legen wir die Ersetzungen für die anderen Platzhalter fest:
attr JUDO_iSoft replacement02Mode text attr JUDO_iSoft replacement02Regex %JUDO_ipaddress% attr JUDO_iSoft replacement02Value <hier eigene IP Adresse im lokalen Netz eintragen> attr JUDO_iSoft replacement03Mode text attr JUDO_iSoft replacement03Regex %JUDO_password% attr JUDO_iSoft replacement03Value <hier Kennwort eintragen> attr JUDO_iSoft replacement04Mode text attr JUDO_iSoft replacement04Regex %JUDO_username% attr JUDO_iSoft replacement04Value <hier Benutzername eintragen> attr JUDO_iSoft replacement05Mode text attr JUDO_iSoft replacement05Regex %JUDO_serial% attr JUDO_iSoft replacement05Value <hier Seriennummer eintragen>
Die Authentifizierung der Anlage erfolgt zwei-stufig. Zunächst muss ein Aufruf mit Benutzername und Kennwort erfolgen. Als Antwort erhält man einen JSON-String, der das Token beinhaltet. Mit diesem Token wird anschließend die Funktion connect aufgerufen und die Seriennummer des Geräts mit übergeben. HTTPMOD erkennt, wenn ein neues Login erforderlich ist, wenn die Judo die Rückmeldung "no token" oder "not logged in" liefert.
Achtung: Als Parameter muss ebenfalls der Typ "i-soft plus" übergeben werden. Vermutlich ist dieser bei anderen Geräten des Herstellers anders. Ich habe ihn hier fix eingetragen, da ich keine Möglichkeit zum Testen anderer Geräte habe.
attr JUDO_iSoft showError 1 attr JUDO_iSoft authRetries 2 attr JUDO_iSoft reAuthRegex (no token)|(not logged in) attr JUDO_iSoft sid01ParseResponse 1 attr JUDO_iSoft sid01URL https://%JUDO_ipaddress%:8124/?group=register&command=login&msgnumber=1&name=login&user=%JUDO_username%&password=%JUDO_password%&role=customer attr JUDO_iSoft sid02URL https://%JUDO_ipaddress%:8124/?group=register&command=connect&msgnumber=6&token=%token%¶meter=i-soft%20plus&serial%20number=%JUDO_serial%
Damit ist die Grundkonfiguration hergestellt und die Anlage kann sich connecten. In den einzelnen JSON-Rückantworten der Anlage werden die Werte zur jeweilige Anfrage immer als "data" zurück geliefert. Mit der Standard-Konfiguration
attr JUDO_iSoft extractAllJSON 1
werden daraus automatisch entsprechernde Readings angelegt. Da wir aber dann immer das Reading "data" überschreiben würde, kommt eine weitere Ersetzung zum Einsatz. In der Antwort steht neben einer Kaskadierung (group) auch der zugehörige Befehl (command). Ich habe mich dafür entschieden, ein neues Reading mit dem jeweiligen Command-Namen anzulegen. Die zugehörigen Ersetzungen sind wie folgt. Erklärung zum Ausdruck reading03OExpr: Zunächst werden die Leerzeichen im Rückgabewert ($val) durch "-" ersetzt. Mit dem so veränderten String erzeugen wir ein neues Reading mit dem Wert aus dem Reading data.
attr JUDO_iSoft reading01JSON data attr JUDO_iSoft reading01Name token attr JUDO_iSoft reading01Regex "token":"([^"]+)" attr JUDO_iSoft reading02JSON group attr JUDO_iSoft reading03JSON command attr JUDO_iSoft reading03OExpr $val =~ s/\s/-/;; $val; readingsBulkUpdate($hash,$val,ReadingsVal("JUDO_iSoft","data",""))
Noch ein paar ergänzende Attribute gesetzt:
attr JUDO_iSoft enableControlSet 1 attr JUDO_iSoft getHeader1 Content-Type: application/json attr JUDO_iSoft getHeader2 Accept: */* attr JUDO_iSoft room 10_Räume->UG->Keller, attr JUDO_iSoft showError attr JUDO_iSoft timeout 5
Damit sind alle Voraussetzungen erledigt. Ab jetzt können wir die einzelnen Get-Befehle implementieren:
attr JUDO_iSoft get01Name SerialNumber attr JUDO_iSoft get01URL https://%JUDO_ipaddress%:8124/?group=spare%20part&command=serial%20number&msgnumber=5&token=%token% attr JUDO_iSoft get02Name WaterCurrent attr JUDO_iSoft get02URL https://%JUDO_ipaddress%:8124/?group=consumption&command=water%20current&msgnumber=1&token=%token% attr JUDO_iSoft get03Name SaltRange attr JUDO_iSoft get03URL https://%JUDO_ipaddress%:8124/?group=consumption&command=salt%20range&msgnumber=1&token=%token% attr JUDO_iSoft get04Name SaltQuantity attr JUDO_iSoft get04URL https://%JUDO_ipaddress%:8124/?group=consumption&command=salt%20quantity&msgnumber=1&token=%token% attr JUDO_iSoft get05Name ResidualHardness attr JUDO_iSoft get05URL https://%JUDO_ipaddress%:8124/?group=settings&command=residual%20hardness&msgnumber=1&token=%token% attr JUDO_iSoft get06Name NaturalHardness attr JUDO_iSoft get06URL https://%JUDO_ipaddress%:8124/?group=info&command=natural%20hardness&msgnumber=1&token=%token% attr JUDO_iSoft get07Name WaterStop attr JUDO_iSoft get07URL https://%JUDO_ipaddress%:8124/?group=waterstop&command=valve&msgnumber=1&token=%token% attr JUDO_iSoft get08Name FlowRate attr JUDO_iSoft get08URL https://%JUDO_ipaddress%:8124/?group=waterstop&command=flow%20rate&msgnumber=1&token=%token% attr JUDO_iSoft get09Name SoftwareVersion attr JUDO_iSoft get09URL https://%JUDO_ipaddress%:8124/?group=version&command=software%20version&msgnumber=1&token=%token% attr JUDO_iSoft get10Name HardwareVersion attr JUDO_iSoft get10URL https://%JUDO_ipaddress%:8124/?group=version&command=hardware%20version&msgnumber=1&token=%token% attr JUDO_iSoft get11Name InstallationDate attr JUDO_iSoft get11URL https://%JUDO_ipaddress%:8124/?group=contract&command=init%20date&msgnumber=1&token=%token% attr JUDO_iSoft get12Name ServiceDate attr JUDO_iSoft get12URL https://%JUDO_ipaddress%:8124/?group=contract&command=service%20date&msgnumber=1&token=%token% attr JUDO_iSoft get13Name WaterTotal attr JUDO_iSoft get13URL https://%JUDO_ipaddress%:8124/?group=consumption&command=water%20total&msgnumber=1&token=%token% attr JUDO_iSoft get14Name WaterAverage attr JUDO_iSoft get14URL https://%JUDO_ipaddress%:8124/?group=consumption&command=water%20average&msgnumber=1&token=%token% attr JUDO_iSoft get15Name Vacation attr JUDO_iSoft get15URL https://%JUDO_ipaddress%:8124/?group=waterstop&command=vacation&msgnumber=1&token=%token% attr JUDO_iSoft get16Name Quantity attr JUDO_iSoft get16URL https://%JUDO_ipaddress%:8124/?group=waterstop&command=quantity&msgnumber=1&token=%token% attr JUDO_iSoft get17Name WaterDaily attr JUDO_iSoft get17URL https://%JUDO_ipaddress%:8124/?group=consumption&command=water%20daily&msgnumber=1&token=%token% attr JUDO_iSoft get18Name ValveState attr JUDO_iSoft get18URL https://%JUDO_ipaddress%:8124/?group=waterstop&command=valve&msgnumber=4&&token=%token%
Zum Setzen einiger Werte werden die folgenden Kommandos zum Schließen und Öffnen des Wasserstopps sowie das Setzen der Wunschwasserhärte implementiert
attr JUDO_iSoft set01Name CloseValve attr JUDO_iSoft set01URL https://%JUDO_ipaddress%:8124/?group=waterstop&command=valve&msgnumber=1&token=%token%¶meter=close attr JUDO_iSoft set02Name OpenValve attr JUDO_iSoft set02URL https://%JUDO_ipaddress%:8124/?group=waterstop&command=valve&msgnumber=1&token=%token%¶meter=open attr JUDO_iSoft set03Name residual-hardness attr JUDO_iSoft set03URL https://%JUDO_ipaddress%:8124/?group=settings&command=residual%20hardness&msgnumber=1&token=%token%¶meter=$val
Userreadings
Um die Originalwerte aus der Anlage benutzerfreundlicher darzzustellen, werden noch Userreadings angelegt.
Die Salzrestdauer soll in Wochen angegeben (Rückgemeldet werden Tage) werden, die verbleibende Salzmenge in Prozent. Die Salzemnge wird in Gramm angegeben, 50.000 entsprechen 100%. Wichtig: Bei den Userreadings muss darauf geachtet werden, dass diese mit Komma separiert und in einer Zeile geschrieben werden.
attr JUDO_iSoft saltRangeInWeeks { int( (ReadingsVal("JUDO_iSoft","salt-range",0)/7))} , saltQuantityInPercent { int( (ReadingsVal("JUDO_iSoft","salt-quantity",0)/50000)*100)}
Readings auslesen
Da die Art der Anbindung nur angepasste Readings liefert, wenn man sie regelmäßig abfragt, habe ich dazu einen Timer aufgesetzt, der 1x am Tag die relevanten Werte abfragt. Das ist eigentlich nur wichtig, falls man ab und an doch noch über einen anderen Weg z.B. die Apps des Herstellers auf die JUDO zugreift und Wert verändert. Bei mir sieht das dann so aus:
Internals: COMMAND get JUDO_iSoft SaltQuantity; get JUDO_iSoft SaltRange; get JUDO_iSoft WaterDaily; get JUDO_iSoft WaterTotal; get JUDO_iSoft WaterAverage; get JUDO_iSoft FlowRate; get JUDO_iSoft ResidualHardness; DEF *23:55:00 get JUDO_iSoft SaltQuantity; get JUDO_iSoft SaltRange; get JUDO_iSoft WaterDaily; get JUDO_iSoft WaterTotal; get JUDO_iSoft WaterAverage; get JUDO_iSoft FlowRate; get JUDO_iSoft ResidualHardness;
Um 1x pro Stunde gegen Ende der vollen Stunde den Wasserbrauch der aktuellen Stunde abzugreifen setze ich einen weiteren Timer auf. Bei mir jewils um :58 der aktuellen STunde. Das ist natürlich nicht ganz exakt. Wenn sich die Uhr der Judo und von fhem auseinander driften bekommt man ggf. schon wieder den Wert der nächsten Stunde.
Internals: CFGFN COMMAND get JUDO_iSoft WaterCurrent DEF +*01:00:00 get JUDO_iSoft WaterCurrent NAME at_Judo_HourlyStats NR 34559 NTM 06:58:00 PERIODIC yes RELATIVE yes REP -1 STATE Next: 06:58:00 TIMESPEC 01:00:00 TRIGGERTIME 1538801880 TRIGGERTIME_FMT 2018-10-06 06:58:00 TYPE at READINGS: 2018-10-06 06:20:53 state Next: 06:58:00 Attributes: alignTime 00:58 room ,00_Masterswitches,10_Räume->UG->Keller
Statistiken
Die iSoftPlus liefert verschiedene Statistiken zum Wasserverbrauch zurück. Die werden allerdings etwas eigentümlich zurückgemeldet. Unter water-current ist der jeweilige Verbrauch je Stunde zusammengefasst. Ich hole kurz vor der vollen Stunde diesen Wert ab, damit er danach im Logfile landet. Unter water-daily werden Tagesstatistiken geliefert. Kurioserweise in 3-Stunden-Paketen, d.h. 8 Werte. Die ersten Wert sind von 0h-3h, 3h-6h usw. Ich habe mich aktuell darauf beschränkt, den stündlichen Verbrauch zu erfassen und zu protokollieren. Es lassen sich aber auch bei Bedarf detaillierte Datumsbezogene Statistiken abrufen. Ich habe noch keinen sinnvollen Weg gefunden, das mit fhem zu verbinden.
Darstellung in Tablet UI
Ich nutze Tablet UI für die Visualisierung. Zur Darstellung der Restmengen Salz nutze ich das knob-widget, für das Setzen des Härtegrades den spinner.
<div class="hbox"> <div class="vbox phone-width"> <div class="card lift"> <header>Zustand Salz</header> <div class="sheet"> <div class="row"> <div class="cell-50 top-align center-align left-space"> <div class="big">Restmenge</div> <div data-type="knob" data-device="JUDO_iSoft" data-get="saltQuantityInPercent" data-unit="%" data-step="1" data-min="0" data-max="100" data-bgcolor="#FF0000" data-fgcolor="#00FF1A" class="small readonly"> </div> </div> <div class="cell-50 top-align center-align left-space"> <div class="big">Reichweite</div> <div data-type="knob" data-device="JUDO_iSoft" data-get="saltRangeInWeeks" data-unit="w" data-step="1" data-min="0" data-max="52" data-bgcolor="#FF0000" data-fgcolor="#00FF1A" class="small readonly"> </div> </div> </div> </div> </div> </div> <div class="vbox phone-width"> <div class="card lift"> <header>Wasserstopp</header> <div class="sheet"> <div class="row top-space"> <div class="cell left-align top-align left-space"> <div data-type="symbol" data-device="JUDO_iSoft" data-get="valve" data-icons='["fa-close","fa-close","oa-sani_water_tap","oa-sani_water_tap"]' data-get-on='["closed","closing","opening","opened"]' data-on-colors='["#ad3333","#ff6633","#3399ff","#33ad33"]' class="big compressed"></div> </div> <div class="cell-60 top-align center-align"> <div class="big"> <div data-type="label" data-get="valve" class="valueonly" data-substitution='["opened","geöffnet","opening","öffnet gerade","closed","geschlossen","closing","schließt gerade"]' data-device="JUDO_iSoft" data-color="lightgrey"> </div> </div> </div> <div class="cell left-align top-align left-space"> <div data-type="push" data-device="JUDO_iSoft" data-set-on="CloseValve 1" data-get-on="valve" data-background-icon="fa-stop-circle-o" data-icon="" class="small"></div> </div> <div class="cell right-align top-align right-space"> <div data-type="push" data-device="JUDO_iSoft" data-set-on="OpenValve 1" data-get-on="valve" data-background-icon="mi-play_circle_filled" data-icon="" class="small"></div> </div> </div> </div> </div> </div> <div class="vbox phone-width"> <div class="card lift"> <header>Wasserhärtegrad</header> <div class="sheet"> <div class="row"> <div class="cell-20 center-align top-align left-space"> <div data-type="symbol" data-device="JUDO_iSoft" data-icon="none" data-color='none' data-height="100" data-background-icon="fa-circle" data-background-colors='["red","blue"]' data-limits='["0","1"]'> <div data-type="label" data-get="natural-hardness" data-unit="°h" class="valueonly" data-device="JUDO_iSoft" data-color="lightgrey"> </div> </div> </div> <div class="cell-20 top-align center-align left-space"> <div data-type="image" data-size="50%" data-url="images/judo.png"></div> </div> <div class="cell-60 top-align center-align left-space"> <div data-type="spinner" data-device="JUDO_iSoft" data-get="residual-hardness" data-set="residual-hardness" data-min=5" data-max="12" data-step="1" data-unit="°h" data-longdelay="800" data-width="200" data-height="60" data-icon-left-color="blue" data-icon-right-color="red" class="valueonly"> </div> </div> </div> </div> </div> </div> <div class="vbox phone-width"> <div class="card lift"> <header>Wasserverbrauch</header> <section> <div id="JUDO_iSoft" data-type="highchart" data-device="JUDO_iSoft" data-logdevice="FileLog_JUDO_ISoft" data-columnspec="4:water-current" data-style="ftui l0fill" data-linenames="Verbrauch" data-linetypes="line" data-yaxis="0,1" data-height="300" data-xunit="Uhrzeit" data-yunit="l" data-tooltip="{series.name} <b>{point.y:,.1f}</b>" data-daysago="7" data-yticks="auto" data-legendalign="right"> </section> </div </div> </div>