Das mit Splines zu machen gefällt mir auch gut.
Toll das auch mal andere Ideen dazu kommen.
Ankündigung
Einklappen
Keine Ankündigung bisher.
Füllstandsmessung Tank (Zisterne) (gerne auf KNX)
Einklappen
X
-
Ah prima. Danke. den hatte ich nicht mehr in Erinnerung. Funktioniert nun prima. Ich habe von Graf die 4800l Zisterne. Auch Unförmig. Meine Arbeitskollegin hat dein Script überarbeitet und die Berechnung der geraden umgebaut.
Ich kann leider mit der Berechnung nichts anfangen, das ist mir zu hoch. Aber ggf. kann jemand anderes das mal bewerten oder es hilft.Code:// zistern litering table (got from manufacturer GRAF) // first column = fillheight in mm // second column = liter const literingTable = [ [0, 0], [100, 135], [200, 320], [300, 550], [400, 825], [500, 1120], [600, 1450], [700, 1800], [800, 2160], [900, 2530], [1000, 2895], [1100, 3245], [1200, 3580], [1300, 3885], [1400, 4160], [1500, 4430], [1600, 4585], [1700, 4720], [1800, 4780], ]; //var msg; var msg2; var msg3; var msg4; // pressure Sensor parameters const max_height = 4; // 4m const max_mA = 20; // mA at max_height const min_mA = 4; // mA at zero height // index to table for lowest level in zistern where water // can still be pumped. Below pump cant reach the water const percent_0_index = 2 // eg, 2 is 976l //const lowest_level_Tindex = 2; // Main starts here var y; var measured_mA = msg.payload; // get mA value from Sensor as input var measured_mA_mean; measured_mA_mean = context.get('measured_mA_mean'); if (context.get('Startup') == 341487) { context.set("Startup", 0) measured_mA_mean = measured_mA; } measured_mA_mean = (measured_mA_mean * 2 + measured_mA) / 3; context.set('measured_mA_mean', measured_mA_mean); if (measured_mA < min_mA) { // if its below allowed range, then exit node.warn("Error ! Input Value below 4mA") return; } // both possible: measured_mA_mean or measured_mA spline(measured_mA_mean) // calculates based on linear relationship. alternative below var high_mm = (max_height * 1000 / (max_mA - min_mA) * (measured_mA_mean - min_mA)); //var x = Math.round(high_mm); var x = high_mm; //search for fitting table area, getting index into table as i for (var i = 0; i < literingTable.length; i++) { if (literingTable[i][0] > x) break; // if "end entry" found, then exit } i = i - 1; // correct index to "start entry" // check if index was inside table and not the last entry if (i < literingTable.length - 1) { // was inside table // get values from table var x1 = literingTable[i + 0][0]; var y1 = literingTable[i + 0][1]; var x2 = literingTable[i + 1][0]; var y2 = literingTable[i + 1][1]; // and calculate the value in between = lineare interpolation y = (y1 + ((x - x1) / (x2 - x1) * (y2 - y1))); } else { // was the last entry, // so return last entry as fixe value from table // no calcuation needed y = literingTable[i + 0][1] } // calculate percentage from table index 2 as 0% to last table index as 100% var percent = 100 / (literingTable[literingTable.length - 1][1] - literingTable[percent_0_index][1]); percent = Math.round(((percent * (y - literingTable[percent_0_index][1])) * 1) * 1e0) / 1e0; if (percent < 0) { percent = -1; } y = Math.round(y); msg.payload = [ [ // first value { // influxdb2 fields "menge": y }, { // influxdb2 tags "typ": "inhalt", "einheit": "liter", "quelle": "drucksensor", "ort": "zisterne" } ], [ // second value { // influxdb2 fields "menge": percent }, { // influxdb2 tags "typ": "inhalt", "einheit": "prozent", "quelle": "drucksensor", "ort": "zisterne" } ] ]; return [msg]; /** * alternative function for hillheight (y) und fillvolume (x) using spline. * @param {float} pressure sensor input or 'cleaned' sensor input using measured_mA_mean */ function spline(pressure) { // normalized needed for spline interpolation const normalized_pressure = (pressure - min_mA) / (max_mA - min_mA); // spline interpolation for x: var interval = -1; // Initialize with an invalid value for (var i = 0; i < literingTable.length - 1; i++) { if (normalized_pressure >= literingTable[i][0] && normalized_pressure <= literingTable[i + 1][0]) { interval = i; break; // if "end entry" found, then exit } } // Errorhandling if (interval === -1) { interval = normalized_pressure < literingTable[0][0] ? 0 : literingTable.length - 2; } // find value between two entries const x1 = literingTable[interval][0]; const y1 = literingTable[interval][1]; const x2 = literingTable[interval + 1][0]; const y2 = literingTable[interval + 1][1]; //non-linear interpolation const t = (normalized_pressure - x1) / (x2 - x1); const a = 2 * y1 - 2 * y2 + 1; const b = -3 * y1 + 3 * y2; const c = y1; // fill height in mm var y = a * Math.pow(t, 3) + b * Math.pow(t, 2) + c * t; // fill volume (1800 based on max_fillheight) in mm var x = (Math.PI * y^2 * (3* (1800/2) - y)) / 3; // return what you need. return y; // or x }
Einen Kommentar schreiben:
-
In NodeRed kann man in einem function-node in Reiter „Start“ Code hinterlegen der nur einmalig beim Start ausgeführt wird.
Einen Kommentar schreiben:
-
Super - vielen Dank! Das war esZitat von TheOlli Beitrag anzeigenNetzteil + auf Sensor rot
Sensor schwarz auf AOI +
Netzteil - auf AOI -
Einen Kommentar schreiben:
-
StefanWE
Ja, hab ich eventuell.Zitat von StefanWE Beitrag anzeigenTechi...
Ich bekomme derzeit 10,46mA geliefert. Dabei ist die Zisterne voll. Aber egal ob ich 10, 10.5 , 15 oder 20 mA als max Full eintrage, ich bekomme immer die Werte 100% 3780l geliefert. Das kann ja nicht sein.
Hast du eine Idee, woran es liegen könnte?
Ist mein Fehler 😔, ich hatte in meinem Post mit dem Code noch vergessen den Programmcode für den Start mit anzugeben.
Ich hab das gerade noch ergänzt.
Sind nur ein paar Zeilen die in der Funktion Node in der Sektion "Start" noch drin sein müssen.
Zuletzt geändert von Techi; 20.08.2023, 07:04.
Einen Kommentar schreiben:
-
Netzteil + auf Sensor rot
Sensor schwarz auf AOI +
Netzteil - auf AOI -
- Likes 1
Einen Kommentar schreiben:
-
Klingt falsch,Zitat von Spikey Beitrag anzeigenFühler rot auf + des AOI
Fühler schwarz auf - des Meanwall 24V
Brücke auf - des AOI und + des Meanwell
schau mal hier:
https://knx-user-forum.de/forum/öffe...48#post1776248
Einen Kommentar schreiben:
-
Fühler rot auf + des AOI
Fühler schwarz auf - des Meanwall 24V
Brücke auf - des AOI und + des Meanwell
Einen Kommentar schreiben:
-
Ohne eine Skizze wie es angeschlossen ist, wird keiner helfen können!Zitat von Spikey Beitrag anzeigenHabt ihr Ideen, was falsch ist? Wenn ihr mehr Infos braucht, nur Bescheid sagen.
VG Spikey
Einen Kommentar schreiben:
-
Hallo zusammen,
ich habe heute auch eine Zisternenüberwachung gebastelt...aber es funktioniert nicht. Mache ich einen Denkfehler?
Ein 4-20mA Sensor hängt in der Zisterne, dazu ein Meanwell 24V Netzteil als REG. Diese hängen zusammen am MDT AOI-0410V.... Das Abfrageergebnis soll dann in eine GA mit 5.001 % geschrieben werden....der Wert ist und bleibt aber konstant null, die Zisterne ist halb voll....
Habt ihr Ideen, was falsch ist? Wenn ihr mehr Infos braucht, nur Bescheid sagen.
VG Spikey
Einen Kommentar schreiben:
-
Techi Danke für dein Script. Ich habe nun auch die Ausliterung meiner Zisterne erhalten. Allerdings bringt mir das Script immer 100%, egal welche Werte ich eintrage.
Ich bekomme derzeit 10,46mA geliefert. Dabei ist die Zisterne voll. Aber egal ob ich 10, 10.5 , 15 oder 20 mA als max Full eintrage, ich bekomme immer die Werte 100% 3780l geliefert. Das kann ja nicht sein.Code:// zistern litering table (got from manufacturer GRAF) // first column = fillheight in mm // second column = liter const literingTable = [ [0, 0], [100, 135], [200, 320], [300, 550], [400, 825], [500, 1120], [600, 1450], [700, 1800], [800, 2160], [900, 2530], [1000, 2895], [1100, 3245], [1200, 3580], [1300, 3885], [1400, 4160], [1500, 4430], [1600, 4585], [1700, 4720], [1800, 4780], ]; //var msg; var msg2; var msg3; var msg4; // pressure Sensor parameters const max_height = 4; // 4m const max_mA = 20; // mA at max_height const min_mA = 4; // mA at zero height // index to table for lowest level in zistern where water // can still be pumped. Below pump cant reach the water const percent_0_index = 2 // eg, 2 is 976l //const lowest_level_Tindex = 2; // Main starts here var y; var measured_mA = msg.payload; // get mA value from Sensor as input var measured_mA_mean; measured_mA_mean = context.get('measured_mA_mean'); if (context.get('Startup') == 341487) { context.set("Startup", 0) measured_mA_mean = measured_mA; } measured_mA_mean = (measured_mA_mean * 2 + measured_mA) / 3; context.set('measured_mA_mean', measured_mA_mean); if (measured_mA < min_mA) { // if its below allowed range, then exit node.warn("Error ! Input Value below 4mA") return; } var high_mm = (max_height * 1000 / (max_mA - min_mA) * (measured_mA_mean - min_mA)); //var x = Math.round(high_mm); var x = high_mm; //search for fitting table area, getting index into table as i for (var i = 0; i < literingTable.length; i++) { if (literingTable[i][0] > x) break; // if "end entry" found, then exit } i = i - 1; // correct index to "start entry" // check if index was inside table and not the last entry if (i < literingTable.length - 1) { // was inside table // get values from table var x1 = literingTable[i + 0][0]; var y1 = literingTable[i + 0][1]; var x2 = literingTable[i + 1][0]; var y2 = literingTable[i + 1][1]; // and calculate the value in between y = (y1 + ((x - x1) / (x2 - x1) * (y2 - y1))); } else { // was the last entry, // so return last entry as fixe value from table // no calcuation needed y = literingTable[i + 0][1] } // calculate percentage from table index 2 as 0% to last table index as 100% var percent = 100 / (literingTable[literingTable.length - 1][1] - literingTable[percent_0_index][1]); percent = Math.round(((percent * (y - literingTable[percent_0_index][1])) * 1) * 1e0) / 1e0; if (percent < 0) { percent = -1; } y = Math.round(y); msg.payload = [ [ // first value { // influxdb2 fields "menge": y }, { // influxdb2 tags "typ": "inhalt", "einheit": "liter", "quelle": "drucksensor", "ort": "zisterne" } ], [ // second value { // influxdb2 fields "menge": percent }, { // influxdb2 tags "typ": "inhalt", "einheit": "prozent", "quelle": "drucksensor", "ort": "zisterne" } ] ]; return [msg];
Hast du eine Idee, woran es liegen könnte?
Einen Kommentar schreiben:
-
Ah verstehe. Ich dachte, das bezog sich auf die Leitung. Habe die Sonde mit Signalausgang 0-4m genommen. Dann sind 20mA eben 4m.
mh da wäre bei mir der 0-2m besser gewesen. Naja ich bin froh, wenn ich halbwegs den Füllstand bekomme.
Einen Kommentar schreiben:


Einen Kommentar schreiben: