Wenn dies dein erster Besuch hier ist, lies bitte zuerst die Hilfe - Häufig gestellte Fragen durch. Du musst dich vermutlich registrieren, bevor du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um den Registrierungsprozess zu starten. Du kannst auch jetzt schon Beiträge lesen. Suche dir einfach das Forum aus, das dich am meisten interessiert.
Bei mir stimmt der Index 2 als 0% schon (200mm Wasserhöhe), weil bei mir bedingt durch die Pumpenansaugung (Schlauch mit schwimmenden Ball) immer min. ca. 20cm in der Zisterne stehen bleiben.
Ich kann das darunter ja nicht verwenden, somit sind bei mir die 0% wenn die Zisterne noch 200mm Wasserhöhe hat.
Schon klar, aber oben im Code sagst du ja
Code:
// 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
Und wenn man den Codeschnipsel übernimmt, dann kann das (wie bei mir) eben falsch sein, weil bei mir ist percent_0_index = 1 ;-)
...
Dabei ist aufgefallen, dass wahrscheinlich bei dieser Zeile:
die 2 ersetzt werden muss mit percent_0_index.
...
Bei mir stimmt der Index 2 als 0% schon (200mm Wasserhöhe), weil bei mir bedingt durch die Pumpenansaugung (Schlauch mit schwimmenden Ball) immer min. ca. 20cm in der Zisterne stehen bleiben.
Ich kann das darunter ja nicht verwenden, somit sind bei mir die 0% wenn die Zisterne noch 200mm Wasserhöhe hat.
Den original Code. Weiter hatte ich den thread gar nicht gelesen gehabt 😉 einen Durchschnitt zu bilden halte ich bei meiner Sonde für nicht nötig. Der ausgegebene Wert ist meist gleich. Ich lasse ihn mir alle Stunde über ntfy auf mein Handy drücken. Ab und an (selten) schwankt der Wert.
Wenn die Sonde "die Wassersäule" misst, wie du es beschreibst, dann meinst du vermutlich eine Sonde, die einen Differenzdruck misst. Also den Unterschied zwischen dem Wasserdruck an ihrem Einbauort und dem Luftdruck der freien Umgebung. Dann kann die Sonde prinzipbedingt nur alles Wasser messen, das sich über ihr befindet. Also in dem Fall auch bis in den Dom hinein.
Wenn die Sonde bspw. mit Ultraschall den Wasserspiegel vermisst, dann hängt die Sonde bzw. der Messkopf oberhalb des Wassers und misst die Entfernung bis zur Wasseroberfläche. So eine Sonde misst prinzipbedingt alles Wasser, das sich unter ihr befindet. In diesem Fall also nicht bis in den Dom hinein.
In den meisten Fällen scheinen hier Sonden eingesetzt zu werden, die den Wasserdruck messen und deshalb relativ nah am Boden des Tank installiert werden.
ich habe den Code mit angepasster Litering-Table übernommen, allerdings jeden Schritt nachvollzogen, da ich auch mehr Werte in der Litering-Table habe und eine Sonde von 0-5m. Ich habe von meinem Hersteller einen Graph bekommen und deswegen habe ich um die nichtlinearen Phasen mehr Punkte angegeben. Ansonsten funktioniert der Code relativ gut. Vielen Dank dafür.
Dabei ist aufgefallen, dass wahrscheinlich bei dieser Zeile:
Bei mir hat in meinem NodeRed auch das toFixed(0) statement nicht funktioniert. Deshalb hab ich das weggelassen und mit folgender Zeile umgeschrieben: percent = Math.round(percent * 10) / 10;
Vielleicht hilft es dem ein oder anderen.
Nur mal eine Verständnisfrage: die Sonde misst die Wassersäule, richtig? Ich stelle mir nur vor, wenn die Sonde unter dem Dom liegt und Wasser im Dom stehen würde, würde dann die Sonde dann trotzdem die Höhe der Wassersäule richtig ausgeben, also bis in den Dom hinein?
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.
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
}
Ich kann leider mit der Berechnung nichts anfangen, das ist mir zu hoch. Aber ggf. kann jemand anderes das mal bewerten oder es hilft.
Techi...
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?
Ja, hab ich eventuell.
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.
Wir verarbeiten personenbezogene Daten über die Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen. Weitere Informationen findest Du in unserer Datenschutzerklärung.
Indem Du unten auf "ICH stimme zu" klickst, stimmst Du unserer Datenschutzerklärung und unseren persönlichen Datenverarbeitungs- und Cookie-Praktiken zu, wie darin beschrieben. Du erkennst außerdem an, dass dieses Forum möglicherweise außerhalb Deines Landes gehostet wird und bist damit einverstanden, dass Deine Daten in dem Land, in dem dieses Forum gehostet wird, gesammelt, gespeichert und verarbeitet werden.
Einen Kommentar schreiben: