1
0
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:
2017-03-15 13:02:39 +01:00
parent e9648994d0
commit 1adda9912b
9 changed files with 216 additions and 38 deletions

View File

@@ -1,2 +1,5 @@
syntax: glob
*.pyc
deb_dist/*
dist/*
revpipycontrol.egg-info/*

4
MANIFEST.in Normal file
View File

@@ -0,0 +1,4 @@
include MANIFEST.in
recursive-include data *
recursive-include revpipycontrol *
global-exclude *.pyc

3
data/revpipycontrol Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
exec "/usr/share/revpipycontrol/revpipycontrol.py" "$@"

View 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

View File

@@ -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 = {}

View File

@@ -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 "
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 "
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)
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"

View File

@@ -26,6 +26,8 @@ def get_connections():
fh = open(savefile, "rb")
connections = pickle.load(fh)
return connections
else:
return {}
class RevPiPlcList(tkinter.Frame):

25
revpipycontrol/revpipycontrol.py Normal file → Executable file
View 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
View 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
)