mirror of
https://github.com/naruxde/revpipycontrol.git
synced 2025-11-08 15:43:52 +01:00
"Monitorfunktion" als Debug zum Hautpfenster hinzugef?gt
Disconnect-Men?eintrag eingebaut (Funktion hinzugef?gt) Funktionen f?r "nur lesen" und "nur schreiben" eingebaut Werte schreiben per MultiCall UI-Texte angepasst DocStrings und CodeStyle
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
import pickle
|
||||
import tkinter
|
||||
from threading import Lock
|
||||
from xmlrpc.client import ServerProxy
|
||||
from xmlrpc.client import ServerProxy, MultiCall
|
||||
|
||||
|
||||
class RevPiCheckClient(tkinter.Frame):
|
||||
@@ -18,17 +18,20 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
def __init__(self, master, xmlcli, xmlmode=0):
|
||||
"""Instantiiert MyApp-Klasse."""
|
||||
super().__init__(master)
|
||||
self.pack(fill="both", expand=True)
|
||||
|
||||
# XML-Daten abrufen
|
||||
self.xmlmode = xmlmode
|
||||
self.cli = xmlcli
|
||||
|
||||
# FIXME: Fehlerabfang
|
||||
self.cli.psstart()
|
||||
|
||||
self.lst_devices = self.cli.ps_devices()
|
||||
self.dict_inps = pickle.loads(self.cli.ps_inps().data)
|
||||
self.dict_outs = pickle.loads(self.cli.ps_outs().data)
|
||||
|
||||
self.lk = Lock()
|
||||
self.lst_wins = []
|
||||
|
||||
self.autorw = tkinter.BooleanVar()
|
||||
self.dowrite = tkinter.BooleanVar()
|
||||
@@ -37,10 +40,25 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
self._createwidgets()
|
||||
|
||||
# Aktuelle Werte einlesen
|
||||
self.readvalues()
|
||||
self.refreshvalues()
|
||||
|
||||
def onfrmconf(self, canvas):
|
||||
canvas.configure(scrollregion=canvas.bbox("all"))
|
||||
def __chval(self, device, io):
|
||||
if self.dowrite.get():
|
||||
with self.lk:
|
||||
self.cli.ps_setvalue(device, io[0], io[5].get())
|
||||
|
||||
# Alles neu einlesen wenn nicht AutoRW aktiv ist
|
||||
if not self.autorw.get():
|
||||
self.refreshvalues()
|
||||
|
||||
def __hidewin(self, win, event=None):
|
||||
win.withdraw()
|
||||
|
||||
def __showwin(self, win):
|
||||
if win.winfo_viewable():
|
||||
win.withdraw()
|
||||
else:
|
||||
win.deiconify()
|
||||
|
||||
def _createiogroup(self, device, frame, iotype):
|
||||
"""Erstellt IO-Gruppen."""
|
||||
@@ -55,7 +73,7 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
|
||||
canvas.create_window((4, 4), window=s_frame, anchor="nw")
|
||||
s_frame.bind(
|
||||
"<Configure>", lambda event, canvas=canvas: self.onfrmconf(canvas)
|
||||
"<Configure>", lambda event, canvas=canvas: self._onfrmconf(canvas)
|
||||
)
|
||||
|
||||
rowcount = 0
|
||||
@@ -76,7 +94,7 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
var = tkinter.BooleanVar()
|
||||
check = tkinter.Checkbutton(s_frame)
|
||||
check["command"] = \
|
||||
lambda device=device, io=io: self.chval(device, io)
|
||||
lambda device=device, io=io: self.__chval(device, io)
|
||||
check["state"] = "disabled" if iotype == "inp" else "normal"
|
||||
check["text"] = ""
|
||||
check["variable"] = var
|
||||
@@ -86,7 +104,7 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
# FIXME: Mehrere Bytes möglich
|
||||
txt = tkinter.Spinbox(s_frame, to=255 * io[1])
|
||||
txt["command"] = \
|
||||
lambda device=device, io=io: self.chval(device, io)
|
||||
lambda device=device, io=io: self.__chval(device, io)
|
||||
txt["state"] = "disabled" if iotype == "inp" else "normal"
|
||||
txt["width"] = 4
|
||||
txt["textvariable"] = var
|
||||
@@ -97,19 +115,8 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
|
||||
rowcount += 1
|
||||
|
||||
def __hidewin(self, win, event=None):
|
||||
win.withdraw()
|
||||
|
||||
def __showwin(self, win):
|
||||
if win.winfo_viewable():
|
||||
win.withdraw()
|
||||
else:
|
||||
win.deiconify()
|
||||
|
||||
def _createwidgets(self):
|
||||
"""Erstellt den Fensterinhalt."""
|
||||
# Hauptfenster
|
||||
self.master.wm_title("RevPi Onlineview")
|
||||
|
||||
devgrp = tkinter.LabelFrame(self)
|
||||
devgrp["text"] = "Devices of RevPi"
|
||||
@@ -123,6 +130,7 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
lambda win=win: self.__hidewin(win)
|
||||
)
|
||||
win.withdraw()
|
||||
self.lst_wins.append(win)
|
||||
|
||||
# Devicegruppe erstellen
|
||||
group = tkinter.LabelFrame(win)
|
||||
@@ -145,44 +153,56 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
cntgrp["text"] = "Control"
|
||||
cntgrp.pack(fill="y", side="right")
|
||||
|
||||
self.btn_refresh = tkinter.Button(cntgrp)
|
||||
self.btn_refresh["text"] = "Alle IOs lesen"
|
||||
self.btn_refresh["command"] = self.refreshvalues
|
||||
self.btn_refresh.pack(fill="x")
|
||||
|
||||
self.btn_read = tkinter.Button(cntgrp)
|
||||
self.btn_read["text"] = "LESEN"
|
||||
self.btn_read["text"] = "Inputs einlesen"
|
||||
self.btn_read["command"] = self.readvalues
|
||||
self.btn_read.pack(fill="x")
|
||||
|
||||
self.btn_write = tkinter.Button(cntgrp)
|
||||
self.btn_write["text"] = "Outputs schreiben"
|
||||
self.btn_write["command"] = self.writevalues
|
||||
self.btn_write.pack(fill="x")
|
||||
|
||||
check = tkinter.Checkbutton(cntgrp)
|
||||
check["command"] = self.toggleauto
|
||||
check["text"] = "autorefresh processimage"
|
||||
check["text"] = "Autorefresh values"
|
||||
check["variable"] = self.autorw
|
||||
check.pack(anchor="w")
|
||||
|
||||
check = tkinter.Checkbutton(cntgrp)
|
||||
check["state"] = "disabled" if self.xmlmode < 3 else "normal"
|
||||
check["text"] = "write values to processimage"
|
||||
check["text"] = "Write values to RevPi"
|
||||
check["variable"] = self.dowrite
|
||||
check.pack(anchor="w")
|
||||
|
||||
def chval(self, device, io):
|
||||
if self.dowrite.get():
|
||||
with self.lk:
|
||||
self.cli.ps_setvalue(device, io[0], io[5].get())
|
||||
def _onfrmconf(self, canvas):
|
||||
canvas.configure(scrollregion=canvas.bbox("all"))
|
||||
|
||||
# Alles neu einlesen wenn nicht AutoRW aktiv ist
|
||||
if not self.autorw.get():
|
||||
self.readvalues()
|
||||
|
||||
def _readvalues(self):
|
||||
def _workvalues(self, io_dicts=None, writeout=False):
|
||||
"""Alle Werte der Inputs und Outputs abrufen."""
|
||||
|
||||
# Abfragelisten vorbereiten
|
||||
if io_dicts is None:
|
||||
io_dicts = [self.dict_inps, self.dict_outs]
|
||||
|
||||
# Werte abrufen
|
||||
with self.lk:
|
||||
ba_values = bytearray(self.cli.ps_values().data)
|
||||
|
||||
# Multicall zum Schreiben vorbereiten
|
||||
if writeout:
|
||||
xmlmc = MultiCall(self.cli)
|
||||
|
||||
for dev in self.lst_devices:
|
||||
# io = [name,bytelen,byteaddr,bmk,bitaddress,(tkinter_var)]
|
||||
|
||||
# IO Typ verarbeiten
|
||||
for iotype in [self.dict_inps, self.dict_outs]:
|
||||
for iotype in io_dicts:
|
||||
# ios verarbeiten
|
||||
for io in iotype[dev[0]]:
|
||||
|
||||
@@ -192,22 +212,50 @@ class RevPiCheckClient(tkinter.Frame):
|
||||
)
|
||||
if io[4] >= 0:
|
||||
# Bit-IO
|
||||
io[5].set(bool(int_byte & 1 << io[4]))
|
||||
new_val = bool(int_byte & 1 << io[4])
|
||||
if writeout and new_val != io[5].get():
|
||||
xmlmc.ps_setvalue(dev[0], io[0], io[5].get())
|
||||
else:
|
||||
io[5].set(new_val)
|
||||
else:
|
||||
# Byte-IO
|
||||
io[5].set(int_byte)
|
||||
if writeout and int_byte != io[5].get():
|
||||
xmlmc.ps_setvalue(dev[0], io[0], io[5].get())
|
||||
else:
|
||||
io[5].set(int_byte)
|
||||
|
||||
# Werte per Multicall schreiben
|
||||
if writeout:
|
||||
with self.lk:
|
||||
xmlmc()
|
||||
|
||||
if self.autorw.get():
|
||||
self.master.after(200, self._readvalues)
|
||||
self.master.after(200, self._workvalues)
|
||||
|
||||
def hideallwindows(self):
|
||||
for win in self.lst_wins:
|
||||
win.withdraw()
|
||||
|
||||
def readvalues(self):
|
||||
if not self.autorw.get():
|
||||
self._readvalues()
|
||||
self._workvalues([self.dict_inps])
|
||||
|
||||
def refreshvalues(self):
|
||||
if not self.autorw.get():
|
||||
self._workvalues()
|
||||
|
||||
def toggleauto(self):
|
||||
self.btn_read["state"] = "disabled" if self.autorw.get() else "normal"
|
||||
stateval = "disabled" if self.autorw.get() else "normal"
|
||||
self.btn_refresh["state"] = stateval
|
||||
self.btn_read["state"] = stateval
|
||||
self.btn_write["state"] = stateval
|
||||
|
||||
if self.autorw.get():
|
||||
self._readvalues()
|
||||
self._workvalues()
|
||||
|
||||
def writevalues(self):
|
||||
if not self.autorw.get():
|
||||
self._workvalues([self.dict_outs], True)
|
||||
|
||||
|
||||
# Testdrive
|
||||
|
||||
@@ -32,6 +32,7 @@ savefile = os.path.join(homedir, ".revpipyplc", "programpath.dat")
|
||||
class RevPiProgram(tkinter.Frame):
|
||||
|
||||
def __init__(self, master, xmlcli, xmlmode, revpi):
|
||||
u"""Init RevPiProgram-Class."""
|
||||
if xmlmode < 2:
|
||||
return None
|
||||
|
||||
@@ -223,7 +224,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
return {}
|
||||
|
||||
def _savedefaults(self):
|
||||
"""Schreibt fuer den Pi die letzen Pfade."""
|
||||
u"""Schreibt fuer den Pi die letzen Pfade."""
|
||||
try:
|
||||
makedirs(os.path.dirname(savefile), exist_ok=True)
|
||||
dict_all = self._loaddefault(full=True)
|
||||
@@ -236,7 +237,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
return True
|
||||
|
||||
def create_filelist(self, rootdir):
|
||||
"""Erstellt eine Dateiliste von einem Verzeichnis.
|
||||
u"""Erstellt eine Dateiliste von einem Verzeichnis.
|
||||
@param rootdir: Verzeichnis fuer das eine Liste erstellt werden soll
|
||||
@returns: Dateiliste"""
|
||||
filelist = []
|
||||
@@ -249,7 +250,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
"""Gibt das rootdir von einem entpackten Verzeichnis zurueck.
|
||||
|
||||
Dabei wird geprueft, ob es sich um einen einzelnen Ordner handelt
|
||||
und ob es eine piCtory Konfiguraiton im rootdir gibt.
|
||||
und ob es eine piCtory Konfiguration im rootdir gibt.
|
||||
@param rootdir: Verzeichnis fuer Pruefung
|
||||
@returns: Abgeaendertes rootdir
|
||||
|
||||
@@ -270,6 +271,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
return (rootdir, None)
|
||||
|
||||
def getpictoryrsc(self):
|
||||
u"""Läd die piCtory Konfiguration herunter."""
|
||||
fh = tkfd.asksaveasfile(
|
||||
mode="wb", parent=self.master,
|
||||
confirmoverwrite=True,
|
||||
@@ -300,6 +302,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
fh.close()
|
||||
|
||||
def getprocimg(self):
|
||||
u"""Läd das aktuelle Prozessabbild herunter."""
|
||||
fh = tkfd.asksaveasfile(
|
||||
mode="wb", parent=self.master,
|
||||
confirmoverwrite=True,
|
||||
@@ -330,6 +333,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
fh.close()
|
||||
|
||||
def setpictoryrsc(self, filename=None):
|
||||
u"""Überträgt die angegebene piCtory-Konfiguration."""
|
||||
if filename is None:
|
||||
fh = tkfd.askopenfile(
|
||||
mode="rb", parent=self.master,
|
||||
@@ -381,6 +385,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
fh.close()
|
||||
|
||||
def picontrolreset(self):
|
||||
u"""Fürt ein Reset der piBridge durch."""
|
||||
ask = tkmsg.askyesno(
|
||||
parent=self.master, title="Frage...",
|
||||
message="Soll piControlReset wirklich durchgeführt werden? \n"
|
||||
@@ -401,6 +406,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
)
|
||||
|
||||
def plcdownload(self):
|
||||
u"""Läd das aktuelle Projekt herunter."""
|
||||
tdown = self.lst_typedown.index(self.var_typedown.get())
|
||||
fh = None
|
||||
dirselect = ""
|
||||
@@ -491,6 +497,7 @@ class RevPiProgram(tkinter.Frame):
|
||||
fh.close()
|
||||
|
||||
def plcupload(self):
|
||||
u"""Lädt das angegebene Projekt auf den RevPi."""
|
||||
tup = self.lst_typeup.index(self.var_typeup.get())
|
||||
dirselect = ""
|
||||
dirtmp = None
|
||||
|
||||
@@ -41,6 +41,8 @@ def addroot(filename):
|
||||
class RevPiPyControl(tkinter.Frame):
|
||||
|
||||
def __init__(self, master=None):
|
||||
u"""Init RevPiPyControl-Class.
|
||||
@param master: tkinter master"""
|
||||
super().__init__(master)
|
||||
self.pack(fill="both", expand=True)
|
||||
|
||||
@@ -48,8 +50,12 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self.dict_conn = revpiplclist.get_connections()
|
||||
self.errcount = 0
|
||||
self.revpiname = None
|
||||
self.xmlfuncs = []
|
||||
self.xmlmode = 0
|
||||
|
||||
# Debugger vorbereiten
|
||||
self.debugframe = None
|
||||
|
||||
# Globale Fenster
|
||||
self.tkcheckclient = None
|
||||
self.tklogs = None
|
||||
@@ -63,14 +69,30 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self.tmr_plcrunning()
|
||||
|
||||
def _btnstate(self):
|
||||
u"""Setzt den state der Buttons."""
|
||||
stateval = "disabled" if self.cli is None else "normal"
|
||||
self.btn_plclogs["state"] = stateval
|
||||
self.btn_plcstart["state"] = stateval
|
||||
self.btn_plcstop["state"] = stateval
|
||||
self.btn_plcrestart["state"] = stateval
|
||||
self.btn_debug["state"] = stateval
|
||||
|
||||
def _closeall(self):
|
||||
u"""Schließt alle Fenster."""
|
||||
if self.tkcheckclient is not None:
|
||||
self.tkcheckclient.destroy()
|
||||
if self.tklogs is not None:
|
||||
self.tklogs.master.destroy()
|
||||
if self.tkoptions is not None:
|
||||
self.tkoptions.destroy()
|
||||
if self.tkprogram is not None:
|
||||
self.tkprogram.destroy()
|
||||
if self.debugframe is not None:
|
||||
self.debugframe.destroy()
|
||||
self.debugframe = None
|
||||
|
||||
def _createwidgets(self):
|
||||
"""Erstellt den Fensterinhalt."""
|
||||
u"""Erstellt den Fensterinhalt."""
|
||||
# Hauptfenster
|
||||
self.master.wm_title("RevPi Python PLC Loader")
|
||||
self.master.wm_iconphoto(
|
||||
@@ -122,26 +144,39 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self.txt_status["textvariable"] = self.var_status
|
||||
self.txt_status.pack(fill="x")
|
||||
|
||||
def _fillmbar(self):
|
||||
# PLC Menü
|
||||
self.mplc = tkinter.Menu(self.mbar, tearoff=False)
|
||||
self.mplc.add_command(label="PLC log...", command=self.plclogs)
|
||||
self.mplc.add_command(label="PLC monitor...", command=self.plcmonitor)
|
||||
self.mplc.add_command(label="PLC options...", command=self.plcoptions)
|
||||
self.mplc.add_command(label="PLC program...", command=self.plcprogram)
|
||||
self.mbar.add_cascade(label="PLC", menu=self.mplc, state="disabled")
|
||||
|
||||
# Connection Menü
|
||||
self.mconn = tkinter.Menu(self.mbar, tearoff=False)
|
||||
self.mbar.add_cascade(label="Connect", menu=self.mconn)
|
||||
self.btn_debug = tkinter.Button(self)
|
||||
self.btn_debug["text"] = "PLC Debugmodus"
|
||||
self.btn_debug["command"] = self.plcdebug
|
||||
self.btn_debug.pack(fill="x")
|
||||
|
||||
def _fillconnbar(self):
|
||||
u"""Generiert Menüeinträge für Verbindungen."""
|
||||
self.mconn.delete(0, "end")
|
||||
for con in sorted(self.dict_conn.keys(), key=lambda x: x.lower()):
|
||||
self.mconn.add_command(
|
||||
label=con, command=partial(self._opt_conn, con)
|
||||
)
|
||||
|
||||
def _fillmbar(self):
|
||||
u"""Generiert Menüeinträge."""
|
||||
# PLC Menü
|
||||
self.mplc = tkinter.Menu(self.mbar, tearoff=False)
|
||||
self.mplc.add_command(
|
||||
label="PLC log...", command=self.plclogs)
|
||||
self.mplc.add_command(
|
||||
label="PLC options...", command=self.plcoptions)
|
||||
self.mplc.add_command(
|
||||
label="PLC program...", command=self.plcprogram)
|
||||
self.mplc.add_separator()
|
||||
|
||||
self.mplc.add_command(
|
||||
label="Disconnect", command=self.serverdisconnect)
|
||||
self.mbar.add_cascade(label="PLC", menu=self.mplc, state="disabled")
|
||||
|
||||
# Connection Menü
|
||||
self.mconn = tkinter.Menu(self.mbar, tearoff=False)
|
||||
self.mbar.add_cascade(label="Connect", menu=self.mconn)
|
||||
|
||||
def _opt_conn(self, text):
|
||||
socket.setdefaulttimeout(2)
|
||||
sp = ServerProxy(
|
||||
@@ -151,6 +186,7 @@ class RevPiPyControl(tkinter.Frame):
|
||||
)
|
||||
# Server prüfen
|
||||
try:
|
||||
self.xmlfuncs = sp.system.listMethods()
|
||||
self.xmlmode = sp.xmlmodus()
|
||||
except:
|
||||
self.servererror()
|
||||
@@ -168,17 +204,30 @@ class RevPiPyControl(tkinter.Frame):
|
||||
))
|
||||
self.mbar.entryconfig("PLC", state="normal")
|
||||
|
||||
def _closeall(self):
|
||||
if self.tkcheckclient is not None:
|
||||
self.tkcheckclient.destroy()
|
||||
if self.tklogs is not None:
|
||||
self.tklogs.master.destroy()
|
||||
if self.tkoptions is not None:
|
||||
self.tkoptions.destroy()
|
||||
if self.tkprogram is not None:
|
||||
self.tkprogram.destroy()
|
||||
def plcdebug(self):
|
||||
u"""Baut den Debugframe und packt ihn."""
|
||||
self.btn_debug["state"] = "disabled"
|
||||
|
||||
# Debugfenster laden
|
||||
if self.debugframe is None:
|
||||
self.debugframe = revpicheckclient.RevPiCheckClient(
|
||||
self, self.cli, self.xmlmode
|
||||
)
|
||||
|
||||
# Show/Hide wechseln
|
||||
if self.debugframe.winfo_viewable():
|
||||
self.debugframe.hideallwindows()
|
||||
self.debugframe.autorw.set(False)
|
||||
self.debugframe.toggleauto()
|
||||
self.debugframe.dowrite.set(False)
|
||||
self.debugframe.pack_forget()
|
||||
else:
|
||||
self.debugframe.pack(fill="y")
|
||||
|
||||
self.btn_debug["state"] = "normal"
|
||||
|
||||
def plclist(self):
|
||||
u"""Öffnet das Fenster für die Verbindungen."""
|
||||
win = tkinter.Toplevel(self)
|
||||
revpiplclist.RevPiPlcList(win)
|
||||
win.focus_set()
|
||||
@@ -188,24 +237,15 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self._fillconnbar()
|
||||
|
||||
def plclogs(self):
|
||||
u"""Öffnet das Fenster für Logdateien."""
|
||||
if self.tklogs is None or len(self.tklogs.children) == 0:
|
||||
win = tkinter.Toplevel(self)
|
||||
self.tklogs = revpilogfile.RevPiLogfile(win, self.cli)
|
||||
else:
|
||||
self.tklogs.focus_set()
|
||||
|
||||
def plcmonitor(self):
|
||||
"""Startet das Monitorfenster."""
|
||||
if self.tkcheckclient is None or len(self.tkcheckclient.children) == 0:
|
||||
win = tkinter.Toplevel(self)
|
||||
self.tkcheckclient = revpicheckclient.RevPiCheckClient(
|
||||
win, self.cli, self.xmlmode
|
||||
)
|
||||
else:
|
||||
self.tkcheckclient.focus_set()
|
||||
|
||||
def plcoptions(self):
|
||||
"""Startet das Optionsfenster."""
|
||||
u"""Startet das Optionsfenster."""
|
||||
if self.xmlmode < 2:
|
||||
tkmsg.showwarning(
|
||||
parent=self.master, title="Warnung",
|
||||
@@ -222,6 +262,7 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self.xmlmode = self.tkoptions.xmlmode
|
||||
|
||||
def plcprogram(self):
|
||||
u"""Startet das Programmfenster."""
|
||||
if self.xmlmode < 2:
|
||||
tkmsg.showwarning(
|
||||
parent=self.master, title="Warnung",
|
||||
@@ -237,23 +278,30 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self.wait_window(win)
|
||||
|
||||
def plcstart(self):
|
||||
u"""Startet das PLC Programm."""
|
||||
self.cli.plcstart()
|
||||
|
||||
def plcstop(self):
|
||||
u"""Beendet das PLC Programm."""
|
||||
self.cli.plcstop()
|
||||
|
||||
def plcrestart(self):
|
||||
u"""Startet das PLC Programm neu."""
|
||||
self.cli.plcstop()
|
||||
self.cli.plcstart()
|
||||
|
||||
def servererror(self):
|
||||
"""Setzt alles auf NULL."""
|
||||
def serverdisconnect(self):
|
||||
u"""Trennt eine bestehende Verbindung."""
|
||||
socket.setdefaulttimeout(2)
|
||||
self.cli = None
|
||||
self._btnstate()
|
||||
self.mbar.entryconfig("PLC", state="disabled")
|
||||
self.var_conn.set("")
|
||||
self._closeall()
|
||||
|
||||
def servererror(self):
|
||||
u"""Setzt alles zurück für neue Verbindungen."""
|
||||
self.serverdisconnect()
|
||||
tkmsg.showerror("Fehler", "Server ist nicht erreichbar!")
|
||||
|
||||
def tmr_plcrunning(self):
|
||||
|
||||
Reference in New Issue
Block a user