Seite 1 von 1

Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Mittwoch 12. Januar 2022, 19:11
von bachatero18
Hallo zusammen,
ich hab folgenden Problem, ich Frage von einem Computer die GPIO Pins eines Raspberry Pi's der im selben Netzwerk ist, ab.

Es kommt mal vor, dass die Verbindung verloren geht. Im Prinzip soll er nach einer Wartezeit nochmals versuchen die Verbindung aufzubauen.
Das tut er aber nicht auch wenn der Raspberry Pi wieder erreichbar sein sollte. Ich muss das Programm dann jedes mal Neustarten und dann geht es wieder.

Was kann ich tun damit er genau das macht?

Anbei einmal der prinzipielle Aufbau des Python-Programms:

Code: Alles auswählen

from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep

factory = PiGPIOFactory(host='192.168.178.5')
led = LED(17, pin_factory=factory)

while True:
    try:
        if led.is_lit:
            print("ON")
            sleep(5)
        else:
            print("OFF")
            sleep(5)

    except:
        print("Verbindungsfehler")
        sleep(5)

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Mittwoch 12. Januar 2022, 19:34
von rogerb
@bachatero18,

andere haben das Problem wohl auch. Ein "Workaround" ist in diesem Thread beschrieben:
https://github.com/gpiozero/gpiozero/issues/659

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Mittwoch 12. Januar 2022, 19:37
von imonbln
Ich sehe im Sourcecode der PiGPIOFactory keinen Code für ein Reconnect. In der Property Connection wird geprüft, ob die Connection da ist und wenn nicht, die Exception einfach ignoriert (siehe https://github.com/gpiozero/gpiozero/bl ... #L112-L121) .

IMHO ist das ein Bug in GPIOZero Package. In einer idealen Welt würdest du das mit den Entwicklern diskutieren und das Package verbessern, oder als dreckigen Workaround in der Realität die Factory und led in deiner Exception neu instantiieren.

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Mittwoch 12. Januar 2022, 20:21
von bachatero18
@rogerb
den hatte ich vorhin tatsächlich auch schon gefunden und hatte zu schnell rüber gelesen und das vor schnell als nicht sinnvoll abgestempelt. Hab es jetzt etwas abgeändert er haut mir bei fehlender Verbindungfehler Fehler raus aber bricht halt nicht ab und baut eine Verbindung wieder auf zumindest versucht er es. Except habe ich die expliziten Fehler rausgenommen weil er bei allen das selbe machen soll. Aber das kann ja nicht die Lösung sein.

@imonbln
ja ich warte mal vielleicht hat noch jemand eine gute Idee. Btw aber so ein reconnect wäre schon nice, einfach eine Zeile dazu und fertig.

Code: Alles auswählen

from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep

while True:
    factory = None
    while not factory:
        
        try:
            factory = PiGPIOFactory(host='192.168.178.39')
        except:
            print("Verbindungsfehler")
            sleep(5)
    led = LED(17, pin_factory=factory)
    led.on()
    sleep(5)
    
    try:
        led.close()
        factory.close()
    except:
        print("verbindungsfehler 2")
        continue

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Mittwoch 12. Januar 2022, 20:41
von __blackjack__
@bachatero18: Das nackte ``except`` geht gar nicht. Was ist wenn da eine Ausnahme kommt die gar nichts mit der Verbindung zu tun hat? Nach so einem Fehler kann man sich dann dusselig suchen.

``sleep(5)`` wir ja letztlich in jedem möglichen Ausgang gemacht, also braucht das da auch nur *einmal* stehen und nicht dreimal.

Code: Alles auswählen

#!/usr/bin/env python3
import struct
from time import sleep

from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOFactory


def main():
    factory = PiGPIOFactory(host="192.168.178.5")
    led = LED(17, pin_factory=factory)

    while True:
        try:
            print("ON" if led.is_lit else "OFF")
        except struct.error:
            print("Verbindungsfehler")
        sleep(5)


if __name__ == "__main__":
    main()

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Mittwoch 12. Januar 2022, 20:58
von bachatero18
Wie ich es abgeändert hat ist auch nur ein Beispiel damit ich sehe was passiert. Und Sleep() soll auch eher wenn es geht gar nicht rein.

Das stimmt wohl mit den nackten except ich werden es eine Zeit lang laufen lassen und die genauen Fehler abspeichern mit ''sys.exc_info()[0] '' und dann kann ich für jeden Fehler ein eigenes except machen wenn es nötig ist.

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 12:56
von bachatero18
Weiß jemand wo ich eine Liste finde die ich für PIGPIO alle Funktionen finde die es gibt?

Problem ist gerade wenn ich die Verbindung zum PI schließe schaltet er auch die LED aus die soll aber angeschaltet bleiben. Es liegt wohl an Factory.close()

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 13:00
von rogerb
bachatero18 hat geschrieben: Donnerstag 13. Januar 2022, 12:56 Weiß jemand wo ich eine Liste finde die ich für PIGPIO alle Funktionen finde die es gibt?
Am besten direkt an der Quelle:
https://github.com/joan2937/pigpio

Da ist auch eine Dokumentation verlinkt

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 13:10
von bachatero18
danke.

Weiß du wo ich da genau suchen muss? weil ich persönlich finde da nichts?

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 13:55
von __deets__
Das ist alles Gehampel. PiGPIO ist super, aber es ist nicht dafuer gemacht. Statt zu versuchen darum herumzuhacken, bau dir einfach einen trivialen flask oder FastAPI-webservice, der die Hardware via pigpio lokal & robust kontrolliert, und dann steuerst du aus deinem entfernten Prozess das alles einfach per HTTP-Requests fern.

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 14:40
von bachatero18
Danke für die Antworten. Ich glaub das bekomm ich nicht hin dafür bin ich noch nicht ausreichend in Python drin.

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 14:56
von __deets__
Man waechst ja an seinen Aufgaben. Was du jetzt vorhast ist auch nicht unkompliziert, und dann auch nur ein Workaround. Ich glaube zB nicht, dass du dein akutes Problem - reset des Levels - geloest bekommst, weil ich in der API nichts dazu sehe. Der geht einfach nicht davon aus, dass man da re-connected, etc.

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 15:07
von bachatero18
Ja habe jetzt einiges gesucht aber auch nichts gefunden.
Da hast du recht aber das ist glaube ich nicht mal eben schnell gelöst.

Ich bin am überlegen ob ich auf dem Raspberry PI noch ein Script laufen lasse der reagiert wenn ein Pin kurz auf High gesetzt wird und wenn ein anderer Pin kurz auf high gesetzt wird hört er mit der Aufgabe auf.

Ich glaube das ist für meinen Wissensstand erstmal das Beste und es ist erstmal lauffähig. Die Verbesserung werden ich mir bei genügend Zeit anschauen und mal gucken ob ich das hinbekomme

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 15:13
von __deets__
Ich wuerde mir ja erstmal anschauen, wie kompliziert es wirklich ist, einen Webservice zu bauen. Das ist ja nicht so, als ob das nicht tausendfach passiert waere, um eben zB GPIOs ueber eine Webseite zu steuern. Aber ist natuerlich dein Problem.

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Donnerstag 13. Januar 2022, 15:27
von bachatero18
Ok das sah jetzt beim rüberfliegen nicht so schwierig aus ich glaube das packe ich aber ich lass mir zeit.

Danke für die Hilfe

Re: Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Verfasst: Freitag 14. Januar 2022, 13:52
von DeaD_EyE
__deets__ hat geschrieben: Donnerstag 13. Januar 2022, 13:55 Das ist alles Gehampel. PiGPIO ist super, aber es ist nicht dafuer gemacht. Statt zu versuchen darum herumzuhacken, bau dir einfach einen trivialen flask oder FastAPI-webservice, der die Hardware via pigpio lokal & robust kontrolliert, und dann steuerst du aus deinem entfernten Prozess das alles einfach per HTTP-Requests fern.
Er hat FastAPI geschrieben <3
Eine gewisse Einarbeitung ist dennoch erforderlich.
Ob jetzt mit RPi.GPIO oder pigpio oder gpiozero gearbeitet wird, ist egal.

Code: Alles auswählen

from __future__ import annotations

import atexit
from typing import Literal

try:
    from RPi import GPIO as gpio
except ImportError:
    from unittest.mock import Mock

    gpio = Mock()

from pydantic import BaseModel
from fastapi import FastAPI
from fastapi.exceptions import HTTPException
from fastapi.responses import RedirectResponse


api = FastAPI()
ON_OFF = Literal[0, 1]

gpio.setup(gpio.BCM)
# gpio.setmode([2, 3, 4, 5, 6, 7], gpio.OUTPUT)
atexit.register(gpio.cleanup)


class ReadResponse(BaseModel):
    """
    Status des gelesenen GPIO Pin
    """

    pin: int
    state: bool


@api.get("/")
def root():
    """
    Umleitung zur Dokumentation
    """

    return RedirectResponse("/docs")


@api.get("/read/{pin}", response_model=ReadResponse)
def read(pin: int):
    """
    GPIO Pin lesen
    """

    try:
        state = bool(gpio.input(pin))
        # 1 / 0
    except Exception as e:
        raise HTTPException(404, e.args[0])

    return {"pin": pin, "state": state}


@api.post("/read/{pin}/{value}")
def write(pin: int, value: ON_OFF):
    """
    GPIO Pin setzen
    """

    try:
        gpio.output(pin, value)
        state = bool(gpio.input(pin))
        # 1 / 0
    except Exception as e:
        raise HTTPException(404, e.args[0])

    return {"pin": pin, "state": state}


# dann das Script mittels uvicorn von der Kommandozeile starten:
# uvicorn datei_ohne_erweiterung:api