Hallo zusammen,
hier habe ich vor über zwei Jahren ein Plugin für das Wiregate veröffentlicht, um einen Resol Solarregler anzubinden. Ein Problem des Plugins ist, daß der Solarregler den Status nur von sich aus sendet und nicht auf Anfrage. Daher muß das Plugin auf ein eingehendes Paket warten und blockiert in der Zeit (AFAIR bis zu 2sec) alle anderen Aktionen/Plugins des Wiregated (soweit ich das verstanden habe).
Mir kam die Idee, daß ein Arduino hilfreich sein könnte: eingehende Pakte werden zwischengespeichert und auf Anforderung dekodiert und als Klartext geschickt.Damit kann die Lösung überall leicht eingesetzt werden. Egal welcher Computer oder welche Programmiersprache (solange USB vorhanden ist und der Arduino als COM-Port erkannt wird).
Es reicht ein simpler Arduino Nano. Durch seine Stiftleisten kann er auch auf Steckbretter gesetzt werden.
WICHTIG: wer sich einen günstigen Nachbau des Nano kaufen will, sollte darauf achten, daß ein FTDI-Chip drauf ist. Viele Nachbauten bei Ebay haben z.B. einen CH340 drauf. So weit ich mich erinnere kann es damit zu Problemen kommen (speziell unter Linux). Die Information mag veraltet oder gar falsch sein, aber FTDI ist mit Sicherheit die problemlosere Variante.
Wer nicht gerade den gleichen Solarregler wie ich besitzt, muß im Code noch einiges anpassen:
vbus_metercount: Anzahl der Werte. Muß unbedingt mit der Anzahl der Einträge der nächsten beiden Arrays entsprechen.
vbus_text: beliebiger Text, der dem jeweiligem Wert vorangestellt wird. Z.B.: "KOL" für die Kollektor Temperatur: KOL:62.5
vbus_meters: siehe anderes Posting zum Ermitteln der Daten aus der entsprechenden XML-Datei. Achtung: im XML ist ein "factor", hier muß aber ein Divisor angegeben werden. Wenn der factor 0.1 ist, ist der "Divider" 10.
vbus_source: die Adresse des Solarreglers. Pakete mit einer anderen Adresse werden verworfen! Siehe ersten Link.
vbus_buffersize: Größe der eingehenden Pakete. Ich weiß leider nicht mehr, woher ich den Wert habe und ob der sich ändern kann... Im Zweifellsfall vorher mit einem Terminalprogramm ermitteln.
Der Arduino kann als Schnittstelle für das "Resol Servicecenter" dienen. Dafür muß er zuerst in den Bridge-Modus gebracht werden:
Beliebiges Terminalprogramm (z.B. HTerm) öffnen und 115200,8n1 einstellen und die Verbindung öffnen. Danach ein einzelnes "b" senden. Der Arduino ändert die Geschwindigkeit auf 9600. Nach Disconnect, anpassen auf 9600 und wieder verbinden sollten einzelne Daten kommen. In HTerm kann man "HEX" zum besseren Ablesen der Pakete aktivieren. Unter "Tools\Modify newline at..." fügt man einen neuen Eintrag hinzu: "Line end marker": HEX AA
Diesen wählt man bei "Newline at" aus. Damit erhält man einen Zeilenumbruch bei jedem neuen Paket (diese beginnen mit 0xAA).
Jetzt HTerm schließen und das Resol Servicecenter starten. Damit sollte sich jetzt eine Verbindung zum Solarregler aufbauen lassen.
Der Arduino kann nur durch einen Reset wieder in den normalen Betrieb zurückgeholt werden.
Im Normalbetrieb sammelt der Arduino eingehende Daten und immer wenn ein Paket vollständig ist, wird dieses zwischengespeichert. es erfolgt keine selbstständige Ausgabe. Durch senden eines einzlenen "s" wird das letzte valide Paket analysiert und die Werte ausgegeben. Z.B. "KOL:7.50 TSP:27.80 ZUL:30.90 RUE:888.80 PDZ:0 PBS:8331 ERR:0 SKL:0 STS:0 SZU:0 SRU:0 STA:0 AGE:229340"
Mein Kollektor (KOL) hat gerade 7,5°C und der Pufferspeicher (TSP) 27,8°C. Der Eintrag AGE gibt das Alter des Pakets in Microsekunden aus.
Die Werte sind TAB-getrennt und lassen sich damit schön zerlegen.
Durch den FTDI-Chip wird der Nano vom Wiregate sofort erkannt und eingerichtet. Ein passendes Plugin gibt es natürlich auch. Weil der Arduino die ganze Arbeit macht und das Plugin nicht warten muß bis ein Paket ankommt, benötigt das Plugin weniger als 100msec.
In der Resol_Arduino.conf müssen die gleichen Einträge wie bei vbus_text stehen.
Mehr fällt mir erstmal nicht ein.
Das war mein erstes Arduinoprojekt und mein erstes C++-Programm. Also bitte ich um ein bisschen Nachsicht, falls etwas nicht so elegant gelöst wurde.
Wenn es Fragen gibt: stellen :-)
VBus.zip
hier habe ich vor über zwei Jahren ein Plugin für das Wiregate veröffentlicht, um einen Resol Solarregler anzubinden. Ein Problem des Plugins ist, daß der Solarregler den Status nur von sich aus sendet und nicht auf Anfrage. Daher muß das Plugin auf ein eingehendes Paket warten und blockiert in der Zeit (AFAIR bis zu 2sec) alle anderen Aktionen/Plugins des Wiregated (soweit ich das verstanden habe).
Mir kam die Idee, daß ein Arduino hilfreich sein könnte: eingehende Pakte werden zwischengespeichert und auf Anforderung dekodiert und als Klartext geschickt.Damit kann die Lösung überall leicht eingesetzt werden. Egal welcher Computer oder welche Programmiersprache (solange USB vorhanden ist und der Arduino als COM-Port erkannt wird).
Es reicht ein simpler Arduino Nano. Durch seine Stiftleisten kann er auch auf Steckbretter gesetzt werden.
WICHTIG: wer sich einen günstigen Nachbau des Nano kaufen will, sollte darauf achten, daß ein FTDI-Chip drauf ist. Viele Nachbauten bei Ebay haben z.B. einen CH340 drauf. So weit ich mich erinnere kann es damit zu Problemen kommen (speziell unter Linux). Die Information mag veraltet oder gar falsch sein, aber FTDI ist mit Sicherheit die problemlosere Variante.
- Der Adapter von VBus zu TTL aus dem verlinktem Thread wird immer noch benötigt
- Ich habe den Nano auf so ein winziges 170 Pin Steckbrett gesteckt.
- Zumindest unter Perl wird beim Öffnen der seriellen Schnittstelle ein Reset des Arduinos ausgelöst. Ungeschickt wenn man eigentlich das letzte empfangene Paket abholen will. Die Lösung ist ein mindestes 10µF großer Kondensator zwischen GND und RST. Freundlicherweise sind die beiden Pins am Nano direkt nebeneinander und ein Elko mit 2,54mm Rastermaß paßt direkt. Es gibt wohl auch Möglichkeiten das im (Perl-)Skript zu lösen, aber der Elko ist IMHO die intelligentere Lösung, da er immer funktioniert (egal wer oder was die serielle Verbindung aufbaut).
WICHTIG: mit dem Elko läßt sich der Nano nicht mehr über USB programmieren. Der Reset wird genutzt, um den Bootloader zu starten. Auf dem Steckbrett kann man den Elko einfach entfernen. Wenn man den Nano aber auf eine andere Platine stecken möchte, sollte man eine Trennmöglichkeit vorsehen (Jumper). - Der Arduino wird per USB mit Strom versorgt und liefert an einem Pin 5V mit denen man die Konverter aus dem ersten Link versorgen kann. Und natürlich GND an GND
- Der Nano hat nur eine serielle Schnittstelle, welche am USB-Port zur Verfügung steht. Zum Glück gibt es mit "SoftwareSerial" eine Library, welche einen UART an I/O-Pins abbildet. Der Soalrregler kommuniziert nur mit 9600bit/s. Dafür reicht es dicke.
In Zeile 11 werden die Digtial-Pins definiert: SoftwareSerial VBusSerial(8, 11); // RX, TX */
In diesem Fall ist RX an D8 und TX an D11 (siehe Beschriftung auf der Platine). Damit muß D8/RX mit TX vom Konverter verbunden werden. D11/TX kann man in diesem Fall ignorieren, da keine Daten zum Solarregler geschickt werden sollen - Der beigefügte Code kann über die Arduino IDE in den Nano geladen werden. Einfach in das Fenster pasten und speichern. Im Tools-Menü muß noch Board, CPU und Port angepaßt werden (Arduino Nano, ATmega328. Unter Port sollte der Nano zu sehen sein)
Eventuell muß vorher noch die Library SoftwareSerial installiert werden: Menü Sketch\Include Library\Manage Libraries...
Wer nicht gerade den gleichen Solarregler wie ich besitzt, muß im Code noch einiges anpassen:
Code:
const byte vbus_metercount = 12; // Anzahl der zu analysierenden Werte // vbus_text: Array für die Bezeichnung der Werte const char* vbus_text[vbus_metercount] = { "KOL", // Temperatur Kollektor "TSP", // Temperatur Speicher "ZUL", // Temperatur Zulauf "RUE", // Temperatur Ruecklauf "PDZ", // Drehzahl Pumpe "PBS", // Betriebsstunden Pumpe "ERR", // ErrorMask "SKL", // Sensor Kollektor defekt "STS", // Sensor Speicher defekt "SZU", // Sensor Zufluss defekt "SRU", // Sensor Ruecklauf defekt "STA" }; // Statusmask // Offset, bitsize, bitpos, Divider, signed const int vbus_meters[vbus_metercount][5] = { { 0, 15, -1, 10, 1 }, { 2, 15, -1, 10, 1 }, { 4, 15, -1, 10, 1 }, { 6, 15, -1, 10, 1 }, { 8, 8, -1, 0, 0 }, { 10, 16, -1, 0, 0 }, { 20, 16, -1, 0, 0 }, { 20, 1, 0, 0, 0 }, { 20, 1, 1, 0, 0 }, { 20, 1, 2, 0, 0 }, { 20, 1, 3, 0, 0 }, { 24, 32, -1, 0, 0 } }; const unsigned int vbus_source = 0x427b; // ID of your own solar device const unsigned int vbus_buffersize = 64; // size in bytes of a valid packet
vbus_text: beliebiger Text, der dem jeweiligem Wert vorangestellt wird. Z.B.: "KOL" für die Kollektor Temperatur: KOL:62.5
vbus_meters: siehe anderes Posting zum Ermitteln der Daten aus der entsprechenden XML-Datei. Achtung: im XML ist ein "factor", hier muß aber ein Divisor angegeben werden. Wenn der factor 0.1 ist, ist der "Divider" 10.
vbus_source: die Adresse des Solarreglers. Pakete mit einer anderen Adresse werden verworfen! Siehe ersten Link.
vbus_buffersize: Größe der eingehenden Pakete. Ich weiß leider nicht mehr, woher ich den Wert habe und ob der sich ändern kann... Im Zweifellsfall vorher mit einem Terminalprogramm ermitteln.
Der Arduino kann als Schnittstelle für das "Resol Servicecenter" dienen. Dafür muß er zuerst in den Bridge-Modus gebracht werden:
Beliebiges Terminalprogramm (z.B. HTerm) öffnen und 115200,8n1 einstellen und die Verbindung öffnen. Danach ein einzelnes "b" senden. Der Arduino ändert die Geschwindigkeit auf 9600. Nach Disconnect, anpassen auf 9600 und wieder verbinden sollten einzelne Daten kommen. In HTerm kann man "HEX" zum besseren Ablesen der Pakete aktivieren. Unter "Tools\Modify newline at..." fügt man einen neuen Eintrag hinzu: "Line end marker": HEX AA
Diesen wählt man bei "Newline at" aus. Damit erhält man einen Zeilenumbruch bei jedem neuen Paket (diese beginnen mit 0xAA).
Jetzt HTerm schließen und das Resol Servicecenter starten. Damit sollte sich jetzt eine Verbindung zum Solarregler aufbauen lassen.
Der Arduino kann nur durch einen Reset wieder in den normalen Betrieb zurückgeholt werden.
Im Normalbetrieb sammelt der Arduino eingehende Daten und immer wenn ein Paket vollständig ist, wird dieses zwischengespeichert. es erfolgt keine selbstständige Ausgabe. Durch senden eines einzlenen "s" wird das letzte valide Paket analysiert und die Werte ausgegeben. Z.B. "KOL:7.50 TSP:27.80 ZUL:30.90 RUE:888.80 PDZ:0 PBS:8331 ERR:0 SKL:0 STS:0 SZU:0 SRU:0 STA:0 AGE:229340"
Mein Kollektor (KOL) hat gerade 7,5°C und der Pufferspeicher (TSP) 27,8°C. Der Eintrag AGE gibt das Alter des Pakets in Microsekunden aus.
Die Werte sind TAB-getrennt und lassen sich damit schön zerlegen.
Durch den FTDI-Chip wird der Nano vom Wiregate sofort erkannt und eingerichtet. Ein passendes Plugin gibt es natürlich auch. Weil der Arduino die ganze Arbeit macht und das Plugin nicht warten muß bis ein Paket ankommt, benötigt das Plugin weniger als 100msec.
Code:
2016-05-16 01:03:31.206,Resol_Arduino, reading conf file [/etc/wiregate/plugin/generic/conf.d/Resol_Arduino.conf]. 2016-05-16 01:03:31.210,Resol_Arduino,conf file [/etc/wiregate/plugin/generic/conf.d/Resol_Arduino.conf] returned result[28] 2016-05-16 01:03:31.222,Resol_Arduino,Serielle Schnittstelle erfolgreich geöffnet: '/dev/usbserial-1-4.5' 2016-05-16 01:03:31.232,Resol_Arduino,'Return' received 2016-05-16 01:03:31.233,Resol_Arduino,Time needed: 0.028102 2016-05-16 01:03:31.233,Resol_Arduino,Answer: 'KOL:7.50 TSP:27.80 ZUL:30.90 RUE:888.80 PDZ:0 PBS:8331 ERR:0 SKL:0 STS:0 SZU:0 SRU:0 STA:0 AGE:229340' 2016-05-16 01:03:31.233,Resol_Arduino,Temperatur Kollektor: 7.50°C 2016-05-16 01:03:31.242,Resol_Arduino,Temperatur Speicher: 27.80°C 2016-05-16 01:03:31.246,Resol_Arduino,Temperatur Vorlauf: 30.90°C 2016-05-16 01:03:31.251,Resol_Arduino,Temperatur Sensor 4: 888.80°C 2016-05-16 01:03:31.256,Resol_Arduino,Drehzahl Pumpe: 0% 2016-05-16 01:03:31.260,Resol_Arduino,Betriebsstunden Pumpe: 8331h 2016-05-16 01:03:31.266,Resol_Arduino,ErrorMask: 0 2016-05-16 01:03:31.266,Resol_Arduino,Sensor Kollektor defekt: 0 2016-05-16 01:03:31.271,Resol_Arduino,Sensor Speicher defekt: 0 2016-05-16 01:03:31.278,Resol_Arduino,Sensor Zufluß defekt: 0 2016-05-16 01:03:31.283,Resol_Arduino,Sensor 4 defekt: 0 2016-05-16 01:03:31.290,Resol_Arduino,Statusmaske: 0 2016-05-16 01:03:31.290,Resol_Arduino,Alter: 229340µs 2016-05-16 01:03:31.290,Resol_Arduino,Time needed: 0.086042 2016-05-16 01:03:31.297,Resol_Arduino,1,0s,
Code:
%values = ( [B]KOL[/B] => { Name_en=>'Temperature sensor 1' , Name_de=>'Temperatur Kollektor' , Unit=>'°C', GA=>'3/7/0' , DPT=>'9.001' }, [B]TSP[/B] => { Name_en=>'Temperature sensor 2' , Name_de=>'Temperatur Speicher' , Unit=>'°C', GA=>'3/7/1' , DPT=>'9.001' }, ....... );
Mehr fällt mir erstmal nicht ein.
Das war mein erstes Arduinoprojekt und mein erstes C++-Programm. Also bitte ich um ein bisschen Nachsicht, falls etwas nicht so elegant gelöst wurde.
Wenn es Fragen gibt: stellen :-)
VBus.zip
Kommentar