addon script GPIO.add_event_detect callback löst nicht aus

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • addon script GPIO.add_event_detect callback löst nicht aus

    Hallo Forum,

    habe in kodi (17.6) unter raspbian strech desktop das folgende addon service script installiert. Leider wird die callback methode nicht gerufen. Unter Linux in der Kommandozeile geht es.

    Der add_event_detect wird offensichtlich ausgeführt, jedoch kommt es nie zur Ausführung des in der callback Methode definierten codes.

    Mein script:

    Quellcode

    1. import xbmc
    2. import xbmcaddon
    3. import RPi.GPIO as GPIO
    4. import time
    5. import keyboard
    6. SENSOR_PIN = 23
    7. GPIO.setmode(GPIO.BCM)
    8. GPIO.setup(SENSOR_PIN, GPIO.IN)
    9. def mein_callback(channel):
    10. ...print('====zum Testen==============================================================')
    11. ...print('===========================Es gab eine Bewegung!==============================')
    12. ...print('=============================================================================')
    13. ...keyboard.press_and_release(77) #Pfeil rechts x'4d' = 77, in kodi definiert über keymapping, Taste löst play next aus.
    14. GPIO.add_event_detect(SENSOR_PIN , GPIO.RISING, callback=mein_callback)
    15. try:
    16. ...while True:
    17. ......# print(time.time())
    18. ......time.sleep(1)
    19. except KeyboardInterrupt:
    20. ...print("Beende...")
    21. GPIO.cleanup()
    Alles anzeigen

    und die XML dazu:

    XML-Quellcode

    1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    2. <addon id="script.service.playnext" name="play-next" version="0.0.1" provider-name="ej">
    3. <requires>
    4. <import addon="xbmc.python" version="2.25.0"/>
    5. </requires>
    6. <extension point="xbmc.service" library="pir.py" />
    7. <extension point="xbmc.addon.metadata">
    8. <summary lang="en_GB">Bewegungsmelder script</summary>
    9. <description lang="en_GB">a script to skip playback to the next titel when movement detected</description>
    10. <language></language>
    11. <platform>all</platform>
    12. </extension>
    13. </addon>
    Alles anzeigen

    Danke euch im voraus, hoffentlich kann mir jemand weiterhelfen, es ist ein Geburtstagsgeschenk für meinen Sohn, der wegen einer Behinderung eine normale Stereoanlage nicht bedienen kann.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von SkyBird1980 ()

  • Bei RPi und GPIO bin ich eigentlich raus. Allerdings:

    - Liegt die pir.py (so sollte dein Script lt. addon.xml heissen) mit im Addon-Verzeichnis?

    Quellcode

    1. try:
    2. ...while True:
    3. ......# print(time.time())
    4. ......time.sleep(1)
    5. except KeyboardInterrupt:
    6. ...print("Beende...")
    Der Code ist eher suboptimal, für ein Service-Addon wird empfohlen, mit xbmc.Monitor.WaitforAbort(int time) zu arbeiten:

    Quellcode

    1. while not xbmc.Monitor.waitForAbort(1):
    2. ...
    3. GPIO.cleanup()
    Auch würde ich keyboard.press_and_release(77) durch einen JSON-Aufruf(next) ersetzen, da die Taste in verschiedenen Menüs unterschiedliche Bedeutung haben kann - allerdings löst das auch nicht Dein Problem.
    AZi (DEV): Leia auf LibreElec Milhouse 9 | Asrock J4205 | 4 GB RAM | 128 GB Sandisk| Rii mini
    WoZi: Leia auf LibreElec Milhouse 9 | Asrock J3455 | 4GB RAM | 128 GB Sandisk SSD | Atric IR | URC7960

    NAS: unRaid, 4x6TB | TV-Server: Futro S550 mit Hauppauge QuadHD DVB-C
    XBMC-/Kodi-Stuff: vdr4bj1.no-ip.org | SaXBMC-Repo: github.com/b-jesch/SaXBMC/raw/…pository.saxbmc-1.0.1.zip
  • Hab leider mein Leben verskillt. Ich kann von allem ein bisschen, aber nichts gscheid.

    Kann leider nicht helfen.
    "I don't caretaker"

    SKIN: Embuary - Donate: HIER de Hoibe bestellen, merci :thumbup:

    HTPC: i3 Skylake NUC NAS: i3 6100 | 8GB | 15tb | OMV3 -- TV: Samsung 55J6289 | 114x Adalight | Denon X1000 | Heco Victa's

    [img]http://beta.speedtest.net/result/6430872363.png[/img]
  • Hallo

    Ich klinke mich hier mal mit ein, weil es spannend klingt ;)

    Ernestopheles schrieb:

    Der add_event_detect wird offensichtlich ausgeführt
    Was veranlasst Dich zu der Annahme?

    Ist der Input richtig konfiguriert (inklusive Pullup oder Pulldown)? Ich sehe im obigen Code nichts davon.

    Kann Pin 23 überhaupt als Input verwendet werden oder liegen da ggf. noch andere Funktionen drauf?

    Hast Du schonmal in einem ganz normalen Polling (z. B. mit while(true)) probiert, ob Du die Zustände des Inputs korrekt lesen kannst?
    Sowas wie:

    Python-Quellcode

    1. while 1:
    2. if GPIO.input(channel):
    3. print('Input was HIGH')
    4. else:
    5. print('Input was LOW')
    6. time.sleep(0.01)

    Werden unerwünschte Seiteneffekte (wie z. B. "Prellen" des Inputs) irgendwie abgefangen (entweder per Software oder per Hardware)? Ich sehe im obigen Code nichts davon, dann wird softwareseitig scheinbar nicht entprellt.

    Läuft der funktionierende Code per sudo oder auch als normaler user ohne root Rechte? Kann mich an was erinnern, dass /dev/gpiomem root Rechte braucht, um direkt auf die Hardware des RPi zugreifen zu können.

    Bitte auch ans "richtige" Einrücken von Code denken. Soweit ich weiß (komme eigentlich aus der C-Welt) wird bei Python immer in 1-er Schritten oder Vielfachen von 8 Leerzeichen eingerückt.

    Ein paar mehr Infos, bitte!
    OpenELEC 5.0 Final (5.0.7 / 5.0.8 github) | SolidRun CuBox-i4Pro (CPU: ARM Cortex A9 | GPU: Vivante GC2000)
    Kein kodi.log => Kein Support!

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von root2 ()

  • Neu

    Dies ist meine funktionierende Lösung. Leider fehlt die Ausgabe des übersprungenen Musikstücks. Vielleicht hat jemand eine Idee?

    Danke euch.

    Quellcode: pir.py

    1. import xbmc
    2. import xbmcaddon
    3. import RPi.GPIO as GPIO
    4. import time
    5. SENSOR_PIN = 23
    6. GPIO.setmode(GPIO.BCM)
    7. GPIO.setup(SENSOR_PIN, GPIO.IN,pull_up_down=GPIO.PUD_UP)
    8. def mein_callback(channel):
    9. # skip = xbmc.executebuiltin("Player.GetPlayingFile")
    10. # skip = xbmc.Player.GetItem()
    11. xbmc.executebuiltin("PlayerControl(Next)")
    12. GPIO.add_event_detect(SENSOR_PIN , GPIO.FALLING, callback=mein_callback)
    13. fobj_out = open('skipped.txt', 'a')
    14. fobj_out.write('Start am ' + time.strftime("%d.%m.%Y %H:%M:%S") + '\n')
    15. fobj_out.close()
    16. monitor = xbmc.Monitor()
    17. try:
    18. while not xbmc.Monitor.waitForAbort(monitor):
    19. time.sleep(1)
    20. except KeyboardInterrupt:
    21. print("Beende...")
    22. fobj_out = open('skipped.txt', 'a')
    23. fobj_out.write('Ende am ' + time.strftime("%d.%m.%Y %H:%M:%S") + '\n')
    24. fobj_out.close()
    25. GPIO.cleanup()
    Alles anzeigen
  • Neu

    Habe etwas weiter gearbeitet, diese Lösung funktioniert noch nicht:

    1. Wenn die Schleife eine Endebedingung über den Abort (Verlassen des Kodi) hat - entweder über die auskommentierte Whilebedingung oder mittels des break - werden nur die Start- und die Endezeile in die Datei geschrieben.

    2. Meistens erhalte ich eine Zeile "not playing audio", obwohl die ganze Zeit über Musik läuft (von einer automatischen Playlist). Das auch dann, wenn ich die Bedingung if GPIO.event_detected(SENSOR_PIN) fortlasse. In wenigen Versuchen erhalte ich tatsächlich eine Ausgabe des Musikstückes, dann allerdings in nicht brauchbarer Form:
    Skipped: musicdb://songs/61.mp3?xsp=%7b%22order%22%3a%7b%22direction%22%3a%22ascending%22%2c%22ignorefolders%22%3a0%2c%22method%22%3a%22random%22%7d%2c%22rules%22%3a%7b%22and%22%3a%5b%7b%22field%22%3a%22time%22%2c%22operator%22%3a%22lessthan%22%2c%22value%22%3a%5b%2210%3a00%22%5d%7d%5d%7d%2c%22type%22%3a%22songs%22%7d

    Das ist offenbar die Definition der Playlist.
    Wenn ich nicht die automatische Playlist laufen habe, sondern Musik so laufen lasse, erhalte ich den Dateinamen in der Datenbank, z.B. 24.m4a, auch nicht wirklich ausagekräftig...

    Durch Fortlassen der Abortbedingung erhöht sich die Frequenz der Dateiausgaben erheblich. Damit wird offenbar hinreichend häufig der verklausulierte Dateinamen ausgegeben, sodass das script so belassen werden kann, wenn ich nur den wirklichen Musiktitel nur irgendwie ausgeben könnte.

    Python-Quellcode

    1. import xbmc
    2. import xbmcaddon
    3. import RPi.GPIO as GPIO
    4. import time
    5. class MyPlayer(xbmc.Player):
    6. def __init__ (self):
    7. xbmc.Player.__init__(self)
    8. SENSOR_PIN = 23
    9. GPIO.setmode(GPIO.BCM)
    10. GPIO.setup(SENSOR_PIN, GPIO.IN,pull_up_down=GPIO.PUD_UP)
    11. def mein_callback(channel):
    12. # skip = xbmc.executebuiltin("Player.GetPlayingFile")
    13. xbmc.executebuiltin("PlayerControl(Next)")
    14. GPIO.add_event_detect(SENSOR_PIN , GPIO.FALLING, callback=mein_callback)
    15. fobj_out = open('skipped.txt', 'a')
    16. fobj_out.write('Start am ' + time.strftime("%d.%m.%Y %H:%M:%S") + '\n')
    17. fobj_out.close()
    18. monitor = xbmc.Monitor()
    19. player = MyPlayer()
    20. try:
    21. # while not xbmc.Monitor.waitForAbort(monitor):
    22. fobj_out = open('skipped.txt', 'a')
    23. while True:
    24. if GPIO.event_detected(SENSOR_PIN):
    25. if player.isPlayingAudio():
    26. text = 'Skipped: ' + str(player.getPlayingFile())
    27. else:
    28. text = 'not playing audio'
    29. fobj_out.write(text + '\n')
    30. time.sleep(1)
    31. if xbmc.Monitor.waitForAbort(monitor):
    32. print("")
    33. # break
    34. except KeyboardInterrupt:
    35. print("Keyboard Interruption issued, Stopping...")
    36. finally:
    37. print("finally reached")
    38. fobj_out.close()
    39. fobj_out = open('skipped.txt', 'a')
    40. fobj_out.write('Ende am ' + time.strftime("%d.%m.%Y %H:%M:%S") + '\n')
    41. fobj_out.close()
    42. GPIO.cleanup()
    Alles anzeigen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Ernestopheles ()

  • Neu

    Jetzt ist alles bestens, bis auf die fehlende Abort-Behandlung. Soll Kodi beim Verlassen also weiterhin das script nach 5 Sec killen, macht fast gar nix.

    Offen ist auch die Frage, warum häufig audio not playing erkannt wird, das aber nur aus akademischem Interesse.
    Dumm ist auch, dass ich 2 Bedingungen für die Bewegungserkennung habe, das kostet unnötige Resourcen, zumal die If-Abfrage ja ständig wiederholt wird.

    Ich lass es jetzt erst mal so, verbessern kann ich immer noch, Hauptsache es läuft.

    Das ganze Projekt stelle ich später als ganzes vor.

    Danke euch allen und liebe Grüße
  • Neu

    du solltest bei "waitForAbort" nicht "monitor" übergeben sonder die Zeit die gewartet werden soll.

    probier mal sowas

    Python-Quellcode

    1. ...
    2. while not monitor.abortRequested():
    3. if GPIO.event_detected(SENSOR_PIN):
    4. if player.isPlayingAudio():
    5. text = 'Skipped: ' + xbmc.getInfoLabel("Player.Title").decode('utf-8')
    6. else:
    7. text = 'not playing audio'
    8. fobj_out.write(text + '\n')
    9. if monitor.waitForAbort(1):
    10. break
    11. ...
    Alles anzeigen
  • Neu

    AcidZero schrieb:

    du solltest bei "waitForAbort" nicht "monitor" übergeben sonder die Zeit die gewartet werden soll.

    probier mal sowas

    Python-Quellcode

    1. ...
    2. while not monitor.abortRequested():
    3. if GPIO.event_detected(SENSOR_PIN):
    4. if player.isPlayingAudio():
    5. text = 'Skipped: ' + xbmc.getInfoLabel("Player.Title").decode('utf-8')
    6. else:
    7. text = 'not playing audio'
    8. fobj_out.write(text + '\n')
    9. if monitor.waitForAbort(1):
    10. break
    11. ...
    Alles anzeigen
    xbmc.Monitor.waitForAbort(1) gab bei mir eine exception, es werde kein integer verlangt, sondern ein object. daher meine Anpassung, die ja funktioniert, wenn auch nicht ohne Nebenwirkungen...
  • Neu

    das hier ein Objekt benötigt wird wäre mir neu
    codedocs.xyz/xbmc/xbmc/group__…d0fddebee906abcda904e8249


    Quellcode

    1. waitForAbort()
    2. bool XBMCAddon::xbmc::Monitor::waitForAbort ( ... )
    3. Function: waitForAbort([timeout])
    4. Wait for Abort
    5. Block until abort is requested, or until timeout occurs. If an abort requested have already been made, return immediately.
    6. Parameters
    7. timeout [opt] float - timeout in seconds. Default: no timeout.
    8. Returns
    9. True when abort have been requested, False if a timeout is given and the
    10. operation times out.
    Alles anzeigen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von AcidZero ()

  • Neu

    Die richtige Syntax sollte sein:

    Quellcode

    1. xbmc.Monitor().waitForAbort(1)
    Normalerweise bildet man eine Instanz des Monitorobjektes, da wandern dann die Klammern mit.
    AZi (DEV): Leia auf LibreElec Milhouse 9 | Asrock J4205 | 4 GB RAM | 128 GB Sandisk| Rii mini
    WoZi: Leia auf LibreElec Milhouse 9 | Asrock J3455 | 4GB RAM | 128 GB Sandisk SSD | Atric IR | URC7960

    NAS: unRaid, 4x6TB | TV-Server: Futro S550 mit Hauppauge QuadHD DVB-C
    XBMC-/Kodi-Stuff: vdr4bj1.no-ip.org | SaXBMC-Repo: github.com/b-jesch/SaXBMC/raw/…pository.saxbmc-1.0.1.zip