[GELÖST] Überwachung / Zugriff auf zweiten Raspi

Begonnen von Markus., 12 Dezember 2019, 10:49:59

Vorheriges Thema - Nächstes Thema

Otto123

Naja mein Test mit PIN5 war eine "ungefährliche" Versuchsvariante, da weiß ich das es geht und nichts passiert :)
An welchem PI Du dein Script testest ist ja egal ;) Da praktisch "nichts" installiert werden muss - ok eine python bibo :)

Ich würde
- ein Device in FHEM machen.
- Etwas per Hand (python Script) per mqtt publishen
- Die GPIO Abfrage mit Print testen (python script)
- Und dann beides "verknüppern" ;)

Oder andersrum :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Markus.

so in etwa hatte ich es vor... :-) Dauert nur etwas länger, da viel neuland auf mich wartet.. :-)
Da wären Abschaltung Mosquitto auf dem Fhem Server. Dann MQTT2_Server drauf neben Python Abfragen, und GPIOs ausklamüsren um raus zubekommen welche LED Warnmeldung an welchem GPIO hängt. Nunja letzteres habe ich jetzt..
Hoffe nur das geht mit dem MQTT2_Server smooth..

Gruß

Markus

Markus.

#17
Hallo Otto,

noch ne Frage ;-) Mal zum Verständnis..
Und zwar werden ja auf dem zweiten Raspi die Outputs über einen Service geschaltet. Wie sieht es dann da bei einem exklusiven Zugriff aus? Kann ich die Outputs eigentlich überhaupt "passiv" lesen?
Zum Beispiel Pin 15 ist ja laut WiringPI (getall) als Output definiert. Wenn ich jetzt "GPIO.setup (15,Output.Out)" mache im Skript wird dann nicht für den Skript-Prozess
der Output exklusiv behandelt und eben für den eigentlichen Service gesperrt?
Und noch was....
Wenn man innerhalb des Skriptes einen GPIO.Setup als OUT definiert, kann man dann GPIO.RISING und GPIO.Faling verwenden auf den als Output definierten Pin ?

So in etwa...

# mqtt initialisieren und eine Startnachricht senden
import paho.mqtt.client as mqtt
client =mqtt.Client("LISAGATEWAY")
broker="192.168.178.41"
client.connect(broker, keepalive=86400)  # per default ist keepalive=60, damit steht die Verbindung nur 1 min :
client.publish("home/states/LED15","{\"GPIO\":\"start\"}")

#gpio initialisieren. Achtung Pin Modus BOARD! Pin 7 LED, Pin 5 Taster
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(15, GPIO.OUT)
GPIO.setwarnings(False)


print("Starte Schleife ... Can be canceled with CTRL+C")
try:
    while True:
        GPIO.wait_for_edge(15, GPIO.RISING)
        client.publish("home/states/LED15","{\"GPIO\":\"AN\"}")
        print("Alarm Pin 15 an")
        GPIO.wait_for_edge(15, GPIO.FALLING)
        client.publish("home/states/LED15","{\"GPIO\":\"AUS\"}")
        print("Alarm Pin 15 aus")
except KeyboardInterrupt:
    print("KeyboardInterrupt has been caught.")

print("Beende Programm")
#GPIO.output(15, False)
GPIO.cleanup()




Ich muss den PIN Status halt "passiv" lesen.

Gruß

markus


Otto123

Hallo Markus,

das hat mich gestern Abend auch noch beschäftigt :)
Dabei hab ich auf die Schnelle noch das probiert:
Abfrage PIN7
#!/usr/bin/env python
#coding: utf8
import RPi.GPIO as GPIO
# Zählweise der Pins festlegen
GPIO.setmode(GPIO.BOARD)
# Pin 7 als Eingang festlegen
GPIO.setup(7, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
# Schleifenzähler
i = 0
# Endlosschleife
while 1:
    # Eingang lesen
    if GPIO.input(7) == GPIO.HIGH:
        # Wenn Eingang HIGH ist, Ausgabe im Terminal erzeugen
        print "Eingang HIGH " + str(i)
        # Schleifenzähler erhöhen
        i = i + 1

Und damit im zweiten Prozess das PIN7 gesetzt:
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD) # Broadcom pin-numbering scheme

GPIO.setup(7, GPIO.OUT) # output rf

# Initial state for LEDs:
print("Testing RF out, Press CTRL+C to exit")

try:
     print("set GIOP high")
     GPIO.output(7, GPIO.HIGH)
     time.sleep(5)
except KeyboardInterrupt: # If CTRL+C is pressed, exit cleanly:
   print("Keyboard interrupt")

except:
   print("some error")

finally:
   print("clean up")
   GPIO.output(7, GPIO.LOW)
   GPIO.cleanup() # cleanup all GPIO


Alles nur geraubt :) Aber prinzipiell funktioniert das. Ok die Flanke ermitteln ist damit nicht geklärt. ;)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Markus.

Hallo Otto,

das ist ja genial.. :-) Hoffe ich komme heute mal zum testen. Aber wenn ich den cleanup richtig verstehe, sollte er doch im lesenden Prozess sein ? Oder?

Viele Grüße

Markus

Otto123

ZitatCleanup
At the end any program, it is good practice to clean up any resources you might have used. This is no different with RPi.GPIO. By returning all channels you have used back to inputs with no pull up/down, you can avoid accidental damage to your RPi by shorting out the pins. Note that this will only clean up GPIO channels that your script has used. Note that GPIO.cleanup() also clears the pin numbering system in use.
Verstehe ich anders...
Im lesenden Prozess habe ich ja nichts verändert/will ich nichts verändern. Ja ok, ich schalte einen PullDown Widerstand. ??? Kann man vielleicht weglassen :)

Dein schreibender Prozess ist ja deine Anwendung.

Ich weiß es ehrlich nicht. Versuch ...
Es gibt noch andere GPIO Bibliotheken: GPIO Zero und pigpio ...
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Markus.

Habe gestern mal ein wenig mit dem Skript gespielt. Bin zwar noch einiges Entfernt von dem was ich haben will, aber zum verstehen des ganzen ist es verdammt hilfreich. Zwei fragen hätte ich dazu :-)

Und zwar, wenn ich client.connect(broker, keepalive=86400) verwende bekomme ich einen Syntax Fehler wie "Struct H blabla" (hab vergessen den zu kopieren).
Wenn ich dann baer das Keepalive raushole funktioniert es. Kann es sein das entweder nur der Host Oder alle 4 Parameter definiert werden müssen?
So wie "connect(host, port=1883, keepalive=60, bind_address="")"
Oder liegt es am Interpretereintrag  den ich verwende #!/usr/bin/python
Und letzte Frage bevor ich heute Abend weiter bastel...
Ich habe das script jetzt im Verzeichnis /home/pi ablegt. Gibt es igrendwie eine Empfehlung wo solche eigenen Scripte liegen sollten?

Gruß

Markus



Otto123

#22
Hallo Markus,

So wie es dastand geht es bei mir, ich kann lediglich nicht keepalive=0 setzen.
Mit dem broker="192.168.56.82"
client.connect(broker, port=1883, keepalive=86400)

hatte ich folgende Probleme:
client.connect("raspib2") hat er gemacht, dann ging plötzlich meine Namensauflösung nicht mehr
client.connect("192.168.56.82") hat er nicht gemacht, da hat er die Punkte angemeckert.

dann habe ich das als extra Variable gemacht und es geht sowohl mit IP als auch mit Namen. Teste vielleicht einen kürzeren keepalive, ich bin da eh nicht sicher wie man richtig macht.

Der Interpreter Eintrag spielt ja nur ne Rolle wenn Du die Datei ausführbar machst, ich spare mir das immer mit python script.py

Wo Du die Scripts hinlegst? das entscheide ich immer aus dem Bauch und nach momentanen Ordnungssinn.
Wenn auf dem pi nicht viel passiert lass ich sie in /home/pi man muss sie ja nur lesen können, und beim bearbeiten ist es einfach.
Man kann auch /opt/scripts machen oder im Web hab ich das gefunden:
ZitatEs gibt auf Linux /usr/local/sbin für SystemScripts und /usr/local/bin für allgemeine Userscripts
Ich habe da irgendwie für mich noch keine Ordnung :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Markus.

Wollte eigentlich vermeiden, auf die "remote" Logfiles zuzugreifen. Aber die RPI.GPIO lib scheint ein wenig statisch zu sein, was den Zugriff auf "im Zugriffbefindliche GPIOs" betrifft (geiles Wort :-) )
pigpio ist die nächste Lib für Python die ich mir mal ansehen will. Da geht auch remote GPIO Monitoring. Aber die Basics mit Python muss ich mir nebenbei auch noch in den Kopf prügeln :-)





Markus.

ja das war die erste Idee.. Aber trotzt allem bin ich offen für jede Möglichkeit... hast du irgendwo einen link oder mehr Infos wie ich das bewerkstelligen könnte. neben meiner GPIO Bastelei :-)

Markus.

#25
So habs mal mit pigpio gemacht. Also das Monitor.py geändert für MQTT ohne irgendwelche Überprüfung ob die Verbindung steht



import sys
import time
import pigpio
import paho.mqtt.client as mqtt

client =mqtt.Client("COMPUTER")
broker="192.168.178.41"
client.connect(broker, keepalive=6000)

last = [None]*32
cb = []

def cbf(GPIO, level, tick):
   if last[GPIO] is not None:
      diff = pigpio.tickDiff(last[GPIO], tick)
      client.publish("G={} l={} d={}".format(GPIO, level, diff))
   last[GPIO] = tick

pi = pigpio.pi()

if not pi.connected:
   exit()

if len(sys.argv) == 1:
   G = range(0, 32)
else:
   G = []
   for a in sys.argv[1:]:
      G.append(int(a))
   
for g in G:
   cb.append(pi.callback(g, pigpio.EITHER_EDGE, cbf))

try:
   while True:
      time.sleep(60)
except KeyboardInterrupt:
   print("\nTidying up")
   for c in cb:
      c.cancel()

pi.stop()




Der Datensatz der gepublished wird, sieht wie folgt aus

G=22 l=0 d=5005442

Also BCM Pin, Zustand vorher / nachher, und Zeit seit letztem Zustand
Das kommt auch so in etwa auf dem FHEM Server an. Aber bekomme für das MQTT Device folgende Meldung im Log

2019.12.19 18:17:47 3: MQTT2_COMPUTER: bad reading name l=0 d=5004293:.* G_22_l_0_d_5004293 (contains not A-Za-z/\d_\.- or is too long)


So nun steh ich auf dem schlauch. Wie bekomm ich den nun ein vernünftiges Reading daraus ?

Gruß

Markus


Markus.

so bin mal ein Stück weiter gekommen:
Publishen tue ich jetzt nur noch den level (0 oder1 ) und die GPIO Nummer


client.publish ("GPIO{}:STATUS{}".format(GPIO, level))


Aber als MQTT Device passt das noch nicht ganz und sieht wie folgt aus


GPIO22_STATUS0     2019-12-19 19:04:20
GPIO22_STATUS1     2019-12-19 19:04:15



Das Reading müsste aber z.b GPIO22 heissen und der Wert eben nur 0 oder 1

Wie kann ich das denn in dem Publish Befehl so einbauen?

Gruß

Markus

Markus.

kann ich das nicht direkt am MQTT2_Device "auseinander pfriemeln"
Am Ende soll ja für jede GPIO ein extra reading automatisch angelegt werden. Es wird ja bei Statusänderung jeweils die PIN Nummer und der Level gepublished..
Da steh ich im Moment auf dem Schlauch mangels Programierkenntnissen in Python.
Ich denke mal am elegantesten wäre es, wenn man das direkt in der Client.publsih Zeile des Skriptes defineren könnte.

client.publish ("GPIO{}:STATUS{}".format(GPIO, level))



Gruß
Markus

Beta-User

Vermutlich tust du dir leichter, wenn du das besser zergliederst und Topictree und Payload trennst. Später auf der FHEM-Seite ist das vermutlich mehr Aufwand... Auf Verdacht:
client.publish ("remotePi/GPIO{}/STATUS{} ".format(GPIO, level))
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Markus.

Danke dir.. Werds nacher mal vesuchen. Was ich jetzt mal in einen "Trockentest" ohne Broker gemacht habe ist folgendes.
print ("home/states/GPIO{}".format(GPIO)),("{}".format(level))
Das gibt mir folgendes Ergenis auf der Konsole bei einem blinkenden Ausgang

home/states/GPIO18 0
home/states/GPIO18 1
home/states/GPIO18 0
home/states/GPIO18 1
home/states/GPIO18 0
home/states/GPIO18 1
home/states/GPIO18 0


Was ja eigentlich schon mal nicht so schlecht aussieht.. oder
Somit habe ich den Topic tree eben dynamisch und payload getrennt mit einem Leerzeichen. Bin nur mal gespannt wenn ich das nachher mal mit dem Broker testen kann und ob MQTT2_Server das device dann auch mit dem reading gpio18 anlegt ;-)