Userattribut Zisternenprojekt

Begonnen von huhu, 11 März 2020, 12:38:03

Vorheriges Thema - Nächstes Thema

huhu

Hallo zusammen,
ich verwende einen Ultraschallsensor um den Füllstand der Zisterne zu ermitteln. Hierbei wird die Entfernung zum Wasser gemessen und entsprechend in einem Userreading umgerechnet (Wasserstandshöhe sowie Liter). Soweit so gut, ist die Zisterne allerdings voll und der Abstand zum Sensor beträgt somit weniger als ~20cm, dann kriege ich falsche Werte (Sensorbedingt).

Meine Idee war, jeden neuen Wert (Distance) gegen den vorherigen Wert zu prüfen, weicht er um weniger als 10% ab, dann nehme den neuen Wert, ansonsten den Alten.

Ich hab es jetzt in etlichen Konstellationen versucht, ich kriege es einfach nicht hin... Weiß jemand wo mein Denkfehler liegt?


Bisher habe ich alle neuen Werte in das Userattrb level und liter geschrieben:
level {
my $lastlevel=ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","level",0);
my $level=150-((ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0))-30);
return $level unless($level >= 160);
return $lastlevel },

liter {
my $level=ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","level",0);
my $liter=47.47*($level);
use Math::Round qw/round/;
return $liter= Math::Round::nearest('10',$liter) }


Oben genannte Idee habe ich so versucht umzusetzen:
level {
my $lastlevel=ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","lastlevel",0);
my $level=150-((ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0))-30);
return $level unless($level <= $lastlevel*1.1);
return $lastlevel },

liter {
my $level=ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","level",0);
my $liter=47.47*($level);
use Math::Round qw/round/;
return $liter= Math::Round::nearest('10',$liter) },

lastlevel {
my $level=ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","level",0);
my $lastlevel=ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","lastlevel",0);
return $level unless($level <= $lastlevel*1.1);
return $lastlevel }


MadMax-FHEM

#1
Ich sehe nichts wo du irgendwas in Attribute schreibst, auch nicht wo du in Readings schreibst (denn lastLevel ist ja ein Reading laut deinem Bild)...

Es gibt das Attribut oldReadings:

Zitat von: commandref
oldreadings
Dieses Attribut enthält eine durch Kommata getrennte Liste von Readings. regex sind erlaubt. Für jedes Reading aus der Liste speichert FHEM intern den vorherigen Wert wenn sich das Reading ändert. Zum Zugriff auf die Werte gibt es die OldReadings.* Routinen.

Dadurch hast du "automatisch" den letzten Readingswert.

Ich habe zuhause auch Code, der das Attribut nutzt.
Vorher wird der ausgelesen (ReadingsVal("Devicename", "oldreading", "Ersatzwert") / evtl. besser ReadingsNum), mit dem aktuellen verglichen und dann eben der alte oder neue genommen.
Nicht als userreadings sondern in einer Sub in myUtils, sollte aber egal sein...

Kann ich mal posten, wenn ich zuhause bin...

Und: poste doch mal ein list von dem Device.

In etwa würde es so gehen (userreadings):


{OldReadingsNum("$name","ReadingsName", 0) > ReadingsNum("name","Readingsname",0) ? return OldReadingsNum("$name","ReadingsName",0) : return ReadingsNum("$name","Readingsname",0)}


ungetestet und aus dem Kopf. EDIT: eieiei, mein Kopf ;)

Ob es in userreadings "$name" gibt weiß ich nicht, könnte auch "$NAME" oder "$DEVICE" etc. sein.
Bzw. zum Test einfach mal den Devicenamen direkt angeben ;)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Otto123

#2
@Joachim Ich greife mal etwas korrigierend ein - die Idee ist gut!
Habe es aber auch nicht getestet, kann sein ich habe mit der "Bandbreite" noch einen Denkfehler :)
Die Bandbreite ist jetzt auch nicht 10 % sondern einfach 10  :-\
{(OldReadingsNum($name,"distance", 0) > (ReadingsNum($name,"distance",0)+10) or OldReadingsNum($name,"distance", 0) < (ReadingsNum($name,"distance",0)-10)) ? OldReadingsNum($name,"distance",0) : ReadingsNum($name,"distance",0)}
https://fhem.de/commandref_DE.html#perl

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

MadMax-FHEM

Hi Otto,

Ups!

Stimmt, war ja anders die Abfrage vom alten Reading ;)

Ich korrigiere dann auch mal nach... ;)

Danke, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

huhu

Vielen Dank für eure Ideen  :)
Um die Oldreadings nutzen zu können, muss der Code dann in die MyUtils oder kann der direkt im userattr genutzt werden?

Bei den Readings aus dem Screen wie level, liter, lastlevel handelt es sich tatsächlich um die Userreadings die ich dort eingetrange habe.

Otto123

Der Code war für Deine userReadings - von userattr habe ich keine Ahnung. Und ich dachte es war bei Dir nur ein Falschversteher Textverdreher.
Du hast doch ein attr Devicename userReadings - oder?
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

huhu

Sorry, dann habe ich das glaube ich falsch verstanden. So siehts aus aktuell:

MadMax-FHEM

Poste doch bitte ein komplettes list...
...in code-Tags (das '#' im "Menü)...
...keine Screenshots...

list Devicename

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Otto123

Vielleicht noch zur Erklärung der Idee, dies ist vielleicht zu kurz gekommen :)
mit attr devicename oldreadings kannst Du die oldreadings aktivieren, d.h. das Gerät hebt dann immer einen Satz alte Readings auf. Damit kannst Du den Vergleich zwischen altem und aktuellen Wert machen und brauchst Dich nicht um die alten Werte kümmern.

Der Vorschlag / Konstrukt von Joachim ist ein Vergleich mit Rückgabe:
{(Bedingung) ? Rückgabe Wert für Ergebnis wahr : Rückgabe Wert für Ergebnis falsch }
Praktisches Beispiel zum Test und Spiel in der FHEM Kommandozeile
{3>2 ? "wahr":"falsch"}

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Tobias

Hi,
ich würde hier eher am Ultraschallsensor direkt ansetzen. Der soll vernünftige Werte liefern anstatt das FHEM hier herumdoktern muss ;)

Gegebenenfalls kannst du in meinem ESP8266 Code etwas abgucken (in sensor.cpp) :
https://github.com/tobiasfaust/ESP8266_PumpControl
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Wzut

Zitat von: Tobias am 12 März 2020, 09:31:29
Der soll vernünftige Werte liefern anstatt das FHEM hier herumdoktern muss ;)
Wenn die Hardware es einfach nicht kann wo ist da der Unterschied ob FHEM doktort oder irgendeine lib ?
Mein US100 will bei vollem Öltank auch nicht so recht, ist der Pegel  mal ein paar Zentimeter gesunken passen die Werte perfekt.
D.h. wenn man schon die Ursache bekämpfen will statt der Symptome, dann hilft es IMHO nur den US mit z.b. einem Rohr mehr Abstand zur Oberfläche zu verschaffen.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Tobias

Da hast du Recht. Verlängerung via Rohr oder ein anderer Ultraschallsensor. Zb. der HCS-04 hat nur wenige cm als Mindestmass
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

huhu

Hallo zusammen,

da habe ich wieder zwei neue Dinge gelernt, zum einen Oldreadings und zum anderen der Vergleich! Ich danke euch!
Den Sensor kann ich leider nicht weiter justieren, aufgrund des Schachtes. Bis zu einem Füllgrad von 100% funktioniert alles sauber, ab 101% (wenn das Wasser nicht schnell genug über den Ablauf versickert), beträgt der Abstand weniger als 20cm und der Sensor schwankt dann extrem stark bis er wieder eine Distanz über 20cm misst (100%)

Aktuell scheint es so zu funktionieren:

level {
my $level=150-((ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0))-30);
return (OldReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance", 0) > (ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0)+10) or OldReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance", 0) < (ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0)-10)) ? OldReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0) : ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0)},

liter {
my $level=ReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","level",0);
my $liter=47.47*($level);
use Math::Round qw/round/;
return $liter= Math::Round::nearest('10',$liter) },

lastdistance {
my $lastdistance=OldReadingsNum("ESPEasy_ESP_Zisterne_DISTANCE","distance",0);
return $lastdistance },


Jetzt kommt das große ABER ;) Ich vermute, dass der Sensor bei aufeinanderfolgenden falschen Werten, die in den 10% Bereich fallen, den falschen Wert übernehmen würde... Oder denke ich da zu kompliziert? Eine andere Idee wäre dann einen Durchschnitt der letzten 5 Messungen zu nehmen und davon 10%?

Beta-User

#13
Anderer Ansatz (falls wirklich nicht einfach ein anderer US-Sensor geht(!)): Bau noch einen billigen Schwimmerschalter dran ;) .

Ist der oben, ist voll, ist der unten, darf der US-Sensor Werte liefern. Ist zwar in FHEM (oder gerne auch der firmware...) etwas schwieriger abzubilden, aber dafür weniger "schätzig".

(Nachtrag: bei userReading sollte man "präventiv" auch immer einen Trigger definieren, auch wenn das Device hier scheinbar nur einen "echten" Readingwert hat, der die userReadings aktualisiert).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors