Vielleicht ist das Programm für den Einen oder Anderen hilfreich. Deshalb möchte ich es der Community zur Verfügung stellen.
Ziel – Was kann das Programm?
- Nutzung der JUDO API über das Connectivity-Modul. Keine Cloud!
- Auslesen der Werte:
Gerätetyp, Gerätenummer, SW-Version Gerätesteuerung, Inbetriebnahme Datum, Betriebsstundenzähler, Wunschwasserhärte, Weichwassermenge.
Gesamtwassermenge (Wasserverbrauch) Tagesstatistik, Wochenstatistik, Monatsstatistik, Jahresstatistik.
- Berechnen der Werte mit Unterstützung der Fa. JUDO:
Gesamtwassermenge (Wasserverbrauch), Anzahl der Regenerierungen, Salzvorrat, Minerallösungsvorrat, gesamter Salzverbrauch, gesamter Minerallösungsverbrauch.
- Warnung für das Nachfüllen und des Salz- und Minerallösungsvorrates. Auch für Sprachassistent, Nachricht und VIS nutzbar.
- Pflegestatus in Textform der Pflegemaßnahmen für Sprachassistent, Nachricht und VIS.
Datenpunkte:
Vorraussetzung
- JUDO SOFTwell Enthärtungsanlage. Funktioniert vermutlich auch für andere Gerätetypen. Bei höherwertigeren Geräten können zum Beispiel der Salzvorrat und andere Werte direkt über die API gelesen werden. Bei SOFTwell fehlt der Sensor, deshalb wird es hier berechnet.
- Das JUDO Connectivity-Modul kann man per LAN oder WLAN mit dem Heimnetzwerk zu verbinden.
Es ermöglicht die Kommunikation über REST API.
- Einstellung in der Javascript Instanz:
Zusätzliche NPM-Module: moment
- Optional: Dosierpumpe JUDO Julia 4 (so wie ich sie habe) oder ähnliche zur Wassersteinverhütung und Korrosionsminderung in Kalt- und Warmwasser-Versorgungsanlagen.
Diese hat keine Schnittstelle. Aber der Minerallösungsverbrauch kann über die Rohwassermenge berechnet werden.
Bedienung und Konfiguration
- Vor dem ersten Start bitte die Voraussetzungen prüfen.
- Im Programm im Abschnitt Settings die Variablen der Kanäle und Datenpunkte richtig setzen.
- Programm starten. Alle Datenpunkte werden angelegt.
- Nach dem Start können folgende Datenpunkte manuell geändert werden:
** regenerierungen
Entweder 0 belassen oder den Wert aus der ju-control.app übertragen.
** salzvorrat
Der Salzvorrat wird initial eingegeben. Bei SOFTwell P ist der maximale Salzvorrat 50 kg. Wenn er noch halb voll ist muss 25 kg eingeben werden.
Wenn nachgefüllt werden muss und es sind noch 2 kg enthalten dann wird bei einem 25 kg Sack der Wert auf 27 kg erhöht.
** mineralvorrat
Auch der Minerallösungsvorrat wird initial eingegeben. Bei der Dosierpumpe JUDO Julia 4 ist der maximale Wert 6 Liter. Wenn es noch halb voll sind es 3 Liter. Wenn der Behälter ersetzt wird muss hier wieder 6 Liter eingeben werden.
** salzverbrauchgesamt und mineralverbrauchgesamt
Wenn man die beiden Werte für den bisherigen Verbrauch weiß, kann man sie eintragen. Ansonsten bleiben sie 0.
Bekannte Probleme
- Der API Zugriff für die Tagesstatistik verursachte bei mir an manchen Tagen eine Fehlermeldung.
Ich habe das der Fa. JUDO gemeldet und das Problem wurde auch erkannt. In einer der nächsten Firmware Updates soll das behoben werden.
Bis dahin kann man über die Konstante tagesStatistikEin = false in den Settings den API-Aufruf deaktivieren.
Bei false wird stattdessen die Tagesstatistik berechnet.
- Die Berechnung der Gesamtwassermenge (Wasserverbrauch) ergibt ca. 1,5% mehr als im Vergleich mit meinem Hauswasserzähler. Das finde ich aber akzeptabel.
- Hardwareversion, Connectifity-Modul Softwareversion, Nächste Wartung, Gesamt-Regenerationsanzahl und Anzahl Wartungen werden in der ju-control.app angezeigt. Es gibt aber keinen entsprechenden API-Aufruf. Dies wurde auch der Fa. JUDO gemeldet. Eventuell gibt in einer der nächsten Firmware Updates eine Änderung.
- Die API wird alle 5 Minuten abgerufen. Zwischen den einzelnen API-Aufrufen sind immer 10 Sekunden Pause. Das Modul scheint keine zu schnellen Zugriffe hintereinander zu vertragen.
Script
JUDO Wasserenthärtung.js:
//
// JUDO Wasserenthärtung.js
//
// 09.10.2024 Version 1.0
// Initialversion
//
//
//--------------------------- Settings ------------------------
const tagesStatistikEin = false; // Manchmal verursacht die Tagesstatistik einen Neustart des Moduls. Für diesen Tag auf false.
// Bei false wird die Tagesstatistik nicht über die API geholt sondern wird berechnet.
const user = "admin";
const password = "xxxxxxxxx"; // Standard "Connectivity"
const url = "http://192.168.178.50";
const dpUserdata = "0_userdata.0.Judo.";
const rohWasserhaerte = 21; // für die Berechnung der Gesamtwassermenge
const kapazitaet = 4950; // für die Berechnung der Regenerierungen. Wert für das Gerät laut Fa. JUDO.
const salzVerbrauch = 180; // Salzverbrauch je Regenerierung in g
const salzVorratsbehaelter = 50; // max. Füllmenge in kg
const mineralVorratsbehaelter = 6; // max. Füllmenge des Minerallösungsbehälter in l
const rohwasserVerbrauchProMineralVorratsbehaelter = 64; // Rohwasserverbrauch je Minerallösungsbehälter (6l) in m³ (aus Betriebsanleitung. DIP-Schalter norm)
const pflegeNotwendigSalz = 5 // In %. Bei Gleichstand oder Unterschreitung des Füllzustandes des Salzbehälters ist Pflege notwendig.
const pflegeNotwendigMineral = 5 // In %. Bei Gleichstand oder Unterschreitung des Füllzustandes des Mineralflüssigkeitbehälters ist Pflege notwendig.
//--------------------------- Settings end --------------------
//--------------------------- Datenpunkte mit API -------------
const myConfig = {
"row": [
{
"dp": "rohwasserhaerte", // Aus Setting
"name": "Lokale Wasserhärte",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "°dH",
},
{
"dp": "zaehlerWeichwasserRegenerierung", // Hilfsdatenpunkt nötig für Berechnungen
"name": "Zähler des Weichwassers bis zur nächsten Regenerierung",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "m³"
},
{
"dp": "zaehlerZeitspanne", // Hilfsdatenpunkt für Berechnungen Tagesstatistik
"name": "Aktuelle Zeitspanne",
"read": true, "write": false,
"type": "string", "role": "value",
"value": "", "unit": ""
},
{
"dp": "zaehlerZeitspanneWasser", // Hilfsdatenpunkt für Berechnungen Tagesstatistik
"name": "Wasserverbrauch in der aktuellen Zeitspanne",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "m³"
},
{
"dp": "regenerierungen", // wenn bekannt wird es initial manuell im Datenpunkt gesetzt und dann berechnet
"name": "Anzahl der Regenerierungen",
"read": true, "write": true,
"type": "number", "role": "value",
"value": "0", "unit": ""
},
{
"dp": "salzvorrat", // wird initial und nach dem Auffüllen manuell im Datenpunkt gesetzt und dann berechnet
"name": "Verfügbares Salz im Behälter",
"read": true, "write": true,
"type": "number", "role": "value",
"value": "0", "unit": "kg"
},
{
"dp": "salzfuellstand", // wird berechnet
"name": "Füllstand des Salzvorratsbehälters",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "%"
},
{
"dp": "salzverbrauchgesamt", // wenn bekannt wird initial manuell im Datenpunkt gesetzt und dann berechnet
"name": "Gesamter Salzverbrauch",
"read": true, "write": true,
"type": "number", "role": "value",
"value": "0", "unit": "kg"
},
{
"dp": "mineralvorrat", // wird initial und nach dem Auffüllen manuell im Datenpunkt gesetzt und dann berechnet
"name": "Verfügbare Minerallösung im Behälter",
"read": true, "write": true,
"type": "number", "role": "value",
"value": "0", "unit": "l"
},
{
"dp": "mineralfuellstand", // wird berechnet
"name": "Füllstand des Minerallösungsbehälters",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "%"
},
{
"dp": "mineralverbrauchgesamt", // wenn bekannt wird initial manuell im Datenpunkt gesetzt und dann berechnet
"name": "Gesamter Verbrauch der Minerallösung",
"read": true, "write": true,
"type": "number", "role": "value",
"value": "0", "unit": "l"
},
{
"dp": "pflege", // Datenpunkt ob Pflege für Salzvorrat oder Mineralvorrat notwendig
"name": "Pflege Salzvorrat oder Mineralvorrat notwendig?",
"read": true, "write": false,
"type": "boolean", "role": "switch",
"value": false, "unit": ""
},
{
"dp": "pflege-salz", // Datenpunkt ob Pflege für Salz notwendig
"name": "Pflege des Salzvorrates notwendig?",
"read": true, "write": false,
"type": "boolean", "role": "switch",
"value": false, "unit": ""
},
{
"dp": "pflege-mineral", // Datenpunkt ob Pflege für Minerallösung notwendig
"name": "Pflege des Mineralvorrates notwendig?",
"read": true, "write": false,
"type": "boolean", "role": "switch",
"value": false, "unit": ""
},
{
"dp": "pflege-speak", // Datenpunkt für Pflegeanfrage
"name": "Status der Wasserenthärtungsanlage",
"read": true, "write": true,
"type": "string", "role": "value",
"value": "", "unit": ""
},
{
"dp": "geraetetyp",
"name": "Gerätetyp",
"read": true, "write": false,
"type": "string", "role": "value",
"value": "", "unit": "",
"api": "/api/rest/FF00",
"geraetetyp": {"51": "i-soft SAVE+","66": "i-soft K SAVE+","50": "i-soft","67": "i-soft K",
"52": "SOFTwell P","53": "SOFTwell S","54": "SOFTwell K","71": "SOFTwell KP","72": "SOFTwell KS",
"68x": "ZEWA i-SAVE","68y": "ZEWA i-SAFE FILT","68z": "PROM-i-SAFE"}
},
{
"dp": "geraetenummer",
"name": "Gerätenummer",
"read": true, "write": false,
"type": "string", "role": "value",
"value": "", "unit": "",
"api": "/api/rest/0600"
},
{
"dp": "software-version",
"name": "SW-Version Gerätesteuerung",
"read": true, "write": false,
"type": "string", "role": "value",
"value": "", "unit": "",
"api": "/api/rest/0100"
},
{
"dp": "inbetriebnahmedatum",
"name": "Inbetriebnahmedatum",
"read": true, "write": false,
"type": "string", "role": "value",
"value": "", "unit": "",
"api": "/api/rest/0E00"
},
{
"dp": "betriebsstundenzaehler",
"name": "Betriebsstundenzähler",
"read": true, "write": false,
"type": "string", "role": "value",
"value": "", "unit": "",
"api": "/api/rest/2500"
},
{
"dp": "gesamtwassermenge",
"name": "Gesamtwassermenge",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "m³"
// "api": "/api/rest/2800" // Wird von Softwell nicht unterstützt. Stattdessen über Weichwassermenge mit Formel berechnet.
},
{
"dp": "weichwassermenge",
"name": "Weichwassermenge",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "m³",
"api": "/api/rest/2900"
},
{
"dp": "wunschwasserhaerte",
"name": "Wunschwasserhärte",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "°dH",
"api": "/api/rest/5100"
},
{
"dp": "WasserTag.00-03",
"name": "Täglicher Wasserverbrauch 00:00 Uhr bis 03:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter",
"api": "/api/rest/FB00"
},
{
"dp": "WasserTag.03-06",
"name": "Täglicher Wasserverbrauch 03:00 Uhr bis 06:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserTag.06-09",
"name": "Täglicher Wasserverbrauch 06:00 Uhr bis 09:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserTag.09-12",
"name": "Täglicher Wasserverbrauch 09:00 Uhr bis 12:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserTag.12-15",
"name": "Täglicher Wasserverbrauch 12:00 Uhr bis 15:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserTag.15-18",
"name": "Täglicher Wasserverbrauch 15:00 Uhr bis 18:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserTag.18-21",
"name": "Täglicher Wasserverbrauch 18:00 Uhr bis 21:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserTag.21-00",
"name": "Täglicher Wasserverbrauch 21:00 Uhr bis 00:00 Uhr",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserWoche.01-montag",
"name": "Wasserverbrauch der aktuellen Woche am Montag",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter",
"api": "/api/rest/FC00"
},
{
"dp": "WasserWoche.02-dienstag",
"name": "Wasserverbrauch der aktuellen Woche am Dienstag",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserWoche.03-mittwoch",
"name": "Wasserverbrauch der aktuellen Woche am Mittwoch",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserWoche.04-donnerstag",
"name": "Wasserverbrauch der aktuellen Woche am Donnerstag",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserWoche.05-freitag",
"name": "Wasserverbrauch der aktuellen Woche am Freitag",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserWoche.06-samstag",
"name": "Wasserverbrauch der aktuellen Woche am Samstag",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserWoche.07-sonntag",
"name": "Wasserverbrauch der aktuellen Woche am Sonntag",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.01",
"name": "Wasserverbrauch im aktuellen Monat Tag 1",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter",
"api": "/api/rest/FD00"
},
{
"dp": "WasserMonat.02",
"name": "Wasserverbrauch im aktuellen Monat Tag 2",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.03",
"name": "Wasserverbrauch im aktuellen Monat Tag 3",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.04",
"name": "Wasserverbrauch im aktuellen Monat Tag 4",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.05",
"name": "Wasserverbrauch im aktuellen Monat Tag 5",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.06",
"name": "Wasserverbrauch im aktuellen Monat Tag 6",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.07",
"name": "Wasserverbrauch im aktuellen Monat Tag 7",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.08",
"name": "Wasserverbrauch im aktuellen Monat Tag 8",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.09",
"name": "Wasserverbrauch im aktuellen Monat Tag 9",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.10",
"name": "Wasserverbrauch im aktuellen Monat Tag 10",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.11",
"name": "Wasserverbrauch im aktuellen Monat Tag 11",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.12",
"name": "Wasserverbrauch im aktuellen Monat Tag 12",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.13",
"name": "Wasserverbrauch im aktuellen Monat Tag 13",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.14",
"name": "Wasserverbrauch im aktuellen Monat Tag 14",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.15",
"name": "Wasserverbrauch im aktuellen Monat Tag 15",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.16",
"name": "Wasserverbrauch im aktuellen Monat Tag 16",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.17",
"name": "Wasserverbrauch im aktuellen Monat Tag 17",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.18",
"name": "Wasserverbrauch im aktuellen Monat Tag 18",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.19",
"name": "Wasserverbrauch im aktuellen Monat Tag 19",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.20",
"name": "Wasserverbrauch im aktuellen Monat Tag 20",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.21",
"name": "Wasserverbrauch im aktuellen Monat Tag 21",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.22",
"name": "Wasserverbrauch im aktuellen Monat Tag 22",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.23",
"name": "Wasserverbrauch im aktuellen Monat Tag 23",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.24",
"name": "Wasserverbrauch im aktuellen Monat Tag 24",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.25",
"name": "Wasserverbrauch im aktuellen Monat Tag 25",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.26",
"name": "Wasserverbrauch im aktuellen Monat Tag 26",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.27",
"name": "Wasserverbrauch im aktuellen Monat Tag 27",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.28",
"name": "Wasserverbrauch im aktuellen Monat Tag 28",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.29",
"name": "Wasserverbrauch im aktuellen Monat Tag 29",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.30",
"name": "Wasserverbrauch im aktuellen Monat Tag 30",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserMonat.31",
"name": "Wasserverbrauch im aktuellen Monat Tag 31",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.01-Januar",
"name": "Wasserverbrauch des aktuellen Jahres im Jannuar",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter",
"api": "/api/rest/FE00"
},
{
"dp": "WasserJahr.02-Februar",
"name": "Wasserverbrauch des aktuellen Jahres im Februar",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.03-März",
"name": "Wasserverbrauch des aktuellen Jahres im März",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.04-April",
"name": "Wasserverbrauch des aktuellen Jahres im April",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.05-Mai",
"name": "Wasserverbrauch des aktuellen Jahres im Mai",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.06-Juni",
"name": "Wasserverbrauch des aktuellen Jahres im Juni",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.07-Juli",
"name": "Wasserverbrauch des aktuellen Jahres im Juli",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.08-August",
"name": "Wasserverbrauch des aktuellen Jahres im August",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.09-September",
"name": "Wasserverbrauch des aktuellen Jahres im September",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.10-Oktober",
"name": "Wasserverbrauch des aktuellen Jahres im Oktober",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.11-November",
"name": "Wasserverbrauch des aktuellen Jahres im November",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
{
"dp": "WasserJahr.12-Dezember",
"name": "Wasserverbrauch des aktuellen Jahres im Dezember",
"read": true, "write": false,
"type": "number", "role": "value",
"value": "0", "unit": "Liter"
},
]
}
//--------------------------- Datenpunkte mit API end ---------
const moment = require('moment');
init();
async function init() {
await createMyConfig(myConfig, dpUserdata);
await await sleep(2*1000);
setState(dpUserdata+"rohwasserhaerte",rohWasserhaerte,true);
schedule("*/5 * * * *", async function () { // Jede 5. Minute starten
try {
await getAPI(myConfig, url, dpUserdata);
} catch (error) {
return;
}
});
//
// Zurücksetzen der Tagesstatistik bei Tageswechsel um 0 Uhr
//
schedule("0 0 * * *", async function () { // Jden Tag um 0 Uhr
try {
if (!tagesStatistikEin) {
resetTagesStatistik();
}
} catch (error) {
return;
}
});
//
// Bei Änderung der Weichwassermenge wird berechnet:
// Gesamtwassermenge, Anzahl der Regenerationen, Regenerierungs-Salzverbrauch, Füllstand des Salzvorratsbehälters
//
on({ id: dpUserdata + "weichwassermenge", change: "ne" }, async (dp) => {
var weichWassermenge = dp.state.val;
var weichWassermengeOld = dp.oldState.val;
var weichWasserhaerte = getState(dpUserdata+"wunschwasserhaerte").val;
//
// Gesamtwassermenge
//
var gesamtWassermenge = (weichWassermenge*rohWasserhaerte)/(rohWasserhaerte-weichWasserhaerte);
setState(dpUserdata+"gesamtwassermenge",gesamtWassermenge,true);
//
// Anzahl der Regenerationen
//
var weichwasserBisZurRegenerierung = (kapazitaet/rohWasserhaerte)/1000; // in m³
var zaehlerWeichwasserRegenerierung = getState(dpUserdata+"zaehlerWeichwasserRegenerierung").val;
if (zaehlerWeichwasserRegenerierung >= weichwasserBisZurRegenerierung){
// Wenn weichwasserBisZurRegenerierung 2- oder mehrfach innerhalb eines Abfragezyklus überschritten wird,
// müsste das hier noch berücksichtigt werden. Da es vermutlich sehr selten vorkommt, wird es vernachlässigt.
//
// Zähler für Weichwasserregenerierung zurück setzen
//
zaehlerWeichwasserRegenerierung = zaehlerWeichwasserRegenerierung-weichwasserBisZurRegenerierung;
setState(dpUserdata+"zaehlerWeichwasserRegenerierung",zaehlerWeichwasserRegenerierung,true);
//
// Anzahl Regenerierungen
//
var regenerierungen = getState(dpUserdata+"regenerierungen").val;
regenerierungen++;
setState(dpUserdata+"regenerierungen",regenerierungen,true);
//
// Salzmenge reduzieren - Salzvorrat
//
var salzvorrat = getState(dpUserdata+"salzvorrat").val;
salzvorrat = salzvorrat - (salzVerbrauch/1000); // in kg
setState(dpUserdata+"salzvorrat",salzvorrat,true);
//
// Regenerierungs-Salzverbrauch
//
var salzverbrauchgesamt = getState(dpUserdata+"salzverbrauchgesamt").val + (salzVerbrauch/1000); // in kg
setState(dpUserdata+"salzverbrauchgesamt",salzverbrauchgesamt,true);
} else {
zaehlerWeichwasserRegenerierung = zaehlerWeichwasserRegenerierung + (weichWassermenge-weichWassermengeOld);
setState(dpUserdata+"zaehlerWeichwasserRegenerierung",zaehlerWeichwasserRegenerierung,true);
}
});
//
// Bei Änderung der Gesamtwassermenge wird berechnet:
// Minerallösungsverbrauch, Tagesstatistik
//
on({ id: dpUserdata + "gesamtwassermenge", change: "ne" }, async (dp) => {
var gesamtWassermenge = dp.state.val;
var gesamtWassermengeOld = dp.oldState.val;
//
// Zähler für Rohwasser erhöhen
//
//
// Mineralverbrauch
//
var rohwasser = dp.state.val - dp.oldState.val;
var mineralVerbrauch = mineralVorratsbehaelter/(rohwasserVerbrauchProMineralVorratsbehaelter/rohwasser);
//
// Mineralvorrat reduzieren
//
setState(dpUserdata+"mineralvorrat",getState(dpUserdata+"mineralvorrat").val - mineralVerbrauch,true);
//
// Minerallösung Gesamt erhohen
//
setState(dpUserdata+"mineralverbrauchgesamt",getState(dpUserdata+"mineralverbrauchgesamt").val + mineralVerbrauch,true);
//
// Tagesstatistik
//
if (!tagesStatistikEin) {
// Wenn nicht über API
setTagesStatistik(gesamtWassermenge-gesamtWassermengeOld);
};
});
//
// Salzfüllstand berechnen wenn sich Salzvorrat geändert hat
//
on({ id: dpUserdata + "salzvorrat", change: "ne" }, async (dp) => {
//
// Füllstand des Salzvorratsbehälters
//
var salzvorrat = dp.state.val;
var salzfuellstand = salzvorrat/(salzVorratsbehaelter/100);
setState(dpUserdata+"salzfuellstand",salzfuellstand,true);
//
// Prüfen ob Pflege für Salzbehälter notwendig ist
//
if (salzfuellstand <= pflegeNotwendigSalz) {
setState(dpUserdata+"pflege-salz",true,true);
} else {
setState(dpUserdata+"pflege-salz",false,true);
}
});
//
// Mineralfüllstand berechnen wenn sich Mineralvorrat geändert hat
//
on({ id: dpUserdata + "mineralvorrat", change: "ne" }, async (dp) => {
//
// Füllstand des Mineralvorratsbehälters
//
var mineralvorrat = dp.state.val;
var mineralfuellstand = mineralvorrat/(mineralVorratsbehaelter/100);
setState(dpUserdata+"mineralfuellstand",mineralfuellstand,true);
//
// Prüfen ob Pflege für Minerallösungsbehälter notwendig ist
//
if (mineralfuellstand <= pflegeNotwendigMineral) {
setState(dpUserdata+"pflege-mineral",true,true);
} else {
setState(dpUserdata+"pflege-mineral",false,true);
}
});
//
// Pflege triggern
//
// const maintenance = [dpUserdata + "pflege-salz", dpUserdata + "pflege-mineral"]
const maintenance = [dpUserdata + "salzvorrat", dpUserdata + "mineralvorrat"]
on({ id: maintenance, change: "ne" }, async (dp) => { // triggert bei Änderung der Datenpunkte
var pflegeSpeak = "";
var mineralfuellstandInt = Math.round(getState(dpUserdata + "mineralfuellstand").val);
var salzfuellstandInt = Math.round(getState(dpUserdata + "salzfuellstand").val);
var maintenance = false;
if(getState(dpUserdata + "pflege-salz").val && getState(dpUserdata + "pflege-mineral").val){
// Salz und Mineral
pflegeSpeak = pflegeSpeak + "Wasserenthärtungsanlage Salzbehälter und Minerallösungsbehälter benötigen Pflege. Füllstand des Salzbehälters ist "+salzfuellstandInt+
" % und der Füllstand des Minerallösungsbehälters ist "+mineralfuellstandInt+" %.";
maintenance = true;
} else if (getState(dpUserdata + "pflege-salz").val && !getState(dpUserdata + "pflege-mineral").val){
// Nur Salz
pflegeSpeak = pflegeSpeak + "Wasserenthärtungsanlage Salzbehälter benötigt Pflege. Füllstand des Salzbehälter ist "+salzfuellstandInt+
" % und der Füllstand des Minerallösungsbehälters ist "+mineralfuellstandInt+" %.";
maintenance = true;
} else if (!getState(dpUserdata + "pflege-salz").val && getState(dpUserdata + "pflege-mineral").val){
// Nur Mineral
pflegeSpeak = pflegeSpeak + "Wasserenthärtungsanlage Minerallösungsbehälter benötigt Pflege. Füllstand des Minerallösungsbehälters ist "+mineralfuellstandInt+
" % und der Füllstand des Salzbehälter ist "+salzfuellstandInt+" %.";
maintenance = true;
} else if (!getState(dpUserdata + "pflege-salz").val && !getState(dpUserdata + "pflege-mineral").val){
// Keine Pflege notwendig
pflegeSpeak = pflegeSpeak + "An der Wasserenthärtungsanlage ist keine Pflegemaßnahmen notwendig. Füllstand des Salzbehälters ist "+salzfuellstandInt+
" % und der Füllstand des Minerallösungsbehälters ist "+mineralfuellstandInt+" %.";
maintenance = false;
}
// Pflege notwendig?
setState(dpUserdata + "pflege", maintenance,true);
setState(dpUserdata + "pflege-speak", pflegeSpeak,true);
});
}
/**
* Objekt erzeugen
* @param {Object} MyConfig Json-Objekt
* @param {String} dpUserdata Workspace
*/
async function createMyConfig(MyConfig, dpUserdata) {
// Config scannen
for (var i = 0; i < MyConfig.row.length; i++) {
//console.log('Erzeuge: '+myConfig.row[i].dp);
await createMyState(dpUserdata + myConfig.row[i].dp, myConfig.row[i].name, myConfig.row[i].name, myConfig.row[i].read, myConfig.row[i].write, myConfig.row[i].type, myConfig.row[i].role, myConfig.row[i].unit, "", myConfig.row[i].value);
}
}
/**
* Wert über API holen, umwandeln und setzen
* @param {Object} myConfig Json-Objekt
* @param {String} url URL der API
* @param {String} dpUserdata Workspace
*/
async function getAPI(myConfig, url, dpUserdata) {
// Config scannen
for (var i = 0; i < myConfig.row.length; i++) {
var myapi = myConfig.row[i].api;
// API anpassen
switch (myapi) {
case "/api/rest/FB00": // Tagesstatistik
// Datum übergeben
var date = new Date();
var day = date.getDate();
var month = date.getMonth();
var month = month + 1;
var year = date.getFullYear();
var hexday = day.toString(16).padStart(2, '0');
var hexmonth = month.toString(16).padStart(2, '0');
var hexyear = year.toString(16).padStart(4, '0');
var formattedDate = hexday + hexmonth + hexyear;
myapi = myConfig.row[i].api + formattedDate;
//console.log("myapi: "+myapi);
break;
case "/api/rest/FC00": // Wochenstatistik
// Kalenderwoche und Jahr übergeben
var now = new moment();
var kw = now.isoWeek();
var hexkw = kw.toString(16).padStart(2, '0');
var date = new Date();
var year = date.getFullYear();
var hexyear = year.toString(16).padStart(4, '0');
var formattedDate = hexkw + hexyear;
myapi = myConfig.row[i].api + formattedDate;
//console.log("myapi: "+myapi);
break;
case "/api/rest/FD00": // Monatsstatistik
// Monat und Jahr übergeben
var date = new Date();
var month = date.getMonth();
var month = month + 1;
var year = date.getFullYear();
var hexmonth = month.toString(16).padStart(2, '0');
var hexyear = year.toString(16).padStart(4, '0');
var formattedDate = hexmonth + hexyear;
myapi = myConfig.row[i].api + formattedDate;
//console.log("myapi: "+myapi);
break;
case "/api/rest/FE00": // Jahresstatistik
// Jahr übergeben
var date = new Date();
var year = date.getFullYear();
var hexyear = year.toString(16).padStart(4, '0');
var formattedDate = hexyear;
myapi = myConfig.row[i].api + formattedDate;
//console.log("myapi: "+myapi);
break;
} // endSwitch
if (typeof myapi !== "undefined") { // Wenn es eine api gibt
if (myConfig.row[i].api != "/api/rest/FB00" || tagesStatistikEin) {
await httpGet(url + myapi,
{
timeout: 2000,
basicAuth: {
user: user,
password: password,
},
},
(err, response) => {
if (!err) {
if (response.statusCode === 200) {
var apiObj = JSON.parse(`${response.data}`);
//console.log("myapi: " + myapi);
setMyState(dpUserdata + myConfig.row[i].dp, apiObj.data, myConfig.row[i].api, i)
} else {
console.log(`StatusCode: ${response.statusCode}`);
}
} else {
console.error(err);
}
}
); // end await httpGet
} // iif (myConfig.row[i].api == "/api/rest/FB00" && tagesStatistikEin){
await sleep(10 * 1000);
}
}
}
/**
* Wenn nicht über API wird die Tagesstatistik berechnet
* @param {number} incrementWasser Gesamtwasserverbrauch seit der letzten Berechnung.
*/
async function setTagesStatistik(incrementWasser) {
// Aktuelles 1/8 Zeitspanne berechnen
let zeitspanne = "";
let date = new Date();
let stunde = parseInt(formatDate(date, "S"));
if (stunde >= 0 && stunde < 3){
zeitspanne = "00-03";
} else if (stunde >= 3 && stunde < 6) {
zeitspanne = "03-06";
} else if (stunde >= 6 && stunde < 9) {
zeitspanne = "06-09";
} else if (stunde >= 9 && stunde < 12) {
zeitspanne = "09-12";
} else if (stunde >= 12 && stunde < 15) {
zeitspanne = "12-15";
} else if (stunde >= 15 && stunde < 18) {
zeitspanne = "15-18";
} else if (stunde >= 18 && stunde < 21) {
zeitspanne = "18-21";
} else if (stunde >= 21) {
zeitspanne = "21-00";
};
// Verbrauch aktualisieren
if (getState(dpUserdata+"zaehlerZeitspanne").val == zeitspanne){
// Verbrauch aktualisieren innerhalb der selben Zeitspanne
let zaehlerZeitspanneWasser = getState(dpUserdata+"zaehlerZeitspanneWasser").val+incrementWasser;
setState(dpUserdata+"zaehlerZeitspanneWasser", zaehlerZeitspanneWasser, true);
setState(dpUserdata+"WasserTag."+zeitspanne, Math.round((zaehlerZeitspanneWasser*1000)), true);
} else {
// Verbrauch aktualisieren bei neuer Zeitspanne
setState(dpUserdata+"zaehlerZeitspanneWasser", incrementWasser, true);
setState(dpUserdata+"WasserTag."+zeitspanne, Math.round((incrementWasser*1000)), true);
setState(dpUserdata+"zaehlerZeitspanne", zeitspanne, true);
};
}
/**
* Zurücksetzen der Tagesstatistik bei Tageswechsel um 0 Uhr
*/
async function resetTagesStatistik() {
// Tageswechsel -> Zeitspannen auf 0 setzen
setState(dpUserdata + "WasserTag." + "00-03", 0, true);
setState(dpUserdata + "WasserTag." + "03-06", 0, true);
setState(dpUserdata + "WasserTag." + "06-09", 0, true);
setState(dpUserdata + "WasserTag." + "09-12", 0, true);
setState(dpUserdata + "WasserTag." + "12-15", 0, true);
setState(dpUserdata + "WasserTag." + "15-18", 0, true);
setState(dpUserdata + "WasserTag." + "18-21", 0, true);
setState(dpUserdata + "WasserTag." + "21-00", 0, true);
setState(dpUserdata + "zaehlerZeitspanneWasser", 0, true);
}
/**
* Objekt setzen
* @param {String} state Objektpfad
* @param {any} value Inhalt
* @param {String} api API Case
* @param {number} index des Json Objekts
*/
async function setMyState(state, value, api, index) {
//console.log("api: "+api);
switch (api) {
case "/api/rest/FF00": // Gerätetyp
var valDez = parseInt(value, 16);
value = myConfig.row[index].geraetetyp[valDez];
//console.log(value);
setState(state, value, true);
break;
case "/api/rest/0600": // Gerätenummer
// Byte Reihenfolge umkehren
var reverseValue = value.substring(4 * 2 - 1 * 2, 4 * 2 - 0 * 2);
reverseValue = reverseValue + value.substring(4 * 2 - 2 * 2, 4 * 2 - 1 * 2);
reverseValue = reverseValue + value.substring(4 * 2 - 3 * 2, 4 * 2 - 2 * 2);
reverseValue = reverseValue + value.substring(4 * 2 - 4 * 2, 4 * 2 - 3 * 2);
var valDez = parseInt(reverseValue, 16);
var dummy = valDez.toString();
setState(state, dummy, true);
break;
case "/api/rest/0100": // SW-Version Gerätesteuerung
// Byte Reihenfolge umkehren
var reverseValue = value.substring(3 * 2 - 1 * 2, 3 * 2 - 0 * 2);
var idummy = parseInt(reverseValue, 16);
var stringvalue = idummy.toString() + ".";
reverseValue = value.substring(3 * 2 - 2 * 2, 3 * 2 - 1 * 2);
var idummy = parseInt(reverseValue, 16)
var stringvalue = stringvalue + idummy.toString();
// nicht relevant
//reverseValue = reverseValue+value.substring(3*2-3*2,3*2-2*2);
setState(state, stringvalue, true);
break;
case "/api/rest/0E00": // Inbetriebnahmedatum
var unixtimestamp = parseInt(value, 16)
var date = new Date(unixtimestamp * 1000);
setState(state, formatDate(date, "TT.MM.JJJJ"), true);
//console.log("Inbetriebnahmedatum: "+date.toString());
break;
case "/api/rest/2500": // Betriebsstundenzähler
// Byte Reihenfolge umkehren
var tag2 = value.substring(4 * 2 - 1 * 2, 4 * 2 - 0 * 2);
var tag1 = value.substring(4 * 2 - 2 * 2, 4 * 2 - 1 * 2);
var std = value.substring(4 * 2 - 3 * 2, 4 * 2 - 2 * 2);
var min = value.substring(4 * 2 - 4 * 2, 4 * 2 - 3 * 2);
var Tage = 0
var tag2multiplikator = parseInt(tag2, 16);
if (tag2multiplikator > 0) {
Tage = parseInt(tag1, 16) + (255*tag2multiplikator);
} else {
Tage = parseInt(tag1, 16);
}
var Std = parseInt(std, 16);
var Min = parseInt(min, 16);
var betrieb = Tage.toString() + " Tage, " + Std.toString() + " Std., " + Min.toString() + " Min.";
setState(state, betrieb, true);
//console.log("value: "+value);
//console.log("Betriebsstundenzähler: "+betrieb);
break;
// case "/api/rest/2800": // Gesamtwassermenge. // Wird von Softwell nicht unterstützt. Stattdessen über Weichwassermenge mit Formel berechnet.
// var reverseValue = value.substring(4*2-1*2,4*2-0*2);
// reverseValue = reverseValue+value.substring(4*2-2*2,4*2-1*2);
// reverseValue = reverseValue+value.substring(4*2-3*2,4*2-2*2);
// reverseValue = reverseValue+value.substring(4*2-4*2,4*2-3*2);
// //console.log(reverseValue);
// var idummy = parseInt(reverseValue, 16)/1000;
// //console.log("Gesamtwassermenge: "+dummy);
// setState(state, idummy, true);
// break;
case "/api/rest/2900": // Weichwassermenge
var reverseValue = value.substring(4 * 2 - 1 * 2, 4 * 2 - 0 * 2);
reverseValue = reverseValue + value.substring(4 * 2 - 2 * 2, 4 * 2 - 1 * 2);
reverseValue = reverseValue + value.substring(4 * 2 - 3 * 2, 4 * 2 - 2 * 2);
reverseValue = reverseValue + value.substring(4 * 2 - 4 * 2, 4 * 2 - 3 * 2);
//console.log(reverseValue);
var idummy = parseInt(reverseValue, 16) / 1000;
//console.log("Weichwassermenge: "+dummy);
setState(state, idummy, true);
break;
case "/api/rest/5100": // Wunschwasserhärte
var reverseValue2 = value.substring(2 * 2 - 1 * 2, 2 * 2 - 0 * 2);
var reverseValue1 = value.substring(2 * 2 - 2 * 2, 2 * 2 - 1 * 2);
var idummy = parseInt(reverseValue1, 16) + parseInt(reverseValue2, 16);
setState(state, idummy, true);
break;
case "/api/rest/FB00": // Tagesstatistik
// Je 4 Byte sind 8 Zeichen
//console.log("/api/rest/FB00: " + value);
var idummy = parseInt(value.substring(1, 8), 16);
setState(state, idummy, true);
idummy = parseInt(value.substring(9, 16), 16);
setState(dpUserdata + myConfig.row[index + 1].dp, idummy, true);
idummy = parseInt(value.substring(17, 24), 16);
setState(dpUserdata + myConfig.row[index + 2].dp, idummy, true);
idummy = parseInt(value.substring(25, 32), 16);
setState(dpUserdata + myConfig.row[index + 3].dp, idummy, true);
idummy = parseInt(value.substring(33, 40), 16);
setState(dpUserdata + myConfig.row[index + 4].dp, idummy, true);
idummy = parseInt(value.substring(41, 48), 16);
setState(dpUserdata + myConfig.row[index + 5].dp, idummy, true);
idummy = parseInt(value.substring(49, 56), 16);
setState(dpUserdata + myConfig.row[index + 6].dp, idummy, true);
idummy = parseInt(value.substring(57, 64), 16);
setState(dpUserdata + myConfig.row[index + 7].dp, idummy, true);
break;
case "/api/rest/FC00": // Wochenstatistik
// Je 4 Byte sind 8 Zeichen
//console.log("/api/rest/FC00: " + value);
var idummy = parseInt(value.substring(1, 8), 16);
setState(state, idummy, true);
idummy = parseInt(value.substring(9, 16), 16);
setState(dpUserdata + myConfig.row[index + 1].dp, idummy, true);
idummy = parseInt(value.substring(17, 24), 16);
setState(dpUserdata + myConfig.row[index + 2].dp, idummy, true);
idummy = parseInt(value.substring(25, 32), 16);
setState(dpUserdata + myConfig.row[index + 3].dp, idummy, true);
idummy = parseInt(value.substring(33, 40), 16);
setState(dpUserdata + myConfig.row[index + 4].dp, idummy, true);
idummy = parseInt(value.substring(41, 48), 16);
setState(dpUserdata + myConfig.row[index + 5].dp, idummy, true);
idummy = parseInt(value.substring(49, 56), 16);
setState(dpUserdata + myConfig.row[index + 6].dp, idummy, true);
break;
case "/api/rest/FD00": // Monatsstatistik
// Je 4 Byte sind 8 Zeichen
//console.log("/api/rest/FD00: " + value);
var idummy = parseInt(value.substring(1, 8), 16);
setState(state, idummy, true);
idummy = parseInt(value.substring(9, 16), 16);
setState(dpUserdata + myConfig.row[index + 1].dp, idummy, true);
idummy = parseInt(value.substring(17, 24), 16);
setState(dpUserdata + myConfig.row[index + 2].dp, idummy, true);
idummy = parseInt(value.substring(25, 32), 16);
setState(dpUserdata + myConfig.row[index + 3].dp, idummy, true);
idummy = parseInt(value.substring(33, 40), 16);
setState(dpUserdata + myConfig.row[index + 4].dp, idummy, true);
idummy = parseInt(value.substring(41, 48), 16);
setState(dpUserdata + myConfig.row[index + 5].dp, idummy, true);
idummy = parseInt(value.substring(49, 56), 16);
setState(dpUserdata + myConfig.row[index + 6].dp, idummy, true);
idummy = parseInt(value.substring(57, 64), 16);
setState(dpUserdata + myConfig.row[index + 7].dp, idummy, true);
idummy = parseInt(value.substring(65, 72), 16);
setState(dpUserdata + myConfig.row[index + 8].dp, idummy, true);
idummy = parseInt(value.substring(73, 80), 16);
setState(dpUserdata + myConfig.row[index + 9].dp, idummy, true);
idummy = parseInt(value.substring(81, 88), 16);
setState(dpUserdata + myConfig.row[index + 10].dp, idummy, true);
idummy = parseInt(value.substring(89, 96), 16);
setState(dpUserdata + myConfig.row[index + 11].dp, idummy, true);
idummy = parseInt(value.substring(97, 104), 16);
setState(dpUserdata + myConfig.row[index + 12].dp, idummy, true);
idummy = parseInt(value.substring(105, 112), 16);
setState(dpUserdata + myConfig.row[index + 13].dp, idummy, true);
idummy = parseInt(value.substring(113, 120), 16);
setState(dpUserdata + myConfig.row[index + 14].dp, idummy, true);
idummy = parseInt(value.substring(121, 128), 16);
setState(dpUserdata + myConfig.row[index + 15].dp, idummy, true);
idummy = parseInt(value.substring(129, 136), 16);
setState(dpUserdata + myConfig.row[index + 16].dp, idummy, true);
idummy = parseInt(value.substring(137, 144), 16);
setState(dpUserdata + myConfig.row[index + 17].dp, idummy, true);
idummy = parseInt(value.substring(145, 152), 16);
setState(dpUserdata + myConfig.row[index + 18].dp, idummy, true);
idummy = parseInt(value.substring(153, 160), 16);
setState(dpUserdata + myConfig.row[index + 19].dp, idummy, true);
idummy = parseInt(value.substring(161, 168), 16);
setState(dpUserdata + myConfig.row[index + 20].dp, idummy, true);
idummy = parseInt(value.substring(169, 176), 16);
setState(dpUserdata + myConfig.row[index + 21].dp, idummy, true);
idummy = parseInt(value.substring(177, 184), 16);
setState(dpUserdata + myConfig.row[index + 22].dp, idummy, true);
idummy = parseInt(value.substring(185, 192), 16);
setState(dpUserdata + myConfig.row[index + 23].dp, idummy, true);
idummy = parseInt(value.substring(193, 200), 16);
setState(dpUserdata + myConfig.row[index + 24].dp, idummy, true);
idummy = parseInt(value.substring(201, 208), 16);
setState(dpUserdata + myConfig.row[index + 25].dp, idummy, true);
idummy = parseInt(value.substring(209, 216), 16);
setState(dpUserdata + myConfig.row[index + 26].dp, idummy, true);
idummy = parseInt(value.substring(217, 224), 16);
setState(dpUserdata + myConfig.row[index + 27].dp, idummy, true);
idummy = parseInt(value.substring(225, 232), 16);
setState(dpUserdata + myConfig.row[index + 28].dp, idummy, true);
idummy = parseInt(value.substring(233, 240), 16);
setState(dpUserdata + myConfig.row[index + 29].dp, idummy, true);
idummy = parseInt(value.substring(241, 248), 16);
setState(dpUserdata + myConfig.row[index + 30].dp, idummy, true);
break;
case "/api/rest/FE00": // Wochenstatistik
// Je 4 Byte sind 8 Zeichen
//console.log("/api/rest/FE00: " + value);
var idummy = parseInt(value.substring(1, 8), 16);
setState(state, idummy, true);
idummy = parseInt(value.substring(9, 16), 16);
setState(dpUserdata + myConfig.row[index + 1].dp, idummy, true);
idummy = parseInt(value.substring(17, 24), 16);
setState(dpUserdata + myConfig.row[index + 2].dp, idummy, true);
idummy = parseInt(value.substring(25, 32), 16);
setState(dpUserdata + myConfig.row[index + 3].dp, idummy, true);
idummy = parseInt(value.substring(33, 40), 16);
setState(dpUserdata + myConfig.row[index + 4].dp, idummy, true);
idummy = parseInt(value.substring(41, 48), 16);
setState(dpUserdata + myConfig.row[index + 5].dp, idummy, true);
idummy = parseInt(value.substring(49, 56), 16);
setState(dpUserdata + myConfig.row[index + 6].dp, idummy, true);
idummy = parseInt(value.substring(57, 64), 16);
setState(dpUserdata + myConfig.row[index + 7].dp, idummy, true);
idummy = parseInt(value.substring(65, 72), 16);
setState(dpUserdata + myConfig.row[index + 8].dp, idummy, true);
idummy = parseInt(value.substring(73, 80), 16);
setState(dpUserdata + myConfig.row[index + 9].dp, idummy, true);
idummy = parseInt(value.substring(81, 88), 16);
setState(dpUserdata + myConfig.row[index + 10].dp, idummy, true);
idummy = parseInt(value.substring(89, 96), 16);
setState(dpUserdata + myConfig.row[index + 11].dp, idummy, true);
break;
} // endSwitch
}
/**
* Objekt erzeugen
* @param {String} state Objektpfad
* @param {String} name Name des Objektes
* @param {String} desc Beschreibung des Objektes
* @param {String} type Type des Objektes string,number
* @param {Boolean} read Leserechte des Objektes
* @param {Boolean} write Schreibrechte des Objektes
* @param {String} role Rolle des Objektes button,...
* @param {String} unit Rolle des Objektes button,...
* @param {String} smartName Smartname für Alexa
* @param {any} value Inhalt
*/
async function createMyState(state, name, desc, read, write, type, role, unit, smartName, value) {
if (type == "number") {
//value = Number(value);
await createStateAsync(state, 0, {
name: name,
desc: desc,
read: read,
write: write,
type: type,
role: role,
unit: unit
});
} else {
if (smartName == "") {
// ohne Smartnamen
await createStateAsync(state, value, {
name: name,
desc: desc,
read: read,
write: write,
type: type,
role: role,
unit: unit
});
} else {
await createStateAsync(state, value, {
// mit Smartnamen
name: name,
desc: desc,
read: read,
write: write,
type: type,
role: role,
unit: unit,
smartName: {
de: smartName
}
});
}
}
}
Benutzung auf eigene Gefahr.
Support kann ich nur eingeschränkt bieten.
Über Feedback würde ich mich freuen.
View
Als kostenlose Zugabe eine View für die Vis
Voraussetzung
- Adapter Material Design Widgets
Für mich das flexibelste und beste Material Widget.
- Vis 1
Leider findet sich niemand, der die Material Design Widgets in Vis 2 anpasst. Das ist sehr schade. Für mich ist das unverzichtbar, deshalb muss ich bei Vis 1 bleiben.
Die einzelnen Views wurden gezipt. Views JUDO Wasserenthärtung.zip:
View JUDO Wasserenthärtung.zip