NEWS
ecoflow-connector-Script zur dynamischen Leistungsanpassung
-
@ralf77 Stimmt, bei mir auch nicht. Hab dann den Shelly 3EM der an meinem GĂ€stehaus hĂ€ngt in der App eingefĂŒgt... Hab gedacht, damit wenigstens etwas gedeckt wird. Dann ist mir aber eingefallen, dass das nicht gehen wird, da die PS die einspeisen nicht am GĂ€stehaus hĂ€ngen, der Shelly also die Einspeisung nicht misstâŠÂ Aber, weiss nicht ob's am Einbinden des Shellies lag oder einfach Zufall war, als ich danach wieder das Script startete ging es wieder.
@sirdir die Regelung lÀuft bei mir auch. Nur springen die Werte extrem hin- und her.
Mal speisen meine Deltas 150W ins öffentliche Netz ein, da zu viel Ins Hausnetz eingespeist wird⊠dann zieht mein Haus wieder 200 Watt aus dem öffentlichen Netz, da die Deltas zu wenig ins Hausnetz einspeisen.Normalerweise sollte ja gar nichts ins öffentliche Netz eingespeist werden und immer leicht aus dem öffentlichen Netz gezogen werden. Das klappt irgendwie gerade nicht gut bei mir.
-
@sirdir die Regelung lÀuft bei mir auch. Nur springen die Werte extrem hin- und her.
Mal speisen meine Deltas 150W ins öffentliche Netz ein, da zu viel Ins Hausnetz eingespeist wird⊠dann zieht mein Haus wieder 200 Watt aus dem öffentlichen Netz, da die Deltas zu wenig ins Hausnetz einspeisen.Normalerweise sollte ja gar nichts ins öffentliche Netz eingespeist werden und immer leicht aus dem öffentlichen Netz gezogen werden. Das klappt irgendwie gerade nicht gut bei mir.
@ralf77 Ich denke das Script muss langfristig die öffentliche API benĂŒtzen. Irgendwann wird der âHackâ bestimmt abgedreht oder geht sonst kaputt. Ich bin mir das grad etwas am anschauen aber hab weder viel Erfahrung mit http Kommunikation unter javascript noch mit VerschlĂŒsselung⊠Mal sehen ob ich was hin krieg.
-
@ralf77 Ich denke das Script muss langfristig die öffentliche API benĂŒtzen. Irgendwann wird der âHackâ bestimmt abgedreht oder geht sonst kaputt. Ich bin mir das grad etwas am anschauen aber hab weder viel Erfahrung mit http Kommunikation unter javascript noch mit VerschlĂŒsselung⊠Mal sehen ob ich was hin krieg.
@sirdir
Sorry, dass ich mich hier so rausnehmen. Aber ich hab wirklich im Moment ĂŒble Probleme, worĂŒber ich jetzt hier nicht jammern möchte.
Ich finde es aber auch extrem frustrierend, dass der Hersteller, obwohl wir hier Funktionserweiterungen entwickelt haben, ganz ohne Gegenleistung, die dazu fĂŒhren, dass mehr Leute, auch im professionellen Bereich auf EF Produkte zurĂŒckgreifen, nicht einmal versucht, Kontakt aufzunehmen, geschweige denn Hilfe anbietet, im gegenteil. Die API Dokumentation ist relativ frustrierend, ich habe schon einige Versuche gemacht damit zu arbeiten, leider bisher ziemlich erfolglos.
NatĂŒrlich wĂ€re eine Umstellung auf die offizielle API sehr wĂŒnschenswert, solange das keine Nachteile bei der Geschwindigkeit oder der QualitĂ€t der Regulierung einbringt.
Ich lade euch herzlich ein, an dieser API Anbindung zu arbeiten.
Theoretisch gibt es dort auch einen MQTT server, der uns die relevanten Daten liefern kann.Hier die Einsiegsseite fĂŒr die API
https://developer-eu.ecoflow.com/usHier mal einer meiner Versuche mit der API zu kommunizieren.
Verbindung wird aufgebaut, aber es kommen keine Telegramme:
Auch konnte ich keine Daten an meine GerĂ€te senden.const axios = require('axios'); const mqtt = require('mqtt'); const crypto = require('crypto'); // Konfigurationen const host = 'api-e.ecoflow.com'; const mqttHost = 'mqtt.ecoflow.com'; const mqttPort = 8883; const mqttProtocol = 'mqtts'; const accessKey = 'DLXXXXXXXXXXXXXXXXXXXXXXXXX6D6'; // Ersetze dies mit deinem tatsĂ€chlichen Access Key const secretKey = 'XxXXXXXXXXXXXXXXXXXXXXXXXXXLA'; // Ersetze dies mit deinem tatsĂ€chlichen Secret Key const deviceSN = 'HW5XXXXXXXXXX55'; // Ersetze dies mit der tatsĂ€chlichen Seriennummer deines GerĂ€ts // Hilfsfunktion zur Erstellung eines HMAC-SHA256-Signatur function createSignature(params, secretKey) { const queryString = Object.keys(params) .sort() .map(key => `${key}=${params[key]}`) .join('&'); return crypto.createHmac('sha256', secretKey).update(queryString).digest('hex'); } // Zertifikate fĂŒr MQTT abrufen async function getMQTTCertification() { const nonce = Math.floor(Math.random() * 1000000); const timestamp = Date.now(); const params = { accessKey: accessKey, nonce: nonce, timestamp: timestamp }; const signature = createSignature(params, secretKey); try { const response = await axios.get(`https://${host}/iot-open/sign/certification`, { headers: { accessKey: accessKey, nonce: nonce, timestamp: timestamp, sign: signature } }); return response.data.data; } catch (error) { console.error('Fehler beim Abrufen der MQTT-Zertifikate:', error); throw error; } } // MQTT-Verbindung herstellen und Daten empfangen async function startMQTTClient() { try { const certification = await getMQTTCertification(); const client = mqtt.connect(`${mqttProtocol}://${mqttHost}:${mqttPort}`, { username: certification.certificateAccount, password: certification.certificatePassword, protocol: mqttProtocol }); const deviceTopic = `/open/${certification.certificateAccount}/${deviceSN}/quota`; const powerstreamTopic = `/open/${certification.certificateAccount}/${deviceSN}/status`; client.on('connect', () => { console.log('Verbunden mit dem MQTT-Broker'); // GerĂ€teliste anfordern //const deviceListTopic = `/open/${certification.certificateAccount.replace("open-", "")}/${deviceSN}/get`; const deviceListTopic = `/open/${certification.certificateAccount}/${deviceSN}/get`; client.subscribe(deviceListTopic, (err) => { if (!err) { console.log(`Abonniert auf GerĂ€teliste-Topic: ${deviceListTopic}`); client.publish(deviceListTopic, JSON.stringify({})); } else { console.error('Fehler beim Abonnieren des GerĂ€teliste-Themas:', err); } }); // Powerstream-Daten abonnieren client.subscribe(powerstreamTopic, (err) => { if (!err) { console.log(`Abonniert auf Powerstream-Daten: ${powerstreamTopic}`); } else { console.error('Fehler beim Abonnieren des Powerstream-Themas:', err); } }); // Alle Topics abonnieren, um alle Nachrichten zu empfangen client.subscribe('#', (err) => { // '#' ist ein Wildcard-Topic, das alle Topics abonniert if (!err) { console.log('Abonniert auf alle Topics (#)'); } else { console.error('Fehler beim Abonnieren aller Topics:', err); } }); }); client.on('message', (topic, message) => { // Ausgabe des empfangenen Telegramms console.log(`Nachricht empfangen von Topic ${topic}: ${message.toString()}`); }); client.on('error', (err) => { console.error('MQTT-Verbindungsfehler:', err); }); client.on('close', () => { console.log('MQTT-Verbindung geschlossen'); }); } catch (error) { console.error('Fehler beim Starten des MQTT-Clients:', error); } } startMQTTClient();Ihr mĂŒsst euch dafĂŒr als Entwickler registrieren (sehr einfach) und euch den
accessKey und secretKey dort generieren.Bei mir treten diese Probleme ĂŒbrigens nicht auf.
Was mich noch interessieren wĂŒrde: wenn keine Daten mehr am Skript ankommen, und ihr das Skript im iobroker einige Male neu startet, kommen dann wieder Daten?Mehr kann ich im Moment nicht beitragen. Sorry.
-
@sirdir
Sorry, dass ich mich hier so rausnehmen. Aber ich hab wirklich im Moment ĂŒble Probleme, worĂŒber ich jetzt hier nicht jammern möchte.
Ich finde es aber auch extrem frustrierend, dass der Hersteller, obwohl wir hier Funktionserweiterungen entwickelt haben, ganz ohne Gegenleistung, die dazu fĂŒhren, dass mehr Leute, auch im professionellen Bereich auf EF Produkte zurĂŒckgreifen, nicht einmal versucht, Kontakt aufzunehmen, geschweige denn Hilfe anbietet, im gegenteil. Die API Dokumentation ist relativ frustrierend, ich habe schon einige Versuche gemacht damit zu arbeiten, leider bisher ziemlich erfolglos.
NatĂŒrlich wĂ€re eine Umstellung auf die offizielle API sehr wĂŒnschenswert, solange das keine Nachteile bei der Geschwindigkeit oder der QualitĂ€t der Regulierung einbringt.
Ich lade euch herzlich ein, an dieser API Anbindung zu arbeiten.
Theoretisch gibt es dort auch einen MQTT server, der uns die relevanten Daten liefern kann.Hier die Einsiegsseite fĂŒr die API
https://developer-eu.ecoflow.com/usHier mal einer meiner Versuche mit der API zu kommunizieren.
Verbindung wird aufgebaut, aber es kommen keine Telegramme:
Auch konnte ich keine Daten an meine GerĂ€te senden.const axios = require('axios'); const mqtt = require('mqtt'); const crypto = require('crypto'); // Konfigurationen const host = 'api-e.ecoflow.com'; const mqttHost = 'mqtt.ecoflow.com'; const mqttPort = 8883; const mqttProtocol = 'mqtts'; const accessKey = 'DLXXXXXXXXXXXXXXXXXXXXXXXXX6D6'; // Ersetze dies mit deinem tatsĂ€chlichen Access Key const secretKey = 'XxXXXXXXXXXXXXXXXXXXXXXXXXXLA'; // Ersetze dies mit deinem tatsĂ€chlichen Secret Key const deviceSN = 'HW5XXXXXXXXXX55'; // Ersetze dies mit der tatsĂ€chlichen Seriennummer deines GerĂ€ts // Hilfsfunktion zur Erstellung eines HMAC-SHA256-Signatur function createSignature(params, secretKey) { const queryString = Object.keys(params) .sort() .map(key => `${key}=${params[key]}`) .join('&'); return crypto.createHmac('sha256', secretKey).update(queryString).digest('hex'); } // Zertifikate fĂŒr MQTT abrufen async function getMQTTCertification() { const nonce = Math.floor(Math.random() * 1000000); const timestamp = Date.now(); const params = { accessKey: accessKey, nonce: nonce, timestamp: timestamp }; const signature = createSignature(params, secretKey); try { const response = await axios.get(`https://${host}/iot-open/sign/certification`, { headers: { accessKey: accessKey, nonce: nonce, timestamp: timestamp, sign: signature } }); return response.data.data; } catch (error) { console.error('Fehler beim Abrufen der MQTT-Zertifikate:', error); throw error; } } // MQTT-Verbindung herstellen und Daten empfangen async function startMQTTClient() { try { const certification = await getMQTTCertification(); const client = mqtt.connect(`${mqttProtocol}://${mqttHost}:${mqttPort}`, { username: certification.certificateAccount, password: certification.certificatePassword, protocol: mqttProtocol }); const deviceTopic = `/open/${certification.certificateAccount}/${deviceSN}/quota`; const powerstreamTopic = `/open/${certification.certificateAccount}/${deviceSN}/status`; client.on('connect', () => { console.log('Verbunden mit dem MQTT-Broker'); // GerĂ€teliste anfordern //const deviceListTopic = `/open/${certification.certificateAccount.replace("open-", "")}/${deviceSN}/get`; const deviceListTopic = `/open/${certification.certificateAccount}/${deviceSN}/get`; client.subscribe(deviceListTopic, (err) => { if (!err) { console.log(`Abonniert auf GerĂ€teliste-Topic: ${deviceListTopic}`); client.publish(deviceListTopic, JSON.stringify({})); } else { console.error('Fehler beim Abonnieren des GerĂ€teliste-Themas:', err); } }); // Powerstream-Daten abonnieren client.subscribe(powerstreamTopic, (err) => { if (!err) { console.log(`Abonniert auf Powerstream-Daten: ${powerstreamTopic}`); } else { console.error('Fehler beim Abonnieren des Powerstream-Themas:', err); } }); // Alle Topics abonnieren, um alle Nachrichten zu empfangen client.subscribe('#', (err) => { // '#' ist ein Wildcard-Topic, das alle Topics abonniert if (!err) { console.log('Abonniert auf alle Topics (#)'); } else { console.error('Fehler beim Abonnieren aller Topics:', err); } }); }); client.on('message', (topic, message) => { // Ausgabe des empfangenen Telegramms console.log(`Nachricht empfangen von Topic ${topic}: ${message.toString()}`); }); client.on('error', (err) => { console.error('MQTT-Verbindungsfehler:', err); }); client.on('close', () => { console.log('MQTT-Verbindung geschlossen'); }); } catch (error) { console.error('Fehler beim Starten des MQTT-Clients:', error); } } startMQTTClient();Ihr mĂŒsst euch dafĂŒr als Entwickler registrieren (sehr einfach) und euch den
accessKey und secretKey dort generieren.Bei mir treten diese Probleme ĂŒbrigens nicht auf.
Was mich noch interessieren wĂŒrde: wenn keine Daten mehr am Skript ankommen, und ihr das Skript im iobroker einige Male neu startet, kommen dann wieder Daten?Mehr kann ich im Moment nicht beitragen. Sorry.
@waly_de okay, ich konnte heute noch ein bisschen Zeit aufbringen und hab es tatsÀchlich geschafft mit dem offiziellen API Server zu kommunizieren. Auch das Schreiben von Werten ist mir gelungen.
Hier ist der Ansatz:const axios = require('axios'); const mqtt = require('mqtt'); const crypto = require('crypto'); //****** HIER DEINE DATEN ****** const accessKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Access Key const secretKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Secret Key const deviceSNs = ['XXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXXX']; // Mehrere GerĂ€te-Seriennummern const MQTT_Clientid = 1 //*********************/ // Konfigurationen const host = 'api-e.ecoflow.com'; const mqttHost = 'mqtt.ecoflow.com'; const mqttPort = 8883; const mqttProtocol = 'mqtts'; const mqttCert = '0_userdata.0.ecoflow.mqttCert' // Globale Variablen fĂŒr client und certification let client; let certification; if (!existsState(mqttCert)) { createState(mqttCert, ""); } // Hilfsfunktion zur Erstellung eines HMAC-SHA256-Signatur function createSignature(params, secretKey) { const queryString = Object.keys(params) .sort() .map(key => `${key}=${params[key]}`) .join('&'); return crypto.createHmac('sha256', secretKey).update(queryString).digest('hex'); } // Funktion zur ĂberprĂŒfung, ob Zertifikat bereits vorhanden ist async function loadMQTTCertification() { return new Promise((resolve, reject) => { // ĂberprĂŒfen, ob der State existiert getState(mqttCert, (err, state) => { if (err) { console.error('Fehler beim ĂberprĂŒfen des Zertifikat-States:', err); return reject(err); } if (state && state.val) { try { const storedCert = JSON.parse(state.val); // ĂberprĂŒfen, ob die Felder im Zertifikat vorhanden sind if (storedCert.certificateAccount && storedCert.certificatePassword) { console.log('Zertifikat aus ioBroker geladen'); return resolve(storedCert); } } catch (error) { console.error('Fehler beim Parsen des Zertifikats:'+ error); } } resolve(null); // Kein Zertifikat gefunden oder ungĂŒltig }); }); } // Zertifikate fĂŒr MQTT abrufen und speichern async function getMQTTCertification() { const nonce = Math.floor(Math.random() * 1000000); const timestamp = Date.now(); const params = { accessKey: accessKey, nonce: nonce, timestamp: timestamp }; const signature = createSignature(params, secretKey); try { const response = await axios.get(`https://${host}/iot-open/sign/certification`, { headers: { accessKey: accessKey, nonce: nonce, timestamp: timestamp, sign: signature } }); const certData = response.data.data; // Zertifikat in ioBroker speichern setState(mqttCert, JSON.stringify(certData), true); console.log('Zertifikat erfolgreich abgerufen und in ioBroker gespeichert'); return certData; } catch (error) { console.error('Fehler beim Abrufen der MQTT-Zertifikate:'+ error); throw error; } } // Funktion zum Setzen von Parametern (z.B. permanentWatts) ohne client und certification als Parameter function setPermanentWatts(deviceSN, wattsValue) { if (!client || !certification) { console.error("MQTT-Client oder Zertifizierung nicht bereit."); return; } const setTopic = `/open/${certification.certificateAccount}/${deviceSN}/set`; const message = { id: Date.now(), // Einzigartige ID version: "1.0", cmdCode: "WN511_SET_PERMANENT_WATTS_PACK", // Befehlscode zum Setzen von permanentWatts params: { permanentWatts: wattsValue // Der Wert, den du setzen möchtest } }; client.publish(setTopic, JSON.stringify(message), (err) => { if (!err) { console.log(`Befehl zum Setzen von permanentWatts auf ${wattsValue} W fĂŒr GerĂ€t ${deviceSN} wurde gesendet.`); } else { console.error(`Fehler beim Senden des permanentWatts-Befehls fĂŒr GerĂ€t ${deviceSN}:` + err); } }); } // MQTT-Verbindung herstellen und Daten empfangen async function startMQTTClient() { try { // Zertifikat aus ioBroker laden, falls vorhanden certification = await loadMQTTCertification(); if (!certification) { // Zertifikat neu generieren, wenn es nicht vorhanden ist certification = await getMQTTCertification(); } client = mqtt.connect(`${mqttProtocol}://${mqttHost}:${mqttPort}`, { clientId: 'EcoFlowClient_' + MQTT_Clientid, username: certification.certificateAccount, password: certification.certificatePassword, protocol: mqttProtocol }); client.on('connect', () => { console.log('Verbunden mit dem MQTT-Broker'); // Abonnieren von Status und anderen Daten fĂŒr jedes GerĂ€t deviceSNs.forEach((deviceSN) => { const quotaTopic = `/open/${certification.certificateAccount}/${deviceSN}/quota`; const statusTopic = `/open/${certification.certificateAccount}/${deviceSN}/status`; // Abonnieren des Status-Themas client.subscribe(statusTopic, (err) => { if (!err) { console.log(`Abonniert auf Status-Topic: ${statusTopic}`); } else { console.error(`Fehler beim Abonnieren des Status-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); // Abonnieren des Quota-Themas client.subscribe(quotaTopic, (err) => { if (!err) { console.log(`Abonniert auf Quota-Topic: ${quotaTopic}`); } else { console.error(`Fehler beim Abonnieren des Quota-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); }); }); client.on('message', (topic, message) => { console.log(`Nachricht empfangen von Topic ${topic}: ${message.toString()}`); }); client.on('error', (err) => { console.error('MQTT-Verbindungsfehler:' + err); client.end(); // Trenne die Verbindung bei einem Fehler console.log('Verbindung getrennt aufgrund eines Fehlers ' + err); }); client.on('close', () => { console.log('MQTT-Verbindung geschlossen'); }); } catch (error) { console.error('Fehler beim Starten des MQTT-Clients:' + error); } } // SchlieĂe die Verbindung, wenn das Skript gestoppt wird onStop(function (callback) { if (client) { client.end(); log("Script gestoppt"); } callback(); }, 2000); // Start der MQTT-Client-Verbindung startMQTTClient(); // Beispielaufruf von setPermanentWatts auĂerhalb von startMQTTClient() setTimeout(() => { setPermanentWatts(deviceSNs[0], 3000); // Setzt permanentWatts fĂŒr ein bestimmtes GerĂ€t auf 300 W }, 5000); // Warte 5 Sekunden, damit der Client verbunden istIch wĂŒrde mich freuen, wenn ihr euch nĂ€her damit befasst. bevor ich das ins Skript einbauen kann, wird noch einige Zeit vergehen. Vielleicht schafft ja einer von euch.
-
@waly_de okay, ich konnte heute noch ein bisschen Zeit aufbringen und hab es tatsÀchlich geschafft mit dem offiziellen API Server zu kommunizieren. Auch das Schreiben von Werten ist mir gelungen.
Hier ist der Ansatz:const axios = require('axios'); const mqtt = require('mqtt'); const crypto = require('crypto'); //****** HIER DEINE DATEN ****** const accessKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Access Key const secretKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Secret Key const deviceSNs = ['XXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXXX']; // Mehrere GerĂ€te-Seriennummern const MQTT_Clientid = 1 //*********************/ // Konfigurationen const host = 'api-e.ecoflow.com'; const mqttHost = 'mqtt.ecoflow.com'; const mqttPort = 8883; const mqttProtocol = 'mqtts'; const mqttCert = '0_userdata.0.ecoflow.mqttCert' // Globale Variablen fĂŒr client und certification let client; let certification; if (!existsState(mqttCert)) { createState(mqttCert, ""); } // Hilfsfunktion zur Erstellung eines HMAC-SHA256-Signatur function createSignature(params, secretKey) { const queryString = Object.keys(params) .sort() .map(key => `${key}=${params[key]}`) .join('&'); return crypto.createHmac('sha256', secretKey).update(queryString).digest('hex'); } // Funktion zur ĂberprĂŒfung, ob Zertifikat bereits vorhanden ist async function loadMQTTCertification() { return new Promise((resolve, reject) => { // ĂberprĂŒfen, ob der State existiert getState(mqttCert, (err, state) => { if (err) { console.error('Fehler beim ĂberprĂŒfen des Zertifikat-States:', err); return reject(err); } if (state && state.val) { try { const storedCert = JSON.parse(state.val); // ĂberprĂŒfen, ob die Felder im Zertifikat vorhanden sind if (storedCert.certificateAccount && storedCert.certificatePassword) { console.log('Zertifikat aus ioBroker geladen'); return resolve(storedCert); } } catch (error) { console.error('Fehler beim Parsen des Zertifikats:'+ error); } } resolve(null); // Kein Zertifikat gefunden oder ungĂŒltig }); }); } // Zertifikate fĂŒr MQTT abrufen und speichern async function getMQTTCertification() { const nonce = Math.floor(Math.random() * 1000000); const timestamp = Date.now(); const params = { accessKey: accessKey, nonce: nonce, timestamp: timestamp }; const signature = createSignature(params, secretKey); try { const response = await axios.get(`https://${host}/iot-open/sign/certification`, { headers: { accessKey: accessKey, nonce: nonce, timestamp: timestamp, sign: signature } }); const certData = response.data.data; // Zertifikat in ioBroker speichern setState(mqttCert, JSON.stringify(certData), true); console.log('Zertifikat erfolgreich abgerufen und in ioBroker gespeichert'); return certData; } catch (error) { console.error('Fehler beim Abrufen der MQTT-Zertifikate:'+ error); throw error; } } // Funktion zum Setzen von Parametern (z.B. permanentWatts) ohne client und certification als Parameter function setPermanentWatts(deviceSN, wattsValue) { if (!client || !certification) { console.error("MQTT-Client oder Zertifizierung nicht bereit."); return; } const setTopic = `/open/${certification.certificateAccount}/${deviceSN}/set`; const message = { id: Date.now(), // Einzigartige ID version: "1.0", cmdCode: "WN511_SET_PERMANENT_WATTS_PACK", // Befehlscode zum Setzen von permanentWatts params: { permanentWatts: wattsValue // Der Wert, den du setzen möchtest } }; client.publish(setTopic, JSON.stringify(message), (err) => { if (!err) { console.log(`Befehl zum Setzen von permanentWatts auf ${wattsValue} W fĂŒr GerĂ€t ${deviceSN} wurde gesendet.`); } else { console.error(`Fehler beim Senden des permanentWatts-Befehls fĂŒr GerĂ€t ${deviceSN}:` + err); } }); } // MQTT-Verbindung herstellen und Daten empfangen async function startMQTTClient() { try { // Zertifikat aus ioBroker laden, falls vorhanden certification = await loadMQTTCertification(); if (!certification) { // Zertifikat neu generieren, wenn es nicht vorhanden ist certification = await getMQTTCertification(); } client = mqtt.connect(`${mqttProtocol}://${mqttHost}:${mqttPort}`, { clientId: 'EcoFlowClient_' + MQTT_Clientid, username: certification.certificateAccount, password: certification.certificatePassword, protocol: mqttProtocol }); client.on('connect', () => { console.log('Verbunden mit dem MQTT-Broker'); // Abonnieren von Status und anderen Daten fĂŒr jedes GerĂ€t deviceSNs.forEach((deviceSN) => { const quotaTopic = `/open/${certification.certificateAccount}/${deviceSN}/quota`; const statusTopic = `/open/${certification.certificateAccount}/${deviceSN}/status`; // Abonnieren des Status-Themas client.subscribe(statusTopic, (err) => { if (!err) { console.log(`Abonniert auf Status-Topic: ${statusTopic}`); } else { console.error(`Fehler beim Abonnieren des Status-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); // Abonnieren des Quota-Themas client.subscribe(quotaTopic, (err) => { if (!err) { console.log(`Abonniert auf Quota-Topic: ${quotaTopic}`); } else { console.error(`Fehler beim Abonnieren des Quota-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); }); }); client.on('message', (topic, message) => { console.log(`Nachricht empfangen von Topic ${topic}: ${message.toString()}`); }); client.on('error', (err) => { console.error('MQTT-Verbindungsfehler:' + err); client.end(); // Trenne die Verbindung bei einem Fehler console.log('Verbindung getrennt aufgrund eines Fehlers ' + err); }); client.on('close', () => { console.log('MQTT-Verbindung geschlossen'); }); } catch (error) { console.error('Fehler beim Starten des MQTT-Clients:' + error); } } // SchlieĂe die Verbindung, wenn das Skript gestoppt wird onStop(function (callback) { if (client) { client.end(); log("Script gestoppt"); } callback(); }, 2000); // Start der MQTT-Client-Verbindung startMQTTClient(); // Beispielaufruf von setPermanentWatts auĂerhalb von startMQTTClient() setTimeout(() => { setPermanentWatts(deviceSNs[0], 3000); // Setzt permanentWatts fĂŒr ein bestimmtes GerĂ€t auf 300 W }, 5000); // Warte 5 Sekunden, damit der Client verbunden istIch wĂŒrde mich freuen, wenn ihr euch nĂ€her damit befasst. bevor ich das ins Skript einbauen kann, wird noch einige Zeit vergehen. Vielleicht schafft ja einer von euch.
@waly_de Hey, danke. Hab das Script mal probiert, hab die Status Infos der konfigurierten GerĂ€te bekommen. Hab dann versucht den gesendeten Befehl auf slowChgWatts fĂŒr die Delta 2 Max zu Ă€ndern und plötzlich bekomme ich nur noch:
MQTT-Verbindungsfehler:Error: Connection refused: Not authorizedKeys stimmen. Seltsam.
Noch zu deiner Frage beim ârichtigenâ Script, ich weiss nicht, es war nicht konsistent. Ne weile kam z.B. einfach immer 0% beim Batteriestand zurĂŒck, auch nach Neustart des Scripts. In anderen Momenten schien ein Neustart zu helfen.
Edit: Die Verbindung geht jetzt wieder, aber ich musste nen neuen Access Key erstellen, der alte war âverbranntâ⊠WTF?
Das slowChgWatts muss ich mir nochmal genauer anschauen, das ist anscheinend in nem Array/Subtopic, k.A. wie das in MQTT aussieht. -
@waly_de Hey, danke. Hab das Script mal probiert, hab die Status Infos der konfigurierten GerĂ€te bekommen. Hab dann versucht den gesendeten Befehl auf slowChgWatts fĂŒr die Delta 2 Max zu Ă€ndern und plötzlich bekomme ich nur noch:
MQTT-Verbindungsfehler:Error: Connection refused: Not authorizedKeys stimmen. Seltsam.
Noch zu deiner Frage beim ârichtigenâ Script, ich weiss nicht, es war nicht konsistent. Ne weile kam z.B. einfach immer 0% beim Batteriestand zurĂŒck, auch nach Neustart des Scripts. In anderen Momenten schien ein Neustart zu helfen.
Edit: Die Verbindung geht jetzt wieder, aber ich musste nen neuen Access Key erstellen, der alte war âverbranntâ⊠WTF?
Das slowChgWatts muss ich mir nochmal genauer anschauen, das ist anscheinend in nem Array/Subtopic, k.A. wie das in MQTT aussieht.@sirdir , musst mit den mqtt Client IDs aufpassen, die sind limitiert pro Tag soweit man bisher weiĂ. Sobald Client ID Limit erreicht ist werden die certificateAccount Daten fĂŒr mqtt wohl gesperrt und Connection per mqtt geht nicht mehr.
Zu dem Zeitpunkt funktioniert http mit den Secret/Key noch.
FĂŒr mqtt hilft dann aktuell tatsĂ€chlich wohl nur neue Secret/Key erstellen.Musst de mal stöbern wenn mehr wissen willst. Bei HA integration ist zb seit v1.1.0 auch eingebaut daĂ immer die gleiche Client ID pro integration verwendet wird, gab da vorher auch Probleme da fĂŒr jedes GerĂ€t zuvor eine eigene Client ID verwendet wurde und dadurch das Limit ruck zuck erreicht war ...
-
@sirdir , musst mit den mqtt Client IDs aufpassen, die sind limitiert pro Tag soweit man bisher weiĂ. Sobald Client ID Limit erreicht ist werden die certificateAccount Daten fĂŒr mqtt wohl gesperrt und Connection per mqtt geht nicht mehr.
Zu dem Zeitpunkt funktioniert http mit den Secret/Key noch.
FĂŒr mqtt hilft dann aktuell tatsĂ€chlich wohl nur neue Secret/Key erstellen.Musst de mal stöbern wenn mehr wissen willst. Bei HA integration ist zb seit v1.1.0 auch eingebaut daĂ immer die gleiche Client ID pro integration verwendet wird, gab da vorher auch Probleme da fĂŒr jedes GerĂ€t zuvor eine eigene Client ID verwendet wurde und dadurch das Limit ruck zuck erreicht war ...
@giovanne Stimmt, in die HA Integration wollte ich mal rein schauen weil mir nicht ganz klar ist, wie die messages genau aufgebaut sein mĂŒssen. Aber wenn es da so enge Limiten gibt, ist das eh wenig nĂŒtzlich, da werden ja z.T. alle paar Sekunden neue Einspeisewerte gesendet zur ZeitâŠ
-
@giovanne Stimmt, in die HA Integration wollte ich mal rein schauen weil mir nicht ganz klar ist, wie die messages genau aufgebaut sein mĂŒssen. Aber wenn es da so enge Limiten gibt, ist das eh wenig nĂŒtzlich, da werden ja z.T. alle paar Sekunden neue Einspeisewerte gesendet zur ZeitâŠ
-
Hab zumindest das jetzt mal hingekriegt. Funktioniert halt wesentlich besser, wenn man das Datenformat unter MQTT nachschaut und nicht unter HTTP :)
@sirdir guter Hinweis mit der Client ID.
Ich hab das Grip mal angepasst und eine Client ID fest vergeben. Damit sollte das Problem erledigt sein.const axios = require('axios'); const mqtt = require('mqtt'); const crypto = require('crypto'); //****** HIER DEINE DATEN ****** const accessKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Access Key const secretKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Secret Key const deviceSNs = ['XXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXXX']; // Mehrere GerĂ€te-Seriennummern const MQTT_Clientid = 1 //*********************/ // Konfigurationen const host = 'api-e.ecoflow.com'; const mqttHost = 'mqtt.ecoflow.com'; const mqttPort = 8883; const mqttProtocol = 'mqtts'; const mqttCert = '0_userdata.0.ecoflow.mqttCert' // Globale Variablen fĂŒr client und certification let client; let certification; if (!existsState(mqttCert)) { createState(mqttCert, ""); } // Hilfsfunktion zur Erstellung eines HMAC-SHA256-Signatur function createSignature(params, secretKey) { const queryString = Object.keys(params) .sort() .map(key => `${key}=${params[key]}`) .join('&'); return crypto.createHmac('sha256', secretKey).update(queryString).digest('hex'); } // Funktion zur ĂberprĂŒfung, ob Zertifikat bereits vorhanden ist async function loadMQTTCertification() { return new Promise((resolve, reject) => { // ĂberprĂŒfen, ob der State existiert getState(mqttCert, (err, state) => { if (err) { console.error('Fehler beim ĂberprĂŒfen des Zertifikat-States:', err); return reject(err); } if (state && state.val) { try { const storedCert = JSON.parse(state.val); // ĂberprĂŒfen, ob die Felder im Zertifikat vorhanden sind if (storedCert.certificateAccount && storedCert.certificatePassword) { console.log('Zertifikat aus ioBroker geladen'); return resolve(storedCert); } } catch (error) { console.error('Fehler beim Parsen des Zertifikats:'+ error); } } resolve(null); // Kein Zertifikat gefunden oder ungĂŒltig }); }); } // Zertifikate fĂŒr MQTT abrufen und speichern async function getMQTTCertification() { const nonce = Math.floor(Math.random() * 1000000); const timestamp = Date.now(); const params = { accessKey: accessKey, nonce: nonce, timestamp: timestamp }; const signature = createSignature(params, secretKey); try { const response = await axios.get(`https://${host}/iot-open/sign/certification`, { headers: { accessKey: accessKey, nonce: nonce, timestamp: timestamp, sign: signature } }); const certData = response.data.data; // Zertifikat in ioBroker speichern setState(mqttCert, JSON.stringify(certData), true); console.log('Zertifikat erfolgreich abgerufen und in ioBroker gespeichert'); return certData; } catch (error) { console.error('Fehler beim Abrufen der MQTT-Zertifikate:'+ error); throw error; } } // Funktion zum Setzen von Parametern (z.B. permanentWatts) ohne client und certification als Parameter function setPermanentWatts(deviceSN, wattsValue) { if (!client || !certification) { console.error("MQTT-Client oder Zertifizierung nicht bereit."); return; } const setTopic = `/open/${certification.certificateAccount}/${deviceSN}/set`; const message = { id: Date.now(), // Einzigartige ID version: "1.0", cmdCode: "WN511_SET_PERMANENT_WATTS_PACK", // Befehlscode zum Setzen von permanentWatts params: { permanentWatts: wattsValue // Der Wert, den du setzen möchtest } }; client.publish(setTopic, JSON.stringify(message), (err) => { if (!err) { console.log(`Befehl zum Setzen von permanentWatts auf ${wattsValue} W fĂŒr GerĂ€t ${deviceSN} wurde gesendet.`); } else { console.error(`Fehler beim Senden des permanentWatts-Befehls fĂŒr GerĂ€t ${deviceSN}:` + err); } }); } // MQTT-Verbindung herstellen und Daten empfangen async function startMQTTClient() { try { // Zertifikat aus ioBroker laden, falls vorhanden certification = await loadMQTTCertification(); if (!certification) { // Zertifikat neu generieren, wenn es nicht vorhanden ist certification = await getMQTTCertification(); } client = mqtt.connect(`${mqttProtocol}://${mqttHost}:${mqttPort}`, { clientId: 'EcoFlowClient_' + MQTT_Clientid, username: certification.certificateAccount, password: certification.certificatePassword, protocol: mqttProtocol }); client.on('connect', () => { console.log('Verbunden mit dem MQTT-Broker'); // Abonnieren von Status und anderen Daten fĂŒr jedes GerĂ€t deviceSNs.forEach((deviceSN) => { const quotaTopic = `/open/${certification.certificateAccount}/${deviceSN}/quota`; const statusTopic = `/open/${certification.certificateAccount}/${deviceSN}/status`; // Abonnieren des Status-Themas client.subscribe(statusTopic, (err) => { if (!err) { console.log(`Abonniert auf Status-Topic: ${statusTopic}`); } else { console.error(`Fehler beim Abonnieren des Status-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); // Abonnieren des Quota-Themas client.subscribe(quotaTopic, (err) => { if (!err) { console.log(`Abonniert auf Quota-Topic: ${quotaTopic}`); } else { console.error(`Fehler beim Abonnieren des Quota-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); }); }); client.on('message', (topic, message) => { console.log(`Nachricht empfangen von Topic ${topic}: ${message.toString()}`); }); client.on('error', (err) => { console.error('MQTT-Verbindungsfehler:' + err); client.end(); // Trenne die Verbindung bei einem Fehler console.log('Verbindung getrennt aufgrund eines Fehlers ' + err); }); client.on('close', () => { console.log('MQTT-Verbindung geschlossen'); }); } catch (error) { console.error('Fehler beim Starten des MQTT-Clients:' + error); } } // SchlieĂe die Verbindung, wenn das Skript gestoppt wird onStop(function (callback) { if (client) { client.end(); log("Script gestoppt"); } callback(); }, 2000); // Start der MQTT-Client-Verbindung startMQTTClient(); // Beispielaufruf von setPermanentWatts auĂerhalb von startMQTTClient() setTimeout(() => { setPermanentWatts(deviceSNs[0], 3000); // Setzt permanentWatts fĂŒr ein bestimmtes GerĂ€t auf 300 W }, 5000); // Warte 5 Sekunden, damit der Client verbunden ist -
@sirdir guter Hinweis mit der Client ID.
Ich hab das Grip mal angepasst und eine Client ID fest vergeben. Damit sollte das Problem erledigt sein.const axios = require('axios'); const mqtt = require('mqtt'); const crypto = require('crypto'); //****** HIER DEINE DATEN ****** const accessKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Access Key const secretKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Secret Key const deviceSNs = ['XXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXXX']; // Mehrere GerĂ€te-Seriennummern const MQTT_Clientid = 1 //*********************/ // Konfigurationen const host = 'api-e.ecoflow.com'; const mqttHost = 'mqtt.ecoflow.com'; const mqttPort = 8883; const mqttProtocol = 'mqtts'; const mqttCert = '0_userdata.0.ecoflow.mqttCert' // Globale Variablen fĂŒr client und certification let client; let certification; if (!existsState(mqttCert)) { createState(mqttCert, ""); } // Hilfsfunktion zur Erstellung eines HMAC-SHA256-Signatur function createSignature(params, secretKey) { const queryString = Object.keys(params) .sort() .map(key => `${key}=${params[key]}`) .join('&'); return crypto.createHmac('sha256', secretKey).update(queryString).digest('hex'); } // Funktion zur ĂberprĂŒfung, ob Zertifikat bereits vorhanden ist async function loadMQTTCertification() { return new Promise((resolve, reject) => { // ĂberprĂŒfen, ob der State existiert getState(mqttCert, (err, state) => { if (err) { console.error('Fehler beim ĂberprĂŒfen des Zertifikat-States:', err); return reject(err); } if (state && state.val) { try { const storedCert = JSON.parse(state.val); // ĂberprĂŒfen, ob die Felder im Zertifikat vorhanden sind if (storedCert.certificateAccount && storedCert.certificatePassword) { console.log('Zertifikat aus ioBroker geladen'); return resolve(storedCert); } } catch (error) { console.error('Fehler beim Parsen des Zertifikats:'+ error); } } resolve(null); // Kein Zertifikat gefunden oder ungĂŒltig }); }); } // Zertifikate fĂŒr MQTT abrufen und speichern async function getMQTTCertification() { const nonce = Math.floor(Math.random() * 1000000); const timestamp = Date.now(); const params = { accessKey: accessKey, nonce: nonce, timestamp: timestamp }; const signature = createSignature(params, secretKey); try { const response = await axios.get(`https://${host}/iot-open/sign/certification`, { headers: { accessKey: accessKey, nonce: nonce, timestamp: timestamp, sign: signature } }); const certData = response.data.data; // Zertifikat in ioBroker speichern setState(mqttCert, JSON.stringify(certData), true); console.log('Zertifikat erfolgreich abgerufen und in ioBroker gespeichert'); return certData; } catch (error) { console.error('Fehler beim Abrufen der MQTT-Zertifikate:'+ error); throw error; } } // Funktion zum Setzen von Parametern (z.B. permanentWatts) ohne client und certification als Parameter function setPermanentWatts(deviceSN, wattsValue) { if (!client || !certification) { console.error("MQTT-Client oder Zertifizierung nicht bereit."); return; } const setTopic = `/open/${certification.certificateAccount}/${deviceSN}/set`; const message = { id: Date.now(), // Einzigartige ID version: "1.0", cmdCode: "WN511_SET_PERMANENT_WATTS_PACK", // Befehlscode zum Setzen von permanentWatts params: { permanentWatts: wattsValue // Der Wert, den du setzen möchtest } }; client.publish(setTopic, JSON.stringify(message), (err) => { if (!err) { console.log(`Befehl zum Setzen von permanentWatts auf ${wattsValue} W fĂŒr GerĂ€t ${deviceSN} wurde gesendet.`); } else { console.error(`Fehler beim Senden des permanentWatts-Befehls fĂŒr GerĂ€t ${deviceSN}:` + err); } }); } // MQTT-Verbindung herstellen und Daten empfangen async function startMQTTClient() { try { // Zertifikat aus ioBroker laden, falls vorhanden certification = await loadMQTTCertification(); if (!certification) { // Zertifikat neu generieren, wenn es nicht vorhanden ist certification = await getMQTTCertification(); } client = mqtt.connect(`${mqttProtocol}://${mqttHost}:${mqttPort}`, { clientId: 'EcoFlowClient_' + MQTT_Clientid, username: certification.certificateAccount, password: certification.certificatePassword, protocol: mqttProtocol }); client.on('connect', () => { console.log('Verbunden mit dem MQTT-Broker'); // Abonnieren von Status und anderen Daten fĂŒr jedes GerĂ€t deviceSNs.forEach((deviceSN) => { const quotaTopic = `/open/${certification.certificateAccount}/${deviceSN}/quota`; const statusTopic = `/open/${certification.certificateAccount}/${deviceSN}/status`; // Abonnieren des Status-Themas client.subscribe(statusTopic, (err) => { if (!err) { console.log(`Abonniert auf Status-Topic: ${statusTopic}`); } else { console.error(`Fehler beim Abonnieren des Status-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); // Abonnieren des Quota-Themas client.subscribe(quotaTopic, (err) => { if (!err) { console.log(`Abonniert auf Quota-Topic: ${quotaTopic}`); } else { console.error(`Fehler beim Abonnieren des Quota-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); }); }); client.on('message', (topic, message) => { console.log(`Nachricht empfangen von Topic ${topic}: ${message.toString()}`); }); client.on('error', (err) => { console.error('MQTT-Verbindungsfehler:' + err); client.end(); // Trenne die Verbindung bei einem Fehler console.log('Verbindung getrennt aufgrund eines Fehlers ' + err); }); client.on('close', () => { console.log('MQTT-Verbindung geschlossen'); }); } catch (error) { console.error('Fehler beim Starten des MQTT-Clients:' + error); } } // SchlieĂe die Verbindung, wenn das Skript gestoppt wird onStop(function (callback) { if (client) { client.end(); log("Script gestoppt"); } callback(); }, 2000); // Start der MQTT-Client-Verbindung startMQTTClient(); // Beispielaufruf von setPermanentWatts auĂerhalb von startMQTTClient() setTimeout(() => { setPermanentWatts(deviceSNs[0], 3000); // Setzt permanentWatts fĂŒr ein bestimmtes GerĂ€t auf 300 W }, 5000); // Warte 5 Sekunden, damit der Client verbunden ist -
@sirdir guter Hinweis mit der Client ID.
Ich hab das Grip mal angepasst und eine Client ID fest vergeben. Damit sollte das Problem erledigt sein.const axios = require('axios'); const mqtt = require('mqtt'); const crypto = require('crypto'); //****** HIER DEINE DATEN ****** const accessKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Access Key const secretKey = 'XXXXXXXXXXXXXXXX'; // Ersetze dies mit deinem tatsĂ€chlichen Secret Key const deviceSNs = ['XXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXXX']; // Mehrere GerĂ€te-Seriennummern const MQTT_Clientid = 1 //*********************/ // Konfigurationen const host = 'api-e.ecoflow.com'; const mqttHost = 'mqtt.ecoflow.com'; const mqttPort = 8883; const mqttProtocol = 'mqtts'; const mqttCert = '0_userdata.0.ecoflow.mqttCert' // Globale Variablen fĂŒr client und certification let client; let certification; if (!existsState(mqttCert)) { createState(mqttCert, ""); } // Hilfsfunktion zur Erstellung eines HMAC-SHA256-Signatur function createSignature(params, secretKey) { const queryString = Object.keys(params) .sort() .map(key => `${key}=${params[key]}`) .join('&'); return crypto.createHmac('sha256', secretKey).update(queryString).digest('hex'); } // Funktion zur ĂberprĂŒfung, ob Zertifikat bereits vorhanden ist async function loadMQTTCertification() { return new Promise((resolve, reject) => { // ĂberprĂŒfen, ob der State existiert getState(mqttCert, (err, state) => { if (err) { console.error('Fehler beim ĂberprĂŒfen des Zertifikat-States:', err); return reject(err); } if (state && state.val) { try { const storedCert = JSON.parse(state.val); // ĂberprĂŒfen, ob die Felder im Zertifikat vorhanden sind if (storedCert.certificateAccount && storedCert.certificatePassword) { console.log('Zertifikat aus ioBroker geladen'); return resolve(storedCert); } } catch (error) { console.error('Fehler beim Parsen des Zertifikats:'+ error); } } resolve(null); // Kein Zertifikat gefunden oder ungĂŒltig }); }); } // Zertifikate fĂŒr MQTT abrufen und speichern async function getMQTTCertification() { const nonce = Math.floor(Math.random() * 1000000); const timestamp = Date.now(); const params = { accessKey: accessKey, nonce: nonce, timestamp: timestamp }; const signature = createSignature(params, secretKey); try { const response = await axios.get(`https://${host}/iot-open/sign/certification`, { headers: { accessKey: accessKey, nonce: nonce, timestamp: timestamp, sign: signature } }); const certData = response.data.data; // Zertifikat in ioBroker speichern setState(mqttCert, JSON.stringify(certData), true); console.log('Zertifikat erfolgreich abgerufen und in ioBroker gespeichert'); return certData; } catch (error) { console.error('Fehler beim Abrufen der MQTT-Zertifikate:'+ error); throw error; } } // Funktion zum Setzen von Parametern (z.B. permanentWatts) ohne client und certification als Parameter function setPermanentWatts(deviceSN, wattsValue) { if (!client || !certification) { console.error("MQTT-Client oder Zertifizierung nicht bereit."); return; } const setTopic = `/open/${certification.certificateAccount}/${deviceSN}/set`; const message = { id: Date.now(), // Einzigartige ID version: "1.0", cmdCode: "WN511_SET_PERMANENT_WATTS_PACK", // Befehlscode zum Setzen von permanentWatts params: { permanentWatts: wattsValue // Der Wert, den du setzen möchtest } }; client.publish(setTopic, JSON.stringify(message), (err) => { if (!err) { console.log(`Befehl zum Setzen von permanentWatts auf ${wattsValue} W fĂŒr GerĂ€t ${deviceSN} wurde gesendet.`); } else { console.error(`Fehler beim Senden des permanentWatts-Befehls fĂŒr GerĂ€t ${deviceSN}:` + err); } }); } // MQTT-Verbindung herstellen und Daten empfangen async function startMQTTClient() { try { // Zertifikat aus ioBroker laden, falls vorhanden certification = await loadMQTTCertification(); if (!certification) { // Zertifikat neu generieren, wenn es nicht vorhanden ist certification = await getMQTTCertification(); } client = mqtt.connect(`${mqttProtocol}://${mqttHost}:${mqttPort}`, { clientId: 'EcoFlowClient_' + MQTT_Clientid, username: certification.certificateAccount, password: certification.certificatePassword, protocol: mqttProtocol }); client.on('connect', () => { console.log('Verbunden mit dem MQTT-Broker'); // Abonnieren von Status und anderen Daten fĂŒr jedes GerĂ€t deviceSNs.forEach((deviceSN) => { const quotaTopic = `/open/${certification.certificateAccount}/${deviceSN}/quota`; const statusTopic = `/open/${certification.certificateAccount}/${deviceSN}/status`; // Abonnieren des Status-Themas client.subscribe(statusTopic, (err) => { if (!err) { console.log(`Abonniert auf Status-Topic: ${statusTopic}`); } else { console.error(`Fehler beim Abonnieren des Status-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); // Abonnieren des Quota-Themas client.subscribe(quotaTopic, (err) => { if (!err) { console.log(`Abonniert auf Quota-Topic: ${quotaTopic}`); } else { console.error(`Fehler beim Abonnieren des Quota-Themas fĂŒr GerĂ€t ${deviceSN}:` + err); } }); }); }); client.on('message', (topic, message) => { console.log(`Nachricht empfangen von Topic ${topic}: ${message.toString()}`); }); client.on('error', (err) => { console.error('MQTT-Verbindungsfehler:' + err); client.end(); // Trenne die Verbindung bei einem Fehler console.log('Verbindung getrennt aufgrund eines Fehlers ' + err); }); client.on('close', () => { console.log('MQTT-Verbindung geschlossen'); }); } catch (error) { console.error('Fehler beim Starten des MQTT-Clients:' + error); } } // SchlieĂe die Verbindung, wenn das Skript gestoppt wird onStop(function (callback) { if (client) { client.end(); log("Script gestoppt"); } callback(); }, 2000); // Start der MQTT-Client-Verbindung startMQTTClient(); // Beispielaufruf von setPermanentWatts auĂerhalb von startMQTTClient() setTimeout(() => { setPermanentWatts(deviceSNs[0], 3000); // Setzt permanentWatts fĂŒr ein bestimmtes GerĂ€t auf 300 W }, 5000); // Warte 5 Sekunden, damit der Client verbunden istIch hab das Format jetzt verstanden un konnte diverse Werte setzen.
Was mir noch nicht ganz klar ist, der z.B. batSoc taucht im quota wohl nur auf, wenn er sich Àndert⊠abfragen kann man den nicht?
und z.B. die Einspeisekontrolle ein/ausschalten, dafĂŒr gibtâs keinen Parameter? Dann liesse sich das Script ja schon mal nicht komplett umschreiben⊠-
Ich hab das Format jetzt verstanden un konnte diverse Werte setzen.
Was mir noch nicht ganz klar ist, der z.B. batSoc taucht im quota wohl nur auf, wenn er sich Àndert⊠abfragen kann man den nicht?
und z.B. die Einspeisekontrolle ein/ausschalten, dafĂŒr gibtâs keinen Parameter? Dann liesse sich das Script ja schon mal nicht komplett umschreibenâŠ@sirdir , aktiv abfragen kannst wenn es per mqtt nicht geht, mit http. Auch setzen geht (alternativ) per http.
Ich nutze mqtt auch mehr fĂŒrs monitoring, man subscribed /abonniert ja topic die einen interessieren und dementsprechend finde ich es korrekt das nur Ănderungen mitgeteilt werden.
Aktiv schalten und co dann per http...Aber gibt sicherlich verschiedene Wege nach Rom đ
Edit: ich glaube Einspeisekontrolle fehlt tatsĂ€chlich (vermutlich) noch, war zumindest damals so. Die kam ja erst in spĂ€terer Firmware und mĂŒsste von Ecoflow in die API aufgenommen werden (wenn nicht vorhanden).
Ich nutze die nicht deshalb habe ich die nicht weiter verfolgt. -
@sirdir , aktiv abfragen kannst wenn es per mqtt nicht geht, mit http. Auch setzen geht (alternativ) per http.
Ich nutze mqtt auch mehr fĂŒrs monitoring, man subscribed /abonniert ja topic die einen interessieren und dementsprechend finde ich es korrekt das nur Ănderungen mitgeteilt werden.
Aktiv schalten und co dann per http...Aber gibt sicherlich verschiedene Wege nach Rom đ
Edit: ich glaube Einspeisekontrolle fehlt tatsĂ€chlich (vermutlich) noch, war zumindest damals so. Die kam ja erst in spĂ€terer Firmware und mĂŒsste von Ecoflow in die API aufgenommen werden (wenn nicht vorhanden).
Ich nutze die nicht deshalb habe ich die nicht weiter verfolgt.@giovanne OK, ich brauch das mit der EinspeisekontrolleâŠÂ
So oder so, ist doch ne ganz schöne Arbeit das Originalscript anzupassen, zumal ich das erst mal richtg analysieren mĂŒsste.
Ich fĂŒhl mich so doof, hab jetzt nochmal den http Weg versuchen wollen und mit der Funktion von Wally zu signieren versucht, aber der Wert den ich raus krieg wenn ich die Parameter aus dem Beispiel von Ecoflow ĂŒbergebe stimmt nicht ĂŒbereinâŠEdit: Man sollte Funktionen, die man benutzt vielleicht auch mal anschauen :) er sortiert das ja um.. ohne das stimmt der Wert.
-
jetzt hats mich auch erwischt und das Script speist nicht mehr ein. Muss irgendwann letzte Nacht um 5 Uhr morgens passiert sein. Seltsamerweise lief es jetzt all die Zeit problemlos, bis ich gestern an der Anlage rumgespielt hatte und den Powerstream AC-seitig vom Strom getrennt hatte. Was ein Mist. Der Realpower -Wert wird in den Objekten noch angezeigt. Woran sieht man eigentlich, dass von EF MQTT nichts mehr zuĂŒrck kommt in den Objekten?
Gibt es irgendwelche Alternativen was man jetzt machen kann? wie habt ihr das alle jetzt gelöst. Vorallem dass ich die Ăberschussladung jetzt nicht mehr nutzen kann nervt ohne Ende.
Im Skript schein er bestimmte Werte vom PS nicht mehr zu lesen.

-
jetzt hats mich auch erwischt und das Script speist nicht mehr ein. Muss irgendwann letzte Nacht um 5 Uhr morgens passiert sein. Seltsamerweise lief es jetzt all die Zeit problemlos, bis ich gestern an der Anlage rumgespielt hatte und den Powerstream AC-seitig vom Strom getrennt hatte. Was ein Mist. Der Realpower -Wert wird in den Objekten noch angezeigt. Woran sieht man eigentlich, dass von EF MQTT nichts mehr zuĂŒrck kommt in den Objekten?
Gibt es irgendwelche Alternativen was man jetzt machen kann? wie habt ihr das alle jetzt gelöst. Vorallem dass ich die Ăberschussladung jetzt nicht mehr nutzen kann nervt ohne Ende.
Im Skript schein er bestimmte Werte vom PS nicht mehr zu lesen.

@accu das ist normal soweit ich weià und and dauert immer kurze Zeit nach eine, Neustart, bis wieder entsprechend historische Werte angelegt sind. Das sollte alles schon wieder funktionieren. Di3se Meldung bekomme ich auch, wenn ich neu starte⊠nach ein paar Minuten geht es dann wieder normal weiter.
Generell habe ich aber auch ein Problem⊠Immer gegen 2 Uhr in der Nacht verdoppelt der ioBroker die Einspeisung. Keine Ahnung, was das ist⊠wir schlafen da alle und es ist auch genĂŒgend Energie im Speicher. Das ist so jetzt schon die 2 Nacht. Jemand eine Ahnung, was das sein kann?

-
Ich hab das Format jetzt verstanden un konnte diverse Werte setzen.
Was mir noch nicht ganz klar ist, der z.B. batSoc taucht im quota wohl nur auf, wenn er sich Àndert⊠abfragen kann man den nicht?
und z.B. die Einspeisekontrolle ein/ausschalten, dafĂŒr gibtâs keinen Parameter? Dann liesse sich das Script ja schon mal nicht komplett umschreibenâŠ@Waly_de Ich hab jetzt die fĂŒr mich wichtigsten Dinge implementiert (ohne Feed-Prio, weil das wohl nicht geht) und es klappt so weit. Eine Frage, ist es normal, dass die Verbindung in unregelmĂ€ssigen AbstĂ€nden (wenige Sekunden) geschlossen und wieder aufgebaut wird?
-
@Waly_de Ich hab jetzt die fĂŒr mich wichtigsten Dinge implementiert (ohne Feed-Prio, weil das wohl nicht geht) und es klappt so weit. Eine Frage, ist es normal, dass die Verbindung in unregelmĂ€ssigen AbstĂ€nden (wenige Sekunden) geschlossen und wieder aufgebaut wird?
@sirdir Ich hatte seit ich die gleiche "clientId" wie Waly_de im Test-Skript verwendet hatte ("Ecoflow_1") den selben Effekt.
Ich habe nun einen komplett kryptischen jedoch konstanten Wert gewÀhlt. - Nun scheint dieses Problem behoben zu sein. -
@sirdir Ich hatte seit ich die gleiche "clientId" wie Waly_de im Test-Skript verwendet hatte ("Ecoflow_1") den selben Effekt.
Ich habe nun einen komplett kryptischen jedoch konstanten Wert gewÀhlt. - Nun scheint dieses Problem behoben zu sein. -
@accu das ist normal soweit ich weià und and dauert immer kurze Zeit nach eine, Neustart, bis wieder entsprechend historische Werte angelegt sind. Das sollte alles schon wieder funktionieren. Di3se Meldung bekomme ich auch, wenn ich neu starte⊠nach ein paar Minuten geht es dann wieder normal weiter.
Generell habe ich aber auch ein Problem⊠Immer gegen 2 Uhr in der Nacht verdoppelt der ioBroker die Einspeisung. Keine Ahnung, was das ist⊠wir schlafen da alle und es ist auch genĂŒgend Energie im Speicher. Das ist so jetzt schon die 2 Nacht. Jemand eine Ahnung, was das sein kann?

-
@ralf77 gestern lief mein Skript plötzlich wieder. Ab heute Morgen 5 uhr wieder das gleich wie am Tag zu vor. Es speist nicht mehr ein.
Hast du irgendeinenen Tipp?@accu Hast du dasselbe Problem wie ich vielleicht? Zusatzakku geht schlafen oder so? (battErrorCode: 8 ) und PS speist deswegen nichts ein. Hab jetzt mein Script so angepasst, dass in dem Fall der andere PS das Doppelte Einspeist, bis die Batterie irgendwann aufwachtâŠ
Weiss auch nicht warum das mit der Batterie jetzt passiert und ob das auch irgendwie von Ecoflow gesteuert wirdâŠ