mirror of
https://github.com/naruxde/revpipycontrol.git
synced 2025-11-08 15:43:52 +01:00
Fenstermen? eingebaut
RevPiOption eingebaut
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
|
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
|
||||||
<!-- eric project file for project revpipycontrol -->
|
<!-- eric project file for project revpipycontrol -->
|
||||||
<!-- Saved: 2017-03-07, 18:53:58 -->
|
<!-- Saved: 2017-03-08, 17:49:43 -->
|
||||||
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
|
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
|
||||||
<Project version="5.1">
|
<Project version="5.1">
|
||||||
<Language>en_US</Language>
|
<Language>en_US</Language>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<ProgLanguage mixed="0">Python3</ProgLanguage>
|
<ProgLanguage mixed="0">Python3</ProgLanguage>
|
||||||
<ProjectType>Console</ProjectType>
|
<ProjectType>Console</ProjectType>
|
||||||
<Description></Description>
|
<Description></Description>
|
||||||
<Version>0.2.0</Version>
|
<Version>0.2.1</Version>
|
||||||
<Author>Sven Sager</Author>
|
<Author>Sven Sager</Author>
|
||||||
<Email>akira@narux.de</Email>
|
<Email>akira@narux.de</Email>
|
||||||
<Eol index="-1"/>
|
<Eol index="-1"/>
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
<Source>setup.py</Source>
|
<Source>setup.py</Source>
|
||||||
<Source>revpipycontrol/revpiplclist.py</Source>
|
<Source>revpipycontrol/revpiplclist.py</Source>
|
||||||
<Source>revpipycontrol/revpilogfile.py</Source>
|
<Source>revpipycontrol/revpilogfile.py</Source>
|
||||||
|
<Source>revpipycontrol/revpioption.py</Source>
|
||||||
</Sources>
|
</Sources>
|
||||||
<Forms/>
|
<Forms/>
|
||||||
<Translations/>
|
<Translations/>
|
||||||
|
|||||||
161
revpipycontrol/revpioption.py
Normal file
161
revpipycontrol/revpioption.py
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
#
|
||||||
|
# RevPiPyControl
|
||||||
|
#
|
||||||
|
# Webpage: https://revpimodio.org/revpipyplc/
|
||||||
|
# (c) Sven Sager, License: LGPLv3
|
||||||
|
#
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import tkinter
|
||||||
|
import tkinter.messagebox as tkmsg
|
||||||
|
|
||||||
|
|
||||||
|
class RevPiOption(tkinter.Frame):
|
||||||
|
|
||||||
|
def __init__(self, master, xmlcli):
|
||||||
|
super().__init__(master)
|
||||||
|
self.pack()
|
||||||
|
|
||||||
|
self.xmlcli = xmlcli
|
||||||
|
|
||||||
|
# Fenster bauen
|
||||||
|
self._createwidgets()
|
||||||
|
self._loadappdata()
|
||||||
|
|
||||||
|
def _createwidgets(self):
|
||||||
|
self.master.wm_title("RevPi Python PLC Connections")
|
||||||
|
self.master.wm_resizable(width=False, height=False)
|
||||||
|
|
||||||
|
cpadw = {"padx": 4, "pady": 2, "sticky": "w"}
|
||||||
|
cpadwe = {"padx": 4, "pady": 2, "sticky": "we"}
|
||||||
|
|
||||||
|
# Gruppe Start/Stop
|
||||||
|
stst = tkinter.LabelFrame(self)
|
||||||
|
stst["text"] = "Start / Stopp Verhalten"
|
||||||
|
stst.grid(columnspan=2, pady=2, sticky="we")
|
||||||
|
|
||||||
|
self.var_start = tkinter.BooleanVar(stst)
|
||||||
|
self.var_reload = tkinter.BooleanVar(stst)
|
||||||
|
self.var_zexit = tkinter.BooleanVar(stst)
|
||||||
|
self.var_zerr = tkinter.BooleanVar(stst)
|
||||||
|
|
||||||
|
ckb_start = tkinter.Checkbutton(stst)
|
||||||
|
ckb_start["text"] = "Programm automatisch starten"
|
||||||
|
ckb_start["variable"] = self.var_start
|
||||||
|
ckb_start.grid(**cpadw)
|
||||||
|
ckb_reload = tkinter.Checkbutton(stst)
|
||||||
|
ckb_reload["text"] = "Programm nach Absturz neustarten"
|
||||||
|
ckb_reload["variable"] = self.var_reload
|
||||||
|
ckb_reload.grid(**cpadw)
|
||||||
|
ckb_zexit = tkinter.Checkbutton(stst, justify="left")
|
||||||
|
ckb_zexit["text"] = "Prozessabbild auf NULL setzen, wenn "
|
||||||
|
"Programm\nerfolgreich beendet wird"
|
||||||
|
ckb_zexit["variable"] = self.var_zexit
|
||||||
|
ckb_zexit.grid(**cpadw)
|
||||||
|
ckb_zerr = tkinter.Checkbutton(stst, justify="left")
|
||||||
|
ckb_zerr["text"] = "Prozessabbild auf NULL setzen, wenn "
|
||||||
|
"Programm\ndurch Absturz beendet wird"
|
||||||
|
ckb_zerr["variable"] = self.var_zerr
|
||||||
|
ckb_zerr.grid(**cpadw)
|
||||||
|
|
||||||
|
# Gruppe Programm
|
||||||
|
prog = tkinter.LabelFrame(self)
|
||||||
|
prog["text"] = "Programm"
|
||||||
|
prog.grid(columnspan=2, pady=2, sticky="we")
|
||||||
|
|
||||||
|
self.var_startpy = tkinter.StringVar(prog)
|
||||||
|
self.var_slave = tkinter.BooleanVar(prog)
|
||||||
|
|
||||||
|
lbl = tkinter.Label(prog)
|
||||||
|
lbl["text"] = "Python PLC Programname"
|
||||||
|
lbl.grid(**cpadw)
|
||||||
|
txt_startpy = tkinter.Entry(prog)
|
||||||
|
txt_startpy["textvariable"] = self.var_startpy
|
||||||
|
txt_startpy.grid(**cpadwe)
|
||||||
|
ckb_slave = tkinter.Checkbutton(prog, justify="left")
|
||||||
|
ckb_slave["text"] = "RevPi als PLC-Slave verwenden"
|
||||||
|
ckb_slave["state"] = "disabled"
|
||||||
|
ckb_slave["variable"] = self.var_slave
|
||||||
|
ckb_slave.grid(**cpadw)
|
||||||
|
|
||||||
|
# Gruppe XMLRPC
|
||||||
|
xmlrpc = tkinter.LabelFrame(self)
|
||||||
|
xmlrpc["text"] = "XML-RPC Server"
|
||||||
|
xmlrpc.grid(columnspan=2, pady=2, sticky="we")
|
||||||
|
|
||||||
|
self.var_xmlon = tkinter.BooleanVar(xmlrpc)
|
||||||
|
self.var_xmlport = tkinter.StringVar(xmlrpc)
|
||||||
|
self.var_xmlport.set("55123")
|
||||||
|
|
||||||
|
ckb_xmlon = tkinter.Checkbutton(xmlrpc)
|
||||||
|
ckb_xmlon["command"] = self.askxmlon
|
||||||
|
ckb_xmlon["text"] = "XML-RPC Server aktiv auf RevPi"
|
||||||
|
ckb_xmlon["variable"] = self.var_xmlon
|
||||||
|
ckb_xmlon.grid(**cpadw)
|
||||||
|
lbl = tkinter.Label(xmlrpc)
|
||||||
|
lbl["text"] = "XML-RPC Serverport"
|
||||||
|
lbl.grid(**cpadw)
|
||||||
|
spb_xmlport = tkinter.Spinbox(xmlrpc)
|
||||||
|
spb_xmlport["to"] = 65535
|
||||||
|
spb_xmlport["from"] = 1024
|
||||||
|
spb_xmlport["textvariable"] = self.var_xmlport
|
||||||
|
spb_xmlport.grid(**cpadwe)
|
||||||
|
|
||||||
|
# Buttons
|
||||||
|
btn_save = tkinter.Button(self)
|
||||||
|
btn_save["command"] = self._setappdata
|
||||||
|
btn_save["text"] = "Speichern"
|
||||||
|
btn_save.grid(column=0, row=3)
|
||||||
|
|
||||||
|
btn_close = tkinter.Button(self)
|
||||||
|
btn_close["command"] = self.master.destroy
|
||||||
|
btn_close["text"] = "Schließen"
|
||||||
|
btn_close.grid(column=1, row=3)
|
||||||
|
|
||||||
|
def _loadappdata(self):
|
||||||
|
dc = self.xmlcli.get_config()
|
||||||
|
|
||||||
|
self.var_start.set(dc["autostart"])
|
||||||
|
self.var_reload.set(dc["autoreload"])
|
||||||
|
self.var_zexit.set(dc["zeroonexit"])
|
||||||
|
self.var_zerr.set(dc["zeroonerror"])
|
||||||
|
|
||||||
|
self.var_startpy.set(dc["plcprogram"])
|
||||||
|
self.var_slave.set(dc["plcslave"])
|
||||||
|
|
||||||
|
self.var_xmlon.set(dc["xmlrpc"])
|
||||||
|
self.var_xmlport.set(dc["xmlrpcport"])
|
||||||
|
|
||||||
|
def _setappdata(self):
|
||||||
|
dc = {}
|
||||||
|
dc["autostart"] = int(self.var_start.get())
|
||||||
|
dc["autoreload"] = int(self.var_reload.get())
|
||||||
|
dc["zeroonexit"] = int(self.var_zexit.get())
|
||||||
|
dc["zeroonerror"] = int(self.var_zerr.get())
|
||||||
|
|
||||||
|
dc["plcprogram"] = self.var_startpy.get()
|
||||||
|
dc["plcslave"] = int(self.var_slave.get())
|
||||||
|
|
||||||
|
dc["xmlrpc"] = int(self.var_xmlon.get())
|
||||||
|
dc["xmlrpcport"] = self.var_xmlport.get()
|
||||||
|
|
||||||
|
ask = tkmsg.askyesnocancel(
|
||||||
|
"Frage", "Die Einstellungen werden jetzt auf den Revolution Pi "
|
||||||
|
"gespeichert.\nSollen die neuen Einstellungen sofort in Kraft "
|
||||||
|
"treten? Dies bedeutet einen Neustart des Dienstes und des ggf. "
|
||||||
|
"laufenden PLC-Programms!", parent=self.master
|
||||||
|
)
|
||||||
|
if ask is not None:
|
||||||
|
self.xmlcli.set_config(dc, ask)
|
||||||
|
tkmsg.showinfo(
|
||||||
|
"Information", "Einstellungen gespeichert.", parent=self.master
|
||||||
|
)
|
||||||
|
|
||||||
|
def askxmlon(self):
|
||||||
|
if not self.var_xmlon.get():
|
||||||
|
ask = tkmsg.askyesno(
|
||||||
|
"Frage", "Soll der XML-RPC Server wirklich beendet werden? "
|
||||||
|
"Sie können dann mit diesem Programm NICHT mehr auf den "
|
||||||
|
"Revolution Pi zugreifen.", parent=self.master
|
||||||
|
)
|
||||||
|
if not ask:
|
||||||
|
self.var_xmlon.set(True)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
#
|
#
|
||||||
# RevPiPyControl
|
# RevPiPyControl
|
||||||
# Version: 0.2.0
|
# Version: 0.2.1
|
||||||
#
|
#
|
||||||
# Webpage: https://revpimodio.org/revpipyplc/
|
# Webpage: https://revpimodio.org/revpipyplc/
|
||||||
# (c) Sven Sager, License: LGPLv3
|
# (c) Sven Sager, License: LGPLv3
|
||||||
@@ -9,10 +9,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import revpicheckclient
|
import revpicheckclient
|
||||||
import revpilogfile
|
import revpilogfile
|
||||||
|
import revpioption
|
||||||
import revpiplclist
|
import revpiplclist
|
||||||
import socket
|
import socket
|
||||||
import tkinter
|
import tkinter
|
||||||
import tkinter.messagebox as tkmsg
|
import tkinter.messagebox as tkmsg
|
||||||
|
from functools import partial
|
||||||
from xmlrpc.client import ServerProxy
|
from xmlrpc.client import ServerProxy
|
||||||
|
|
||||||
socket.setdefaulttimeout(3)
|
socket.setdefaulttimeout(3)
|
||||||
@@ -47,27 +49,22 @@ class RevPiPyControl(tkinter.Frame):
|
|||||||
self.master.wm_resizable(width=False, height=False)
|
self.master.wm_resizable(width=False, height=False)
|
||||||
|
|
||||||
# Menü ganz oben
|
# Menü ganz oben
|
||||||
self.var_opt = tkinter.StringVar(self)
|
self.mbar = tkinter.Menu(self.master)
|
||||||
self.lst_opt = [
|
self.master.config(menu=self.mbar)
|
||||||
"Connections...",
|
|
||||||
"------------------",
|
menu1 = tkinter.Menu(self.mbar, tearoff=False)
|
||||||
"PLC log...",
|
menu1.add_command(label="Connections...", command=self.plclist)
|
||||||
"PLC monitor...",
|
menu1.add_separator()
|
||||||
"PLC options...",
|
menu1.add_command(label="Exit", command=self.master.destroy)
|
||||||
"PLC program...",
|
self.mbar.add_cascade(label="Main", menu=menu1)
|
||||||
"------------------",
|
|
||||||
"Exit",
|
self._fillmbar()
|
||||||
]
|
self._fillconnbar()
|
||||||
self.opt_menu = tkinter.OptionMenu(
|
|
||||||
self, self.var_opt, *self.lst_opt, command=self._opt_do)
|
|
||||||
self.opt_menu.pack(fill="x")
|
|
||||||
|
|
||||||
# Verbindungen
|
|
||||||
self.var_conn = tkinter.StringVar(self)
|
self.var_conn = tkinter.StringVar(self)
|
||||||
self.lst_conn = sorted(self.dict_conn.keys(), key=lambda x: x.lower())
|
self.txt_connect = tkinter.Entry(
|
||||||
self.opt_conn = tkinter.OptionMenu(
|
self, textvariable=self.var_conn, state="readonly", width=30)
|
||||||
self, self.var_conn, *self.lst_conn, command=self._opt_conn)
|
self.txt_connect.pack(fill="x")
|
||||||
self.opt_conn.pack(fill="x")
|
|
||||||
|
|
||||||
self.btn_plcstart = tkinter.Button(self)
|
self.btn_plcstart = tkinter.Button(self)
|
||||||
self.btn_plcstart["text"] = "PLC Start"
|
self.btn_plcstart["text"] = "PLC Start"
|
||||||
@@ -93,9 +90,28 @@ class RevPiPyControl(tkinter.Frame):
|
|||||||
self.txt_status = tkinter.Entry(self)
|
self.txt_status = tkinter.Entry(self)
|
||||||
self.txt_status["state"] = "readonly"
|
self.txt_status["state"] = "readonly"
|
||||||
self.txt_status["textvariable"] = self.var_status
|
self.txt_status["textvariable"] = self.var_status
|
||||||
self.txt_status.pack()
|
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)
|
||||||
|
|
||||||
|
def _fillconnbar(self):
|
||||||
|
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 _opt_conn(self, text):
|
def _opt_conn(self, text):
|
||||||
|
print(text)
|
||||||
sp = ServerProxy(
|
sp = ServerProxy(
|
||||||
"http://{}:{}".format(
|
"http://{}:{}".format(
|
||||||
self.dict_conn[text][0], int(self.dict_conn[text][1])
|
self.dict_conn[text][0], int(self.dict_conn[text][1])
|
||||||
@@ -108,27 +124,10 @@ class RevPiPyControl(tkinter.Frame):
|
|||||||
self.servererror()
|
self.servererror()
|
||||||
else:
|
else:
|
||||||
self.cli = sp
|
self.cli = sp
|
||||||
|
self.var_conn.set("{} - {}:{}".format(
|
||||||
def _opt_do(self, text):
|
text, self.dict_conn[text][0], int(self.dict_conn[text][1])
|
||||||
optselect = self.lst_opt.index(text)
|
))
|
||||||
if optselect == 0:
|
self.mbar.entryconfig("PLC", state="normal")
|
||||||
# Verbindungen
|
|
||||||
self.plclist()
|
|
||||||
elif optselect == 2:
|
|
||||||
# Logs
|
|
||||||
self.plclogs()
|
|
||||||
elif optselect == 3:
|
|
||||||
pass
|
|
||||||
# self.plcmonitor()
|
|
||||||
elif optselect == 4:
|
|
||||||
# Optionen
|
|
||||||
pass
|
|
||||||
elif optselect == 5:
|
|
||||||
# Programm updown
|
|
||||||
pass
|
|
||||||
elif optselect == 7:
|
|
||||||
self.master.destroy()
|
|
||||||
self.var_opt.set("")
|
|
||||||
|
|
||||||
def plclist(self):
|
def plclist(self):
|
||||||
win = tkinter.Toplevel(self)
|
win = tkinter.Toplevel(self)
|
||||||
@@ -136,15 +135,29 @@ class RevPiPyControl(tkinter.Frame):
|
|||||||
win.focus_set()
|
win.focus_set()
|
||||||
win.grab_set()
|
win.grab_set()
|
||||||
self.wait_window(win)
|
self.wait_window(win)
|
||||||
|
self.dict_conn = revpiplclist.get_connections()
|
||||||
|
self._fillconnbar()
|
||||||
|
|
||||||
def plclogs(self):
|
def plclogs(self):
|
||||||
|
# TODO: nicht doppelt starten
|
||||||
win = tkinter.Toplevel(self)
|
win = tkinter.Toplevel(self)
|
||||||
self.tklogs = revpilogfile.RevPiLogfile(win, self.cli)
|
self.tklogs = revpilogfile.RevPiLogfile(win, self.cli)
|
||||||
|
|
||||||
def plcmonitor(self):
|
def plcmonitor(self):
|
||||||
|
# TODO: Monitorfenster
|
||||||
#self.tkmonitor = revpicheckclient.RevPiCheckClient(self.master, self.cli)
|
#self.tkmonitor = revpicheckclient.RevPiCheckClient(self.master, self.cli)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def plcoptions(self):
|
||||||
|
# TODO: Optionsfenster
|
||||||
|
win = tkinter.Toplevel(self)
|
||||||
|
revpioption.RevPiOption(win, self.cli)
|
||||||
|
self.wait_window(win)
|
||||||
|
|
||||||
|
def plcprogram(self):
|
||||||
|
# TODO: Programfenster
|
||||||
|
pass
|
||||||
|
|
||||||
def plcstart(self):
|
def plcstart(self):
|
||||||
self.cli.plcstart()
|
self.cli.plcstart()
|
||||||
|
|
||||||
@@ -158,6 +171,7 @@ class RevPiPyControl(tkinter.Frame):
|
|||||||
def servererror(self):
|
def servererror(self):
|
||||||
self.cli = None
|
self.cli = None
|
||||||
self._btnstate()
|
self._btnstate()
|
||||||
|
self.mbar.entryconfig("PLC", state="disabled")
|
||||||
self.var_conn.set("")
|
self.var_conn.set("")
|
||||||
tkmsg.showerror("Fehler", "Server ist nicht erreichbar!")
|
tkmsg.showerror("Fehler", "Server ist nicht erreichbar!")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user