Zdravím,
potřeboval bych od zdejších guru trošku pomoci s problémem. Mám na stole projekt na ovládání turniketu včetně počítání osob. Technicky je ovládání turniketu vyřešeno (pomocí RFID čipu). Turniket má 5 RPi 3B(2x vchod, 2x východ a "polikač karet) a je ovládán přes seplé relé. Čtečky jsou připojené přes UART (+ bižuterie okolo - převodníky UART na 485 kvuli délce, diagnostické diody, pípak...). RPi komunikují se serverem přes API, který vyhodnocuje možnost průchodu a posílá zpět na RPi informaci, zda uživatel může projít, či ne. Poté je hlídáno "rameno" turniketu, zda člověk skutečně prošel, nebo se někde "zakecal" a turniketem neprošel. S tímto problém zatím nemám.
Problém nastává trochu s logikou. Pokud na 1 RPi někdo čipne, potřebuji zablokovat načítání čipů na protější RPi (aby se lidé v turniketu nesrazili čelem ). Toto řeším pomocí REMOTEGPIO a pythonu pomocí knihovny GPIOZero. Na 1 RPi sepnu pin pokud je přiložen čip a druhá malina po LAN načítá stav tohoto pinu - podle stavu pinu se zařídím (je-li remotePIN(26).on zastavím threading.Thread s načítáním čipů, pokud je off, odpauznu thread). Dále pomocí PingServer hlídám dostupnost ostatních RPi, pokud neodpovídá některá z RPi, nespínám blokovací pin.
Tak sem se trochu rozepsal a teď k problému. Pokud mi vypadne LAN, tak toto mám ošetřené. Pokud ale protější RPi restartuju, tak mi nastává chyba "Broken Pipe" a nejsem schopen se z ní "nějak" vymotat. Problém je pravděpodobně v tom, že než RPi zdetekuje, že je protější RPi off-line, tak tam vlítně ještě nějaký dotaz na stav pinu a ten už není možné vyřídit a celá komunikace se rozsype.
Dá se nějak v GPIOZero uzavřít navázaná komunikace a znovu ji sestavit? Nebo Broken Pipe nějak jinak ošetřit? Pokud někomu pomůže python kód, tak mu ho klidně zašlu, ale má cca 800 řádků a sem ho asi nemá smysl dávat...
Za jakýkoliv nápad děkuji
GPIOZero
- PetrSmetana
- Příspěvky:313
- Registrován:pon 22. črc 2019 9:06:45
- Bydliště:Mnich
- Dal poděkování: 28 poděkování
- Dostal poděkování: 60 poděkování
- Kontaktovat uživatele:
Re: GPIOZero
Ahoj, já bych to asi centralizoval a udělal někde mqtt brokera místo použití GPIO přes síť. Podle toho co popisuješ tam budou problémy se "zaseknutými" sockety na straně GPIOZero. Pokud je to open source, tak se v tom můžeš zkusit pošťourat, ale jinak bych si od toho moc nesliboval a radši se vydal nějakou standardizovanou cestou. Pokud tam máš tolik RPi a chtěl bys tam mít navíc zajištěnou nějakou redundanci, tak bych zvážil nasazení k8s por tento účel.
Modré z nebe na počkání, zázraky do dvou dnů.
Re: GPIOZero
Zdravím,
díky za pošťouchnutí, MQTT jsem zprovoznil, nastavil. Dělá přesně to, co potřebuji (na 98% ). Na jednom RPi mi běží Broker (pro redudanci v každém turniketu zvlášť), klienti se hlásí do adresářů, kde ukládají/načítají data a podle toho přepínají stav RFID čteček (může čipovat / čtečka odpojena). Pokud některé RPi restaruju (nebo odpojím od LAN), tak se pošle will_set a ostatní o tom vědí.
Abych byl zcela uspokojen ( ), dá se nějak vypsat, který klient poslal zprávu, nebo se odpojil? Používám client = mqtt.Client("Stanice1"), popřípadě jsem zkoušel i client = mqtt.Client(client_id = "Stanice1"), ale nějak jsem nepřišel na to, jak client_id někde vypsat...
Za nápady děkuji.
díky za pošťouchnutí, MQTT jsem zprovoznil, nastavil. Dělá přesně to, co potřebuji (na 98% ). Na jednom RPi mi běží Broker (pro redudanci v každém turniketu zvlášť), klienti se hlásí do adresářů, kde ukládají/načítají data a podle toho přepínají stav RFID čteček (může čipovat / čtečka odpojena). Pokud některé RPi restaruju (nebo odpojím od LAN), tak se pošle will_set a ostatní o tom vědí.
Abych byl zcela uspokojen ( ), dá se nějak vypsat, který klient poslal zprávu, nebo se odpojil? Používám client = mqtt.Client("Stanice1"), popřípadě jsem zkoušel i client = mqtt.Client(client_id = "Stanice1"), ale nějak jsem nepřišel na to, jak client_id někde vypsat...
Za nápady děkuji.
Re: GPIOZero
Tak doreseno, samozrejme spatny if . V definici on_message jsem odchytaval pouze stav "1" a else jsem nezobrazoval. Ted odchytavam stav "0" a "1" a ostatni zobrazim. Do will_set generuju nazev stanice a ten se mi krasne propise na ostatni RPi, takze vsechny vedi, ktere RPi vypadlo a muzu se podle toho zaridit. Na RPi, kde vypadne LAN, tak tento stav odchytavam na client.on_disconnect a taky se podle toho zaridim (pruchod cipem porovnavam s lokalni databazi). PERFEKTNI!!!
Diky za napad, jak toto udelat.
Diky za napad, jak toto udelat.