JKBMS auslesen über BLE (Bluetooth) oder RS485 Adapter mittels EPS, ioBroker

VIELEN DANK dir dafür schon mal ...
ich bin ehrlich gesagt kein freund von dem RTOS weil es einfach für solch "einfache" Anwendung zu viel Speicher etc verbraucht ;)
oder ich kenne mich damit einfach nicht gut genug aus ;) bin ja kein Informatiker :mrgreen:
Der ESP32 ist hierfür sicherlich vollkommen überdimensioniert. Wenn man mehr IOs benötigt ohne Peripherie-ICs dann ist er gut oder man braucht Rechenleistung für Webseiten etc.
Ansonsten reicht ein einfacher ESP8266 aus (wenn man RS485 nutzt, bei BLE muss man halt den ESP32 nehmen). Aber wer Funk kennt, nimmt Kabel ;)
RTOS muss aber sein, da wir hier 2 Cores haben, die parallel arbeiten. Das muss verwaltet werden.
und zwar in der If schleife von " if (doConnect == true) {" Zeile 415
wird in Zeile 420 -> "BLEClient* pClient = BLEDevice::createClient();" das pClient angelegt ...
kannst du mir sagen wie ich das "global" oder "übergeben" bekomme das ich in der Zeile 522 anstelle "ESP.restart();" -> "pClient->disconnect();" aufrufen kann ?
dann könnte ich anstelle des ESP Neustart "einfach" das BLE Verbindung sauber trennen und dann wiederherstellen....
hier würde ich eine globale Variable nehmen:
BLEClient* pClient;

im setup dann einfach:

pClient = BLEDevice::createClient();

Dann kannst du überall mit dem Pointer-Operator -> darauf zugreifen:

pClient->disconnect();

Wenn du es einer Methode übergeben möchtest:

void irgendEineMethode(BLEClient* myMethodClientVariable) {
myMethodClientVariable->tuWas();
}
Aufruf: irgendEineMethode(pClient); // (pClient ist ja schon eine Adresse, kein Objekt, wenn es ein Objekt wäre, müsstest du die Startadresse des Objekts mitteilen &pClientObjekt)

Durch den Zeiger speicherst du nur die Adresse des Objekts im Hauptspeicher ab. Die Methoden haben grob gesprochen eine Entfernung von der Objektadresse gespeichert. Wenn du nun ->tuWas() ausrufst, geht der Stack auf die Sprungmarke "AdresseObjekt+EntfernungMethode" und arbeitet ab da weiter den Code ab.

Gruß
Jörg

ByTheWay: Was spricht gegen folgenden Ansatz:

1. BLE Verbindung aufbauen
2. Daten abrufen
3. BLE Verbindung schließen

Das Ganze zyklisch durchführen. Da es meines Erachtens aber asynchron läuft, müsste man

1. Verbindung aufbauen (in der Main oder über Task)
2. Abfrage senden
==warten
3. Antwort erhalten
4.Verbindung schließen (am besten in der Asynchronen Nachricht vom BLE Device

Gruß
Jörg

@scotty89

ich habe die 1.72 am laufen, mal sehen wie diese auf meine WLAN Nachtschaltung reagiert.
Aber mit dem Staus im MQTT passt was nicht.

Und die Idee von @DerLang finde ich gut, ich denke das die BT Verbindung nicht wirklich für dauerhafte Verbindungen gedacht ist.
Die APP parametriert das BMS und dann ist gut... :wink:

Eventuell versuche ich mal am Wochende die Kabelversion. Daher die Frage welche GPIO's hast Du für die Kabelversion genutzt?
RX/TX oder?


Danke
JUF

N'Abend,

habe mich mal ein wenig mit BLE beschäftigt.

Ich glaube so wie du es machst, funktioniert das nicht sauber.

Ich würde wie folgt vorgehen.

Im Setup den Scan wieder einschalten. Wenn ich es richtig verstanden habe, ist pBLEScan->start kein blockierendes Statement.
Lediglich die Scan Zeit start(5, false) würde ich auf start(0, false) setzen. Damit wird ständig gesucht und muss manuell beendet werden.
Genau das wird ja in dem Callback MyAdvertisedDeviceCallbacks gemacht, wenn die UUIDs stimmen, man also sein Gerät gefunden hat.

Jetzt wird es spannend. Die reconnectBLE Methode würde ich übernehmen und im loop jedesmal aufrufen, wenn keine Verbindung vorhanden ist.
In der reconnectBLE Methode wird ja nach erfolgreichen abfragen des service und Characteristic das Flag "verbunden" gesetzt.
Wenn die BLE connection weg geht, dann wird das ja auch im Client-Callback festgehalten und beim nächsten loop wird dann wieder reconnectBLE aufgerufen und eine Verbindung versucht.

Im Falle des Startens wird zwar in der loop die reconnectBLE Methode aufgerufen obwohl kein BLEClient vorhanden ist. Das macht erstmal nichts, da wahrscheinlich der Aufruf getService nichts zurück liefert und somit an der Stelle der Verbindungsversuch abgebrochen wird. Ist man beim Starten weit entfernt vom Device oder das Device ist aus, oder was auch immer, wird kurz gescannt, dann gewartet, kurz gescannt und gewartet. Dieser Zyklus geht so lange wie man es beim ->start(x, false) definiert hat. Also x Sekunden. Wenn x=0 dann wird der Zyklus nicht beendet und damit der Scan fortlaufend weiter durchgeführt. Vergisst man im Callback den Scan zu stoppen, wird auch lecker weiter gescannt bis der Arzt kommt oder wahrscheinlicher ein Reboot stattfindet weil irgendein Speicher vollgelaufen ist.

Damit sollte auch einer dauerhaften Verbindung nichts im Weg stehen. Es sei denn, man muss irgendein Kommando an das BMS senden, um den Vorgang abzuschließen oder auch hier ein KeepAlive Nachricht integrieren. Gibt es eine Spez seitens JKBMS?

Gruß
Jörg

@scotty89

ich habe die 1.72 am laufen, mal sehen wie diese auf meine WLAN Nachtschaltung reagiert.
Aber mit dem Staus im MQTT passt was nicht.

Danke
JUF
@Scotty: Schau mal in mein Beispiel, ich würde die Topics stets mit einem define versehen, dann brauchst du nur an einer Stelle den Topic anpassen wenn notwendig und du hast ihn definitiv an jeder Stelle gleich geschrieben (kein Tippfehler, passiert auch mit Copy-Paste ;) .

Gruß
Jörg

:smiley: Heute Morgen sieht es mit der 1.72 gut aus ich bekomme immer noch Daten. :smiley:

@DerLang: War auch mein erster Tipp, dass der Speicher vollgelaufen ist. Vielleicht kann irgendwer den Code nochmal auf weitere Speicherleaks durchgehen, sonst verschiebt sich das Problem im schlimmsten Fall einfach nur nach hinten. Mir fehlt momentan die Zeit dafür.
Oder irgendwer packt noch schnell einen Garbage Collector rein :lol:

Guten morgen zusammen,

@Juf

das doch mal erfreulich das es voran geht :wink:
bestätigt was ich mir auch gedacht hatte...

@DerLan

Vielen vielen Dank für den ganzen Input .. ich werd mir das am Wochenende mal in ruhe anschauen und davon ein paar ideen übernehmen !

etwas Hintergrund wissen für alle:

eine Spec oder ähnliches gibt es nicht von der LBE Schnittstelle des BMS :wink: alles was ich dort mache habe ich probiert und oder durch Sniffing raus bekommen :wink:

bezüglich des BSM ist es aber grob gesagt so:

das BMS verfügt über eine entsprechende UUID´s (ein Serivce und ein Char.)
Grundlegend ist ist es so das man sich mit dem BSM verbinden muss und dann eine bestimmte "Sequenz" anfragen, Abonieren, ... muss (macht das connectToServer). Wenn das erfolgt ist fängt es von sich an die Daten die uns interessieren per Nofiy "regelmäßig" zu senden.

daher die Idee sich nur kurz mit dem BSM zu verbinden hatte ich mal Probiert macht aber mehr Probleme als es nützt. :wink:
Aktuell ist die Strategie folgende:

WLAN und MQTT verbinden und Regelmäßig prüfen ob die Verbidnung besteht, wenn nicht versuchen neu herzustellen. -> das ist nun gelöst und geht ... (Code Räume ich in 2.0 auf versprochen....)
Dann BLE Verbidnung aufbauen und "Pattern" Senden damit das BMS anfängt die für uns interessanten Daten zu senden.
bezüglich BLE Verbidnung hab ich es so gemacht das er für eine Zeit X Scannen soll und nicht endlos lang und das wird regelmäßig wiederholt bis unser Gerät gefunden wurde.
bin kein Freund von endlos suchen bis ... da vergisst man immer das zu beenden :wink:

Die Daten werden nach jedem Vollständigen Empfang verarbeitet, ausgewertet und entsprechendes des Sendeslot über MQTT gesendet...

das alles geht bisher ohne Probleme und lief bei mir auch schon einmal 5 Tage ...

was nun bei uns allen passiert ist das BSM hört "einfach" auf die Daten zu senden die uns interessieren... das komische dabei ist das die BLE Verbindung nicht getrennt wird.

Nun habe ich ein "Checker" drin der prüft wann das letzte mal "gültige" Daten gekommen sind, wenn das länger als 60sekunden her ist wird jetzt der EPS einfach neu gestartet...
-> somit täglich grüst das Murmeltier :wink:


ich würde eigentlich lieber die BLE verbidnung sauber trennen wollen und dann wieder erneuern als den ESP neu zu starten.. aber ich bin / war zu Dumm den Aufruf dafür "verfügbar" zu machen ... deshalb der ESP neustart der ja auch hilft ...

zum Thema Speicherüberschreiben etc das hatte ich auch erst befürchtet aber dann würde im Serial Monitor eine entsprechende "excaption log" kommen :wink: und das haben wir bisher ja noch nicht gesehen. er bekam schlichtweg keine neuen Daten die er verarbeiten kann und dann machte er nur noch die Prüfung ob MQTT und WFI Verbidung da ist ...

wie gesagt ich geh davon aus das die Version 1.72 nun damit klar kommen sollte wenn das BMS das senden einstellt .. indem wir den ESP einfach neu starten..

ich Schau mir am Wochenende mal an was man im Code "schöner" machen kann an und vor allem wie ich anstelle des ESP neu start die BLE verbindung trennen und wiederherstellen kann.
Dann könnten wir das als Basis für die 2.0 nehmen mit dem Ziel dort ggf auch OTA und die CAN BUS Schnittstelle für Victron bspw einzubauen.
gibt es sonst wünsche die noch benötigt werden ?

@scotty89: Ich werds später auch testen, bei mir kamen die Abbrüche immer sehr schnell. Vielleicht klappts ja jetzt. Abgesehen davon finde ich das Projekt und auch die Zusammenarbeit hier sehr schön, also danke dafür :thumbup: Wenn das alles sauber läuft, kann ich das auch gerne auf YT vorstellen und kurz vorführen wie man das flasht usw., das interessiert ja vielleicht noch andere und man spart sich wiederkehrende Fragen.

Hi

finde ich auch.
Gleich mal getestet und funktioniert. Jetzt fehlt nur mehr die Einbindung in den ioBroker.
Habe noch einen JK nur aktive Balancer mit 5A, werde versuchen den auch mal abzufragen.
Noch eine Frage:
Was ist der unterschied zwischen den beiden Werten und muß beim ersten nicht "A" für den Strom stehen.

Serial.print("Current Balancer = ");
Serial.print(Current_Balancer, 3);
Serial.println("V, ");


Serial.print("Balance_Curr = ");
Serial.print(Balance_Curr, 3);
Serial.println("A, ");

Serial.print("Balance_Curr = ");
Serial.print(Balance_Curr, 3);
Serial.println("A, ");
ich muss nachschauen die Einheit ist mit Sicherheit nicht ganz korrekt ;)
aber ich meine das ich zu beginn das Current_Balancer hatte es sich dann aber rausgestellt hat das es nicht die Info über den Balancer Strom ist .. und ich dafür dann das Balance_Curr aufgemacht habe.

ich muss mal schauen was da aktuell stehen für werte...

OK
Das JK nur Balnancer Gerät bring kein sauberen Daten. Vermutlich andere Adressen.
Werde mal mit meinen China Kontakt versuchen die Daten für dieses Geräüt zu bekommen.

@scotty89
:frowning: bin gerade aus dem Office zurück und sehe/empfange keine Daten mehr.
Ping ist da, aber keine MQTT Meldungen mehr.

Da das Teil im Schuppen hängt habe ich auch keine Log's.
Das schaffe ich eventuell am Freitag.

Grüße
JUF

Guten Abend zusammen...

ich habe mir jetzt mal ein paar Minuten genommen und eine erste 2.0 Version gemacht :crazy:

neu in 2.0

-> OTA Update fähig :wink: beachtet das Setting siehe Bild
-> anstelle des ESP Reset hab ich es jetzt hinbekommen das jetzt nun die BLE Verbindung getrennt und wiederhergestellt werden soll ... (müssten wir mal zusammenschauen was besser ist reset oder halt BLE "Reset")
-> dann habe ich den gesamten Code mal sortiert und aufgeräumt -- -> @ DerLang vielen dank für deine Ideen hab da bissel was übernommen und auch entsprechen modifiziert :wink:

bei mir läuft es soweit...
bin gespannt was von euch kommt... :angel:

@scotty89
:-( bin gerade aus dem Office zurück und sehe/empfange keine Daten mehr.
Ping ist da, aber keine MQTT Meldungen mehr.
mqttbms_1.jpg

Da das Teil im Schuppen hängt habe ich auch keine Log's.
Das schaffe ich eventuell am Freitag.

Grüße
JUF

:shock: :shock: :shock: :shock:
welche Version ? 1.72 ??
da brauch ich ein Fulllog ....

@Scotty89
Gerade getestet und funktioniert.
Jetzt gefällt mir der Code schon besser.
Tolle Arbeit, respekt und vielen Dank für die Mühe.

@scotty89

„welche Version ? 1.72 ??
da brauch ich ein Fulllog ....„

Ja war die 1.72, bin auch schon auf die 2.0 gegangen.
Und ja Freitag dann mit full_log, geht ja jetzt einfach per OTA.

DANKE

N'Abend,
und sorry...

1.

WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED && wifi_retry < 10  ) {
WiFi.begin(ssid, password);

In der while nicht nochmal begin aufrufen! Das ist kontra produktiv. WiFi benötigt Zeit für die Verbindung, daher die Warteschleife bis die Verbindung da ist. Wenn dann immer wieder begin gemacht wird, fliegt er aus dem Verbindungsversuch...

2. in der Loop würde ich nicht einfach WiFi.begin nutzen, wie gesagt, wifi braucht seine Zeit. Ruf doch einfach initWiFi auf, wenn die erneute Verbindung nicht klappt, führt er sogar ein reset aus. Stichwort: Bufferprobleme
Es kann so wie du es gemacht hast funktionieren, aber es ist ehrlich gesagt ein Glücksspiel.

Ansonsten finde ich den Quelltext schon um einiges übersichtlicher. Mal schauen, wenn das halbwegs stabil läuft, baue ich eine weitere mit einer kleinen webseite zur Konfiguration, also Passwort/Username/MqttAdresse etc. einstellbar. Ggfs auch eine Möglichkeit entweder BLE zu aktivieren oder per R485 Verbindung.

Well done, keep it up!

Gruß
Jörg

Feedback zur 2.0
WLAN nach Nachtschaltung nicht wieder verbunden.

Ist wirklich keine wlan Verbindung also kannst ihn nicht mehr an pingen?