Verständnisfragen zum Webframework und Python - Python Projekt realisierbar?

Django, Flask, Bottle, WSGI, CGI…
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

Moin,

ich müsste im Vorfeld ein paar Dinge zu meinem besseren Verständnis abklären, bevor ich weitermache. Ich möchte eine Steuerung für eine Hausautomatisierung bewerkstelligen, dazu wurde bereits eine Steuerung mittels pymodbus erstellt um die Geräte per Relais usw. anzusprechen, die Hardwareimplementierung funktioniert so weit testweise. Das ganze soll jetzt mittels Python für den Webbrowser implementiert werden, ursprünglich wollte ich das in PHP machen, weil ich damit besser vertraut bin, allerdings sollen auch Variablen bzw. Werte bidirektional übergeben werden, also schreibe Wert nach Pythonsteuerung oder lese Wert von Pythonsteuerung. Deswegen habe ich mir überlegt, gleich ein Python-Framework zu verwenden, damit ich direkt Variablen, Funktionen oder Klassen damit aufrufen kann. Zur Steuerung selber sollen erstmal nur einfache Werte wie an oder aus gesetzt werden, später wäre es aber ganz nett, wenn man zum Beispiel auch Intervalle wie z.B. zwischen 0 und 10 V setzen kann.

Meine Frage zum Verständnis ist, sollten die Skripte nur beim Aufbau der Seite einmal geladen werden, weil ich permanent Werte einlesen möchte, quasi eine Temperatur live Ansicht. Aber wie mache ich das am besten, soll dann einmal ein Python Programm permanent im Hintergrund laufen, welches die Daten einliest und die Webseite holt sich die Werte dann per Javascript, ohne dabei ständig neu geladen zu werden? Falls das überhaupt möglich ist, ich vermute fast das die Daten irgendwo abgelegt werden müssten, in eine Datei oder Datenbank?

Oder ist das von der Realisierung her zu kompliziert und es wäre einfacher, die Web Seite nach einer gewissen Zeit neu zu laden und damit die Werte neu einzulesen. Beim Betätigen von einem Button zum Beispiel ist es ja so, zumindest kenne ich das von PHP so, dass die Variable übergeben und die Seite neu geladen wird.

Na ja, Ihr seht schon, da sind noch einige Wissenslücken vorhanden, bevor ich damit weitermache, wollte ich das erst mal abklären, ob dieser Plan so überhaupt Sinn ergibt oder man es einfacher oder besser machen könnte.

Würde mich über Hilfe freuen, Danke im Voraus!

Viele Grüße
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Gibt es einen Grund, dieses schon sehr oft erfundene Rad noch eine weitere Variante beizusteuern? Nicht, dass ich nicht selbst den Spass am umsetzen von allem moeglichen habe, dass es schon gibt - aber wenn es doch sehr deutlich an den Grundlagen hapert, dann steht dem Ziel da ggf doch ein zu langer Lauf bevor. Und man faehrt mit einer fertigen Loesung besser.

Was deine Fragen angeht: sowas setzt man heutzutage als JavaScript-basierte Seite, oft sogar "single page", um, die dann mit Aufrufen an den Backend-Server bzw. mit Events von letzterem via SSE oder websockets mit Updates versorgt werden. Dieser Server laeuft die ganze Zeit, und kann auch problemlos Werte vorhalten, ohne dass man die zwingen speichern muss. Das macht man nur dann, wenn man die Historie dieser Werte interessant findet - zur eigentlichen Steuerung/Regelung traegt das aber selten bis nie bei.

Aber wie schon gesagt: FHEM und wie sie alle heissen koennen solche Dinge schon, und haben Communities, die sich nur um dieses Thema drehen. Ich wuerde so einer Loesung immer den Vorzug vor etwas selbstgebasteltem geben.
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

Danke für die schnelle Antwort, ich habe einfach großen Spaß an dem Projekt und möchte es zumindest versuchen, auch wenn am Ende nichts bei rumkommt. So habe ich dennoch ein wenig dabei gelernt.

Gibt es noch eine Alternative zu JavaSkript? Das mit den Websocket habe ich auch schon öfter gelesen, da muss ich direkt mich weiter einlesen.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Die eine Frage hat mit der anderen nicht zu tun.
Zu 1) wie werden Werte im Browser aktualisiert: man kann entweder die gesamte Seite neu laden, entweder periodisch, oder in dem ein Link geclickt wird. Dazu ist dann kein Javascript nötig. Heutzutage ist es üblich, Messdaten im Hintergrund neu zu laden, das heißt also, dass mit Hilfe von Javascript regelmäßig ein Request an den Server abgesetzt wird, um neue Daten zu holen.
Aus Sicht des Webservers sind aber beide Methoden identisch: es wird ein Request empfangen, der mit den Messdaten beantwortet werden muß.
Zu 2) wie der Server die Daten ermittelt, hängt davon ab, wie das konkret zu tun ist. Wenn es sich um eine einfache Abfrage handelt, die man schnell anstoßen kann, dann ist das einfachste, bei jedem Request sich die Daten zu besorgen. Das wäre auch immer der erste Ansatz, und man würde nur zu etwas komplzierterem übergeben (also mehrere Programme, die im Hintergrund Daten austauschen oder über Datenbanken persistieren), wenn der Einfache Ansatz, Messungen direkt abzufragen, aus welchen Gründen auch immer, nicht performant genug ist.

Bei solchen Projekten ist es wichtig, die Struktur des Programms von Anfang an richtig zu planen.
Man braucht eine Abstraktionsschicht, die den Zustand Deiner Hausautomatisierung in Form einer Klasse abbildet und Methoden exisitieren, die diesen Zustand abfragen und solche, die ihn ändern können. Diese Abstraktionsschicht testet man ausgiebig und erst dann, wenn man einen stabiles, funktionierendes Modul hat, programmiert man dafür einen Webserver (z.B. mit Flask), der nur die Schnittstelle der Hausautomatisierungsklasse in Form von REST-Requests zugänglich macht, und in Javascript eine Browseroberfläche, mit der dann der Anwender diese steuern kann.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

die Grundidee hinter Python Webprogrammierung ist ziemlich simple und im WSGI Standard, dem die allermeisten Webframeworks für Python folgen: du bindest an eine URL ein Python Funktion. Die Funktion wird beim Aufruf der URL ausgeführt, macht was und liefert etwas zurück (etwas = irgendwas, was die Gegenseite verarbeiten kann wie HTML, JSON, ein Videostream, ein JPG-Bild). Dann wartet der Server auf die nächste Anfrage.

Im Prinzip kann die Pythonfunktion beliebig komplex sein - nur wenn die Antwort zu lange dauert wirft der Browser irgendwann einen Timeout Fehler. Je nach dem, was du serverseitig vorhast, musst du dich halt auch noch mit nebenläufiger Programmierung, Kommunikation zwischen unabhängig laufenden Skripten oder asynchronen Task Queues beschäftigen. Das kann relativ simpel sein, dass kann aber auch quasi beliebig komplex werden.

Wenn die Hausautomatisierung wirklich "produktiv" eingesetzt wird und nicht "just vor fun" ist, dann würde ich wie __deets__ ein fertige, etablierte und vor allem getestete Lösung empfehlen.

Gruß, noisefloor
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Soulpilot hat geschrieben: Sonntag 24. April 2022, 13:21 Gibt es noch eine Alternative zu JavaSkript? Das mit den Websocket habe ich auch schon öfter gelesen, da muss ich direkt mich weiter einlesen.
Nein, gibt es nicht. Jedenfalls keine substantielle, TypeScript ist auch nur JavaScript, und der Rest - coffeescript, WASM-Loesungen - zu nieschig und im Zweifel viel zu komplex fuer dich.
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

Sirius3 hat geschrieben: Sonntag 24. April 2022, 13:23 Bei solchen Projekten ist es wichtig, die Struktur des Programms von Anfang an richtig zu planen.
Man braucht eine Abstraktionsschicht, die den Zustand Deiner Hausautomatisierung in Form einer Klasse abbildet und Methoden exisitieren, die diesen Zustand abfragen und solche, die ihn ändern können. Diese Abstraktionsschicht testet man ausgiebig und erst dann, wenn man einen stabiles, funktionierendes Modul hat, programmiert man dafür einen Webserver (z.B. mit Flask), der nur die Schnittstelle der Hausautomatisierungsklasse in Form von REST-Requests zugänglich macht, und in Javascript eine Browseroberfläche, mit der dann der Anwender diese steuern kann.
Ok Danke, dazu werde ich mir auch noch mal Gedanken machen und mich wieder melden.

noisefloor hat geschrieben: Sonntag 24. April 2022, 13:24 Hallo,

die Grundidee hinter Python Webprogrammierung ist ziemlich simple und im WSGI Standard, dem die allermeisten Webframeworks für Python folgen: du bindest an eine URL ein Python Funktion. Die Funktion wird beim Aufruf der URL ausgeführt, macht was und liefert etwas zurück (etwas = irgendwas, was die Gegenseite verarbeiten kann wie HTML, JSON, ein Videostream, ein JPG-Bild). Dann wartet der Server auf die nächste Anfrage.

Im Prinzip kann die Pythonfunktion beliebig komplex sein - nur wenn die Antwort zu lange dauert wirft der Browser irgendwann einen Timeout Fehler. Je nach dem, was du serverseitig vorhast, musst du dich halt auch noch mit nebenläufiger Programmierung, Kommunikation zwischen unabhängig laufenden Skripten oder asynchronen Task Queues beschäftigen. Das kann relativ simpel sein, dass kann aber auch quasi beliebig komplex werden.

Wenn die Hausautomatisierung wirklich "produktiv" eingesetzt wird und nicht "just vor fun" ist, dann würde ich wie __deets__ ein fertige, etablierte und vor allem getestete Lösung empfehlen.

Gruß, noisefloor
Danke, FEHM habe ich bereits in Erwägung gezogen und in der Community wurde auch schon über pymodbus gesprochen, ob ich das damit hinbekomme müsste ich mir noch mal genauer anschauen.
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

Ich bins noch mal :-)

Also ich habe mir jetzt ein einfaches Websocket Beispiel aus dem Netz kopiert, dabei funktioniert das senden und empfangen von Nachrichten zwischen zwei Rechnern bzw. zwei Linux Systemen. Der Socket funktioniert einmal als Python Server und HTML/Java Client. Was leider noch nicht so wirklich funktioniert ist, das wenn ich einen String als Nachricht an den Server schicke, dass ich diesen String nicht mittels if Anweisung überprüfen kann und ich verstehe nicht, warum das so ist.

Dabei werden durch Buttons einfache Nachrichten in Java generiert und an den Socket Server übermittelt, diese kommen auch korrekt an.

Wie müsste ich den String verarbeiten, damit ich diesen mittels if und elif differenzieren kann? Was ich zu der Struktur des Pythoncodes auch noch fragen wollte ist, sollte ich für die Relais und Temperatur extra Klassen anlegen? Ich habe mir dazu schon was überlegt, mit UML aber müsste das noch auf Papier bringen. Mir geht es jetzt auch gar nicht um die perfekte Ausarbeitung, sondern ich würde das gerne direkt am Beispiel lernen. Würde mich freuen, wenn Ihr mir noch den einen oder anderen Tipp geben könntet, Danke im Voraus!

Der Quellcode.

websock.py

Code: Alles auswählen

#Websocket demo, from iosoft.blog

import time
from pymodbus.client.sync import ModbusTcpClient as ModbusClient

#Für Modbus
UNIT = 0x1
HOST = '192.168.0.50'
PORT = 502
COILBASE = 512 # Coil Output Base Address

import signal, sys
from SimpleWebSocketServer import WebSocket, SimpleWebSocketServer

PORTNUM = 8001 #Socket

def main():
    client = ModbusClient(host=HOST, port=PORT)
    client.connect()


# Websocket class to echo received data
class Echo(WebSocket):

    def handleMessage(self):
        print("Echoing '%s'" % self.data)
        self.sendMessage(self.data)

#        return self.data
#        while True:
#        try:

        if self.data() == relais1:
            print("debug")
            rq = client.write_coil(COILBASE + 0, True, unit= UNIT)
            print("debug")
#                return(self.data)
            continue
#        elif self.data() == relais1off:
#            rq = client.write_coil(COILBASE + 0, False, unit= UNIT)

#        elif self.data() == relais2:
#            rq = client.write_coil(COILBASE + 1, True, unit= UNIT)
#            print("debug")
#        elif self.data() == relais2off:
#            rq = client.write_coil(COILBASE + 1, False, unit= UNIT)


    def handleConnected(self):
        print("Connected")

    def handleClose(self):
        print("Disconnected")

# Handle ctrl-C: close server
def close_server(signal, frame):
    server.close()
    client.close()
    sys.exit()

if __name__ == "__main__":
    main()
    print("Websocket server on port %s" % PORTNUM)
    server = SimpleWebSocketServer('', PORTNUM, Echo)
    signal.signal(signal.SIGINT, close_server)
    server.serveforever()

websock.html

Code: Alles auswählen

<!DOCTYPE html>
<meta charset="utf-8"/>
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">

  // Client for Python SimpleWebsocketServer
  const portnum = 8001;
  var host, server, connected = false, relais1 = false, relais2 = false;

  // Display the given text
  function display(s)
  {
    document.myform.text.value += s;
    document.myform.text.scrollTop = document.myform.text.scrollHeight;
  }

  // Initialisation
  function init()
  {
    host = "192.168.0.24";
//    host = location.host ? String(location.host) : "unknown";
//    host = host.replace("127.0.0.1", "localhost");
//    server = host.replace(/:\d*\b/, ":" + portnum);
    server = "192.168.0.24:8001";
    document.myform.text.value = "Host " + host + "\n";
    window.setInterval(timer_tick, 1000);
  }

  // Open a Websocket connection
  function connect()
  {
    var url = "ws://" + server + "/";
    display("Opening websocket " + url + "\n");
    websock = new WebSocket(url);
    websock.onopen    = function(evt) {sock_open(evt)};
    websock.onclose   = function(evt) {sock_close(evt)};
    websock.onmessage = function(evt) {sock_message(evt)};
    websock.onerror   = function(evt) {sock_error(evt)};
    connected = true;
  }
  // Close a Websocket connection
  function disconnect()
  {
    connected = false;
    websock.close();
  }

  // Timer tick handler
  function timer_tick()
  {
//    if (connected)
//      websock.send('*');
  }

  function relais1_on()
  {
    relais1 = true;

      if (relais1 === true)
        websock.send('relais1');
        alert("button pressd" + relais1);
  }

  function relais2_on()
  {
    relais2 = true;
    //alert("button pressd" + relais2);

      if (relais2 === true)
        websock.send('relais2');
        alert("button pressd" + relais2);
  }  function relais1_off()
  {
    relais1 = false;

      if (relais1 === false)
        websock.send('relais1off');
        alert("button pressd" + relais1);
  }

  function relais2_off()
  {
    relais2 = false;

      if (relais2 === false)
        websock.send('relais2off');
        alert("button pressd" + relais2);
  }

//  function timer_tick()
  {
//    if (relais1 === off)
//      websocket.send('relais1 = false');
  }

  // Display incoming data
  function sock_message(evt)
  {
    display(evt.data);
  }

  // Handlers for other Websocket events
  function sock_open(evt)
  {
    display("Connected\n");
  }
  function sock_close(evt)
  {
    display("\nDisconnected\n");
  }
  function sock_error(evt)
  {
    display("Socket error\n");
    websock.close();
  }

  // Do initialisation when page is loaded
  window.addEventListener("load", init, false);

</script>
<form name="myform">
  <h2>Websocket test</h2>
  <p>
  <textarea name="text" rows="10" cols="60">
  </textarea>
  </p>
  <p>
  <input type="button" value="Connect" onClick="connect();">
  <input type="button" value="Disconnect" onClick="disconnect();">
  </p>
  <input type="button" value="relais1_on" onClick="relais1_on();">
  </p>
  <input type="button" value="relais1_off" onClick="relais1_off();">
  </p>
  <input type="button" value="relais2_on" onClick="relais2_on();">
  </p>
  <input type="button" value="relais2_off" onClick="relais2_off();">
</form>
</html>
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich sehe kein relais1, bzw. nicht, wo das definiert wird. Darum kann ich auch nicht sagen, warum du das nicht vergleichen kannst. Allgemein hilft bei sowas immer mal die Ausgabe der Daten, ggf. auch deren Typen.
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

__deets__ hat geschrieben: Mittwoch 27. April 2022, 22:13 Ich sehe kein relais1, bzw. nicht, wo das definiert wird. Darum kann ich auch nicht sagen, warum du das nicht vergleichen kannst. Allgemein hilft bei sowas immer mal die Ausgabe der Daten, ggf. auch deren Typen.
Das wird aus dem Client übergeben. Wo müsste ich das definieren, brauche ich für die Klasse ein __init__(self, relais1) zum Beispiel. Das mit dem Konstruktor hatte ich bereits versucht, leider habe ich nur sehr oberflächliche Kenntnisse über OOP.
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

__deets__ hat geschrieben: Mittwoch 27. April 2022, 22:13 Ich sehe kein relais1, bzw. nicht, wo das definiert wird. Darum kann ich auch nicht sagen, warum du das nicht vergleichen kannst. Allgemein hilft bei sowas immer mal die Ausgabe der Daten, ggf. auch deren Typen.
Relais1 ist ein String, der übergeben wird. Ich habe mal versucht innerhalb der Klasse die Variable relais1 definiert aber mein Problem wird nicht gelöst. Wo bzw. wie würdest du es definieren?

Code: Alles auswählen

    def handleMessage(self):
        print("Echoing '%s'" % self.data)
        self.sendMessage(self.data)

        print(type(self.data))

Code: Alles auswählen

Websocket server on port 8001
Connected
Echoing 'relais1'
<class 'str'>
Disconnected
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich würde gar nix definieren. Du kannst dich einfach mit dem STRING!!! “relais1” vergleichen. beachte die Anführungszeichen. Und dann machen, was auch immer du willst.

Ein gutes Programm würde hier natürlich Abstraktionen anbieten, also zb das anlegen eines schaltbaren Objektes unter einem Namen (“relais1” zb, auch wenn das natürlich ein sehr schlechter Name ist. Warum nicht relais 3127854?) , und eine Menge von Operationen darauf, wie an/aus/Status. Sowas macht halt FHEM.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Soulpilot: Da sind zwei offensichtliche Fehler. Der *Name* `relais1` ist nirgends definiert und Du versuchst `self.data` *aufzurufen* als wenn das eine Methode oder Funktion wäre. Beide Fehler für sich führen zu einer Ausnahme. Schau wo die landet, denn ohne so etwas zu sehen werden Fehlersuchen nahezu unmöglich.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

__deets__ hat geschrieben: Mittwoch 27. April 2022, 22:47 Ich würde gar nix definieren. Du kannst dich einfach mit dem STRING!!! “relais1” vergleichen. beachte die Anführungszeichen. Und dann machen, was auch immer du willst.

Ein gutes Programm würde hier natürlich Abstraktionen anbieten, also zb das anlegen eines schlagbaren Objektes unter einem Namen (“relais1” zb, auch wenn das natürlich ein sehr schlechter Name ist. Warum nicht relais 3127854?) , und eine Menge von Operationen darauf, wie an/aus/Status. Sowas macht halt FHEM.
Ging mir ja nur, um was dabei zu lernen. Eine Klasse Relais hatte ich schon in Planung, will das erst mal zum laufen bekommen. Könntest du mir helfen, die Klasse zu formulieren?
__blackjack__ hat geschrieben: Mittwoch 27. April 2022, 22:51 @Soulpilot: Da sind zwei offensichtliche Fehler. Der *Name* `relais1` ist nirgends definiert und Du versuchst `self.data` *aufzurufen* als wenn das eine Methode oder Funktion wäre. Beide Fehler für sich führen zu einer Ausnahme. Schau wo die landet, denn ohne so etwas zu sehen werden Fehlersuchen nahezu unmöglich.
Danke Dir! Ich habe folgendes gemacht:

Code: Alles auswählen

        command = self.data 

Code: Alles auswählen

        if command == "relais1":
            print("debug")
            rq = client.write_coil(COILBASE + 0, True, unit= UNIT)
            print("debug")

Code: Alles auswählen

Connected
Echoing 'relais1'
<class 'str'>
debug
Disconnected
Den ersten "Debug" bekomme ich zurück, mein Aufruf aus der Modbus Lib

Code: Alles auswählen

rq = client.write_coil(COILBASE + 0, True, unit= UNIT)
funktioniert innerhalb der Klasse

Code: Alles auswählen

class Echo(WebSocket): 
nicht. Verwundert mich einerseits nicht aber wie ich das Problem löse, weiß ich auch nicht^^ ??? :-)
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Soulpilot: Im Code wird zweimal "debug" ausgegeben, in der Ausgabe steht das aber nur einmal. Offenbar bricht der Code bei dem `client.write_coil()`-Aufruf aus irgendeinem Grund ab.

Wenn Du den Aufruf durch 1/0 ersetzt, siehst Du dann irgendwo den `ZeroDivisionError` den das auslöst?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

__blackjack__ hat geschrieben: Mittwoch 27. April 2022, 23:19 @Soulpilot: Im Code wird zweimal "debug" ausgegeben, in der Ausgabe steht das aber nur einmal. Offenbar bricht der Code bei dem `client.write_coil()`-Aufruf aus irgendeinem Grund ab.

Wenn Du den Aufruf durch 1/0 ersetzt, siehst Du dann irgendwo den `ZeroDivisionError` den das auslöst?
Leider nein.

Code: Alles auswählen

        if command == "relais1":
                     print("debug")
                     1/0
# rq = client.write_coil(COILBASE + 0, True, unit= UNIT)
                      print("debug")

Code: Alles auswählen

Connected
Echoing 'relais1'
<class 'str'>
debug
Disconnected
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

Dann habe ich noch eine Ausgabe debug2 hinzugefügt. Warum kann ich innerhalb der Klasse nicht `client.write_coil()` aufrufen?

Code: Alles auswählen

        if command == "relais1":
            print("debug")
#            1/0
#            rq = client.write_coil(COILBASE + 0, True, unit= UNIT)
            print("debug2")

Code: Alles auswählen

Connected
Echoing 'relais1'
<class 'str'>
debug
debug2
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Keine Ahnung. Da sollten Fehler Ausgaben kommen. Wenn die nicht kommen, musst du rausfinden, wie du die aktivierst.
Soulpilot
User
Beiträge: 63
Registriert: Sonntag 24. April 2022, 12:19

Ich habe noch ein wenig rumprobiert und es funktioniert in dieser Konstellation, ohne dass die Socket Verbindung abbricht und die Relais geschaltet werden. Ich weiß nicht wieso, würde dennoch gerne verstehen, warum? Wie sollte ich eine Klasse mit den Geräten einführen, sodass die beiden Klassen auch miteinander kommunizieren können?

Also sowohl def main() als auch client = ModbusClient(host=HOST, port=PORT) client.connect() müssen drinnen stehen: (strange :geek: )

Code: Alles auswählen

client = ModbusClient(host=HOST, port=PORT)
client.connect()

def main():
    client = ModbusClient(host=HOST, port=PORT)
    client.connect()
    print("main")

Code: Alles auswählen

 # Websocket demo, from iosoft.blog

import pdb
import time
from pymodbus.client.sync import ModbusTcpClient as ModbusClient

UNIT = 0x1
HOST = '192.168.0.50'
PORT = 502
COILBASE = 512 # Coil Output Base Address

import signal, sys
from SimpleWebSocketServer import WebSocket, SimpleWebSocketServer

PORTNUM = 8001
#state = 0

client = ModbusClient(host=HOST, port=PORT)
client.connect()


def main():
    client = ModbusClient(host=HOST, port=PORT)
    client.connect()
    print("main")

# Websocket class to echo received data
class Echo(WebSocket):

#    def __init__(self, relais):
#        self.relais = relais

#    relais1 = True

    def handleMessage(self):
        print("Echoing '%s'" % self.data)
        self.sendMessage(self.data)

#        print(type(self.data))
#        relais1 = True
        command = self.data

        if command == "relais1":
            print("debug")
            rq = client.write_coil(COILBASE + 0, True, unit= UNIT)
            print("debug2")

        if command == "relais1off":
            rq = client.write_coil(COILBASE + 0, False, unit= UNIT)

        elif command == "relais2":
            rq = client.write_coil(COILBASE + 1, True, unit= UNIT)

        elif command == "relais2off":
            rq = client.write_coil(COILBASE + 1, False, unit= UNIT)

    def handleConnected(self):
        print("Connected")

    def handleClose(self):
        print("Disconnected") 

Code: Alles auswählen

 Websocket server on port 8001
Connected
Echoing 'relais1off'
Echoing 'relais1'
debug
debug2
Echoing 'relais1'
debug
debug2
Echoing 'relais2'
Echoing 'relais1off' 
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Aus meiner Perspektive ist das kein lauffaehiger Code. Denn der Socket-Handler wird nirgendwo genutzt. Und er ist *sehr* verquast, mit allem moeglichen unnoetigen, doppeltem, unsortiertem.
Antworten