Python Skript in FHEM ausführen

Begonnen von mediastudio, 05 Juli 2024, 00:01:53

Vorheriges Thema - Nächstes Thema

mediastudio

Hallo,
ich habe einiges gelesen aber keine Antwort gefunden.
ich habe ein einfaches python-skript für die Textausgabe
auf ein I2C-Display gemacht. Das Beste ist, es funktioniert
ohne Problem über die Eingabe in der Konsole.
Bei eingabe über die Fehm Kommandozeile bekomme ich als Ausgabe
ein -1 aber keine Funktion.

Hier mal die Eingabe über die Fhem-Kommandozeile: {system("sudo ./lcd/wf_IP.py &")}ergibt -1

Hier mal die Eingabe über die Konsole: python ./lcd/wf_IP.pydas funktioniert.

Hier mal das python-script: #! /usr/bin/env python

import drivers
from time import sleep
from datetime import datetime
from subprocess import check_output
display = drivers.Lcd()
IP_adresse = check_output(["hostname", "-I"], encoding="utf8").split()[0]
IP = "IP "
try:
    print("Writing to display")
    while True:
        display.lcd_backlight(1)

        display.lcd_display_string(str(datetime.now()), 1)  # Write line of text to first line of display
        display.lcd_display_string("wf-consulting.eu", 2)   # Write line of text to second line of display
        # Give time for the message to be read
        sleep(5)
        # Clear the display of any data
        display.lcd_clear()                                 
       
        display.lcd_display_string("IP Adresse", 1)
        display.lcd_display_string(str(IP_adresse),2)
        # Give time for the message to be read
        sleep(5)
        # Clear the display of any data
        display.lcd_clear()
       
        display.lcd_display_string("PV - \xF5berschuss", 1)  # Write line of text to first line of display
        display.lcd_display_string("Smart Grid Ready", 2)    # Write line of text to second line of display
        # Give time for the message to be read
        sleep(5)
        # Clear the display of any data
        display.lcd_clear()
         
except KeyboardInterrupt:
    # If there is a KeyboardInterrupt (when you press ctrl+c), exit the program and cleanup
    print("System Stop")
    display.lcd_clear()


was mache ich falsch?

mumpitzstuff

Unter FHEM bist du als User fhem unterwegs und hast im Normalfall keine Adminrechte.

Otto123

#2
Guten Tag,

vielleicht hilft Dir in meiner Notiz: https://heinz-otto.blogspot.com/2017/08/raspberry-ausschalten-mit-fhem.html
der Abschnitt für die notwendige Einrichtung für sudo weiter.

Besser und einfacher wäre, Du bräuchtest kein sudo. Dazu verstehe ich dein Script zu wenig.
Bei python kann es noch sein, das die python Umgebung für user fhem nicht stimmt. Hängt davon wie, wo und ob Du was dazu installiert hast.

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

Zitat von: mediastudio am 05 Juli 2024, 00:01:53Hier mal die Eingabe über die Fhem-Kommandozeile:
{system("sudo ./lcd/wf_IP.py &")}

Zitat von: mediastudio am 05 Juli 2024, 00:01:53Hier mal die Eingabe über die Konsole:
python ./lcd/wf_IP.py

Neben den bereits erwähnten Punkten, gerade Python und Umgebung/env (ist mir auch schon immer etwas "suspekt" gewesen)...
...du bist eben in fhem als fhem unterwegs.
D.h. "home" ist dabei (standardmässig) /opt/fhem

Also bei ./Verzeichnis/Irgendwas beginnst du (verm.) eben in /opt/fhem

Auf der Console bist du User X und (auf Linux meist) eben "home": /home/X

D.h. mit ./Verzeichnis/Irgendwas beginnst du in /home/X

Steht denn beim Ausführen irgendwas im fhem Log?

Neben dem, dass du erst mal prüfen solltest, ob du sudo brauchst, weil der Befehl auf der Console ist ja auch ohne sudo?

Und dann eben noch: "findet" fhem python "einfach so"? Oder wäre die Angabe des ABSOLUTEN Pfades zu python notwendig/besser?
Ebenso ABSOLUTER Pfad zur python-Datei die du ausführen willst, siehe oben "home von usern"...

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)

mediastudio

Hallo,
ich habe weitere Ergebnisse bezüglich ein Pythonscript aus Fhem ausführen.
Ich habe eine PV-Überschuss Smart Grid Software in Fhem programmiert.
Die Steuerung beinhaltet SMA Wechselrichter Sunny Tripower 8.0 und
SMA Wechselrichter Sunny Tripower 10.0 sowie Fronius
SYMO-GEN24-8.0-PLUS  - Hybrid-Wechselrichter. Der Raspberry steuert
eine Vissmann Vitocal 200-a Wärmepumpe mit Smart Grid Eingängen, warm Wasser und Heizung und
ein Pool mit Umwälzpumpe und Wärmepumpe. Das nur zum Verständnis was der
Rest der Steuerung bringen soll. Ich habe nun die Zustände der ausgeführten 
Funktionen als Text auf einem Display I2C LCD 1602 Module Serial 16x2 gebracht.
Da hier einfache Pyhton- Befehle zur Anwendung kommen, habe ich erst das Problem
mit der Ansteuerung aus Fhem gehabt. Das Problem ist soweit gelöst und ich gebe
die Meldungen auf dem Display aus. Ich habe im root-Ordner ein Unterordner ,,lcd"
angelegt. In diesen Ordner habe ich den Ordner ,,drivers"  reinkopiert, der bei der Installation
von ,,git clone https://github.com/the-raspberry-pi-guy/lcd" in User PI angelegt wurde.
Dann habe ich mir für mich brauchbare pyhton-scripte mit der Textausgabe gefertigt.
Als Anregung sind die demo-scripte sehr nützlich. Meine Scripte liegen im ,,lcd" Ordner
von Fhem. Wichtig, die Skripte müssen Ausführbar gemacht werden. Als nun der Text
angezeigt wurde hatte ich schon das nächste Problem. Wenn ein Pythoscript gestartet
wird, dann läuft es als Task und muss manuell gestoppt werden. Wenn das nicht gemacht
wird, dann wird der Text nur Hieroglyphen angezeigt und ist unbrauchbar. Also habe ich
ein Script  ,,clear_display.py" um den letzten Text zu löschen. Hier mal den Ablauf
wenn eine Meldung über ein Ereignis ausgegeben wird Ausgabe:
 
1 ) Als erstes den alten Text löschen ,,clear_display.py"
2 ) Danach das Skript mit dem auszugebenen Text starten.

Text löschen für neue Textausgabe:
1 )  SmartGrid_Heizen.py  Task löschen
2 )  Den alten Text löschen ,,clear_display.py"

FHEM:
######################################
# Python_Dilplayausgabe  Date/Time/IP#
######################################
define Python_Test_1 dummy
attr Python_Test_1 alias Display System Info
attr Python_Test_1 devStateIcon on:power.on off:power.off
attr Python_Test_1 group Display_System
attr Python_Test_1 icon funk_steckdose.png
attr Python_Test_1 room LCD-TEST
attr Python_Test_1 setList on off
define Python_Test_1_on  notify Python_Test_1:on  {system("sudo  pkill -f -SIGTERM  ./lcd/clear_display.py &")}\
{system("sudo ./lcd/Information.py &")}

define Python_Test_1_off notify Python_Test_1:off {system("sudo  pkill -f -SIGTERM  ./lcd/Information.py &")}\
{system("sudo ./lcd/clear_display.py &")}


######################################
# Python_Dilplayausgabe  Heizen      #
######################################
define Python_Test_2 dummy
attr Python_Test_2 alias Smart Grid Heizen
attr Python_Test_2 devStateIcon on:power.on off:power.off
attr Python_Test_2 group Display_System
attr Python_Test_2 icon funk_steckdose.png
attr Python_Test_2 room LCD-TEST
attr Python_Test_2 setList on off
define Python_Test_2_on  notify Python_Test_2:on  {system("sudo  pkill -f -SIGTERM  ./lcd/clear_display.py &")}\
{system("sudo ./lcd/SmartGrid_Heizen.py &")}

define Python_Test_2_off notify Python_Test_2:off {system("sudo  pkill -f -SIGTERM  ./lcd/SmartGrid_Heizen.py &")}\
{system("sudo ./lcd/clear_display.py &")}


######################################
# Python_Dilplayausgabe  Warm- Wsser #
######################################
define Python_Test_3 dummy
attr Python_Test_3 alias Smart Grid Warm- Wsser
attr Python_Test_3 devStateIcon on:power.on off:power.off
attr Python_Test_3 group Display_System
attr Python_Test_3 icon funk_steckdose.png
attr Python_Test_3 room LCD-TEST
attr Python_Test_3 setList on off
define Python_Test_3_on  notify Python_Test_3:on  {system("sudo  pkill -f -SIGTERM  ./lcd/clear_display.py &")}\
{system("sudo ./lcd/SmartGrid_Wasser.py &")}

define Python_Test_3_off notify Python_Test_3:off {system("sudo  pkill -f -SIGTERM  ./lcd/SmartGrid_Wasser.py &")}\
{system("sudo ./lcd/clear_display.py &")}


Den Ordner "lcd" angelegt: fhem/lcd
Wie beschrieben den Ordner drivers reinkopieren: fhem/lcd/drivers
Die Python-Scripte in: fhem/lcd
clear_display.py
#! /usr/bin/env python

import drivers
from time import sleep
from datetime import datetime
from subprocess import check_output
display = drivers.Lcd()
try:
    print("Writing to display")
    while True:
 
       
     display.lcd_clear()     
       
except KeyboardInterrupt:
    # If there is a KeyboardInterrupt (when you press ctrl+c), exit the program and cleanup
    print("System Stop")
    display.lcd_clear()
Information.py[code]
#! /usr/bin/env python

import drivers
from time import sleep
from datetime import datetime
from subprocess import check_output
display = drivers.Lcd()
IP_adresse = check_output(["hostname", "-I"], encoding="utf8").split()[0]
IP = "IP "
try:
    print("Writing to display")
    while True:
   
       
        display.lcd_backlight(1)

        display.lcd_display_string(str(datetime.now()), 1)  # Write line of text to first line of display
        display.lcd_display_string("wf-consulting.eu", 2)   # Write line of text to second line of display
        # Give time for the message to be read
        sleep(5)
        # Clear the display of any data
        display.lcd_clear()                                 
       
        display.lcd_display_string("IP Adresse", 1)
        display.lcd_display_string(str(IP_adresse),2)
        # Give time for the message to be read
        sleep(5)
        # Clear the display of any data
        display.lcd_clear()
       
        display.lcd_display_string("PV - \xF5berschuss", 1)  # Write line of text to first line of display
        display.lcd_display_string("Smart Grid Ready", 2)    # Write line of text to second line of display
        # Give time for the message to be read
        sleep(5)
        # Clear the display of any data
        display.lcd_clear()
       
       
               
       
        display.lcd_clear()     
       
except KeyboardInterrupt:
    # If there is a KeyboardInterrupt (when you press ctrl+c), exit the program and cleanup
    print("System Stop")
    display.lcd_clear()

SmartGrid_Heizen.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-

# Example: Scrolling text on display if the string length is major than columns in display.
# Created by D�dac Garc�a.

# Import necessary libraries for communication and display use
import drivers
from time import sleep

# Load the driver and set it to "display"
# If you use something from the driver library use the "display." prefix first
display = drivers.Lcd()

# Main body of code
try:


def long_string(display, text='', num_line=1, num_cols=16):
"""
Parameters: (driver, string to print, number of line to print, number of columns of your display)
Return: This function send to display your scrolling string.
"""
if len(text) > num_cols:
display.lcd_display_string(text[:num_cols], num_line)
sleep(0.2)
for i in range(len(text) - num_cols + 1):
text_to_print = text[i:i+num_cols]
display.lcd_display_string(text_to_print, num_line)
sleep(0.2)
sleep(0.1)
else:
display.lcd_display_string(text, num_line)


# Example of short string
long_string(display, "Smart Grid", 1)


# Example of long string
long_string(display, "Heizen -- Heizen -- Heizen --", 2)


while True:
# An example of infinite scrolling text
long_string(display, "Heizen -- Heizen -- Heizen --", 2)


except KeyboardInterrupt:
# If there is a KeyboardInterrupt (when you press ctrl+c), exit the program and cleanup
print("Cleaning up!")
display.lcd_clear()

SmartGrid_Wasser.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-

# Example: Scrolling text on display if the string length is major than columns in display.
# Created by D�dac Garc�a.

# Import necessary libraries for communication and display use
import drivers
from time import sleep

# Load the driver and set it to "display"
# If you use something from the driver library use the "display." prefix first
display = drivers.Lcd()

# Main body of code
try:


def long_string(display, text='', num_line=1, num_cols=16):
"""
Parameters: (driver, string to print, number of line to print, number of columns of your display)
Return: This function send to display your scrolling string.
"""
if len(text) > num_cols:
display.lcd_display_string(text[:num_cols], num_line)
sleep(0.2)
for i in range(len(text) - num_cols + 1):
text_to_print = text[i:i+num_cols]
display.lcd_display_string(text_to_print, num_line)
sleep(0.2)
sleep(0.1)
else:
display.lcd_display_string(text, num_line)


# Example of short string
long_string(display, "Smart Grid", 1)


# Example of long string
long_string(display, "Warm Wasser -- Warm Wasser -- Warm Wasser --", 2)


while True:
# An example of infinite scrolling text
long_string(display, "Warm Wasser -- Warm Wasser -- Warm Wasser --", 2)


except KeyboardInterrupt:
# If there is a KeyboardInterrupt (when you press ctrl+c), exit the program and cleanup
print("Cleaning up!")
display.lcd_clear()


Eventuell gibt es da etwas eleganteres, aber ich habe das erstmal so gelöst damit Fhem
meine Texte auf dem Display ausgibt. Das schöne ist ja das das Display mit nur vier Adern
an den Raspberry angeschlossen wird und komplett 3 – 6 EUR kostet.
Sollte jemand Interesse haben, hier mal meine Skripte.