diff --git a/.hgignore b/.hgignore
index 9e0632f..fe4cdbb 100644
--- a/.hgignore
+++ b/.hgignore
@@ -3,6 +3,6 @@ syntax: glob
deb_dist/*
dist/*
revpipycontrol.egg-info/*
-doc/*
deb/*
.eric6project/*
+*.directory
diff --git a/doc/revpicheckclient.html b/doc/revpicheckclient.html
new file mode 100644
index 0000000..79c32c2
--- /dev/null
+++ b/doc/revpicheckclient.html
@@ -0,0 +1,136 @@
+
+
+revpicheckclient
+
+
+
+
+revpicheckclient
+
+
+Global Attributes
+
+
+Classes
+
+
+Functions
+
+
+
+RevPiCheckClient
+
+
+Derived from
+tkinter.Frame
+
+Class Attributes
+
+
+Class Methods
+
+
+Methods
+
+
+Static Methods
+
+
+
+RevPiCheckClient (Constructor)
+RevPiCheckClient(master, xmlcli, xmlmode=0)
+
+Instantiiert MyApp-Klasse.
+
+
+RevPiCheckClient.__hidewin
+__hidewin(win, event=None)
+
+
+RevPiCheckClient.__showwin
+__showwin(win)
+
+
+RevPiCheckClient._createiogroup
+_createiogroup(device, frame, iotype)
+
+Erstellt IO-Gruppen.
+
+
+RevPiCheckClient._createwidgets
+_createwidgets()
+
+Erstellt den Fensterinhalt.
+
+
+RevPiCheckClient._readvalues
+_readvalues()
+
+Alle Werte der Inputs und Outputs abrufen.
+
+
+RevPiCheckClient.chval
+chval(device, io)
+
+
+RevPiCheckClient.onfrmconf
+onfrmconf(canvas)
+
+
+RevPiCheckClient.readvalues
+readvalues()
+
+
+RevPiCheckClient.toggleauto
+toggleauto()
+
+
+
+
\ No newline at end of file
diff --git a/doc/revpilogfile.html b/doc/revpilogfile.html
new file mode 100644
index 0000000..e97a54a
--- /dev/null
+++ b/doc/revpilogfile.html
@@ -0,0 +1,114 @@
+
+
+revpilogfile
+
+
+
+
+revpilogfile
+
+
+Global Attributes
+
+
+Classes
+
+
+Functions
+
+
+
+RevPiLogfile
+
+
+Derived from
+tkinter.Frame
+
+Class Attributes
+
+
+Class Methods
+
+
+Methods
+
+
+Static Methods
+
+
+
+RevPiLogfile (Constructor)
+RevPiLogfile(master, xmlcli)
+
+
+RevPiLogfile._createwidgets
+_createwidgets()
+
+
+RevPiLogfile.btn_clearapp
+btn_clearapp()
+
+
+RevPiLogfile.btn_clearplc
+btn_clearplc()
+
+
+RevPiLogfile.get_applines
+get_applines()
+
+
+RevPiLogfile.get_applog
+get_applog()
+
+
+RevPiLogfile.get_plclines
+get_plclines()
+
+
+RevPiLogfile.get_plclog
+get_plclog()
+
+
+
+
\ No newline at end of file
diff --git a/doc/revpioption.html b/doc/revpioption.html
new file mode 100644
index 0000000..417e9fd
--- /dev/null
+++ b/doc/revpioption.html
@@ -0,0 +1,100 @@
+
+
+revpioption
+
+
+
+
+revpioption
+
+
+Global Attributes
+
+
+Classes
+
+
+Functions
+
+
+
+RevPiOption
+
+
+Derived from
+tkinter.Frame
+
+Class Attributes
+
+
+Class Methods
+
+
+Methods
+
+
+Static Methods
+
+
+
+RevPiOption (Constructor)
+RevPiOption(master, xmlcli, xmlmode)
+
+
+RevPiOption._createwidgets
+_createwidgets()
+
+
+RevPiOption._loadappdata
+_loadappdata()
+
+
+RevPiOption._setappdata
+_setappdata()
+
+
+RevPiOption.askxmlon
+askxmlon()
+
+
+RevPiOption.xmlmods
+xmlmods()
+
+
+
+
\ No newline at end of file
diff --git a/doc/revpiplclist.html b/doc/revpiplclist.html
new file mode 100644
index 0000000..9d27221
--- /dev/null
+++ b/doc/revpiplclist.html
@@ -0,0 +1,151 @@
+
+
+revpiplclist
+
+
+
+
+revpiplclist
+
+
+Global Attributes
+
+
+Classes
+
+
+Functions
+
+
+
+RevPiPlcList
+
+
+Derived from
+tkinter.Frame
+
+Class Attributes
+
+
+Class Methods
+
+
+Methods
+
+
+Static Methods
+
+
+
+RevPiPlcList (Constructor)
+RevPiPlcList(master)
+
+
+RevPiPlcList._createwidgets
+_createwidgets()
+
+
+RevPiPlcList._loadappdata
+_loadappdata()
+
+
+RevPiPlcList._saveappdata
+_saveappdata()
+
+
+RevPiPlcList.build_listconn
+build_listconn()
+
+
+RevPiPlcList.evt_btnadd
+evt_btnadd()
+
+
+RevPiPlcList.evt_btnclose
+evt_btnclose()
+
+
+RevPiPlcList.evt_btnnew
+evt_btnnew()
+
+
+RevPiPlcList.evt_btnremove
+evt_btnremove()
+
+
+RevPiPlcList.evt_btnsave
+evt_btnsave()
+
+
+RevPiPlcList.evt_keypress
+evt_keypress(evt=None)
+
+
+RevPiPlcList.evt_listconn
+evt_listconn(evt=None)
+
+
+
+
+get_connections
+get_connections()
+
+
+
+
\ No newline at end of file
diff --git a/doc/revpiprogram.html b/doc/revpiprogram.html
new file mode 100644
index 0000000..a00d6cf
--- /dev/null
+++ b/doc/revpiprogram.html
@@ -0,0 +1,187 @@
+
+
+revpiprogram
+
+
+
+
+revpiprogram
+
+
+Global Attributes
+
+
+Classes
+
+
+Functions
+
+
+
+RevPiProgram
+
+
+Derived from
+tkinter.Frame
+
+Class Attributes
+
+
+Class Methods
+
+
+Methods
+
+
+Static Methods
+
+
+
+RevPiProgram (Constructor)
+RevPiProgram(master, xmlcli, xmlmode, revpi)
+
+
+RevPiProgram._createwidgets
+_createwidgets()
+
+
+RevPiProgram._evt_optdown
+_evt_optdown(text="")
+
+
+RevPiProgram._evt_optup
+_evt_optup(text="")
+
+
+RevPiProgram._loaddefault
+_loaddefault(full=False)
+
+Uebernimmt fuer den Pi die letzen Pfade.
+
+
+RevPiProgram._savedefaults
+_savedefaults()
+
+Schreibt fuer den Pi die letzen Pfade.
+
+
+RevPiProgram.check_replacedir
+check_replacedir(rootdir)
+
+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.
+
+- rootdir:
+-
+Verzeichnis fuer Pruefung
+
+
+- Returns:
+-
+Abgeaendertes rootdir
+
+
+
+RevPiProgram.create_filelist
+create_filelist(rootdir)
+
+Erstellt eine Dateiliste von einem Verzeichnis.
+
+- rootdir:
+-
+Verzeichnis fuer das eine Liste erstellt werden soll
+
+
+- Returns:
+-
+Dateiliste
+
+
+
+RevPiProgram.getpictoryrsc
+getpictoryrsc()
+
+
+RevPiProgram.getprocimg
+getprocimg()
+
+
+RevPiProgram.picontrolreset
+picontrolreset()
+
+
+RevPiProgram.plcdownload
+plcdownload()
+
+
+RevPiProgram.plcupload
+plcupload()
+
+
+RevPiProgram.setpictoryrsc
+setpictoryrsc(filename=None)
+
+
+
+
\ No newline at end of file
diff --git a/doc/revpipycontrol.html b/doc/revpipycontrol.html
new file mode 100644
index 0000000..11750e5
--- /dev/null
+++ b/doc/revpipycontrol.html
@@ -0,0 +1,209 @@
+
+
+revpipycontrol
+
+
+
+
+revpipycontrol
+
+
+Global Attributes
+
+
+Classes
+
+
+Functions
+
+
+| addroot |
+Hängt root-dir der Anwendung vor Dateinamen. |
+
+
+
+
+RevPiPyControl
+
+
+Derived from
+tkinter.Frame
+
+Class Attributes
+
+
+Class Methods
+
+
+Methods
+
+
+Static Methods
+
+
+
+RevPiPyControl (Constructor)
+RevPiPyControl(master=None)
+
+
+RevPiPyControl._btnstate
+_btnstate()
+
+
+RevPiPyControl._closeall
+_closeall()
+
+
+RevPiPyControl._createwidgets
+_createwidgets()
+
+Erstellt den Fensterinhalt.
+
+
+RevPiPyControl._fillconnbar
+_fillconnbar()
+
+
+RevPiPyControl._fillmbar
+_fillmbar()
+
+
+RevPiPyControl._opt_conn
+_opt_conn(text)
+
+
+RevPiPyControl.plclist
+plclist()
+
+
+RevPiPyControl.plclogs
+plclogs()
+
+
+RevPiPyControl.plcmonitor
+plcmonitor()
+
+Startet das Monitorfenster.
+
+
+RevPiPyControl.plcoptions
+plcoptions()
+
+Startet das Optionsfenster.
+
+
+RevPiPyControl.plcprogram
+plcprogram()
+
+
+RevPiPyControl.plcrestart
+plcrestart()
+
+
+RevPiPyControl.plcstart
+plcstart()
+
+
+RevPiPyControl.plcstop
+plcstop()
+
+
+RevPiPyControl.servererror
+servererror()
+
+Setzt alles auf NULL.
+
+
+RevPiPyControl.tmr_plcrunning
+tmr_plcrunning()
+
+
+
+
+addroot
+addroot(filename)
+
+Hängt root-dir der Anwendung vor Dateinamen.
+
+ Je nach Ausführungsart der Anwendung muss das root-dir über
+ andere Arten abgerufen werden.
+
+- filename:
+-
+Datei oder Ordnername
+
+
+- Returns:
+-
+root dir
+
+
+
+
+
\ No newline at end of file
diff --git a/revpipycontrol.api b/revpipycontrol.api
index 41dff9d..ae08326 100644
--- a/revpipycontrol.api
+++ b/revpipycontrol.api
@@ -1,15 +1,15 @@
-revpicheckclient.RevPiCheckClient._autorw?5()
+revpicheckclient.RevPiCheckClient.__hidewin?6(win, event=None)
+revpicheckclient.RevPiCheckClient.__showwin?6(win)
revpicheckclient.RevPiCheckClient._createiogroup?5(device, frame, iotype)
revpicheckclient.RevPiCheckClient._createwidgets?5()
-revpicheckclient.RevPiCheckClient._readvaluesdev?5(device, iotype)
-revpicheckclient.RevPiCheckClient._writevaluesdev?5(device)
-revpicheckclient.RevPiCheckClient.myapp?7
+revpicheckclient.RevPiCheckClient._readvalues?5()
+revpicheckclient.RevPiCheckClient.chval?4(device, io)
+revpicheckclient.RevPiCheckClient.cli?7
revpicheckclient.RevPiCheckClient.onfrmconf?4(canvas)
revpicheckclient.RevPiCheckClient.readvalues?4()
-revpicheckclient.RevPiCheckClient.root?7
+revpicheckclient.RevPiCheckClient.tk?7
revpicheckclient.RevPiCheckClient.toggleauto?4()
-revpicheckclient.RevPiCheckClient.writevalues?4()
-revpicheckclient.RevPiCheckClient?1(master, xmlcli)
+revpicheckclient.RevPiCheckClient?1(master, xmlcli, xmlmode=0)
revpilogfile.RevPiLogfile._createwidgets?5()
revpilogfile.RevPiLogfile.btn_clearapp?4()
revpilogfile.RevPiLogfile.btn_clearplc?4()
diff --git a/revpipycontrol.e4p b/revpipycontrol.e4p
index 68fd5fa..2908aac 100644
--- a/revpipycontrol.e4p
+++ b/revpipycontrol.e4p
@@ -1,7 +1,7 @@
-
+
en_US
@@ -9,7 +9,7 @@
Python3
Console
- 0.2.12
+ 0.4.0
Sven Sager
akira@narux.de
@@ -30,6 +30,7 @@
data
doc
revpipycontrol.api
+ stdeb.cfg
revpipycontrol/revpipycontrol.py
diff --git a/revpipycontrol/revpicheckclient.py b/revpipycontrol/revpicheckclient.py
index 1076251..e6443ee 100644
--- a/revpipycontrol/revpicheckclient.py
+++ b/revpipycontrol/revpicheckclient.py
@@ -9,28 +9,29 @@
import pickle
import tkinter
-from argparse import ArgumentParser
-from concurrent.futures import ThreadPoolExecutor
-from time import sleep
-from xmlrpc.client import ServerProxy, Binary, MultiCall
+from threading import Lock
+from xmlrpc.client import ServerProxy
class RevPiCheckClient(tkinter.Frame):
- def __init__(self, master, xmlcli):
+ 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
+ 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.lst_devices = self.cli.get_devicenames()
- self.lst_group = []
- self.dict_inpvar = {}
- self.dict_outvar = {}
+ self.lk = Lock()
self.autorw = tkinter.BooleanVar()
- self.fut_autorw = None
+ self.dowrite = tkinter.BooleanVar()
# Fenster aufbauen
self._createwidgets()
@@ -38,33 +39,6 @@ class RevPiCheckClient(tkinter.Frame):
# Aktuelle Werte einlesen
self.readvalues()
- def _autorw(self):
- dict_inp = {}
- dict_out = {}
-
- while self.autorw.get():
- for dev in self.lst_devices:
- try:
- dict_out[dev] = [
- value[8].get() for value in self.dict_outvar[dev]
- ]
- except:
- print("lasse {} aus".format(dev))
-
- dict_inp = self.cli.refreshvalues(
- Binary(pickle.dumps(dict_out, 3))
- )
- dict_inp = pickle.loads(dict_inp.data)
-
- for dev in dict_inp:
- for io in self.dict_inpvar[dev]:
- try:
- io[8].set(dict_inp[dev].pop(0))
- except:
- print("lasse {} aus".format(io[0]))
-
- sleep(0.1)
-
def onfrmconf(self, canvas):
canvas.configure(scrollregion=canvas.bbox("all"))
@@ -85,23 +59,34 @@ class RevPiCheckClient(tkinter.Frame):
)
rowcount = 0
- for io in self.cli.get_iolist(device, iotype):
- # io = [name,default,anzbits,adressbyte,export,adressid,bmk,bitaddress,tkinter_var]
+
+ if iotype == "inp":
+ lst_io = self.dict_inps[device]
+ else:
+ lst_io = self.dict_outs[device]
+
+ for io in lst_io:
+ # io = [name,bytelen,byteaddr,bmk,bitaddress,(tkinter_var)]
tkinter.Label(s_frame, text=io[0]).grid(
column=0, row=rowcount, sticky="w"
)
- if io[7] >= 0:
+ if io[4] >= 0:
var = tkinter.BooleanVar()
check = tkinter.Checkbutton(s_frame)
+ check["command"] = \
+ lambda device=device, io=io: self.chval(device, io)
check["state"] = "disabled" if iotype == "inp" else "normal"
check["text"] = ""
check["variable"] = var
check.grid(column=1, row=rowcount)
else:
var = tkinter.IntVar()
- txt = tkinter.Spinbox(s_frame, to=256)
+ # 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)
txt["state"] = "disabled" if iotype == "inp" else "normal"
txt["width"] = 4
txt["textvariable"] = var
@@ -109,116 +94,127 @@ class RevPiCheckClient(tkinter.Frame):
# Steuerelementvariable in IO übernehmen
io.append(var)
- if iotype == "inp":
- self.dict_inpvar[device].append(io)
- elif iotype == "out":
- self.dict_outvar[device].append(io)
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"
+ devgrp.pack(fill="y", side="left")
+
for dev in self.lst_devices:
- # Variablen vorbereiten
- self.dict_inpvar[dev] = []
- self.dict_outvar[dev] = []
+ win = tkinter.Toplevel(self)
+ win.wm_title(dev[1])
+ win.protocol(
+ "WM_DELETE_WINDOW",
+ lambda win=win: self.__hidewin(win)
+ )
+ win.withdraw()
# Devicegruppe erstellen
- group = tkinter.LabelFrame(self)
- group["text"] = dev
+ group = tkinter.LabelFrame(win)
+ group["text"] = dev[1]
group.pack(side="left", fill="both", expand=True)
- self.lst_group.append(group)
for iotype in ["inp", "out"]:
frame = tkinter.Frame(group)
frame.pack(side="left", fill="both", expand=True)
- self._createiogroup(dev, frame, iotype)
+ self._createiogroup(dev[0], frame, iotype)
-# self.btn_update = tkinter.Button(self)
-# self.btn_update["text"] = "UPDATE"
-# self.btn_update["command"] = self._autorw
-# self.btn_update.pack(anchor="s", side="bottom", fill="x")
+ # Button erstellen
+ btn = tkinter.Button(devgrp)
+ btn["command"] = lambda win=win: self.__showwin(win)
+ btn["text"] = dev[1]
+ btn.pack(fill="x", padx=10, pady=5)
- self.btn_write = tkinter.Button(self)
- self.btn_write["text"] = "SCHREIBEN"
- self.btn_write["command"] = self.writevalues
- self.btn_write.pack(side="bottom", fill="x")
+ # Steuerungsfunktionen
+ cntgrp = tkinter.LabelFrame(self)
+ cntgrp["text"] = "Control"
+ cntgrp.pack(fill="y", side="right")
- self.btn_read = tkinter.Button(self)
+ self.btn_read = tkinter.Button(cntgrp)
self.btn_read["text"] = "LESEN"
self.btn_read["command"] = self.readvalues
- self.btn_read.pack(side="bottom", fill="x")
+ self.btn_read.pack(fill="x")
- check = tkinter.Checkbutton(self)
+ check = tkinter.Checkbutton(cntgrp)
check["command"] = self.toggleauto
- check["text"] = "autoupdate"
+ check["text"] = "autorefresh processimage"
check["variable"] = self.autorw
- check.pack(side="bottom")
+ check.pack(anchor="w")
- def _readvaluesdev(self, device, iotype):
- """Ruft alle aktuellen Werte fuer das Device ab."""
- # Multicall vorbereiten
- mc_values = MultiCall(self.cli)
+ check = tkinter.Checkbutton(cntgrp)
+ check["state"] = "disabled" if self.xmlmode < 3 else "normal"
+ check["text"] = "write values to processimage"
+ check["variable"] = self.dowrite
+ check.pack(anchor="w")
- if iotype == "inp":
- lst_ios = self.dict_inpvar[device]
- elif iotype == "out":
- lst_ios = self.dict_outvar[device]
+ def chval(self, device, io):
+ if self.dowrite.get():
+ with self.lk:
+ self.cli.ps_setvalue(device, io[0], io[5].get())
- for io in lst_ios:
- mc_values.get_iovalue(device, io[0])
+ # Alles neu einlesen wenn nicht AutoRW aktiv ist
+ if not self.autorw.get():
+ self.readvalues()
- i = 0
- for value in mc_values():
- value = pickle.loads(value.data)
- if type(value) == bytes:
- value = int.from_bytes(value, byteorder="little")
-
- lst_ios[i][8].set(value)
- i += 1
-
- def _writevaluesdev(self, device):
- """Sendet Werte der Outputs fuer ein Device."""
- # Multicall vorbereiten
- mc_values = MultiCall(self.cli)
- lst_ios = lst_ios = self.dict_outvar[device]
-
- for io in lst_ios:
- mc_values.set_iovalue(device, io[0], pickle.dumps(io[8].get(), 3))
-
- # Multicall ausführen
- mc_values()
-
- def readvalues(self):
+ def _readvalues(self):
"""Alle Werte der Inputs und Outputs abrufen."""
- # Werte aus Prozessabbild einlesen
- self.cli.readprocimg()
+
+ # Werte abrufen
+ with self.lk:
+ ba_values = bytearray(self.cli.ps_values().data)
for dev in self.lst_devices:
- self._readvaluesdev(dev, "inp")
- self._readvaluesdev(dev, "out")
+ # io = [name,bytelen,byteaddr,bmk,bitaddress,(tkinter_var)]
+
+ # IO Typ verarbeiten
+ for iotype in [self.dict_inps, self.dict_outs]:
+ # ios verarbeiten
+ for io in iotype[dev[0]]:
+
+ # Bytes umwandeln
+ int_byte = int.from_bytes(
+ ba_values[io[2]:io[2] + io[1]], byteorder="little"
+ )
+ if io[4] >= 0:
+ # Bit-IO
+ io[5].set(bool(int_byte & 1 << io[4]))
+ else:
+ # Byte-IO
+ io[5].set(int_byte)
+
+ if self.autorw.get():
+ self.master.after(200, self._readvalues)
+
+ def readvalues(self):
+ if not self.autorw.get():
+ self._readvalues()
def toggleauto(self):
self.btn_read["state"] = "disabled" if self.autorw.get() else "normal"
- self.btn_write["state"] = "disabled" if self.autorw.get() else "normal"
- if self.autorw.get() \
- and (self.fut_autorw is None or self.fut_autorw.done()):
- e = ThreadPoolExecutor(max_workers=1)
- self.fut_autorw = e.submit(self._autorw)
+ if self.autorw.get():
+ self._readvalues()
- def writevalues(self):
- """Alle Outputs senden."""
- pass
- #for dev in self.lst_devices:
- #self._writevaluesdev(dev)
-
- # Werte in Prozessabbild schreiben
- #self.cli.writeprocimg()
+# Testdrive
if __name__ == "__main__":
- root = tkinter.Tk()
- myapp = RevPiCheckClient(root)
- myapp.mainloop()
+ cli = ServerProxy("http://192.168.50.35:55123")
+ cli.psstart()
+
+ tk = tkinter.Tk()
+ RevPiCheckClient(tk, cli, 3)
+ tk.mainloop()
diff --git a/revpipycontrol/revpiprogram.py b/revpipycontrol/revpiprogram.py
index 01abff2..06dff81 100644
--- a/revpipycontrol/revpiprogram.py
+++ b/revpipycontrol/revpiprogram.py
@@ -17,7 +17,7 @@ from os import environ
from os import makedirs
from shutil import rmtree
from sys import platform
-from tempfile import mktemp, mkdtemp
+from tempfile import mkstemp, mkdtemp
from xmlrpc.client import Binary
@@ -363,7 +363,7 @@ class RevPiProgram(tkinter.Frame):
message="Die Übertragung der piCtory Konfiguration "
"wurde erfolgreich ausgeführt")
- #Einstellungen speichern
+ # Einstellungen speichern
self.opt["setpictoryrsc_dir"] = os.path.dirname(fh.name)
self._savedefaults()
elif ec < 0:
@@ -382,7 +382,7 @@ class RevPiProgram(tkinter.Frame):
def picontrolreset(self):
ask = tkmsg.askyesno(
- parent=self.master, title="Frage...",
+ parent=self.master, title="Frage...",
message="Soll piControlReset wirklich durchgeführt werden? \n"
"Das Prozessabbild und die Steuerung werden dann unterbrochen!!!"
)
@@ -415,7 +415,7 @@ class RevPiProgram(tkinter.Frame):
)
if type(dirselect) == str and dirselect != "":
- fh = open(mktemp(), "wb")
+ fh = open(mkstemp(), "wb")
elif tdown == 1:
# Zip
diff --git a/revpipycontrol/revpipycontrol.py b/revpipycontrol/revpipycontrol.py
index 4f518d6..c107e62 100755
--- a/revpipycontrol/revpipycontrol.py
+++ b/revpipycontrol/revpipycontrol.py
@@ -1,12 +1,13 @@
#!/usr/bin/python3
#
# RevPiPyControl
-# Version: 0.2.12
+# Version: 0.4.0
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
+import revpicheckclient
import revpilogfile
import revpioption
import revpiplclist
@@ -50,6 +51,7 @@ class RevPiPyControl(tkinter.Frame):
self.xmlmode = 0
# Globale Fenster
+ self.tkcheckclient = None
self.tklogs = None
self.tkoptions = None
self.tkprogram = None
@@ -124,7 +126,7 @@ class RevPiPyControl(tkinter.Frame):
# 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 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")
@@ -167,6 +169,8 @@ 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:
@@ -191,10 +195,17 @@ class RevPiPyControl(tkinter.Frame):
self.tklogs.focus_set()
def plcmonitor(self):
- # TODO: Monitorfenster
- pass
+ """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."""
if self.xmlmode < 2:
tkmsg.showwarning(
parent=self.master, title="Warnung",
diff --git a/setup.py b/setup.py
index 0af49cd..2d518aa 100644
--- a/setup.py
+++ b/setup.py
@@ -23,7 +23,7 @@ globsetup = {
"author_email": "akira@narux.de",
"url": "https://revpimodio.org/revpipyplc/",
"license": "LGPLv3",
- "version": "0.2.12",
+ "version": "0.4.0",
"name": "revpipycontrol",