NEWS
Aqualink Pool Automation in iobroker integrieren
-
@negalein sagte in Aqualink Pool Automation in iobroker integrieren:
Ah ok, ich dachte du hast auch eine Zodiac-Anlage.
nee leider nein.. sry
-
Meine alte Zodiac TriExpert hat diese Saison das Zeitliche gesegnet.
Läuft bei einem von euch beiden die Integration der Zodiac Exo IQ in iobroker ?
Falls ja, ist das stabil und für den Dauerbetrieb/Automatisierungen verwendbar ?Ihr würdet mir damit bei der Kaufentscheidung sehr helfen.
Danke.
Beste Grüße
-
Im Nodered Forum hat jemand einen Flow gepostet mit dem es anscheinend auch funktionieren sollte die Daten der Zodiac Exo IQ auszulesen:
Hier ist der Flow:
[ { "id": "6c519c18faf10a1e", "type": "tab", "label": "Zodiac Exo", "disabled": false, "info": "", "env": [] }, { "id": "1e47a52e3f1755e1", "type": "inject", "z": "6c519c18faf10a1e", "name": "Every hour", "repeat": "3540", "crontab": "", "once": true, "onceDelay": "60", "topic": "", "payload": "", "payloadType": "date", "x": 130, "y": 60, "wires": [ [ "6808aab954fc8b01" ] ] }, { "id": "7849f0c750568181", "type": "http request", "z": "6c519c18faf10a1e", "name": "", "method": "use", "ret": "obj", "paytoqs": "ignore", "url": "", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 610, "y": 60, "wires": [ [ "18bf3f43ad2e6aa4" ] ] }, { "id": "18bf3f43ad2e6aa4", "type": "change", "z": "6c519c18faf10a1e", "name": "IDToken", "rules": [ { "t": "move", "p": "payload.userPoolOAuth.IdToken", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 840, "y": 60, "wires": [ [ "ea244732498b9412" ] ] }, { "id": "6808aab954fc8b01", "type": "function", "z": "6c519c18faf10a1e", "name": "Format Post Request", "func": "msg.method = 'POST';\nmsg.headers = {};\nmsg.headers['Host'] = 'prod.zodiac-io.com';\nmsg.headers['accept'] = 'application/json';\nmsg.headers['content-type'] = 'application/json';\nmsg.headers['accept-encoding'] = '*';\nmsg.headers['user-agent'] = 'okhttp/3.12.0';\nmsg.url = 'https://prod.zodiac-io.com/users/v1/login';\nmsg.payload = '{\"api_key\":\"yourapikeyhere\", \"email\":\"youremail@address.com\", \"password\":\"youriAqualinkpassword\"}';\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 380, "y": 60, "wires": [ [ "7849f0c750568181" ] ] }, { "id": "ea244732498b9412", "type": "function", "z": "6c519c18faf10a1e", "name": "Set variable IDToken", "func": "global.set(\"IDToken\",msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1080, "y": 60, "wires": [ [] ] }, { "id": "dcd9bc84914a71f6", "type": "http request", "z": "6c519c18faf10a1e", "name": "Chlorinator", "method": "use", "ret": "obj", "paytoqs": "ignore", "url": "", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 610, "y": 380, "wires": [ [ "02b59259a14e8461", "b8075e9783a1eb4f", "f0bb9145a81ce74a", "eba07f6046f035d6", "4ac01fee0ba334b1", "018a8ddf5da0b1f2", "9c4298d655076b55" ] ] }, { "id": "9df6c312e595c863", "type": "function", "z": "6c519c18faf10a1e", "name": "Format Get Request", "func": "let bearer = global.get(\"IDToken\");\nmsg.method = 'GET';\nmsg.headers = {};\nmsg.headers['Host'] = 'prod.zodiac-io.com';\nmsg.headers['accept'] = 'application/json';\nmsg.headers['authorization'] = bearer;\nmsg.headers['accept-encoding'] = '*';\nmsg.headers['user-agent'] = 'okhttp/3.12.0';\nmsg.url = 'https://prod.zodiac-io.com/devices/v1/yourDeviceIDhere/shadow';\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 380, "y": 380, "wires": [ [ "dcd9bc84914a71f6" ] ] }, { "id": "a56824124abf6deb", "type": "inject", "z": "6c519c18faf10a1e", "name": "Every 10 mins", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "600", "crontab": "", "once": true, "onceDelay": "300", "topic": "", "payloadType": "date", "x": 140, "y": 380, "wires": [ [ "9df6c312e595c863" ] ] }, { "id": "02b59259a14e8461", "type": "change", "z": "6c519c18faf10a1e", "name": "ORP", "rules": [ { "t": "move", "p": "payload.state.reported.equipment.swc_0.sns_2.value", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 830, "y": 300, "wires": [ [] ] }, { "id": "b8075e9783a1eb4f", "type": "change", "z": "6c519c18faf10a1e", "name": "pH", "rules": [ { "t": "move", "p": "payload.state.reported.equipment.swc_0.sns_1.value", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 830, "y": 140, "wires": [ [ "0e3f2e3e62511c3a" ] ] }, { "id": "f0bb9145a81ce74a", "type": "change", "z": "6c519c18faf10a1e", "name": "Filter Temp", "rules": [ { "t": "move", "p": "payload.state.reported.equipment.swc_0.sns_3.value", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 850, "y": 460, "wires": [ [] ] }, { "id": "0e3f2e3e62511c3a", "type": "range", "z": "6c519c18faf10a1e", "minin": "0", "maxin": "10", "minout": "0", "maxout": "1", "action": "scale", "round": false, "property": "payload", "name": "Divide by 10", "x": 1050, "y": 140, "wires": [ [] ] }, { "id": "eba07f6046f035d6", "type": "change", "z": "6c519c18faf10a1e", "name": "ORP Setpoint", "rules": [ { "t": "move", "p": "payload.state.reported.equipment.swc_0.orp_sp", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 860, "y": 380, "wires": [ [] ] }, { "id": "4ac01fee0ba334b1", "type": "change", "z": "6c519c18faf10a1e", "name": "pH Setpoint", "rules": [ { "t": "move", "p": "payload.state.reported.equipment.swc_0.ph_sp", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 850, "y": 220, "wires": [ [ "874e523fa6c7da37" ] ] }, { "id": "874e523fa6c7da37", "type": "range", "z": "6c519c18faf10a1e", "minin": "0", "maxin": "10", "minout": "0", "maxout": "1", "action": "scale", "round": false, "property": "payload", "name": "Divide by 10", "x": 1050, "y": 220, "wires": [ [] ] }, { "id": "018a8ddf5da0b1f2", "type": "change", "z": "6c519c18faf10a1e", "name": "Zodiac Error Code", "rules": [ { "t": "move", "p": "payload.state.reported.equipment.swc_0.error_code", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 870, "y": 540, "wires": [ [] ] }, { "id": "9c4298d655076b55", "type": "change", "z": "6c519c18faf10a1e", "name": "Low Setting", "rules": [ { "t": "move", "p": "payload.state.reported.equipment.swc_0.low", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 850, "y": 620, "wires": [ [] ] } ]
und hier die Anleitung dazu:
Note that in the Function node (Format Post Request) preceeding the first HTTP Request , you will require three bits of info -
API Key (generic for all users) - EOOEMOW4YR6QNB11
Email
PasswordIn the Function node (Format Get Request) preceeding the Device, you will need 'yourDeviceIDhere' where specified. It's the serial number of the device and looks something like -
JT19000123
or
JX19100123The post you originally linked to has the curl commands necessary to pull the DeviceID. They might also be physically printed on the device somewhere but I haven't looked.
PULL DEVICE ID:
The steps required to login to iAqualink are as follows (note the api_key is the same for all users)
curl -X POST -H "Host:prod.zodiac-io.com" -H "accept:application/json" -H "content-type:application/json" -H "accept-encoding:gzip" -H "user-agent:okhttp/3.12.0" -d '{"api_key":"EOOEMOW4YR6QNB11", "email":"XXXX@XXXX", "password":"XXXXXX"}' "https://prod.zodiac-io.com/users/v1/login"
The iAqualink server returns a page of data (X's blank out personal data) -
{ "username": "XXXXXXXXXXXXXXXXXX", "email": "XXXXXXXXXXX@gmail.com", "first_name": "XXX", "last_name": "XXXXXX", "address": "XXX\n, XXX, XX, au, XXX", "address_1": "XXXXXXXXXXX", "address_2": null, "city": "XXXXXXXXXXX", "state": "XX", "country": "au", "postal_code": "XXXX", "id": "XXXXXX", "authentication_token": "XXXXXXXXXXXXXXXXXXXX", "session_id": "XXXXXXXXXXXXXXXXXXXX", "created_at": "2019-12-09T03:12:57.000Z", "updated_at": "2019-12-09T03:12:57.000Z", "time_zone": "Australia/XXXXXX", "phone": "XXXXXXXXXX", "opt_in_1": "1", "opt_in_2": "0", "role": "customer", "cognitoPool": { "appClientId": "XXXXXXXXXXXXXXXXXXXXX", "poolId": "us-east-1_XXXXXXXXX", "region": "us-east-1" }, "credentials": { "AccessKeyId": "XXXXXXXXXXXXXXXXXXXX", "SecretKey": "XXXXXXXXXXXXXXXXXXXXXX", "SessionToken": "XXXXXX.............XXXXXXXX", "Expiration": "2020-04-26T05:24:59.000Z", "IdentityId": "us-east-1:XXXXXXXXXXXXXXXX" }, "userPoolOAuth": { "AccessToken": "XXXXXXX...............XXXXXXX", "ExpiresIn": 3600, "TokenType": "Bearer", "RefreshToken": "XXXXXX..........XXXXXXXXX", "IdToken": "XXXXXXXXXX.........XXXXXXXXXXX" }
The important fields in the preceeding data block are -
"id": (a 6 digit number that remains the same across logins),
"authentication_token": (a 20 character field that remains the same across logins),
"IdToken": (a 1740 character field that expires in 3600 seconds).
Armed with this data, a second command will elicit the device serial numbers registered to the user's account (user_id = id from block above) -
curl 'https://support.iaqualink.com/devices.json?api_key=EOOEMOW4YR6QNB07&authentication_token=XXXXXXXXXXXXXXXXXXXX&user_id=XXXXXX' -H "Host:support.iaqualink.com" -H "accept:application/json" -H "user-agent:okhttp/3.12.0" -H "content-type:application/json"
This is the returned data block for the two devices I have (a chlorinator and a heat pump) -
[ { "id":"XXXXXX", "serial_number":"XXXXXXXXXX", "created_at":"2020-01-07T09:41:41.000Z", "updated_at":"2020-01-07T09:41:41.000Z", "name":"Z400 iQ TD7", "device_type":"hpm", "owner_id":null, "updating":false, "firmware_version":null, "target_firmware_version":null, "update_firmware_start_at":null, "last_activity_at":null }, { "id":"XXXXXX", "serial_number":"XXXXXXXXXX", "created_at":"2019-12-09T03:18:18.000Z", "updated_at":"2019-12-09T03:18:18.000Z", "name":"eXO-Pro iQ", "device_type":"exo", "owner_id":null, "updating":false, "firmware_version":null, "target_firmware_version":null, "update_firmware_start_at":null, "last_activity_at":null } ]
INFORMATION RETRIEVAL AND CONTROL
With the DEVICE_SERIAL_NUMBER ("serial_number" in the block above), and ID_TOKEN ("IdToken" from the first block of data) the next GET command can be populated to retrieve the pH and ORP values for the chlorinator -
curl -X GET -H "Host:prod.zodiac-io.com" -H "accept:application/json" -H "authorization:ID_TOKEN" -H "accept-encoding:gzip" -H "user-agent:okhttp/3.12.0" "https://prod.zodiac-io.com/devices/v1/DEVICE_SERIAL_NUMBER/shadow"
Control of the chlorinator production (On/Off) can done using a POST command ("production" to be set to 0 or 1) -
curl -X POST -H "Host:prod.zodiac-io.com" -H "accept:application/json" -H "authorization:ID_TOKEN" -H "content-type:application/json; charset=UTF-8" -H "content-length:62" -H "accept-encoding:gzip" -H "user-agent:okhttp/3.12.0" -d '{"state":{"desired":{"equipment":{"swc_0":{"production":0}}}}}' "https://prod.zodiac-io.com/devices/v1/DEVICE_SERIAL_NUMBER/shadow"
I have the DEVICE_SERIAL_NUMBER for the components in my system (this value is fixed).
I now need a mechanism to record the variable ID_TOKEN and subsequently plug this into the commands above.Kann das eventuell mal jemand testen, der eine Zodiac Exo im Einsatz hat ?
-
Besten Dank für die Info.
Anhand dieser konnte ich per Javascript die Pool-Daten auslesen und im iobroker als object ablegen. Danach habe ich mit weiteren scripts die entsprechenden Daten ausgefiltert und diese ebenfalls in ein Object abgelegt.const axios = require('axios'); // Daten für die POST-Anfrage const daten = { api_key: "EOOEMOW4YR6QNB11", email: "xxxxxxxxxxxx", password: "xxxxxxxxxxxx" }; // Erste Anfrage zur Authentifizierung axios.post('https://prod.zodiac-io.com/users/v1/login', daten, { headers: { 'Host': 'prod.zodiac-io.com', 'accept': 'application/json', 'Content-Type': 'application/json', 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.0' } }).then((response) => { setState('javascript.0.iAquaLink.IdToken', JSON.stringify(response.data), true); console.log('Daten erfolgreich in ioBroker gespeichert.'); // Extrahieren des idTokens let jsonObject = response.data; let idToken = jsonObject.userPoolOAuth.IdToken; if (idToken) { console.log("idToken extrahiert:", idToken); setState('javascript.0.iAquaLink.IdToken_clean', idToken, true); // Zweite Anfrage unter Verwendung des idTokens const options = { method: 'GET', url: 'https://prod.zodiac-io.com/devices/v1/serialnumberxxxxxx/shadow', headers: { 'Host': 'prod.zodiac-io.com', 'accept': 'application/json', 'authorization': idToken, 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.0' } }; return axios.request(options); } else { throw new Error("Kein idToken gefunden!"); } }).then(response => { console.log(response.data); setState('0_userdata.0.Pool.Pooldata', response.data, true); }).catch(error => { console.error('Fehler:', error); });
-
Hallo
welchen Typ benötigen diese DP?
javascript.0.iAquaLink.IdToken
javascript.0.iAquaLink.IdToken_clean
0_userdata.0.Pool.Pooldata -
Alle DPs => Typ: "String" und Rolle: "State"
Am besten alle DP in 0_userdata.0.xxxx vorab anlegen. -
ich bekomm einen Fehler.
Ist nicht ersichtlich woher.javascript.0 14:59:13.580 info Start JavaScript script.js.Pool.iAqualink (Javascript/js) javascript.0 14:59:13.589 info registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions javascript.0 14:59:14.322 error Fehler:
-
Zeile 29: Richtige bzw. eigene Serien Nr. verwendet ?
-
@hexagon sagte in Aqualink Pool Automation in iobroker integrieren:
Zeile 29: Richtige bzw. eigene Serien Nr. verwendet ?
ahhhhh, übersehn
jetzt kommen Daten, aber mit Warn.
DP werden befüllt
javascript.0 15:35:55.780 info Start JavaScript script.js.Pool.iAqualink (Javascript/js) javascript.0 15:35:55.789 info registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions javascript.0 15:35:56.600 info Daten erfolgreich in ioBroker gespeichert. javascript.0 15:35:56.600 info idToken extrahiert: javascript.0 15:35:56.886 info { state: { reported: { aws: [Object], vr: 'V85E4', vr_esp: 'V85E4', equipment: [Object], schedules: [Object] } }, deviceId: 'JT22008430', ts: 1747056956 } javascript.0 15:35:56.889 warn at script.js.Pool.iAqualink:45:5
-
ok prima, jetzt kannst du mit entsprechenden Filterungen weitere Datenpunkte befüllen, je nachdem was du benötigst:
Beispiel für ORP Werte:
// Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.Pool.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.Pool.Pooldata_ORP"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_2` extrahieren let sns_2 = jsonObject.state.reported.equipment.swc_0.sns_2.value; if (sns_2) { console.log("sns_2 extrahiert:", sns_2); // sns_2 in das neue ioBroker-Objekt speichern setState(targetObject, sns_2, true); } else { console.log("Kein sns_2 gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } });
-
@hexagon sagte in Aqualink Pool Automation in iobroker integrieren:
ok prima, jetzt kannst du mit entsprechenden Filterungen weitere Datenpunkte befüllen, je nachdem was du benötigst:
Danke
hast du auch noch für pH, Chlorination und Temp?
-
ORP Wert entspricht bereits dem Chlorinator
Für PH Wert ist es genau das gleiche nur der Sensor 1 => sns_1:
Die Kommastelle kannst du dann mit dem VIS Editor entsprechend setzen.// Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.Pool.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.Pool.Pooldata_PH"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_1` extrahieren let sns_1 = jsonObject.state.reported.equipment.swc_0.sns_1.value; if (sns_1) { console.log("sns_1 extrahiert:", sns_1); // sns_1 in das neue ioBroker-Objekt speichern setState(targetObject, sns_1, true); } else { console.log("Kein sns_1 gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } });
Nach diesem Muster kannst du dir auch die Temp Werte bauen.
-
@hexagon sagte in Aqualink Pool Automation in iobroker integrieren:
ORP Wert entspricht bereits dem Chlorinator
schaut in der App so aus
Meinte Salzelektrolysegerät (Pumpe)
sns_3 ist dann die Temp?
oder wie finde ich das raus?
-
Schau dir die Werte im DP Pooldata an:
0_userdata.0.Pool.PooldataDort sollten alle Daten ersichtlich sein:
Beispiel Temperatur:
"sns_3": { "sensor_type": "Water temp", "state": 1, "value": 25
-
@hexagon sagte in Aqualink Pool Automation in iobroker integrieren:
Dort sollten alle Daten ersichtlich sein:
ahhh, ich war blind. hab nur die ersten paar zeilen gesehn.
und die gewünschten pack ich alle in das Script von dir?
-
die Pumpe scheint so auf:
"filter_pump": { "state": 1, "type": 1 },
Binde ich die dann so ein?
// Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.Pool.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.Pool.Pooldata_Pumpe"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_2` extrahieren let sns_2 = jsonObject.state.reported.equipment.swc_0.filter_pump.value; if (sns_2) { console.log("sns_2 extrahiert:", filter_pump); // sns_2 in das neue ioBroker-Objekt speichern setState(targetObject, filter_pump, true); } else { console.log("Kein filter_pump gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } });
Und alle 4 in 1 Script?
const axios = require('axios'); // Daten für die POST-Anfrage const daten = { api_key: "EOOEMOW4YR6QNB11", email: "xxxxxxxx@xxxxxx.xx", password: "xxxxxxxxxxx" }; // Erste Anfrage zur Authentifizierung axios.post('https://prod.zodiac-io.com/users/v1/login', daten, { headers: { 'Host': 'prod.zodiac-io.com', 'accept': 'application/json', 'Content-Type': 'application/json', 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.0' } }).then((response) => { setState('0_userdata.0.iAquaLink.IdToken', JSON.stringify(response.data), true); console.log('Daten erfolgreich in ioBroker gespeichert.'); // Extrahieren des idTokens let jsonObject = response.data; let idToken = jsonObject.userPoolOAuth.IdToken; if (idToken) { console.log("idToken extrahiert:", idToken); setState('0_userdata.0.iAquaLink.IdToken_clean', idToken, true); // Zweite Anfrage unter Verwendung des idTokens const options = { method: 'GET', url: 'https://prod.zodiac-io.com/devices/v1/JT22005060/shadow', headers: { 'Host': 'prod.zodiac-io.com', 'accept': 'application/json', 'authorization': idToken, 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.0' } }; return axios.request(options); } else { throw new Error("Kein idToken gefunden!"); } }).then(response => { console.log(response.data); setState('0_userdata.0.iAquaLink.Pooldata', response.data, true); }).catch(error => { console.error('Fehler:', error); }); // Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.Pool.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.Pool.Pooldata_PH"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_1` extrahieren let sns_1 = jsonObject.state.reported.equipment.swc_0.sns_1.value; if (sns_1) { console.log("sns_1 extrahiert:", sns_1); // sns_1 in das neue ioBroker-Objekt speichern setState(targetObject, sns_1, true); } else { console.log("Kein sns_1 gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } }); // Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.Pool.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.Pool.Pooldata_ORP"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_2` extrahieren let sns_2 = jsonObject.state.reported.equipment.swc_0.sns_2.value; if (sns_2) { console.log("sns_2 extrahiert:", sns_2); // sns_2 in das neue ioBroker-Objekt speichern setState(targetObject, sns_2, true); } else { console.log("Kein sns_2 gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } }); // Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.Pool.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.Pool.Pooldata_Pumpe"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_2` extrahieren let sns_2 = jsonObject.state.reported.equipment.swc_0.filter_pump.value; if (sns_2) { console.log("sns_2 extrahiert:", filter_pump); // sns_2 in das neue ioBroker-Objekt speichern setState(targetObject, filter_pump, true); } else { console.log("Kein filter_pump gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } });
-
Guten Morgen
hab einen Fehler.
Kannst du bitte mal drüberschaun?javascript.0 08:51:34.699 info Start JavaScript script.js.Pool.iAqualink (Javascript/js) javascript.0 08:51:34.700 error script.js.Pool.iAqualink compile failed: at script.js.Pool.iAqualink:79
const axios = require('axios'); // Daten für die POST-Anfrage const daten = { api_key: "EOOEMOW4YR6QNB11", email: "xxxxxxxxx@xxxxxxx.at", password: "xxxxxxxxx" }; // Erste Anfrage zur Authentifizierung axios.post('https://prod.zodiac-io.com/users/v1/login', daten, { headers: { 'Host': 'prod.zodiac-io.com', 'accept': 'application/json', 'Content-Type': 'application/json', 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.0' } }).then((response) => { setState('0_userdata.0.iAquaLink.IdToken', JSON.stringify(response.data), true); console.log('Daten erfolgreich in ioBroker gespeichert.'); // Extrahieren des idTokens let jsonObject = response.data; let idToken = jsonObject.userPoolOAuth.IdToken; if (idToken) { console.log("idToken extrahiert:", idToken); setState('0_userdata.0.iAquaLink.IdToken_clean', idToken, true); // Zweite Anfrage unter Verwendung des idTokens const options = { method: 'GET', url: 'https://prod.zodiac-io.com/devices/v1/JT22005060/shadow', headers: { 'Host': 'prod.zodiac-io.com', 'accept': 'application/json', 'authorization': idToken, 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.0' } }; return axios.request(options); } else { throw new Error("Kein idToken gefunden!"); } }).then(response => { console.log(response.data); setState('0_userdata.0.iAquaLink.Pooldata', response.data, true); }).catch(error => { console.error('Fehler:', error); }); // Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.iAquaLink.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.iAquaLink.Pooldata_PH"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_1` extrahieren let sns_1 = jsonObject.state.reported.equipment.swc_0.sns_1.value; if (sns_1) { console.log("sns_1 extrahiert:", sns_1); // sns_1 in das neue ioBroker-Objekt speichern setState(targetObject, sns_1, true); } else { console.log("Kein sns_1 gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } }); // Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.iAquaLink.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.iAquaLink.Pooldata_ORP"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_2` extrahieren let sns_2 = jsonObject.state.reported.equipment.swc_0.sns_2.value; if (sns_2) { console.log("sns_2 extrahiert:", sns_2); // sns_2 in das neue ioBroker-Objekt speichern setState(targetObject, sns_2, true); } else { console.log("Kein sns_2 gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } }); // Name des Quell-Objekts im ioBroker, das den JSON-String enthält let sourceObject = "0_userdata.0.iAquaLink.Pooldata"; // Name des Ziel-Objekts, in das das idToken gespeichert werden soll let targetObject = "0_userdata.0.iAquaLink.Pooldata_Pumpe"; // JSON-String aus ioBroker-Objekt abrufen getState(sourceObject, function (err, state) { if (err || !state || !state.val) { console.log("Fehler beim Abrufen des JSON-Strings oder Objekt ist leer."); return; } try { // JSON-String in ein Objekt konvertieren let jsonObject = JSON.parse(state.val); // `sns_2` extrahieren let sns_2 = jsonObject.state.reported.equipment.swc_0.filter_pump.value; if (sns_2) { console.log("sns_2 extrahiert:", filter_pump); // sns_2 in das neue ioBroker-Objekt speichern setState(targetObject, filter_pump, true); } else { console.log("Kein filter_pump gefunden!"); } } catch (error) { console.log("Fehler beim Parsen des JSON-Strings:", error); } });
-
Der Pfad in Zeile 120 stimmt nicht.
Es gibt unter filter_pump kein "value" sondern nur "state" oder "type"Zudem hast du im Rest vom script alles auf "sns_2" belassen. sns_2 verwendest du bereits für ORP. Du willst aber jetzt den Status der Pumpe auslesen. Also => sns_2 in filter_pump umbenennen.
-
@hexagon sagte in Aqualink Pool Automation in iobroker integrieren:
Es gibt unter filter_pump kein "value" sondern nur "state" oder "type"
Danke
muss ich dann
let filter_pump = jsonObject.state.reported.equipment.swc_0.filter_pump.state;
verwenden, um zu sehen, ob die Pumpe läuft? -
genau, und darunter ebenfalls alles noch umbenennen wo sns_2 auftaucht.