Hallo,
bin zwar nicht mehr neu als Benutzer vom Fhem aber würde sagen trotzdem noch blutiger Anfänger.
Habe mir in meine Zisterne einen Ultraschalsensor eingebaut um den Wasserstand zu messen( mit einen Python Script),funktioniert auch alles.
Script wird über Contab Befehl ausgeführt. Kann auch über Fhem das Script aufrufen dort schreibt es mir die Daten in die Logfile. Jetzt möchte ich über einen Dummy das Script ausführen und die gemessenen Daten in Fhem mir anzeigen lassen. Es wird auch ausgeführt bloß bekomme ich die Daten nicht zu gesicht , nur wieder in der Logdatei.
auszug vom script
[ Meine Tanks haben Maximal 5000 Liter bei 220 cm Füllhöhe
# Zusätzlich 4 cm Offset vom Einbauort des Sensors
Fuelstand = 250 - Distance
Liter = 5000 / 250 * Fuelstand
Zeit = time.time()
ZeitStempel = datetime.datetime.fromtimestamp(Zeit).strftime('%Y-%m-%d_%H:%M:%S')
print (ZeitStempel),("Zisterne Fuelhoehe: %.1f cm" % Fuelstand),("Liter: %.0f l" % Liter)
time.sleep(2)]
das Device
defmod actWasserstandZisterne notify WasserstandZisterne {my $Value=ReadingsVal("Zisterne_Inhalt_Reading", "Zisterne Fuelhoehe","");; system ("sudo /home/pi/zisterne.py & Value")}
Biite um eure Hilfe
Lieber direkt aus deinem Python Skript die Readings setzen.
Da Du Werte setzen möchtest, müsstest Du mit qx() statt system() arbeiten. Das wäre dann ein blokierendes Call. Alle andere Alternativen bedeuten viel mehr Code.
ZitatLieber direkt aus deinem Python Skript die Readings setzen.
Dafür evtl. das Fhem Client von Otto schauen https://github.com/heinz-otto/fhemcl
Werte an FHEM uebergeben
#fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand Fuelhoehe "
#os.system(perl /opt/fhem/fhem.pl7072 ("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
#fh.pl7072("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
#echo -en "set Zisterne_Inhalt Fuelhoehe\nquit\n" | nc -w 5 localhost 7072 >/dev/null
#def fhem_set( var, value):
#print "set " + var + " " + value
#subprocess.call(['perl', '/opt/fhem/fhem.pl', '7072', 'set '+ var +' ' + value])
#fhem_set("Zisterne_Inhalt",Wasserstand)
Das hatte ich schon ausprobiert, habe es aber nicht hinbekommen
Und? An welcher Stelle hat es nicht funktioniert, und mit welcher Fehlermeldung?
#Werte an FHEM uebergeben
fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand Fuelhoehe "
os.system(perl /opt/fhem/fhem.pl7072 ("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
fh.pl7072("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
SyntaxError: invalid syntax
echo -en "set Zisterne_Inhalt Fuelhoehe\nquit\n" | nc -w 5 localhost 7072 >/dev/null
IdentationError: unexpected ident
Woher kommt die fh.pl7072() Funktion?
habe das aus dem Netz von verschiedenen seiten zusammen gesucht.
wie gesagt bin da echt der Neuling und habe bisher alle immer zusammen gesucht und das hat auch immer bisher geklappt.
Sind ja verschiedene Befehle die ich im script stehen gelassen habe und nur deaktiviert habe.
Also....
fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand Fuelhoehe "
Das kann aus einem python Skript nicht funktionieren, das es Perl rufen sollte.
os.system(perl /opt/fhem/fhem.pl7072 ("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
Damit es eine Chance hatzu funktionieren, muss mindestens ein Leerzeichen vor 7072 stehen
fh.pl7072("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
Damit es funktioniert, muss die Funktion fh.pl7072 (oder fh.pl mit Leerzeichen und dann 7072) zuerst definiert werden. Das klingt aber wiederum wie ein Perl Skript (siehe 1)
Kannst auch hier schauen: https://github.com/domschl/python-fhem
Aber bitte nicht einfach blind kopieren, sondern versuchen zu verstehen
fh.pl 7072("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
bringt den Fehler
File "zisterne.py", line 101
fh.pl 7072("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
^
SyntaxError: invalid syntax
os.system(perl /opt/fhem/fhem.pl 7072 ("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
bringt den Fehler
File "zisterne.py", line 99
os.system(perl /opt/fhem/fhem.pl 7072 ("setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand ))
^
SyntaxError: invalid syntax
Mit
('perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelhoehe"+str(Fuelstand)')
habe ich keinen fehler aber trozdem kein wert (eintrag) in Fhem
Was sagt die Fhem Log?
2019.11.24 21:28:21 3: actWasserstandZisterne return value: -1
sudo: /etc/sudoers.d ist für alle beschreibbar (world writable)
2019-11-24_21:28:25 Zisterne Fuelhoehe: 180.8 cm Liter: 3616 l
bin mir aber nicht sicher was nach setreading stehen muß
('perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Zisterne Fuelhoehe"+str(Fuelhoehe)')
('perl /opt/fhem/fhem.pl 7072 "setreading >Device< >gemessener Wert< "+str(>einheit<)')
# Meine Tanks haben Maximal 5000 Liter bei 220 cm Füllhöhe
# Zusätzlich 7 cm Offset vom Einbauort des Sensors
Fuelstand = 250 - Distance
Liter = 5000 / 250 * Fuelstand
Zeit = time.time()
ZeitStempel = datetime.datetime.fromtimestamp(Zeit).strftime('%Y-%m-%d_%H:%M:%S')
print (ZeitStempel),("Zisterne Fuelhoehe: %.1f cm" % Fuelstand),("Liter: %.0f l" % Liter)
time.sleep(2)
#Werte an FHEM uebergeben
('perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Zisterne Fuelhoehe"+str(Fuelhoehe)')
Was willst Du in welchen Reading von welchem Device setzen? Syntax ist
setreading <device> <reading> <wert>
+ ist Konkatenation von Strings. Es muss sicher ausserhalb der Hochkommas stehen
ich möchte Zisterne Fuelhoehe in den Device Zisterne_Inhalt_Reading stehen haben
hier die RAW Definiotion
defmod Zisterne_Inhalt_Reading readingsGroup Zisterne_Inhalt:<%Inhalt>
Man schreibt aber keinen Wert in ein Reading eines readingsGroup.
Was ist Zisterne_Inhalt für ein Device? Da willst Du den Wert als Reading schreiben, oder? Dann wäre
setreading Zisterne_Inhalt Fuelstand 130
der Befehl?
Dann
('perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand '+str(Fuelhoehe) + '"')
I.ä. Bin kein python Profi aber ich finde diese Art von Systembefehl komisch. Sicher, dass es perl startet?
ich hab ja auch nicht so die Ahnung
wenn ich den Befehl eingebe kommt diese Fehlermeldung
sudo: /etc/sudoers.d ist für alle beschreibbar (world writable)
2019-11-24_22:03:26 Zisterne Fuelhoehe: 180.6 cm Liter: 3612 l
Traceback (most recent call last):
File "zisterne.py", line 128, in <module>
main()
File "zisterne.py", line 100, in main
('perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand '+str(Fuelhoehe) + '"')
NameError: global name 'Fuelhoehe' is not defined
Naja klar, mein Schuld, aber verstehst Du überhaupt, was dein Skript macht?
Statt Fuelhoehe, natürlich Fuelstand
wenn ich ehrlich bin nicht , nur bruchteile
habe jetzt keine Fehlermeldung,aber auch kein eintrag .
wie muß der device den angelegt sein , das er mir den wert anzeigt?
Moment... Jetzt bin ich komplett verloren.
Willst Du einen Wert aus dem python Skript in Fhem setzen, oder einen Wert aus Fhem lesen, und in Python benutzen?
Guten morgen,
ich möchte einen Wert aus dem Python Skript in Fhem setzen
Ok. Dann sind wir in die richtige Richtung.
Was ergibt perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100"
in der Console? Wir auf Zisterne_Inhalt das Reading Fuelstand gesetzt? Wenn nicht, gibt es eine Fehlermeldung in der Console oder in der Fhem Log?
in der Console gibt es den Fehler
('perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100" ')
-bash: perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100" : Datei oder Verzeichnis nicht gefunden
in Fhem Log keinen Fehler, der Fuelstand wird ins Log geschrieben
Hmm mit Console meinte ich ein Terminal direkt auf dem Linux Rechner. Du hast wahrscheinlich die python Console benutzt (da musst Du wahrscheinlich den Path zu perl mit eingeben: /usr/bin/perl )?
der Raspi ist bei mir im Schuppen ,da greife ich über Putty drauf zu
('usr/bin/perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100" ')
-bash: usr/bin/perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100" : Datei oder Verzeichnis nicht gefunden
Fehlendes / am Anfang ...
('/usr/bin/perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100" ')
-bash: /usr/bin/perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100" : Datei oder Verzeichnis nicht gefunden
Zitat von: saschaev am 25 November 2019, 11:19:34
der Raspi ist bei mir im Schuppen ,da greife ich über Putty drauf zu
Dann direkt nach dem Login über Putty eingeben, ohne irgendwas mit python anzufangen.
perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100"
Da Ihr über telnet daten versendet, warum nicht gleich "Hardcore" über nc?
Spart recourcen ...
perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100"
Can't connect to localhost:7072
@Wernieman: Hatte ich für später bei Seite gelassen. Ich möchte zuerst verstehen, wo es bei ihm hängt. Im Moment kann ich mir nicht vorstellen, wie/was/wo er macht
@saschaev: na dann musst Du gucken, ob in deinem Fhem eine telent Instanz definiert ist. Man mal über die Fhem Oberfläsche ein "list TYPE=telnet"
Wenn ich
list TYPE=telnet
Eingebe kommt nichts
Also hab ich es nicht eingerichtet?
Hab jetzt das Device angelegt
Ausgabe bei Fhem
Internals:
CFGFN
CONNECTS 1
DEF 7072 global
FD 15
FUUID 5ddbd046-f33f-c00a-765a-9a553c7c276da2d3
NAME telnetPort
NR 1304
PORT 7072
STATE Initialized
TYPE telnet
READINGS:
2019-11-25 13:59:50 state Initialized
Attributes:
So habe jetzt das in die Konsole eingeben
perl /opt/fhem/fhem.pl 7072 "setreading Zisterne_Inhalt Fuelstand 100"
Dann zeigt er mir in den dummy Ziterne_Inhalt bei Readings 100 an . Aber da muss ich auf den Dummy gehen.
Hier mal die Raw Definition
defmod Zisterne_Inhalt dummy
attr Zisterne_Inhalt room Zisterne
attr Zisterne_Inhalt stateFormat Wasserstand
attr Zisterne_Inhalt userReadings Zisterne Fuelhoehe
setstate Zisterne_Inhalt Wasserstand
setstate Zisterne_Inhalt 2019-11-25 17:23:09 Fuelstand 100
stateFormat
Und bitte die Dokumentation lesen. Oder wegen meiner YouTube Videos schauen.
OK das ist schon mal gut. Du kannst von ausserhalb Fhem einen Wert in Fhem setzen.
Wie sieht es jetzt mit python aus?
Ich glaube immer noch nicht, dass ('.......') eine richtige Syntax ist, um ein shell Kommando aus einem Python Skript zu starten. Es soll eher so gemacht werden:
cmd = 'setreading Zisterne_Inhalt Fuelstand ' + str(Fuelstand)
import subprocess
subprocess.run(['perl', '/opt/fhem/fhem.pl', '7072', cmd])
Wie gesagt, bin aber kein python Entwickler.
Letztens musst Du entscheiden, wo genau Du diesen Wert in Fhem speichern möchtest. Wenn Du es als state des Dummys willst, dann statt
setreading Zisterne_Inhalt Fuelstand <Wert>
eher
set Zisterne_Inhalt <Wert>
Oder wie CoolTux sagt, stateFormat benutzen.
Und wie Wernieman geschrieben hat, noch besser wäre es mit nc
cmd = 'setreading Zisterne_Inhalt Fuelstand ' + str(Fuelstand)
import subprocess
p1 = subprocess.run(['echo', cmd], stdout=subprocess.PIPE)
p2 = subprocess.run(['nc', '127.0.0.1', '7072'], stdin=p1.stdout)
nicht getestet, und vielleicht gibt es elegantete Art und Weise.
Bei
cmd = 'setreading Zisterne_Inhalt Fuelstand ' + str(Fuelstand)
import subprocess
subprocess.run(['perl', '/opt/fhem/fhem.pl', '7072', cmd])
Bekomme ich Fehler
^
SyntaxError: invalid syntax
sh: 1: Value: not found
2019.11.25 18:07:43 3: actWasserstandZisterne return value: -1
sudo: /etc/sudoers.d ist für alle beschreibbar (world writable)
File "/home/pi/zisterne.py", line 103
import subprocess
^
IndentationError: unexpected unindent
Zeig dein komplettes Skript (bitte in Code Tags - das # Zeichen im Edit Menu des Forums). Da sind anscheinend mehrere Fehler drin
Sorry es waren die Leerzeichen, bin auf der Arbeit mit dem Handy am gange.Ist ein wenig unübersichtlich.
Jetzt kommt der Fehler.
IndentationError: unexpected unindent
sh: 1: Value: not found
2019.11.25 18:27:22 3: actWasserstandZisterne return value: -1
sudo: /etc/sudoers.d ist für alle beschreibbar (world writable)
2019-11-25_18:27:27 Zisterne Fuelhoehe: 180.7 cm Liter: 3614 l
Traceback (most recent call last):
File "/home/pi/zisterne.py", line 126, in <module>
main()
File "/home/pi/zisterne.py", line 104, in main
subprocess.run(['perl', '/opt/fhem/fhem.pl', '7072', cmd])
AttributeError: 'module' object has no attribute 'run'
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# import required modules
import time
import datetime
import RPi.GPIO as GPIO
# define GPIO pins
GPIOTrigger = 18
GPIOEcho = 24
# function to measure the distance
def MeasureDistance():
# set trigger to high
time.sleep(0.2)
GPIO.output(GPIOTrigger, True)
# set trigger after 10Ã,µs to low
time.sleep(0.0001)
GPIO.output(GPIOTrigger, False)
# store initial start time
StartTime = time.time()
# store start time
while GPIO.input(GPIOEcho) == 0:
StartTime = time.time()
# store stop time
while GPIO.input(GPIOEcho) == 1:
StopTime = time.time()
# calculate distance
TimeElapsed = StopTime - StartTime
Distance = (TimeElapsed * 34400) / 2
return Distance
# main function
def main():
try:
# while True:
Distance0 = MeasureDistance()
Distance01 = MeasureDistance()
Distance02 = MeasureDistance()
Distance03 = MeasureDistance()
Distance04 = MeasureDistance()
Distance05 = MeasureDistance()
Distance06 = MeasureDistance()
Distance07 = MeasureDistance()
Distance08 = MeasureDistance()
Distance09 = MeasureDistance()
Distance10 = MeasureDistance()
Distance11 = MeasureDistance()
Distance12 = MeasureDistance()
Distance13 = MeasureDistance()
Distance14 = MeasureDistance()
Distance15 = MeasureDistance()
Distance16 = MeasureDistance()
Distance17 = MeasureDistance()
Distance18 = MeasureDistance()
Distance19 = MeasureDistance()
Distance20 = MeasureDistance()
Distance_sum = Distance01 + Distance02 + Distance03 + Distance04 + Distance05 + Distance06 + Distance07 + Distance08 + Distance09 + Distance10 + Distance11 + Distance12 + Distance13 + Distance14 + Distance15 + Distance16 + Distance17 + Distance18 + Distance19 + Distance20
Distance = round(Distance_sum / 20,1)
# Meine Tanks haben Maximal 5000 Liter bei 220 cm Füllhöhe
# Zusätzlich 7 cm Offset vom Einbauort des Sensors
Fuelstand = 250 - Distance
Liter = 5000 / 250 * Fuelstand
Zeit = time.time()
ZeitStempel = datetime.datetime.fromtimestamp(Zeit).strftime('%Y-%m-%d_%H:%M:%S')
print (ZeitStempel),("Zisterne Fuelhoehe: %.1f cm" % Fuelstand),("Liter: %.0f l" % Liter)
time.sleep(2)
#Werte an FHEM uebergeben
cmd = 'setreading Zisterne_Inhalt Fuelstand ' + str(Fuelstand)
import subprocess
subprocess.run(['perl', '/opt/fhem/fhem.pl', '7072', cmd])
# reset GPIO settings if user pressed Ctrl+C
except KeyboardInterrupt:
print("Measurement stopped by user")
if __name__ == '__main__':
# set GPIO disable warnings
GPIO.setwarnings(False)
GPIO.cleanup()
# use GPIO pin numbering convention
GPIO.setmode(GPIO.BCM)
# set up GPIO pins
GPIO.setup(GPIOTrigger, GPIO.OUT)
GPIO.setup(GPIOEcho, GPIO.IN)
# set trigger to false
GPIO.output(GPIOTrigger, False)
# call main function
main()
Was sagt python -V
?
#!/usr/bin/env python
Das es Python Skript ist
Was sagt
python -V
, wenn Du das in einem Linux Terminal eingibst. Ich will deine Version von Python kennen
EDIT: Naja... wahrscheinlich kleiner als 3.5
Dann stattsubprocess.run(['perl', '/opt/fhem/fhem.pl', '7072', cmd])
mach
subprocess.Popen(['perl', '/opt/fhem/fhem.pl', '7072', cmd])
Super vielen vielen Dank für deine Unendliche Gedult mit mir, sag ja das ich echt nicht viel Ahnung habe.
Jetzt muss ich nur noch es hin bekommen das er es im device anzeigt
Du meinst in der Raumübersicht.
Wie gesagt
stateFormat
Habe das auch hin bekommen, natürlich nur mit eurer Hilfe.
Nochmals vielen Dank :D