Python Automatisierter Aufruf einer Funktion jede Minute

X_Clamp

Lieutenant
Registriert
Sep. 2010
Beiträge
931
Hallo,

ich habe hier ein Python Programm, das für einen Enigma 2 Linux Receiver geschrieben ist:
https://pastebin.com/AdEDPkRm

Ich möchte, dass die Funktion
Code:
def aktualisieren(self):
 self.updateInfos()
automatisch alle 60 Sekunden aufgerufen wird (Funktion ist in Zeile 426 + 427 definiert). Irgendwie bin ich zu doof, das Ganze per Thread umzusetzen. Ich hoffe, dass mir ein Python Programmierer hier weiterhelfen kann.

Danke schon mal!
 
Na du machst ne endlos loop in der steht:
- funktion aufrufen
- 60sekunden sleepen

Das ist super einfach aber etwas ungenau falls deine funktion größere laufzeiten hat.
Dauert das update zb 20 sekunden hättest du so nur alle 20+60 ein update
Un es gebauer zu machen brauchst du 2 parallel laufende dinge: timer alle 60 und ausführung der funktion
Da python keine threads kann macht man das in python zwangsläufig mit mehreren prozessen
 
An und für sich ist mir die Umsetzung schon einigermaßen klar (gibt zig Beispiele auf stackoverflow) und ich habe auch schon ca 3 Stunden damit verbracht. Jedoch hat bei mir nie die automatisierte, wiederholte Ausführung geklappt.
Wärst du so nett und sagst mir, in welche Zeile ich welchen Aufruf setzen muss?
 
Für solche Kleinigkeiten würde ich Koroutinen verwenden. In Python gibt es dafür eine Library namens asyncio:

Code:
import asyncio



async def updateInfos():
    while(True):
      print("updateInfos wurde aufgerufen!")
      await asyncio.sleep(60)


async def coroutine_main():
    while(True):
        print("das hauptprogramm wird ausgeführt!")
        # await asyncio.sleep(2)




def main():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(
        updateInfos(),
        coroutine_main(),
    ))
    loop.close()




main()
 
Wie gesagt, da ich nun schon mehrere Stunden erfolglos herumgedoktort habe, wäre ich dankbar, wenn mir jemand gleich am konkreten Source Code zeigen kann, wo was platziert werden muss.
 
Da die Klasse VirtualZap nur einen Konstruktor aber keine Main-Methode mit dem Programmablauf beinhaltet, wirds schwierig da Threads oder Koroutinen zu implementieren.

Die einzige Möglichkeit die ich sehe:

Zeile 144:
Code:
def main(session,**kwargs):
    session.open(VirtualZap, kwargs["servicelist"])

Vielleicht gibt es eine Möglichkeit über die session an die Methodenaufrufe von VirtualZap ran zu kommen. Falls das ginge, könnte man hier die Threads/Koroutinen starten.

Das Skript ist ziemlich hässlich und schlecht dokumentiert :rolleyes:

​Aber vielleicht hat ja noch jemand anderes ne Idee. ;)
 
Zuletzt bearbeitet:
Also die besagte Methode "aktualisieren" kann über die gelbe Taste auf der Fernbedienung des Receivers manuell aufgerufen werden:
Code:
     self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ChannelSelectBaseActions", "ChannelSelectEPGActions", "ColorActions"],
        {
            "ok": self.ok,
            "cancel": self.closing,
            "right": self.nextService,
            "left": self.prevService,
            "nextBouquet": self.nextBouquet,
            "prevBouquet": self.prevBouquet,
            "showEPGList": self.openEventView,
            "blue": self.standardPiP,
            "yellow": self.aktualisieren,
            "red": self.HideVZ,
            "green": self.ShowVZ,
            "down": self.openServiceList,
            "up": self.showFavourites,
        },-2)

Die Frage ist nun quasi, ob man den Tastendruck automatisieren kann. Dann könnte man an die Funktion ja einen Threading Timer.start() hinzufügen.

Also sowas in der Art:
Code:
import threading

def hello_world():
  threading.Timer(60.0, hello_world).start() # called every minute
  print("Hello, World!")

hello_world()
 
Zuletzt bearbeitet:
Und wenn man eine eigene Klasse für den automatisierten Aufruf anlegt? Irgendwie sollte doch da was möglich sein? ;)
 
Ich weiß halt nicht wie dieses Plugin-System von dem Enigma genau funktioniert.

So etwas hast aber schon probiert, oder? (natürlich den import in der Klasse nicht vergessen)
Code:
    def aktualisieren(self):
​        threading.Timer(60, aktualisieren).start() 
        self.updateInfos()

bzw.

Code:
    def aktualisieren(self):
​        threading.Timer(60, self.updateInfos()).start() 
        self.updateInfos()
 
Zuletzt bearbeitet:
Ja, genauso habe ich es schon probiert. Blöd gefragt, wo muss ich dann die Funktion genau aufrufen (also aitomatisiert ohne Tastendruck)?
 
Dann brauche ich die oben von dir geposteten Erweiterungen nicht vornehmen, oder? Ich werde das mit der Main morgen genauer testen ...
 
Und woher weiß ich, wie es korrekt eingerückt ist?
 
Du musst es genau auf die gleiche Höhe, wie die der anderen Methoden in der Klasse rücken.
Auch wichtig: Python unterscheidet zwischen Tabs und Leerzeichen

​So in etwa:
Code:
    def __onClose(self):
        # reverse changes of ChannelSelection
        self.servicelist.zap = self.servicelist_orig_zap
        self.servicelist["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
            {
                "cancel": self.servicelist.cancel,
                "ok": self.servicelist.channelSelected,
                "keyRadio": self.servicelist.setModeRadio,
                "keyTV": self.servicelist.setModeTv,
            })


    if __name__ == "__main__":
        threading.Timer(60, self.updateInfos()).start()
 
Zuletzt bearbeitet:
Einrücken aber dann hoffentlich schon per Tab?
 
Nutzt Du Python 3? Dann dürfen Tabs und Leerzeichen nicht vermischt werden, also entweder nur Tabs oder nur Leerzeichen nutzen. Ansonsten ist es egal.

Im Zweifel würde ich mir anschauen, was in der Datei genutzt wird (vermutlich Leerzeichen) und die Einrückung ebenso vornehmen.
Was passiert, wenn man die Tab-Taste drückt, kommt auf die Editor-Konfiguration an. Standardmäßig wird meist ein Tabulator eingefügt. Vermutlich nicht, was hier notwendig ist.
 
Zurück
Oben