Darstellung eines Wertes auf einer Website mit Flask

Django, Flask, Bottle, WSGI, CGI…
Antworten
unknown2346
User
Beiträge: 6
Registriert: Dienstag 28. Januar 2020, 19:22

Mittwoch 5. Februar 2020, 20:21

Hallo Leute,

vlt könntet ihr mir helfen?

ich habe für unsere Fahrzeughalle in der Firma eine kleine Hausautmation in Python geschrieben welche die Tore steuert. Unsere Fahrer können zwar die Tore per Fernbedienung und Taster am Tor steuern aber wenn der Chef heim geht, will er nicht immer durch den Bau rennen sondern vorne an einem Display sehen ob ein Tor noch offen ist und es dann auch schließen können.

Damit der Pi auch messen kann das ein Tor geschlossen ist, hab ich mir Magnetkontakte besorgt und an die Pin's angeschlossen. Im Python-Script kommt das auch an (sobald ein Stromkreis sich öffnet oder schließt wird das per print-Befehl angezeit) aber wie stelle ich das auf der Website dar?
Wie ich den Steuerbefehl für die Tore, über eine Website per Flask an den Pi schicke hab ich schon hinbekommen.

MfG
ein Neuling
Sirius3
User
Beiträge: 11299
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 5. Februar 2020, 20:48

Dann zeig doch mal, was Du hast, damit wir sehen, wo man da noch was einbauen könnte.
unknown2346
User
Beiträge: 6
Registriert: Dienstag 28. Januar 2020, 19:22

Donnerstag 6. Februar 2020, 22:36

Hier mal der Script

Code: Alles auswählen

import importlib.util
try:
    importlib.util.find_spec('RPi.GPIO')
    from RPi import GPIO
except ImportError:
    import FakeRPi.GPIO as GPIO
    
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

for pin in[7,10,12,13,19,33,35,36,37,38]:
    GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

sensor_tor1 = 7
sensor_tor2 = 19
sensor_tor3 = 36
sensor_tor4 = 38
sensor_tor5 = 37
sensor_tor6 = 35
sensor_tor7 = 33
sensor_tuerhalle1 = 10
sensor_tuerwerkstatt = 12
sensor_tuerhalle2 = 13


for pin in[11,15,18,24,26,29,31]:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin,True)

tor1 = 24
tor2 = 29
tor3 = 31
tor4 = 11
tor5 = 15
tor6 = 18
tor7 = 26



def steuerung_tor1():
    GPIO.output(tor1, False)
    sleep(0.5)
    GPIO.output(tor1, True)

def steuerung_tor2():
    GPIO.output(tor2, False)
    sleep(0.5)
    GPIO.output(tor2, True)
    

def steuerung_tor3():
    GPIO.output(tor3, False)
    sleep(0.5)
    GPIO.output(tor3, True)

def steuerung_tor4():
    GPIO.output(tor4, False)
    sleep(0.5)
    GPIO.output(tor4, True)

def steuerung_tor5():
    GPIO.output(tor5, False)
    sleep(0.5)
    GPIO.output(tor5, True)

def steuerung_tor6():
    GPIO.output(tor6, False)
    sleep(0.5)
    GPIO.output(tor6, True)

def steuerung_tor7():
    GPIO.output(tor7, False)
    sleep(0.5)
    GPIO.output(tor7, True)
    

def info_tor1(channel):
    if channel == sensor_tor1:
        if GPIO.input(sensor_tor1) == GPIO.HIGH:
            print('tor 1 offen')
	else:
            print('tor 1 geschlossen')

def info_tor2(channel):
    if channel == sensor_tor2:
        if GPIO.input(sensor_tor2) == GPIO.HIGH:
            print('tor 2 offen')
	else:
            print('tor 2 geschlossen')

def info_tor3(channel):
    if channel == sensor_tor3:
        if GPIO.input(sensor_tor3) == GPIO.HIGH:
            print('tor 3 offen')
	else:
            print('tor 3 geschlossen')

def info_tor4(channel):
    if channel == sensor_tor4:
        if GPIO.input(sensor_tor4) == GPIO.HIGH:
            print('tor 4 offen')
	else:
            print('tor 4 geschlossen')

def info_tor5(channel):
    if channel == sensor_tor5:
        if GPIO.input(sensor_tor5) == GPIO.HIGH:
            print('tor 5 offen')
	else:
            print('tor 5 geschlossen')

def info_tor6(channel):
    if channel == sensor_tor6:
        if GPIO.input(sensor_tor6) == GPIO.HIGH:
            print('tor 6 offen')
	else:
            print('tor 6 geschlossen')

def info_tor7(channel):
    if channel == sensor_tor7:
        if GPIO.input(sensor_tor7) == GPIO.HIGH:
            print('tor 7 offen')
	else:
            print('tor 7 geschlossen')

def info_tuerhalle1(channel):
    if channel == sensor_tuerhalle1:
        if GPIO.input(sensor_tuerhalle1) == GPIO.HIGH:
            print('Tuer Halle 1 offen')
	else:
            print('Tuer Halle 1 geschlossen')

def info_tuerhalle2(channel):
    if channel == sensor_tuerhalle2:
        if GPIO.input(sensor_tuerhalle2) == GPIO.HIGH:
            print('Tuer Halle 2 offen')
	else:
            print('Tuer Halle 2 geschlossen')

def info_tuerhalle1(channel):
    if channel == sensor_tuerwerkstatt:
        if GPIO.input(sensor_tuerwerkstatt) == GPIO.HIGH:
            print('Tuer Werkstatt offen')
	else:
            print('Tuer Werkstatt geschlossen')

GPIO.add_event_detect(sensor_tor1, GPIO.BOTH, callback=info_tor1, bouncetime=300)
GPIO.add_event_detect(sensor_tor2, GPIO.BOTH, callback=info_tor2, bouncetime=300)
GPIO.add_event_detect(sensor_tor3, GPIO.BOTH, callback=info_tor3, bouncetime=300)
GPIO.add_event_detect(sensor_tor4, GPIO.BOTH, callback=info_tor4, bouncetime=300)
GPIO.add_event_detect(sensor_tor5, GPIO.BOTH, callback=info_tor5, bouncetime=300)
GPIO.add_event_detect(sensor_tor6, GPIO.BOTH, callback=info_tor6, bouncetime=300)
GPIO.add_event_detect(sensor_tor7, GPIO.BOTH, callback=info_tor7, bouncetime=300)
GPIO.add_event_detect(sensor_tuerhalle1, GPIO.BOTH, callback=info_tuerhalle1, bouncetime=300)
GPIO.add_event_detect(sensor_tuerhalle2, GPIO.BOTH, callback=info_tuerhalle2, bouncetime=300)
GPIO.add_event_detect(sensor_tuerwerkstatt, GPIO.BOTH, callback=info_tuerwerkstatt, bouncetime=300)

from flask import Flask, render_template
from flask import jsonify

app = Flask (__name__, template_folder='home/pi/Desktop/tore')

@app.route('/')
def start():
	return render_template(index.html)

@app.route('/api/button_tor1', methods=['POST']
def button_tor1:
	steuerung_tor1()
	return render_template('index.html')

@app.route('/api/button_tor2', methods=['POST']
def button_tor2:
	steuerung_tor2()
	return render_template('index.html')

@app.route('/api/button_tor3', methods=['POST']
def button_tor3:
	steuerung_tor3()
	return render_template('index.html')

@app.route('/api/button_tor4', methods=['POST']
def button_tor4:
	steuerung_tor4()
	return render_template('index.html')

@app.route('/api/button_tor5', methods=['POST']
def button_tor5:
	steuerung_tor5()
	return render_template('index.html')

@app.route('/api/button_tor6', methods=['POST']
def button_tor6:
	steuerung_tor6()
	return render_template('index.html')

@app.route('/api/button_tor7', methods=['POST']
def button_tor7:
	steuerung_tor7()
	return render_template('index.html')

if __name__ == '__main__':
	app.run(host="192.168.1.190", port=3100)
und hier mal die Seite im Anfangsstadium. Wie gesagt es scheitert bei mir bei der Anzeige der Tür/ Tor-Kontakte

Code: Alles auswählen

<html>
<head>
#meta http-equiv="refresh" content="5; URL=http://192.168.1.190:3099"
<title>Torsteuerung</title>
</head>
<body bgcolor="grey">
<font face="arial">
<h1>Torsteuerung</h1>

<table>
<tr>

<td><div class="auto-style1">
<b>Tor 1</b>&nbsp;&nbsp;&nbsp
<br>&nbsp
<br>Info-Text Tor<br>

<form type="button" method="POST" action="/api/button_tor1">
<input type="hidden" name="switch" value="Tor 1">
<input type="submit" name="switch" value="Tor 1">
</form>
</div>
</td>
</div>
</table>


</body>
</html>
den automatischen Refresh hab ich jetzt mal als text rein gesetzt damit es sich nicht andauernd selbst lädt.

@Sirius3: ich sag jetzt schon mal danke!
Benutzeravatar
__blackjack__
User
Beiträge: 5117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Freitag 7. Februar 2020, 02:40

@unknown2346: Das ist bestimmt nicht das was Du tatsächlich laufen hast, denn das hat einen Syntaxfehler der sieben mal kopiert wurde, kommt also nicht mal am Compiler vorbei. Wobei es ja eigentlich nur ein Fehler ist, denn man kopiert nicht dauernd den eigentlich gleichen Code und klatscht da überall Nummern an Namen.

Bei den ebenfalls kopierten `info_*()`-Funktionen hast Du Tabs und Leerzeichen gemischt. Die Struktur sieht nur richtig aus, ist es aber zumindest bei mir im Editor dann nicht mal. Eingerückt wird mit vier Leerzeichen, keine Tabs. Die Info-Funktionen bringen in einer Webanwendung auch nichts, da muss man entweder vom Client aus ”pollen” oder mit Websockets arbeiten. Auf jeden Fall braucht man dann JavaScript auf Client-Seite.

Importe gehören an den Anfang des Moduls und nicht irgenwo mitten rein.

Was soll das mit `importlib` bewirken?

`jsonify` wird importiert, aber nirgends verwendet.

`info_tuerhalle1` wird zweimal definier, `info_tuerwerkstatt` gar nicht. Auch das wäre Dir schon mal selber aufgefallen wenn Du den Code mal laufen lassen hättest.

Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Konstanten werden KOMPLETT_GROSS geschrieben. Und sollten dann auch verwendet werden. Für die Pin-Nummern definierst Du zwar Namen, verwendest die für das Setup dann aber nicht, sondern schreibst da noch mal die literalen Pin-Nummern hin.

Die Startseite kann man auch nicht aufrufen weil `index` nicht definiert ist. Die ganzen `steuerung*()`-Funktionen verwenden ein nicht definiertes `sleep()`.

Da läuft nix von. Nicht mal als zwei Einzelprogramme wäre das so jemals gelaufen. Zeig doch mal den tatsächlichen Code.
long long ago; /* in a galaxy far far away */
Sirius3
User
Beiträge: 11299
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 7. Februar 2020, 09:37

Als erstes muß man all die Code-Dopplungen entfernen. Statt Code zu kopieren benutzt man passende Datenstrukturen. Warnungen sind dazu da, dass man sie behebt, nicht dass man sie ignoriert.

Ungetestet könnte das ungefähr so aussehen:

Code: Alles auswählen

from functools import partial
from flask import Flask, render_template
try:
    from RPi import GPIO
except ImportError:
    import FakeRPi.GPIO as GPIO

SENSOR_TOR_PINS = {
    7: "Tor 1",
    19: "Tor 2",
    36: "Tor 3",
    38: "Tor 4",
    37: "Tor 5",
    35: "Tor 6",
    33: "Tor 7",
    10: "Tuer Halle 1",
    13: "Tuer Halle 2",
    12: "Tuer Werkhalle",
}
STEUER_TOR_PINS = [24,29,31,11,15,18,26]

def steuerung_tor(pin):
    GPIO.output(pin, GPIO.LOW)
    sleep(0.5)
    GPIO.output(pin, GPIO.HIGH)

def info_tor(channel, sensor_pin):
    if channel == sensor_pin:
        if GPIO.input(sensor_pin) == GPIO.HIGH:
            print(f'{SENSOR_TOR_PINS[sensor_pin]} offen')
        else:
            print(f'{SENSOR_TOR_PINS[sensor_pin]} geschlossen')


def setup_gpio():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(SENSOR_TOR_PINS.keys(), GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(STEUER_TOR_PINS, GPIO.OUT, initial=GPIO.HIGH)
    for pin in SENSOR_TOR_PINS:
        GPIO.add_event_detect(pin, GPIO.BOTH, callback=partial(info_tor, pin), bouncetime=300)

app = Flask (__name__, template_folder='/home/pi/Desktop/tore')

@app.route('/')
def start():
    return render_template('index.html')

@app.route('/api/button_tor<n:int>', methods=['POST'])
def button_tor(n):
    steuerung_tor(STEUER_TOR_PINS[n-1])
    return render_template('index.html')

def main():
    try:
        setup_gpio()
        app.run(host="192.168.1.190", port=3100)
    finally:
        GPIO.cleanup()

if __name__ == '__main__':
    main()
Zum Anzeigen des Tor-Status mußt Du diesen zum Rendern des Templates abfragen.
Beim HTML solltest Du Dich entscheiden, ob Du die Tornummer als URL oder als hidden-Input übergibst. Bei POST-Requests wäre zweiteres ganz sinnvoll.
unknown2346
User
Beiträge: 6
Registriert: Dienstag 28. Januar 2020, 19:22

Freitag 7. Februar 2020, 22:01

@__blackjack__: ja sorry da hast du vollkommen recht, irgendwie hat es mit dem copy über vnc nicht so geklappt und ich musste alles von hand zu fuß im editor schreiben.

ich danke euch beiden für diese konstruktive kritik bzw. anmerkungen. wie ich schon geschrieben hab bin ich noch recht neu auf dem gebiet unterwegs und muss noch verdammt viel lernen.

also nochmal vielen lieben dank!!!!
unknown2346
User
Beiträge: 6
Registriert: Dienstag 28. Januar 2020, 19:22

Sonntag 9. Februar 2020, 18:54

Ok das Python-Script sieht mal weit besser aus als meines :shock:

aber wo übergebe ich die Werte an die html-seite und wie stelle ich es in html dar??

mfg
Sirius3
User
Beiträge: 11299
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 10. Februar 2020, 16:42

So wie Du auch jeden anderen Wert ans HTML-Template übergeben würdest. Am besten Du fragst die GPIO-Pins bei jeder Anfrage ab.
unknown2346
User
Beiträge: 6
Registriert: Dienstag 28. Januar 2020, 19:22

Dienstag 11. Februar 2020, 21:07

von der theorie her, im python-script

@app.route("/")
def index():
return render_template (index.html, wert_sensor1=wert_sensor1)

und in der html-file müsste ich dann an der passenden stelle {{ wert_sensor1 }} eintragen

wobei wert_sensor1 jetzt nur exemplarisch ist, ist das so korrekt?
Benutzeravatar
__blackjack__
User
Beiträge: 5117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Dienstag 11. Februar 2020, 21:35

@unknown2346: Nur `wert_sensor` und irgendwie muss da noch die 1 als Wert herein kommen.
long long ago; /* in a galaxy far far away */
unknown2346
User
Beiträge: 6
Registriert: Dienstag 28. Januar 2020, 19:22

Donnerstag 13. Februar 2020, 22:07

Ja das ist etwas da komme ich im Moment noch nicht ganz klar bzw. da hab ich mir die letzten Tage etwas die Zähne ausgebissen, genau wie mir noch nicht ganz klar ist was functools bewirkt aber da bin ich gerade noch am lesen.
Antworten