Sunstone Power SLPO 48-200 auslesen?

Welche Geräte sollen noch implementiert werden?
Was sollte man ändern / verbessern / ergänzen an der Solaranzeige? Hier kann Jeder seine Ideen einbringen.
Außerdem steht hier, woran gerade gerbeitet wird.

Moderator: Ulrich

Forumsregeln
Wenn neue Geräte implementiert werden sollen ist die Protokollbeschreibung der Schnittstelle vom Hersteller Voraussetzung.

Bitte nur konkrete Ideen hier eintragen und in jedem Beitrag bitte nur eine Erweiterung / Änderung, damit das Ganze noch überschaubar bleibt. Ein ganzes Sammelsorium von Ideen in einem Thread ist zu unübersichtlich. Nicht alles kann und wird auch verwirklicht werden.
tomatojoe
Beiträge: 7
Registriert: Mi 8. Jun 2022, 20:38

Sunstone Power SLPO 48-200 auslesen?

Beitrag von tomatojoe »

Hallo,

ist es möglich, einen Sunstone Power SLPO 48-200 (Sunstone Power LiFePO4 Lithium Battery 48 V 200 Ah 9.6 kWh) über RS485 auszulesen?
Ich finde keine Geräte ID dazu, aber ggf. gibt es ja etwas "baugleiches" ?

tomatojoe
Beiträge: 7
Registriert: Mi 8. Jun 2022, 20:38

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von tomatojoe »

Ich habe leider nur das Handbuch zum Gerät als PDF. Eventuell hilft das jemandem weiter.
Ich habe bisher noch keine Lösung gefunden.
Dateianhänge
SLPO48-200 Handbuch.pdf
(7.52 MiB) 189-mal heruntergeladen

tomatojoe
Beiträge: 7
Registriert: Mi 8. Jun 2022, 20:38

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von tomatojoe »

Vom Händler Support habe ich die angehängte Protokollbeschreibung dazu erhalten.
The serial port uses 485 communication, and the device address is distinguished by dial code (1~15, the soft address is used when the dial code is empty, the default is 170), the 485 baud rate is 9600, the data bit is 8 bits, the stop bit is 1, and there is no check.
Wie genau muss man vorgehen, um nun Daten damit erhalten zu können? Hat irgendjemand eine Idee?
Dateianhänge
48100lithium iron phosphate battery module communication data sheet_AP.pdf
(228.87 KiB) 201-mal heruntergeladen

tomatojoe
Beiträge: 7
Registriert: Mi 8. Jun 2022, 20:38

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von tomatojoe »

Leider ist der Support von Sunstone etwas knapp mit Informationen.
Mir wurde gesagt, dass es möglich sein soll, die Daten mittels Ethernet Kabel vom RS485 -> Raspi LAN zu lesen.

Ich gehe davon aus, dass man das mit Modbus macht? Leider habe ich noch keine Ahnung davon.
Muss ich am Raspi irgendwas aktivieren? Wie kann ich dann auf die Modbus Schnittstelle zugreifen?

Muss ich ggf. noch weitere Informationen, Fotos usw. bereitstellen, damit mir möglicherweise jemand helfen kann? ;)

tomatojoe
Beiträge: 7
Registriert: Mi 8. Jun 2022, 20:38

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von tomatojoe »

3 Monate später ... und ich bin noch keinen Schritt weiter gekommen. :o

Ich kann doch nicht der Einzige sein, der so ein Gerät nutzt, oder?

bohrer
Beiträge: 1
Registriert: Mi 28. Sep 2022, 07:32

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von bohrer »

Hallo,

ich habe die 48-100 Akkus von denen vor 4 Wochen bekommen und wollte die mit dem Igrid IV verbinden.
Der Igrid IV unterstützt ja die gängisten Formate . Laut Sunstone sollen die ja an einem SMA Inverter laufen
angeblich mit dem Pylontech Protokoll.
Habe es weder per CAN noch per RS485 ans Rennen bekommen.

Aussage des Sunstone Support
Die Implementierung wäre erst seit kurzem fertig und meine Batterien hätten noch nicht die aktuelle Version
drauf. Ich solle die Batterien kostenfrei zurückschicken und die würden upgedatet.

Da habe ich allerdings keine Lust drauf weil ich eine 3 Phasen Offgridanlage habe die ich dann solange nicht benutzen kann.

Wenn ich etwas mehr Zeit habe versuche ich auch mal die in Solaranzeige zu integrieren

Gruß Udo

User5518
Beiträge: 5
Registriert: Fr 28. Okt 2022, 21:29

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von User5518 »

Hallo zusammen,

habe ebenfalls einen SLOP48-200 im Keller stehen und würde gerne die Daten von dem Gerät via RS485 auslesen. Daher war ich froh diesen Thread gefunden zu haben und zu lesen, dass wohl prinzipiell möglich ist.

Habe mir einen RS485 zu USB-Adapter gekauft (https://www.amazon.de/gp/product/B016IG6X7), welcher auf einem CH340E basiert. Der Stick hängt an einem Raspberry Pi (1. Gen) und wird auch auf /dev/ttyUSB0 erkannt. (Etwas merkwürdig ist, dass ich den Pi mit dem Stick booten muss, wenn ich nachträglich anschließe, schaltet sich der PI ab - nicht sehr vertrauenerweckend, aber gut...)

Laut Handbuch müssen die Pins eines RJ45 Steckers wie folgt angeschlossen werden:

Pin 4 -> A
Pin 5 -> B
Pin 7 und 8 -> GND

Habe dafür ein altes Ethernet-Kabel aufgeschnitten und die entsprechenden Pins mit dem RS485-Adapter verbunden.

Habe bisher für die serielle Kommunikation auf einem PI immer "jpnevulator" verwendet, was auch bisher gut funktioniert hat.

Zum Lesen der Daten gehe ich wie folgt vor:
Zuerst muss die Baud-Rate festgelegt werden:

Code: Alles auswählen

stty -F /dev/ttyUSB0 9600
und dann der Lese-Befehl ausgeführt werden:

Code: Alles auswählen

sudo jpnevulator --ascii --timing-print --tty /dev/ttyUSB0 --read

Das Problem ist jetzt allerdings, das BMS zu überreden, die gewünschten Daten zu übermitteln.

Wenn ich mir die Daten aus "48100lithium iron phosphate battery module communication data sheet_AP.pdf" ansehe, müsste der Request wie folgt aussehen:

Code: Alles auswählen

0xAA 0x04 0x00 0x03 0x00 0x01
CRC: D8 11

0xAA ist wohl die "device address". Da ich nur einen Akku habe, gehe ich hier vom Default "170" aus, was Hex 0xAA entspricht.
0x04 ist wohl der "Function code". Laut PDF: "Use 03H/04H to obtain". Ich weiß nur nicht, wann man 03 und wann man 04 benutzt.
0x00 0x03 ist die "Register address"
0x00 0x01 ist die Quantity - keine Ahnung, ob hier "1" korrekt ist.

Ich weiß auch nicht, ob ich den CRC mit übertragen muss. Laut Doku gibt es keinen Check.
Den CRC habe ich mittels http://www.sunshine2k.de/coding/javascr ... rc_js.html berechnet.
CRC witdth: CRC-16
CRC parametrization: CRC16_MODBUS
CRC Input Data: Bytes
0xAA 0x04 0x00 0x03 0x00 0x01

Als Resultat wird "0x11D8" ausgeben. Allerdings wird bei dem Beispiel in der Doku mit dem Online-Calculator auch "0xD0A9" ausgeben und im PDF steht "A9D0", also hab ich auch in meinem Fall die Bytes einfach getauscht.


Wenn ich zum Beispiel mit

Code: Alles auswählen

echo "0xAA 0x04 0x00 0x03 0x00 0x01" | jpnevulator --print --tty /dev/ttyUSB0 --write
die Daten wegschicke, bekomme ich nichts zurück. Ich habe auch mal mit den Beispielen herumgespielt, leider ebenfalls ohne Erfolg.

Leider habe ich nur einen USB-RS485-Adapter, allerdings habe ich noch ein paar "UART <=> RS485"-Adapter. Werde hoffentlich in den nächsten Tagen dazu kommen, mit diesen Adaptern eine Kommunikation unter 2 Raspberry-Pis ans Laufen zu bekommen. Das sollte man besser debuggen können. Wenn das läuft, kann werde mich noch mal an den SLOP48-200 gehen.

User5518
Beiträge: 5
Registriert: Fr 28. Okt 2022, 21:29

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von User5518 »

Hallo zusammen,

zwischenzeitlich bin ich einen Schritt weiter - wenn auch noch nicht am Ziel:

Es gib eine aktuellere Version zur Kommunikation mit dem Akku unter
https://www.sunstonepower.de/products/4 ... erie-solar => "Downloads" => Kommunikationsprotokoll => Protokoll (RS485)
Bzw. um genau zu sein, hier: https://cdn.shoplazza.com/7898dd8491fa3 ... 8e453c.pdf

In dem Kommunikationsprotokoll ist angegeben, dass der Standard MODBUS-RTU genutzt wird. Das ist durchaus praktisch, da es Wrapper-Libs für Python gibt, die einem relativ viel Arbeit abnehmen. Habe mir bisher nur "MinimalModbus" näher angesehen: https://minimalmodbus.readthedocs.io/en ... eadme.html

Um minimalmodbus nutzen zu können, müssen "pyserial" und natürlich auch "minimalmodbus" installiert sein:

Code: Alles auswählen

sudo pip3 install -U pyserial
sudo pip3 install -U minimalmodbus
("pip3" kann man via

Code: Alles auswählen

sudo apt-get install python3-pip
auf einem RaspberryPi installieren)

Mit diesem Skript habe ich bisher herumgespielt:

Code: Alles auswählen

#!/usr/bin/env python3
import minimalmodbus
import serial

instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 170)  # port name, slave addre>
instrument.serial.baudrate = 9600         # Baud
instrument.serial.bytesize = 8
instrument.serial.parity   = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout  = 1.5          # seconds

instrument.mode = minimalmodbus.MODE_RTU

instrument.debug = False

instrument.clear_buffers_before_each_transaction = True

try:
    value = instrument.read_register(3, 4)
    print (value)
except minimalmodbus.NoResponseError:
    print ("NoResponseError")
    
instrument.serial.close()
Kleiner Hinweis: Ich bin kein Python-Enwickler und habe mir den Code nur aus den Docs zusammenkopiert.

Bisher bekomme ich allerdings immer wieder den "NoResponseError".

Das bedeutet (wie der Name schon sagt), dass das BMS des Akkus nicht antwortet.
Wenn man "instrument.debug" auf "True" setzte, sieht man, was die Lib versendet:

Code: Alles auswählen

user@solar-akku-pi:~ $ sudo python akku.py
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): AA 03 00 03 00 01 6D D1 (8 bytes)
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 11490585.17 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Response from instrument:  (0 bytes), roundtrip time: 0.0 ms. Timeout for reading: 20.0 ms.

NoResponseError
Das sieh eigentlich nicht schlecht aus, auch wenn das 6. bit immer "01" ist... Eigentlich hätte ich erwartet, dass sich das in Abhängigkeit von "4" in der Zeile

Code: Alles auswählen

value = instrument.read_register(3, 4)
ändert und das die "number of decimals" angibt. Aber gut, "1" wäre ja auch in Ordnung, um zu sehen, dass überhaupt irgendetwas zurückkommt.

Hier "hänge" ich aktuell. Ich habe noch immer den USB-Adapter, den ich in meinem letzten Beitrag erwähnt habe, im Einsatz. Ggf. ist der auch das Problem. Habe sonst mal testweise mit diesen Modulen: https://www.amazon.de/gp/product/B08394 ... UTF8&psc=1
zwei RaspberryPis verbunden und kommunizieren lassen. Das hat funktioniert - natürlich ohne die MinimalModbus-Lib, da in dem Fall nur RS232 gesprochen wird und die Module die Übersetzung zu RS485 vornehmen. Der Aufbau war wie folgt:
[RaspberryPi_A] <=> [UART to RS485 Adapter] <=> [UART to RS485 Adapter] <=> [RaspberryPi_B]
Also relativ simple.

Ich habe das Gefühl, dass bei der Kommunikation mit dem Akku über RS485 nicht mehr viel fehlt. Evtl. habe ich die falschen Pins aus dem RJ45-Anschluss angeschlossen. Das werde ich in den nächsten Tagen noch mal prüfen. Oder ich werde mal so ein "UART to RS485 Adapter" am Pi mit dem Akku verwenden - bei den Modulen weiß ich wenigstens, dass sie tendenziell funktionieren.

Edit:
Habe gerade noch einen "UART to RS485 Adapter" an den Akku angeschlossen: leider mit dem gleichen Ergebnis: "NoResponseError".
Werde in den nächsten Tagen noch mal die Verkabelung prüfen und hoffe dort den Fehler zu finden. Sonst gibt es noch die Python-Lib "PyModbus", welche man noch ausprieren kann: https://pymodbus.readthedocs.io/en/latest/readme.html

User5518
Beiträge: 5
Registriert: Fr 28. Okt 2022, 21:29

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von User5518 »

Erfolg!

Es funktioniert jetzt. :D Ich kann jetzt den SLPO48-200 mittels RS485 auslesen. :)

Eigentlich hätte schon gestern alles funktionieren können, aber naja. Am Ende hatte ich die falschen Adern des RJ45-Steckers mit dem RS485-Adapter verbunden. *autsch*

Also, mein Ethernet-Kabel entspricht der Standard EIA/TIA-T568B-Belegung. Unter http://www.netzmafia.de/skripten/netze/twisted.html wird gut erklärt, was das genau ist. Wichtig ist nur, dass man weiß, dass der Akku die Pins wie folgt belegt hat:

Pin 4: 485-A
Pin 5: 485-B
Pin 7: GND
Pin 8: GND

Für T568B gilt:
Pin 4: blau
Pin 5: blau-weiß
Pin 7: braun-weiß
Pin 8: braun

Ich habe das ganze mit diesem Adapter:
"USB to RS485": https://www.amazon.de/gp/product/B016IG6X7I (Farbe: #1)
und auch diesem Adapter:
"UART to RS485": https://www.amazon.de/gp/product/B083943T9J
ans Laufen bekommen.

Der "USB to RS485"-Stick ist in der Handhabung natürlich etwas einfacher.

Beide Adapter haben aber an einem Ende die Anschlüsse "A", "B" und "GND"

Im Falle von T568B verbindet man die Anschlüsse "A", "B" und "GND" des entsprechenden Adapters wie folgt:
"A" -> (Pin 4) blau
"B" -> (Pin 5) blau-weiß
"GND" -> (Pin 7) braun-weiß
und/oder
"GND" -> (Pin 8) braun

Gerade bei der blau-weiß-Ader sowie der braun-weißen Ader aufpassen, die nicht anderen Adern vertauscht werden. (Hier lag gestern mein Fehler: Ich hatte "B" -> mit (Pin 3) grün-weiß verbunden anstatt "B" -> (Pin 5) blau-weiß. :roll: )

Wenn man den "USB to RS485"-Adapter hat, muss man diesen dann nur noch in einen Raspberry-Pi oder anderen Linux-Rechner stecken. Der "UART to RS485"-Adapter hat folgende Anschlüsse:
- GND
- RxD
- TxD
- Vcc

Das Pinout des RaspberryPis kann man hier einsehen: https://de.pinout.xyz/

Verkabelt wird der "UART to RS485"-Adapter wie folgt:
GND auf GND des Pis
RxD auf RxD des Pis (Ja, auf RxD, GPIO 15, NICHT auf TxD)
TxD auf TxD des Pis (Ja, auf TxD, GPIO 14, NICHT auf RxD)
Vcc auf 3,3V des Pis

Dann ist alles richtig verkabelt und es kann mit der Software losgehen.

Ich verwende Raspberry Pi OS Lite, Kernel version: 5.15, Debian version: 11 (bullseye) - also die aktuelle Version (ohne Desktop).
Wenn der "UART to RS485"-Adapter verwendet wird, muss man die Serielle Schnittstelle des Pis noch wie folgt aktivieren:
Das ist hier sehr gut beschrieben: https://www.abelectronics.co.uk/kb/arti ... erry-pi-os

Wie gestern schon beschrieben muss man dann noch Pip3 sowie zwei Python-Module über Pip3 installieren. Einfach die folgenden Befehle im Terminal bzw. auf der Konsole auf dem Pi ausführen:

Code: Alles auswählen

sudo apt-get install python3-pip

Code: Alles auswählen

sudo pip3 install -U pyserial
sudo pip3 install -U minimalmodbus
Dann kann man einfach folgendes Skript verwenden:

Code: Alles auswählen

#!/usr/bin/env python3
import minimalmodbus
import serial
import json

instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 170)  # port name, slave address (in decimal)
instrument.serial.baudrate = 9600         # Baud
instrument.serial.bytesize = 8
instrument.serial.parity   = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout  = 0.5          # seconds

instrument.mode = minimalmodbus.MODE_RTU
instrument.debug = False
instrument.clear_buffers_before_each_transaction = True

try:
    total_voltage = instrument.read_register(3, 2, 3, True)
    current = instrument.read_register(4, 1, 3, True)
    soc = instrument.read_register(5, 0, 3, True)
    soh = instrument.read_register(6, 0, 3, True)
    cycles = instrument.read_register(7, 0, 3, True)
    heatsink_temperature = instrument.read_register(25, 1, 3, True)
    temperature_1 = instrument.read_register(26, 1, 3, True)
    temperature_2 = instrument.read_register(27, 1, 3, True)
    temperature_3 = instrument.read_register(28, 1, 3, True)
    warnings = instrument.read_register(1000, 0, 3, False)
except minimalmodbus.NoResponseError:
    data = {
        "SLPO48-200":{
            "is_communication_error": 1,
            "communication_error": "NoResponseError"
        }
    }
    print (json.dumps(data))
    instrument.serial.close()
    quit()

instrument.serial.close()
data = {
"SLPO48-200":{
  "total_voltage": total_voltage,
  "current": current,
  "soc": soc,
  "soh": soh,
  "cycles": cycles,
  "heatsink_temperature": temperature_1,
  "temperature_1": temperature_1,
  "temperature_2": temperature_2,
  "temperature_3": temperature_3,
  "warnings": warnings,
  "is_communication_error": 0
 }
}

print (json.dumps(data))
Das gezeigte Beispiel nutzt den "USB to RS485"-Adapter. Für den "UART to RS485"-Adapter muss folgende Zeile geändert werden:

Code: Alles auswählen

instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 170)  # port name, slave address (in decimal)
zu

Code: Alles auswählen

instrument = minimalmodbus.Instrument('/dev/serial0', 170)  # port name, slave address (in decimal)
Solltet ihr einen anderen Port nutzen, dann einfach den Port-Namen ändern.

Ausführen kann man das Skript dann wie folgt:

Code: Alles auswählen

sudo python akku_USB.py
"akku_USB.py" muss natürlich mit Dateinamen ersetzt werden, den ihr gewählt habt.

Die Ausgabe sollte wie folgt aussehen:

Code: Alles auswählen

{
   "SLPO48-200":{
      "total_voltage":48.13,
      "current":-0.6,
      "soc":9,
      "soh":100,
      "cycles":10,
      "heatsink_temperature":15.9,
      "temperature_1":15.9,
      "temperature_2":15.5,
      "temperature_3":15.3,
      "warnings":0,
      "is_communication_error":0
   }
}
Natürlich kann man das Array bzw. das JSON auch noch mit weiteren Werten füllen.

Edit:
Diese Adapter funktionieren auch: https://www.amazon.de/gp/product/B08XLT21S6
Quasi genauso, wie die anderen "UART to RS485"-Module.

tomatojoe
Beiträge: 7
Registriert: Mi 8. Jun 2022, 20:38

Re: Sunstone Power SLPO 48-200 auslesen?

Beitrag von tomatojoe »

Hallo User5518,

das sind ja gute Neuigkeiten! :)

Ich werde am Wochenende mal schauen, ob ich das so, wie von dir aufgezeigt, reproduzieren und nutzen kann.
du hast vorher geschrieben (ist jetzt irgendwie nicht mehr zu finden?), dass der SOC-Wert noch nicht korrekt ist. Hst du das schon hinbekommen?

Was genau muss ich bei dem Adapter/Kabel beachten?

Antworten