NEWS
[gelöst]Serielle Schnittstelle auslesen Heizölfüllstand Leveljet
-
Vielleicht kann mir mal jemand auf die Sprünge helfen. Ich möchte über die serielle Schnittstelle ttyUSB0 die Werte meiner Heizöl-Füllstandsanzeige Leveljet auslesen. Über ein Javascript, was ich mir von hier irgendwo kopiert habe, konnte ich feststellen, dass die Schnittstelle die richtigen Daten liefert (es sind nur 12 Byte, die jede Sekunde ausgegeben werden).
Das script habe ich wieder gelöscht (war vielleicht ein Fehler), und versuche nun, über modbus das Ganze zu machen. Allerdings weiß ich nun gar nicht, wo ich was eintragen soll (K.A., warum das Bild hier dreimal kommt).
Meine Vermutung war, im Tab Eingangsregister die gelieferten Werte einzutragen:Das führt allerdings zu keinem Ergebnis, sondern:
Die Dokumentation zum modBus ist ja sehr rudimentär, ich hoffe , hier kann mir jemand weiterhelfen.
Oder wäre es vielleicht doch einfacher, das Ganze per Script zu machen?
Vor ein paar Wochen habe ich hier ein Script gesehen, wo man einfach ein paar seriell gelieferte Werte auswerten und in Datenpunkte schreiben kann, leider habe ich die Seite nicht gespeichert und jetzt finde ich es natürlich nicht mehr…..
-
Nehme im ersten Schritt mal den haken bei "Aliase benutzen" raus.
-
Hab ich probiert, immer noch "Wrong CRC for frame" und keine Werte.
-
Kannst du erstmal mit nur einem Wert versuchen und dann auch mal unter Eingangsregister?
Sind die Kommunikationseinstellungen im Adapter wirklich identisch zu deiner Füllstandsanzeige (welche überhaupt?) und stimmt "unsigned 16-bit" ?
Und du bist sicher das es mit Script über Modbus lief und nicht etwas anderes ausgelesen wurde?
Welche Adapter Version?
Serialport installiert?
-
Die Kommunikationseinstellungen sind 19200,N,8,1, so wie hier www.projet.de/Software/Leveljet_seriell.pdf beschrieben. Dort steht auch die Bedeutung der 12 Bytes.
Das script lief nicht über modbus, sondern über javascript, dieses hier:
! var SerialPort = require("serialport");
! var port = new SerialPort("/dev/ttyUSB0", {
! baudRate: 19200,
! xon: true,
! xoff: true,
! //flowControl: false
! //parser: SerialPort.parsers.byteDelimiter([2,4])
! platformOptions: {vmin: 0, vtime: 10, hupcl: false}
! },
! function (err) {
! if (err) {
! return console.log('Error: ', err.message);
! }
! // Flush input
! port.flush();
! });
! port.on('data', function (data) {
! console.log('Data: ' + data.toString('hex'));
! });
! port.on('open', function() {
! console.log('Connected');
! });
! port.on('error', function(err) {
! console.log('Error: ', err.message);
! });
! // close port if the script stopped (to be able to open it again)
! onStop(function (callback) {
! if (port && port.isOpen()) {
! port.close();
! console.log('port closed');
! }
! callback();
! });Mit dem Script hatte ich fortlaufend diese Werte auf der Schnittstelle:
javascript.0 script.js.common.Leveljet: Data: 00105d00300092002200da93
also genau die 12 Bytes:
0010 Gerätekennung
5d00 Distanz 0x005d=93
3000 Füllhöhe 0x0030=48
9200 Liter 0x0092=146
22 Prozent 0x22=34
00
da93
was den Werten auf der Anzeige entspricht.
modbus brint auch bei nur einem Wert im Eingangsregister nichts.
Wenn ich wüsste, wie man einzelne Bytes aus dem Datenblock rausnimmt und umrechnet und dann in einen Datenpunkt schreibt, würde ich das Ganze auch mit einem Script machen können (ohne modbus).
-
Dann kannst du den Modbus Adapter eh nicht nutzen. Scheinbar kann dein Device kein Modbus Protokoll sondern sendet einfach diesen String.
Du musst das "zerlegen" ist aber ein anderes Thema und hat mal mit Modbus so gar nichts zu tun.
Schau mal in einem von den beiden Threads findest du ein Script welches auch einen Datenstring zerlegt, das kannst du als Grundlage nehmen und anpassen.
-
OK, das war dann wohl ein Verständnisfehler von mir, ich hatte gedacht mit modbus kann man generell serielle Schnittstellen auslesen.
Mit dem folgenden Script funktioniert es auch, die Datenpunkte werden geschrieben.
! createState('Leveljet.Daten.Raw');
! createState('Leveljet.Daten.Distance');
! createState('Leveljet.Daten.Fillheight');
! createState('Leveljet.Daten.Volume');
! createState('Leveljet.Daten.Percent');
! createState('Leveljet.Daten.Status');
! // To use theByteLength
parser:
! const SerialPort = require('serialport');
! const ByteLength = SerialPort.parsers.ByteLength;
! const port = new SerialPort("/dev/ttyUSB0", {
! baudRate: 19200,
! dataBits : 8,
! parity : 'none',
! stopBits: 1
! // flowControl : false
! }, function (err) {
! if (err) {
! return console.log('Error1: ', err.message);
! }
! const parser = port.pipe(new ByteLength({ length: 12 }));
! parser.on('data', function (data) {
! console.log('Data received: ' + data.toString('hex'));
! //Rohdaten speichern
! var daten = data.toString('hex');
! setState('Leveljet.Daten.Raw', daten, true);
! //Distanz Lesekopf
! var distanz = parseInt(daten.substr(6,2) + daten.substr(4,2),16);
! setState('Leveljet.Daten.Distance',distanz,true);
! //Füllhöhe
! var fheight = parseInt(daten.substr(10,2) + daten.substr(8,2),16);
! setState('Leveljet.Daten.Fillheight',fheight,true);
! //Füllmenge, muss mit 10 multiplziert werden
! var fvol =10 * (parseInt(daten.substr(14,2) + daten.substr(12,2),16));
! setState('Leveljet.Daten.Volume',fvol,true);
! //Prozenzangabe Füllmenge, nur 1 Byte
! var pct = parseInt(daten.substr(16,2),16);
! setState('Leveljet.Daten.Percent',pct,true);
! //Status von 0-3 schreiben, zur optischen Anzeige in VIS
! var fstate = 0;
! if (pct > 40) {fstate = 3;} else
! if (pct > 25) {fstate = 2;} else
! if (pct > 10) {fstate = 1;} else
! fstate = 0;
! setState('Leveljet.Daten.Status',fstate,true);
! //Wenn ich hier nicht den Port schliesse, schreibt er jede Sekunde Datenpunkte, unnötig….
! port.close();
! return;
! });
! // Flush input
! port.flush();
! // send Data
! // port.close();
! });
! port.on('open', function() {
! console.log('Connected');
! });
! port.on('error', function(err) {
! console.log('Error2: ', err.message);
! // port.close();
! });
! // close port if the script stopped (to be able to open it again)
! onStop(function (callback) {
! if (port && port.isOpen) {
! port.close();
! console.log('port closed');
! }
! });Jetzt habe ich nur noch das Problem, dass, wenn ich den Port nach dem Einlesen nicht schließe, jede Sekunde Datenpunkte geschrieben werden, was völlig unnötig ist. Einmal am Tag würde reichen. Ein schedule an den Anfang zu stellen, hat nicht funktioniert, aber wahrscheinlich habe ich nur was falsch gemacht.
-
Ich starte das Script einmal am Tag und beende es über den dazugehörigen Datenpunkt Script.enabled.
Dadurch wird auch der com Port sauber geschlossen.
Gesendet von iPhone mit Tapatalk Pro
-
Das wars! Der Tipp mit script.enabled war der goldene Hinweis.
Nach dem Einlesen der Daten setze ich im script selber .enabled auf 'false', gestartet wird einmal täglich über einen Blockly Zeitplan.
Danke schön!
So sieht das ganze derzeit in VIS aus:
-
Gerne!
Bitte den Betreff vom ersten Post noch um ein````
GelöstGesendet von iPhone mit Tapatalk Pro
-
Hallo,
ich bin Newbie was ioBroker angeht.
Ich habe auch einen LevelJet jedoch für die Zisterne.
Jetzt wollt ich mal fragen wo ich das Script anlegen muss oder gibt es schon einen Adapter?
Ich möchte das er die Werte in eine Log schreibt, alle 4h Stunden damit man ein Diagramm erstellen kann.
Hab ihr da Ideen? Könnt ihr mir da helfen?
MfG
AcidSubway
-
Hi,
hast du den denn Javascript Adapter schon installiert auf dem System welches mit dem LevelJet verbunden ist?
Wenn ja musst du unter Javascript ein neues Script anlegen (nicht unter "Global"), einen Namen vergeben, es Speichern und bei bedarf starten.
Gruß