mirror of
https://github.com/naruxde/revpipycontrol.git
synced 2025-11-08 15:43:52 +01:00
Python Version f?r PLC w?hlbar
setup.py aufgebaut
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
syntax: glob
|
||||
*.pyc
|
||||
deb_dist/*
|
||||
dist/*
|
||||
revpipycontrol.egg-info/*
|
||||
|
||||
4
MANIFEST.in
Normal file
4
MANIFEST.in
Normal file
@@ -0,0 +1,4 @@
|
||||
include MANIFEST.in
|
||||
recursive-include data *
|
||||
recursive-include revpipycontrol *
|
||||
global-exclude *.pyc
|
||||
3
data/revpipycontrol
Normal file
3
data/revpipycontrol
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec "/usr/share/revpipycontrol/revpipycontrol.py" "$@"
|
||||
11
data/revpipycontrol.desktop
Normal file
11
data/revpipycontrol.desktop
Normal file
@@ -0,0 +1,11 @@
|
||||
[Desktop Entry]
|
||||
Name=RevPi PLC Control
|
||||
Comment=Controls the Python PLC program on your RevolutionPI
|
||||
Name[de]=RevPi PLC Steuerung
|
||||
Comment[de]=Kontrolliert das Python PLC Programm auf dem RevolutionPI
|
||||
Exec=/usr/bin/revpipycontrol
|
||||
Icon=revpipycontrol
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Application;
|
||||
#StartupNotify=true
|
||||
@@ -1,4 +1,11 @@
|
||||
# Thranks to: http://stackoverflow.com/questions/3085696/adding-a-scrollbar-to-a-group-of-widgets-in-tkinter
|
||||
#
|
||||
# RevPiPyControl
|
||||
#
|
||||
# Webpage: https://revpimodio.org/revpipyplc/
|
||||
# (c) Sven Sager, License: LGPLv3
|
||||
#
|
||||
# Thranks to: http://stackoverflow.com/questions/3085696/adding-a-
|
||||
# scrollbar-to-a-group-of-widgets-in-tkinter
|
||||
|
||||
import pickle
|
||||
import tkinter
|
||||
@@ -10,28 +17,13 @@ from xmlrpc.client import ServerProxy, Binary, MultiCall
|
||||
|
||||
class RevPiCheckClient(tkinter.Frame):
|
||||
|
||||
def __init__(self, master, xmlcli=None):
|
||||
def __init__(self, master, xmlcli):
|
||||
"""Instantiiert MyApp-Klasse."""
|
||||
super().__init__(master)
|
||||
self.pack(fill="both", expand=True)
|
||||
|
||||
# Command arguments
|
||||
parser = ArgumentParser(
|
||||
description="Revolution Pi IO-Client"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-a", "--address", dest="address", default="127.0.0.1",
|
||||
help="Server address (Default: 127.0.0.1)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", "--port", dest="port", type=int, default=55074,
|
||||
help="Use port to connect to server (Default: 55074)"
|
||||
)
|
||||
self.pargs = parser.parse_args()
|
||||
self.cli = xmlcli
|
||||
|
||||
self.cli = xmlcli if xmlcli is not None else ServerProxy(
|
||||
"http://{}:{}".format(self.pargs.address, self.pargs.port)
|
||||
)
|
||||
self.lst_devices = self.cli.get_devicenames()
|
||||
self.lst_group = []
|
||||
self.dict_inpvar = {}
|
||||
|
||||
@@ -47,38 +47,51 @@ class RevPiOption(tkinter.Frame):
|
||||
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["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["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["text"] = "PLC Programm"
|
||||
prog.grid(columnspan=2, pady=2, sticky="we")
|
||||
|
||||
self.var_pythonver = tkinter.IntVar(prog)
|
||||
self.var_startpy = tkinter.StringVar(prog)
|
||||
self.var_slave = tkinter.BooleanVar(prog)
|
||||
|
||||
self.var_pythonver.set(3)
|
||||
|
||||
lbl = tkinter.Label(prog)
|
||||
lbl["text"] = "Python Version"
|
||||
lbl.grid(columnspan=2, row=0, **cpadw)
|
||||
rbn = tkinter.Radiobutton(prog)
|
||||
rbn["text"] = "Python2"
|
||||
rbn["value"] = 2
|
||||
rbn["variable"] = self.var_pythonver
|
||||
rbn.grid(column=0, row=1, **cpadw)
|
||||
rbn = tkinter.Radiobutton(prog)
|
||||
rbn["text"] = "Python3"
|
||||
rbn["value"] = 3
|
||||
rbn["variable"] = self.var_pythonver
|
||||
rbn.grid(column=1, row=1, **cpadw)
|
||||
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)
|
||||
lbl.grid(columnspan=2, **cpadw)
|
||||
opt_startpy = tkinter.OptionMenu(
|
||||
prog, self.var_startpy, *self.xmlcli.get_filelist())
|
||||
opt_startpy.grid(**cpadwe)
|
||||
opt_startpy.grid(columnspan=2, **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)
|
||||
ckb_slave.grid(columnspan=2, **cpadw)
|
||||
|
||||
# Gruppe XMLRPC
|
||||
xmlrpc = tkinter.LabelFrame(self)
|
||||
@@ -86,6 +99,8 @@ class RevPiOption(tkinter.Frame):
|
||||
xmlrpc.grid(columnspan=2, pady=2, sticky="we")
|
||||
|
||||
self.var_xmlon = tkinter.BooleanVar(xmlrpc)
|
||||
self.var_xmlmod2 = tkinter.BooleanVar(xmlrpc)
|
||||
self.var_xmlmod3 = tkinter.BooleanVar(xmlrpc)
|
||||
self.var_xmlport = tkinter.StringVar(xmlrpc)
|
||||
self.var_xmlport.set("55123")
|
||||
|
||||
@@ -94,6 +109,17 @@ class RevPiOption(tkinter.Frame):
|
||||
ckb_xmlon["text"] = "XML-RPC Server aktiv auf RevPi"
|
||||
ckb_xmlon["variable"] = self.var_xmlon
|
||||
ckb_xmlon.grid(**cpadw)
|
||||
self.ckb_xmlmod2 = tkinter.Checkbutton(xmlrpc, justify="left")
|
||||
self.ckb_xmlmod2["command"] = self.xmlmods
|
||||
self.ckb_xmlmod2["text"] = \
|
||||
"Download von piCtory Konfiguration und\nPLC Programm zulassen"
|
||||
self.ckb_xmlmod2["variable"] = self.var_xmlmod2
|
||||
self.ckb_xmlmod2.grid(**cpadw)
|
||||
self.ckb_xmlmod3 = tkinter.Checkbutton(xmlrpc, justify="left")
|
||||
self.ckb_xmlmod3["text"] = \
|
||||
"Upload von piCtory Konfiguration und\nPLC Programm zualssen"
|
||||
self.ckb_xmlmod3["variable"] = self.var_xmlmod3
|
||||
self.ckb_xmlmod3.grid(**cpadw)
|
||||
lbl = tkinter.Label(xmlrpc)
|
||||
lbl["text"] = "XML-RPC Serverport"
|
||||
lbl.grid(**cpadw)
|
||||
@@ -123,9 +149,13 @@ class RevPiOption(tkinter.Frame):
|
||||
self.var_zerr.set(dc["zeroonerror"])
|
||||
|
||||
self.var_startpy.set(dc["plcprogram"])
|
||||
self.var_pythonver.set(dc["pythonversion"])
|
||||
self.var_slave.set(dc["plcslave"])
|
||||
|
||||
self.var_xmlon.set(dc["xmlrpc"])
|
||||
self.var_xmlon.set(dc["xmlrpc"] >= 1)
|
||||
self.var_xmlmod2.set(dc["xmlrpc"] >= 2)
|
||||
self.var_xmlmod3.set(dc["xmlrpc"] >= 3)
|
||||
|
||||
self.var_xmlport.set(dc["xmlrpcport"])
|
||||
|
||||
def _setappdata(self):
|
||||
@@ -136,9 +166,17 @@ class RevPiOption(tkinter.Frame):
|
||||
dc["zeroonerror"] = int(self.var_zerr.get())
|
||||
|
||||
dc["plcprogram"] = self.var_startpy.get()
|
||||
dc["pythonversion"] = self.var_pythonver.get()
|
||||
dc["plcslave"] = int(self.var_slave.get())
|
||||
|
||||
dc["xmlrpc"] = int(self.var_xmlon.get())
|
||||
dc["xmlrpc"] = 0
|
||||
if self.var_xmlon.get():
|
||||
dc["xmlrpc"] += 1
|
||||
if self.var_xmlmod2.get():
|
||||
dc["xmlrpc"] += 1
|
||||
if self.var_xmlmod3.get():
|
||||
dc["xmlrpc"] += 1
|
||||
|
||||
dc["xmlrpcport"] = self.var_xmlport.get()
|
||||
|
||||
ask = tkmsg.askyesnocancel(
|
||||
@@ -148,10 +186,16 @@ class RevPiOption(tkinter.Frame):
|
||||
"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
|
||||
)
|
||||
if self.xmlcli.set_config(dc, ask):
|
||||
tkmsg.showinfo(
|
||||
"Information", "Einstellungen gespeichert.", parent=self.master
|
||||
)
|
||||
else:
|
||||
tkmsg.showerror(
|
||||
"Fehler", "Die Einstellungen konnten nicht gesichert"
|
||||
"werden. Dies kann passieren, wenn Werte falsch sind!",
|
||||
parent=self.master
|
||||
)
|
||||
|
||||
def askxmlon(self):
|
||||
if not self.var_xmlon.get():
|
||||
@@ -162,3 +206,11 @@ class RevPiOption(tkinter.Frame):
|
||||
)
|
||||
if not ask:
|
||||
self.var_xmlon.set(True)
|
||||
|
||||
self.xmlmods()
|
||||
|
||||
def xmlmods(self):
|
||||
self.ckb_xmlmod2["state"] = \
|
||||
"normal" if self.var_xmlon.get() else "disabled"
|
||||
self.ckb_xmlmod3["state"] = \
|
||||
"normal" if self.var_xmlmod2.get() else "disabled"
|
||||
|
||||
@@ -25,7 +25,9 @@ def get_connections():
|
||||
if os.path.exists(savefile):
|
||||
fh = open(savefile, "rb")
|
||||
connections = pickle.load(fh)
|
||||
return connections
|
||||
return connections
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
class RevPiPlcList(tkinter.Frame):
|
||||
|
||||
25
revpipycontrol/revpipycontrol.py
Normal file → Executable file
25
revpipycontrol/revpipycontrol.py
Normal file → Executable file
@@ -7,19 +7,36 @@
|
||||
# (c) Sven Sager, License: LGPLv3
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
import revpicheckclient
|
||||
import revpilogfile
|
||||
import revpioption
|
||||
import revpiplclist
|
||||
import revpiprogram
|
||||
import socket
|
||||
import sys
|
||||
import tkinter
|
||||
import tkinter.messagebox as tkmsg
|
||||
from functools import partial
|
||||
from os.path import dirname
|
||||
from os.path import join as pathjoin
|
||||
from xmlrpc.client import ServerProxy
|
||||
|
||||
socket.setdefaulttimeout(3)
|
||||
|
||||
def addroot(filename):
|
||||
u"""Hängt root-dir der Anwendung vor Dateinamen.
|
||||
|
||||
Je nach Ausführungsart der Anwendung muss das root-dir über
|
||||
andere Arten abgerufen werden.
|
||||
|
||||
@param filename: Datei oder Ordnername
|
||||
@returns: root dir
|
||||
|
||||
"""
|
||||
if getattr(sys, "frozen", False):
|
||||
return pathjoin(dirname(sys.executable), filename)
|
||||
else:
|
||||
return pathjoin(dirname(__file__), filename)
|
||||
|
||||
|
||||
class RevPiPyControl(tkinter.Frame):
|
||||
|
||||
@@ -48,6 +65,9 @@ class RevPiPyControl(tkinter.Frame):
|
||||
"""Erstellt den Fensterinhalt."""
|
||||
# Hauptfenster
|
||||
self.master.wm_title("RevPi Python PLC Loader")
|
||||
self.master.wm_iconphoto(
|
||||
True, tkinter.PhotoImage(file=addroot("revpipycontrol.png"))
|
||||
)
|
||||
self.master.wm_resizable(width=False, height=False)
|
||||
|
||||
# Menü ganz oben
|
||||
@@ -115,6 +135,7 @@ class RevPiPyControl(tkinter.Frame):
|
||||
)
|
||||
|
||||
def _opt_conn(self, text):
|
||||
socket.setdefaulttimeout(20)
|
||||
sp = ServerProxy(
|
||||
"http://{}:{}".format(
|
||||
self.dict_conn[text][0], int(self.dict_conn[text][1])
|
||||
@@ -160,7 +181,6 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self.wait_window(win)
|
||||
|
||||
def plcprogram(self):
|
||||
# TODO: Programfenster
|
||||
win = tkinter.Toplevel(self)
|
||||
revpiprogram.RevPiProgram(win, self.cli, self.revpiname)
|
||||
win.focus_set()
|
||||
@@ -178,6 +198,7 @@ class RevPiPyControl(tkinter.Frame):
|
||||
self.cli.plcstart()
|
||||
|
||||
def servererror(self):
|
||||
socket.setdefaulttimeout(3)
|
||||
self.cli = None
|
||||
self._btnstate()
|
||||
self.mbar.entryconfig("PLC", state="disabled")
|
||||
|
||||
90
setup.py
Normal file
90
setup.py
Normal file
@@ -0,0 +1,90 @@
|
||||
#! /usr/bin/env python3
|
||||
#
|
||||
# (c) Sven Sager, License: LGPLv3
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Setupscript fuer RevPiPyLoad."""
|
||||
import distutils.command.install_egg_info
|
||||
from sys import platform
|
||||
from glob import glob
|
||||
|
||||
|
||||
class MyEggInfo(distutils.command.install_egg_info.install_egg_info):
|
||||
|
||||
u"""Disable egg_info installation, seems pointless for a non-library."""
|
||||
|
||||
def run(self):
|
||||
u"""just pass egg_info."""
|
||||
pass
|
||||
|
||||
|
||||
globsetup = {
|
||||
"author": "Sven Sager",
|
||||
"author_email": "akira@narux.de",
|
||||
"url": "https://revpimodio.org/revpipyplc/",
|
||||
"license": "LGPLv3",
|
||||
"version": "0.2.1",
|
||||
|
||||
"name": "revpipycontrol",
|
||||
|
||||
"description": "PLC Loader für Python-Projekte auf den RevolutionPi",
|
||||
"long_description": ""
|
||||
"Dieses Programm startet beim Systemstart ein angegebenes Python PLC\n"
|
||||
"Programm. Es überwacht das Programm und startet es im Fehlerfall neu.\n"
|
||||
"Bei Abstruz kann das gesamte /dev/piControl0 auf 0x00 gesettz werden.\n"
|
||||
"Außerdem stellt es einen XML-RPC Server bereit, über den die Software\n"
|
||||
"auf den RevPi geladen werden kann. Das Prozessabbild kann über ein Tool\n"
|
||||
"zur Laufzeit überwacht werden.",
|
||||
}
|
||||
|
||||
if platform == "linux":
|
||||
from setuptools import setup
|
||||
setup(
|
||||
maintainer="Sven Sager",
|
||||
maintainer_email="akira@revpimodio.org",
|
||||
|
||||
scripts=["data/revpipycontrol"],
|
||||
|
||||
data_files=[
|
||||
("share/applications", ["data/revpipycontrol.desktop"]),
|
||||
("share/icons/hicolor/32x32/apps", ["data/revpipycontrol.png"]),
|
||||
("share/revpipycontrol", glob("revpipycontrol/*.*")),
|
||||
],
|
||||
|
||||
install_requires=["tkinter"],
|
||||
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: "
|
||||
"GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
],
|
||||
cmdclass={"install_egg_info": MyEggInfo},
|
||||
**globsetup
|
||||
)
|
||||
|
||||
elif platform == "win32":
|
||||
import sys
|
||||
from cx_Freeze import setup, Executable
|
||||
|
||||
sys.path.append("revpipycontrol")
|
||||
|
||||
exe = Executable(
|
||||
script="revpipycontrol/revpipycontrol.py",
|
||||
base="Win32GUI",
|
||||
compress=False,
|
||||
copyDependentFiles=True,
|
||||
appendScriptToExe=True,
|
||||
appendScriptToLibrary=False,
|
||||
icon="data/revpipycontrol.ico"
|
||||
)
|
||||
|
||||
setup(
|
||||
options={"build_exe": {
|
||||
"include_files": [
|
||||
"revpipycontrol/revpipycontrol.png",
|
||||
# "m4server/locale"
|
||||
]
|
||||
}},
|
||||
executables=[exe],
|
||||
**globsetup
|
||||
)
|
||||
Reference in New Issue
Block a user