Raspberry Pi GPIO Netzwerkverbindung verloren und erneut versuchen zu verbinden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@bachatero18,

andere haben das Problem wohl auch. Ein "Workaround" ist in diesem Thread beschrieben:
https://github.com/gpiozero/gpiozero/issues/659
imonbln
User
Beiträge: 202
Registriert: Freitag 3. Dezember 2021, 17:07

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.
Benutzeravatar
__blackjack__
User
Beiträge: 14379
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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()
Who is General Failure and why is he reading my hard disk?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

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
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1339
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

__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

sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten