@AlCalzone
Es ist vollbracht 👍
es Funktioniert DANKE!!!!! Ein besonderes Dankeschön an @AlCalzone!
Hier das Fertige Skript für alle Paradigma Nutzer die sich über folgenden Link einen Adapter gelötet haben.
Seite mit Bauanleitung:
createState("Paradigma_Kollektor");
createState("Paradigma_Speichertemperatur");
createState("Paradigma_Solarvorlauf");
createState("Paradigma_Aussentemperatur");
createState("Paradigma_Solarrücklauf");
createState("Paradigma_Durchfluss");
createState("Paradigma_PWMPumpe");
createState("Paradigma_Tagesleistung");
createState("Paradigma_Gesamtleistung");
createState("Paradigma_Status");
createState("Paradigma_StatusText");
createState("Paradigma_Fehlercode");
createState("Paradigma_FehlercodeText");
const { Transform } = require("stream");
class PreambleParser extends Transform {
/**
* @param {Buffer} preamble
* @param {number} payloadLength
*/
constructor(preamble, payloadLength) {
super();
this.receiveBuffer = Buffer.allocUnsafe(0);
this.preamble = preamble;
this.payloadLength = payloadLength;
}
_transform(chunk, encoding, callback) {
this.receiveBuffer = Buffer.concat([this.receiveBuffer, chunk]);
while (this.receiveBuffer.length >= this.preamble.length) {
// Check if the buffer starts with the preamble
const preambleIndex = this.receiveBuffer.indexOf(this.preamble);
if (preambleIndex === -1) {
// not found, wait for the next chunk
break;
}
// Skip bytes before the preamble
this.receiveBuffer = skipBytes(this.receiveBuffer, preambleIndex);
// Check if we still have enough data
if (
this.receiveBuffer.length >=
this.preamble.length + this.payloadLength
) {
// Yes, emit it
this.push(
this.receiveBuffer.slice(
this.preamble.length,
this.preamble.length + this.payloadLength
)
);
// And skip the bytes
this.receiveBuffer = skipBytes(
this.receiveBuffer,
this.preamble.length + this.payloadLength
);
} else {
// no, wait until we do
break;
}
}
callback();
}
}
/** Skips the first n bytes of a buffer and returns the rest */
function skipBytes(buf, n) {
return Buffer.from(buf.slice(n));
}
// ---
const parser = new PreambleParser(
Buffer.from("fc3e2401", "hex"), // Start der Datenpakete
38 // Wie viele Bytes nach dem Start ausgewertet werden
);
parser.on("data", (chunk) => {
if (Date.now() - lastCheck < 30000) return;
lastCheck = Date.now();
//console.log(chunk.toString("hex"));
val = chunk.readUInt16LE(0) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Kollektor', val /10, true);
val = chunk.readUInt16LE(2) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Speichertemperatur', val /10, true);
val = chunk.readUInt16LE(4) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Solarvorlauf', val /10, true);
val = chunk.readInt16LE(6) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Aussentemperatur', val /10, true);
val = chunk.readUInt16LE(10) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Solarrücklauf', val /10, true);
val = chunk.readUInt16LE(12) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Durchfluss', val /10, true);
val = chunk.readUInt8(14) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_PWMPumpe', val /10, true);
val = chunk.readUInt16LE(29) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Tagesleistung', val , true);
val = chunk.readUInt16LE(32) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Gesamtleistung', val , true);
val = chunk.readUInt8(17) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Status', val, true);
switch(val) {
case 0:
setState('Paradigma_StatusText', 'Warten auf Sonne', true);
break;
case 1:
setState('Paradigma_StatusText', 'Frostschutz', true);
break;
case 2:
setState('Paradigma_StatusText', 'Anschieben', true);
break;
case 3:
setState('Paradigma_StatusText', 'Einschaltverzögerung', true);
break;
case 4:
setState('Paradigma_StatusText', 'erwärmt Speicher', true);
break;
case 5:
setState('Paradigma_StatusText', 'Speicher voll', true);
break;
case 6:
setState('Paradigma_StatusText', 'Kollektor überhitzt', true);
break;
case 7:
setState('Paradigma_StatusText', 'Hand, Test oder Aus', true);
break;
case 8:
setState('Paradigma_StatusText', 'Messung', true);
break;
default:
setState('Paradigma_StatusText', val, true);
}
val = chunk.readUInt8(18) // liest eine 2-byte-Zahl ab Position 0 ohne Bytes zu tauschen
setState('Paradigma_Fehlercode', val, true);
switch(val) {
case 0:
setState('Paradigma_FehlercodeText', 'OK', true);
break;
case 1:
setState('Paradigma_FehlercodeText', 'Kein Volumenstrom', true);
break;
case 2:
setState('Paradigma_FehlercodeText', 'Luft in der Anlage', true);
break;
case 4:
setState('Paradigma_FehlercodeText', 'Vor- u. Rücklauf vertauscht', true);
break;
case 5:
setState('Paradigma_FehlercodeText', 'Zonenventil defekt', true);
break;
case 6:
setState('Paradigma_FehlercodeText', 'Falsche Uhrzeit', true);
break;
case 7:
setState('Paradigma_FehlercodeText', 'Druckabfall in der Anlage', true);
break;
case 9:
setState('Paradigma_FehlercodeText', 'Falsche Hydraulik', true);
break;
case 10:
setState('Paradigma_FehlercodeText', 'Rohrisolierung', true);
break;
case 11:
setState('Paradigma_FehlercodeText', 'Stromversorgung n. konstant', true);
break;
case 12:
setState('Paradigma_FehlercodeText', 'OLV defekt', true);
break;
case 13:
setState('Paradigma_FehlercodeText', 'Zu wenig Volumenstrom', true);
break;
case 14:
setState('Paradigma_FehlercodeText', 'Speicher unterkühlt durch Frostschutz', true);
break;
case 20:
setState('Paradigma_FehlercodeText', 'Fühler Außentemperatur falsch montiert', true);
break;
case 21:
setState('Paradigma_FehlercodeText', 'Ausfall Kollektorfühler', true);
break;
case 22:
setState('Paradigma_FehlercodeText', 'Ausfall Fühler Solarrücklauf', true);
break;
case 23:
setState('Paradigma_FehlercodeText', 'Störung Kollektrofühler', true);
break;
case 24:
setState('Paradigma_FehlercodeText', 'Frostschutz', true);
break;
case 25:
setState('Paradigma_FehlercodeText', 'Fühler TSA u. TAM vertauscht', true);
break;
case 26:
setState('Paradigma_FehlercodeText', 'Ausfall Fühler Solarvorlauf', true);
break;
case 27:
setState('Paradigma_FehlercodeText', 'Ausfall Fühler Außentemperatur', true);
break;
case 34:
setState('Paradigma_FehlercodeText', 'Überhitzung Speicher 1', true);
break;
case 35:
setState('Paradigma_FehlercodeText', 'Überhitzung Speicher 2', true);
break;
case 49:
setState('Paradigma_FehlercodeText', 'Solarstation unterkühlt', true);
break;
case 50:
setState('Paradigma_FehlercodeText', 'Kollektor eingefroren', true);
break;
default:
setState('Paradigma_FehlercodeText', val, true);
}
});
let lastCheck = 0; // 0 sorgt dafür, dass gleich zu Beginn einmal ausgelesen wird
const SerialPort = require('serialport');
// Port öffnen
const port = new SerialPort('/dev/ttyUSB0');
port.pipe(parser);
// Port bei Skriptende schließen:
onStop(() => {
port.close();
});