From 5950c819f252b7f5b5bf1f2cab74309e5a534ffb Mon Sep 17 00:00:00 2001 From: NaruX Date: Tue, 27 Jun 2017 13:51:54 +0200 Subject: [PATCH 1/9] =?UTF-8?q?mktemp=20gegen=20mkstemp=20getauscht=20proc?= =?UTF-8?q?imgserver=20hinzugef=C3=BCgt=20XML-RPC=20Aufruffunktionen=20f?= =?UTF-8?q?=C3=BCr=20ProcimgServer=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/procimgserver.html | 183 +++++++++++++++++++++++++++++++++++ doc/revpipyload.html | 28 ++++++ eric-revpipyload.api | 9 ++ revpipyload.e4p | 7 +- revpipyload/procimgserver.py | 169 ++++++++++++++++++++++++++++++++ revpipyload/revpipyload.py | 44 ++++++++- setup.py | 4 +- stdeb.cfg | 6 +- 8 files changed, 442 insertions(+), 8 deletions(-) create mode 100644 doc/procimgserver.html create mode 100644 revpipyload/procimgserver.py diff --git a/doc/procimgserver.html b/doc/procimgserver.html new file mode 100644 index 0000000..6057977 --- /dev/null +++ b/doc/procimgserver.html @@ -0,0 +1,183 @@ + + +procimgserver + + + +

+procimgserver

+

+Stellt Funktionen bereit um das Prozessabbild zu ueberwachen. +

+Bei ausreichend Rechten koennen Ausgaenge auch gesetzt werden um einen +IO-Check bei Inbetriebname durchzufuehren. +

+

+Global Attributes

+ + +
None
+

+Classes

+ + + + + +
ProcimgServerServerkomponente fuer zusaetzliche XML-RPC Funktionen.
+

+Functions

+ + +
None
+

+ +

ProcimgServer

+

+Serverkomponente fuer zusaetzliche XML-RPC Funktionen. +

+ Diese Klasse registriert zusaetzliche Funktionen an einem besthenden + XML-RPC-Server. Der Funktionsumfang wird erweitert um zyklisch das + Prozessabbild zu empfangen und bei ausreichend Rechten Ausgaenge zu + setzen. +

+ +

+

+Derived from

+None +

+Class Attributes

+ + +
None
+

+Class Methods

+ + +
None
+

+Methods

+ + + + + + + + + + + + + + + + + + + + + + + +
ProcimgServerInstantiiert RevPiCheckServer()-Klasse.
devicesGeneriert Deviceliste mit Position und Namen.
iosGeneriert ein dict() der Devices und IOs.
setvalueSetzt einen Wert auf dem RevPi.
startRegistriert XML Funktionen.
stopEntfernt XML-Funktionen.
valuesLiefert Prozessabbild an Client.
+

+Static Methods

+ + +
None
+ +

+ProcimgServer (Constructor)

+ProcimgServer(logger, xmlserver, configrsc, procimg, aclmode) +

+Instantiiert RevPiCheckServer()-Klasse. +

+
xmlserver:
+
+XML-RPC Server +
procimg:
+
+Pfad zum Prozessabbild +
configrsc:
+
+Pfad zur piCtory Konfigurationsdatei +
logger:
+
+Loggerinstanz +
aclmode:
+
+Zugriffsrechte +
+
+

+ProcimgServer.devices

+devices() +

+Generiert Deviceliste mit Position und Namen. +

+
Returns:
+
+list() mit Tuple (pos, name) +
+
+

+ProcimgServer.ios

+ios(type) +

+Generiert ein dict() der Devices und IOs. +

+
type:
+
+IO Typ inp/out +
+
+
Returns:
+
+pickled dict() +
+
+

+ProcimgServer.setvalue

+setvalue(device, io, value) +

+Setzt einen Wert auf dem RevPi. +

+
device:
+
+Device Position oder Name +
io:
+
+IO Name fuer neuen Wert +
value:
+
+Neuer Wert +
+
+

+ProcimgServer.start

+start() +

+Registriert XML Funktionen. +

+

+ProcimgServer.stop

+stop() +

+Entfernt XML-Funktionen. +

+

+ProcimgServer.values

+values() +

+Liefert Prozessabbild an Client. +

+
Returns:
+
+Binary() bytes or None +
+
+
Up
+
+ \ No newline at end of file diff --git a/doc/revpipyload.html b/doc/revpipyload.html index 16b3a4e..d954d32 100644 --- a/doc/revpipyload.html +++ b/doc/revpipyload.html @@ -497,6 +497,12 @@ Methods xml_plcuploadclean Loescht das gesamte plcworkdir Verzeichnis. +xml_psstart +Starten den Prozessabbildserver. + +xml_psstop +Stoppt den Prozessabbildserver. + xml_reload Startet RevPiPyLoad neu und verwendet neue Konfiguraiton. @@ -727,6 +733,28 @@ Loescht das gesamte plcworkdir Verzeichnis.
True, wenn erfolgreich
+ +

+RevPiPyLoad.xml_psstart

+xml_psstart() +

+Starten den Prozessabbildserver. +

+
Returns:
+
+True, wenn start erfolgreich +
+
+

+RevPiPyLoad.xml_psstop

+xml_psstop() +

+Stoppt den Prozessabbildserver. +

+
Returns:
+
+True, wenn stop erfolgreich +

RevPiPyLoad.xml_reload

diff --git a/eric-revpipyload.api b/eric-revpipyload.api index 080cf22..e42cade 100644 --- a/eric-revpipyload.api +++ b/eric-revpipyload.api @@ -1,3 +1,10 @@ +procimgserver.ProcimgServer.devices?4() +procimgserver.ProcimgServer.ios?4(type) +procimgserver.ProcimgServer.setvalue?4(device, io, value) +procimgserver.ProcimgServer.start?4() +procimgserver.ProcimgServer.stop?4() +procimgserver.ProcimgServer.values?4() +procimgserver.ProcimgServer?1(logger, xmlserver, configrsc, procimg, aclmode) proginit.cleanup?4() proginit.configure?4() proginit.forked?7 @@ -48,6 +55,8 @@ revpipyload.RevPiPyLoad.xml_plcstart?4() revpipyload.RevPiPyLoad.xml_plcstop?4() revpipyload.RevPiPyLoad.xml_plcupload?4(filedata, filename) revpipyload.RevPiPyLoad.xml_plcuploadclean?4() +revpipyload.RevPiPyLoad.xml_psstart?4() +revpipyload.RevPiPyLoad.xml_psstop?4() revpipyload.RevPiPyLoad.xml_reload?4() revpipyload.RevPiPyLoad.xml_setconfig?4(dc, loadnow=False) revpipyload.RevPiPyLoad.xml_setpictoryrsc?4(filebytes, reset=False) diff --git a/revpipyload.e4p b/revpipyload.e4p index 279b131..5f9d6d9 100644 --- a/revpipyload.e4p +++ b/revpipyload.e4p @@ -1,7 +1,7 @@ - + en_US @@ -9,7 +9,7 @@ Python3 Console Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten. - 0.3.0 + 0.4.0 Sven Sager akira@narux.de @@ -17,6 +17,7 @@ revpipyload/proginit.py setup.py revpipyload/revpipyload.py + revpipyload/procimgserver.py @@ -28,7 +29,9 @@ doc debian eric-revpipyload.api + stdeb.cfg + revpipyload/revpipyload.py Mercurial diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py new file mode 100644 index 0000000..be9da2e --- /dev/null +++ b/revpipyload/procimgserver.py @@ -0,0 +1,169 @@ +# +# RevPiPyLoad +# +# Webpage: https://revpimodio.org/revpipyplc/ +# (c) Sven Sager, License: LGPLv3 +# +# -*- coding: utf-8 -*- +"""Stellt Funktionen bereit um das Prozessabbild zu ueberwachen. + +Bei ausreichend Rechten koennen Ausgaenge auch gesetzt werden um einen +IO-Check bei Inbetriebname durchzufuehren. + +""" +import pickle +import revpimodio +from xmlrpc.client import Binary + + +class ProcimgServer(): + + """Serverkomponente fuer zusaetzliche XML-RPC Funktionen. + + Diese Klasse registriert zusaetzliche Funktionen an einem besthenden + XML-RPC-Server. Der Funktionsumfang wird erweitert um zyklisch das + Prozessabbild zu empfangen und bei ausreichend Rechten Ausgaenge zu + setzen. + + """ + + def __init__(self, logger, xmlserver, configrsc, procimg, aclmode): + """Instantiiert RevPiCheckServer()-Klasse. + + @param xmlserver: XML-RPC Server + @param procimg: Pfad zum Prozessabbild + @param configrsc: Pfad zur piCtory Konfigurationsdatei + @param logger: Loggerinstanz + @param aclmode: Zugriffsrechte + + """ + # Logger übernehmen + self.logger = logger + self.logger.debug("enter ProcimgServer.__init__()") + self.acl = aclmode + + # XML-Server übernehmen + self.xmlsrv = xmlserver + self.xmlreadfuncs = { + "ps_devices": self.devices, + "ps_inps": lambda: self.ios("inp"), + "ps_outs": lambda: self.ios("out"), + "ps_mems": lambda: self.ios("mem"), + "ps_values": self.values, + } + self.xmlwritefuncs = { + "ps_setvalue": self.setvalue, + } + + # RevPiModIO-Modul Instantiieren + self.logger.debug("create revpimodio class") + self.rpi = revpimodio.RevPiModIO( + configrsc=configrsc, + procimg=procimg, + ) + self.rpi.devices.syncoutputs(device=0) + self.logger.debug("created revpimodio class") + + self.logger.debug("leave ProcimgServer.__init__()") + + def devices(self): + """Generiert Deviceliste mit Position und Namen. + @returns: list() mit Tuple (pos, name)""" + return [ + (dev.position, dev.name) for dev in self.rpi.devices + ] + + def ios(self, type): + """Generiert ein dict() der Devices und IOs. + @param type: IO Typ inp/out + @returns: pickled dict()""" + dict_ios = {} + for dev in self.rpi.devices: + dict_ios[dev.position] = [] + + # IO Typen auswerten + if type == "inp": + lst_io = dev.get_inps() + elif type == "out": + lst_io = dev.get_outs() + elif type == "mem": + lst_io = dev.get_mems() + else: + lst_io = [] + + for io in lst_io: + dict_ios[dev.position].append([ + io.name, + 1 if io._bitlength == 1 else int(io._bitlength / 8), + io.slc_address.start + dev.offset, + io.bmk, + io._bitaddress, + ]) + return Binary(pickle.dumps(dict_ios)) + + def setvalue(self, device, io, value): + """Setzt einen Wert auf dem RevPi. + + @param device: Device Position oder Name + @param io: IO Name fuer neuen Wert + @param value: Neuer Wert + + """ + # Zugriffsrechte prüfen + if self.acl < 3: + raise PermissionError( + "not allowed in XML-RPC permission mode {}".format(self.acl) + ) + + self.rpi.devices.syncoutputs(device=device) + + # Neuen Wert übernehmen + if type(value) == bytes or type(value) == bool: + self.rpi.devices[device][io].set_value(value) + else: + self.rpi.devices[device][io].value = value.to_bytes( + self.rpi.devices[device][io].length, byteorder="little" + ) + + self.rpi.devices.writeprocimg(device=device) + + def values(self): + """Liefert Prozessabbild an Client. + @returns: Binary() bytes or None""" + if self.rpi.devices.readprocimg() and self.rpi.devices.syncoutputs(): + bytebuff = b'' + for dev in self.rpi.devices: + bytebuff += bytes(dev) + return Binary(bytebuff) + else: + return None + + def start(self): + """Registriert XML Funktionen.""" + self.logger.debug("enter ProcimgServer.start()") + + # Registriere Funktionen + for xmlfunc in self.xmlreadfuncs: + self.xmlsrv.register_function(self.xmlreadfuncs[xmlfunc], xmlfunc) + if self.acl >= 3: + for xmlfunc in self.xmlwritefuncs: + self.xmlsrv.register_function( + self.xmlwritefuncs[xmlfunc], xmlfunc + ) + + self.logger.debug("leave ProcimgServer.start()") + + def stop(self): + """Entfernt XML-Funktionen.""" + self.logger.debug("enter ProcimgServer.stop()") + + # Entferne Funktionen + for xmlfunc in self.xmlreadfuncs: + if xmlfunc in self.xmlsrv.funcs: + del self.xmlsrv.funcs[xmlfunc] + if self.acl >= 3: + for xmlfunc in self.xmlwritefuncs: + if xmlfunc in self.xmlsrv.funcs: + del self.xmlsrv.funcs[xmlfunc] + + self.logger.debug("leave ProcimgServer.stop()") diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index a639f46..651ee49 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -45,7 +45,7 @@ from json import loads as jloads from re import match as rematch from shutil import rmtree from sys import stdout as sysstdout -from tempfile import mktemp +from tempfile import mkstemp from threading import Thread, Event, Lock from time import sleep, asctime from xmlrpc.client import Binary @@ -54,7 +54,7 @@ from xmlrpc.server import SimpleXMLRPCServer configrsc = None picontrolreset = "/opt/KUNBUS/piControlReset" procimg = "/dev/piControl0" -pyloadverion = "0.3.0" +pyloadverion = "0.4.0" class LogReader(): @@ -512,6 +512,7 @@ class RevPiPyLoad(): self.tfile = {} self.tpe = None self.xsrv = None + self.xml_ps = None # Load config self._loadconfig() @@ -592,6 +593,23 @@ class RevPiPyLoad(): self.xsrv.register_function(self.xml_plcstop, "plcstop") self.xsrv.register_function(self.xml_reload, "reload") + # Erweiterte Funktionen anmelden + try: + import procimgserver + self.xml_ps = procimgserver.ProcimgServer( + proginit.logger, self.xsrv, configrsc, procimg, self.xmlrpc + ) + self.xsrv.register_function(self.xml_psstart, "psstart") + self.xsrv.register_function(self.xml_psstop, "psstop") + except: + self.xml_ps = None + proginit.logger.warning( + "can not load revpimodio module. maybe its not installed " + "or an old version (required at least 0.11.0). if you " + "like to use the process monitor feature, update/install " + "revpimodio: 'apt-get install python3-revpimodio'" + ) + # XML Modus 2 Einstellungen lesen und Programm herunterladen if self.xmlrpc >= 2: self.xsrv.register_function( @@ -691,7 +709,7 @@ class RevPiPyLoad(): @returns: Dateinamen des Archivs """ - filename = mktemp(suffix=".packed", prefix="plc") + filename = mkstemp(suffix=".packed", prefix="plc") if mode == "zip": fh_pack = zipfile.ZipFile(filename, mode="w") @@ -1008,6 +1026,8 @@ class RevPiPyLoad(): if chk not in jconfigrsc: return -2 + # TODO: Module prüfen, ob sie existieren + try: with open(configrsc, "wb") as fh: fh.write(filebytes.data) @@ -1019,6 +1039,24 @@ class RevPiPyLoad(): else: return 0 + def xml_psstart(self): + """Starten den Prozessabbildserver. + @returns: True, wenn start erfolgreich""" + if self.xml_ps is not None: + self.xml_ps.start() + return True + else: + return False + + def xml_psstop(self): + """Stoppt den Prozessabbildserver. + @returns: True, wenn stop erfolgreich""" + if self.xml_ps is not None: + self.xml_ps.stop() + return True + else: + return False + if __name__ == "__main__": root = RevPiPyLoad() diff --git a/setup.py b/setup.py index ae17d66..b916ab3 100644 --- a/setup.py +++ b/setup.py @@ -27,10 +27,12 @@ setup( license="LGPLv3", name="revpipyload", - version="0.3.0", + version="0.4.0", scripts=["data/revpipyload"], + install_requires=["revpimodio"], + data_files=[ ("/etc/default", ["data/etc/default/revpipyload"]), ("/etc/revpipyload", ["data/etc/revpipyload/revpipyload.conf"]), diff --git a/stdeb.cfg b/stdeb.cfg index 2d9a383..b6c3754 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -1,4 +1,6 @@ [DEFAULT] -X-Python3-Version: 3.2- +Debian-Version: 1 +Depends3: python3-revpimodio (>= 0.11.0) Package: revpipyload -Suite: stable \ No newline at end of file +Suite: stable +X-Python3-Version: >=3.2 From 16263bb9ec7e30d96937d3583604c4ed34d21e3e Mon Sep 17 00:00:00 2001 From: NaruX Date: Thu, 29 Jun 2017 18:01:41 +0200 Subject: [PATCH 2/9] =?UTF-8?q?Ausg=C3=A4nge=20im=20procimgserver=20immer?= =?UTF-8?q?=20als=20Bytes=20umgerechnet=20setzen=20XML-Server=20f=C3=BCr?= =?UTF-8?q?=20multicall=20konfigurieren=20LogReader=20auf=20Byte=C3=BCbert?= =?UTF-8?q?ragung=20umgeschrieben=20Neue=20XML-Funktionen=20f=C3=BCr=20Log?= =?UTF-8?q?Reader=20Byte=C3=BCbertragung=20eingebaut=20logger=20bei=20prog?= =?UTF-8?q?init.configure()=20nicht=20doppelt=20erzeugen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- revpipyload.e4p | 4 +- revpipyload/procimgserver.py | 6 +- revpipyload/proginit.py | 3 +- revpipyload/revpipyload.py | 113 +++++++++++------------------------ setup.py | 2 +- 5 files changed, 45 insertions(+), 83 deletions(-) diff --git a/revpipyload.e4p b/revpipyload.e4p index 5f9d6d9..b090706 100644 --- a/revpipyload.e4p +++ b/revpipyload.e4p @@ -1,7 +1,7 @@ - + en_US @@ -9,7 +9,7 @@ Python3 Console Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten. - 0.4.0 + 0.4.1 Sven Sager akira@narux.de diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index be9da2e..9861d8f 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -121,8 +121,10 @@ class ProcimgServer(): if type(value) == bytes or type(value) == bool: self.rpi.devices[device][io].set_value(value) else: - self.rpi.devices[device][io].value = value.to_bytes( - self.rpi.devices[device][io].length, byteorder="little" + self.rpi.devices[device][io].set_value( + value.to_bytes( + self.rpi.devices[device][io].length, byteorder="little" + ) ) self.rpi.devices.writeprocimg(device=device) diff --git a/revpipyload/proginit.py b/revpipyload/proginit.py index 6340bd6..3bc0e98 100644 --- a/revpipyload/proginit.py +++ b/revpipyload/proginit.py @@ -102,7 +102,8 @@ def configure(): # Program logger global logger - logger = logging.getLogger() + if logger is None: + logger = logging.getLogger() # Alle handler entfernen for lhandler in logger.handlers: diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 651ee49..6a86d1c 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -33,7 +33,6 @@ begrenzt werden! import gzip import proginit import os -import pickle import shlex import signal import subprocess @@ -54,7 +53,7 @@ from xmlrpc.server import SimpleXMLRPCServer configrsc = None picontrolreset = "/opt/KUNBUS/piControlReset" procimg = "/dev/piControl0" -pyloadverion = "0.4.0" +pyloadverion = "0.4.1" class LogReader(): @@ -71,9 +70,9 @@ class LogReader(): def __init__(self): """Instantiiert LogReader-Klasse.""" self.fhapp = None - self.posapp = 0 + self.fhapplk = Lock() self.fhplc = None - self.posplc = 0 + self.fhplclk = Lock() def closeall(self): """Fuehrt close auf File Handler durch.""" @@ -82,84 +81,45 @@ class LogReader(): if self.fhplc is not None: self.fhplc.close() - def get_applines(self): - """Gibt neue Zeilen ab letzen Aufruf zurueck. - @returns: list() mit neuen Zeilen""" + def load_applog(self, start, count): + """Uebertraegt Logdaten Binaer. + + @param start: Startbyte + @param count: Max. Byteanzahl zum uebertragen + @returns: Binary() der Logdatei + + """ if not os.access(proginit.logapp, os.R_OK): - return Binary(pickle.dumps([])) + return Binary(b'\x16') #  + elif start > os.path.getsize(proginit.logapp): + return Binary(b'\x19') #  else: - if self.fhapp is None or self.fhapp.closed: - self.fhapp = open(proginit.logapp) + with self.fhapplk: + if self.fhapp is None or self.fhapp.closed: + self.fhapp = open(proginit.logapp, "rb") - lst_new = [] - while True: - self.posapp = self.fhapp.tell() - line = self.fhapp.readline() - if line: - lst_new.append(line) - else: - self.fhapp.seek(self.posapp) - break + self.fhapp.seek(start) + return Binary(self.fhapp.read(count)) - proginit.logger.debug( - "got {} new app log lines".format(len(lst_new)) - ) - return Binary(pickle.dumps(lst_new)) + def load_plclog(self, start, count): + """Uebertraegt Logdaten Binaer. - def get_applog(self): - """Gibt die gesamte Logdatei zurueck. - @returns: str() mit Logdaten""" - if not os.access(proginit.logapp, os.R_OK): - proginit.logger.error( - "can not access logfile {}".format(proginit.logapp) - ) - return Binary(pickle.dumps("")) - else: - if self.fhapp is None or self.fhapp.closed: - self.fhapp = open(proginit.logapp) - self.fhapp.seek(0) - return Binary(pickle.dumps(self.fhapp.read())) + @param start: Startbyte + @param count: Max. Byteanzahl zum uebertragen + @returns: Binary() der Logdatei - def get_plclines(self): - """Gibt neue Zeilen ab letzen Aufruf zurueck. - @returns: list() mit neuen Zeilen""" + """ if not os.access(proginit.logplc, os.R_OK): - proginit.logger.error( - "can not access logfile {}".format(proginit.logplc) - ) - return Binary(pickle.dumps([])) + return Binary(b'\x16') #  + elif start > os.path.getsize(proginit.logplc): + return Binary(b'\x19') #  else: - if self.fhplc is None or self.fhplc.closed: - self.fhplc = open(proginit.logplc) + with self.fhplclk: + if self.fhplc is None or self.fhplc.closed: + self.fhplc = open(proginit.logplc, "rb") - lst_new = [] - while True: - self.posplc = self.fhplc.tell() - line = self.fhplc.readline() - if line: - lst_new.append(line) - else: - self.fhplc.seek(self.posplc) - break - - proginit.logger.debug( - "got {} new pyloader log lines".format(len(lst_new)) - ) - return Binary(pickle.dumps(lst_new)) - - def get_plclog(self): - """Gibt die gesamte Logdatei zurueck. - @returns: str() mit Logdaten""" - if not os.access(proginit.logplc, os.R_OK): - proginit.logger.error( - "can not access logfile {}".format(proginit.logplc) - ) - return Binary(pickle.dumps("")) - else: - if self.fhplc is None or self.fhplc.closed: - self.fhplc = open(proginit.logplc) - self.fhplc.seek(0) - return Binary(pickle.dumps(self.fhplc.read())) + self.fhplc.seek(start) + return Binary(self.fhplc.read(count)) class PipeLogwriter(Thread): @@ -581,12 +541,11 @@ class RevPiPyLoad(): allow_none=True ) self.xsrv.register_introspection_functions() + self.xsrv.register_multicall_functions() # XML Modus 1 Nur Logs lesen und PLC Programm neu starten - self.xsrv.register_function(self.logr.get_applines, "get_applines") - self.xsrv.register_function(self.logr.get_applog, "get_applog") - self.xsrv.register_function(self.logr.get_plclines, "get_plclines") - self.xsrv.register_function(self.logr.get_plclog, "get_plclog") + self.xsrv.register_function(self.logr.load_applog, "load_applog") + self.xsrv.register_function(self.logr.load_plclog, "load_plclog") self.xsrv.register_function(self.xml_plcexitcode, "plcexitcode") self.xsrv.register_function(self.xml_plcrunning, "plcrunning") self.xsrv.register_function(self.xml_plcstart, "plcstart") diff --git a/setup.py b/setup.py index b916ab3..e0a6495 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ setup( license="LGPLv3", name="revpipyload", - version="0.4.0", + version="0.4.1", scripts=["data/revpipyload"], From ff29500ccd7b28361f73150e9d1fd53b21a5d88b Mon Sep 17 00:00:00 2001 From: NaruX Date: Fri, 30 Jun 2017 17:18:41 +0200 Subject: [PATCH 3/9] =?UTF-8?q?Name=20im=20init.d=20Script=20angepasst=20P?= =?UTF-8?q?rocimgServer.setvalue()=20gibt=20Liste=20als=20R=C3=BCckgabewer?= =?UTF-8?q?t=20mit=20Ergebnissen=20Buxfix:=20mkstemp=20Umstellung=20=C3=9C?= =?UTF-8?q?bertragene=20piCtory=20Konfiguration=20auf=20existierende=20Mod?= =?UTF-8?q?ule=20testen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/revpipyload.init | 4 +-- doc/procimgserver.html | 5 +++ doc/revpipyload.html | 68 +++++++++++++++--------------------- eric-revpipyload.api | 7 ++-- revpipyload/procimgserver.py | 30 ++++++++++------ revpipyload/revpipyload.py | 39 +++++++++++++++++---- 6 files changed, 92 insertions(+), 61 deletions(-) diff --git a/debian/revpipyload.init b/debian/revpipyload.init index 5d19d9c..fa2f8e0 100755 --- a/debian/revpipyload.init +++ b/debian/revpipyload.init @@ -5,8 +5,8 @@ # Required-Stop: $remote_fs $syslog $piControl # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 -# Short-Description: Start RevPiPyLoad to execute python plc program -# Description: This file starts the RevPiPyLoad on system +# Short-Description: RevPiPyLoad to execute python plc program +# Description: This file manages the RevPiPyLoad on system # boot. The Loader starts your python plc program and # check whether it is running. ### END INIT INFO diff --git a/doc/procimgserver.html b/doc/procimgserver.html index 6057977..6b7e157 100644 --- a/doc/procimgserver.html +++ b/doc/procimgserver.html @@ -154,6 +154,11 @@ IO Name fuer neuen Wert
Neuer Wert
+
+
Returns:
+
+list() [device, io, status, msg] +

ProcimgServer.start

diff --git a/doc/revpipyload.html b/doc/revpipyload.html index d954d32..4c67169 100644 --- a/doc/revpipyload.html +++ b/doc/revpipyload.html @@ -32,7 +32,7 @@ begrenzt werden!

Global Attributes

- +
configrsc
picontrolreset
procimg
pyloadverion
configrsc
picontrolreset
procimg
pyloadverion
rapcatalog

Classes

@@ -92,17 +92,11 @@ Methods closeall Fuehrt close auf File Handler durch. -get_applines -Gibt neue Zeilen ab letzen Aufruf zurueck. +load_applog +Uebertraegt Logdaten Binaer. -get_applog -Gibt die gesamte Logdatei zurueck. - -get_plclines -Gibt neue Zeilen ab letzen Aufruf zurueck. - -get_plclog -Gibt die gesamte Logdatei zurueck. +load_plclog +Uebertraegt Logdaten Binaer.

@@ -122,49 +116,43 @@ LogReader.closeall

closeall()

Fuehrt close auf File Handler durch. -

+

-LogReader.get_applines

-get_applines() +LogReader.load_applog +load_applog(start, count)

-Gibt neue Zeilen ab letzen Aufruf zurueck. +Uebertraegt Logdaten Binaer.

-
Returns:
+
start:
-list() mit neuen Zeilen +Startbyte +
count:
+
+Max. Byteanzahl zum uebertragen
-
-

-LogReader.get_applog

-get_applog() -

-Gibt die gesamte Logdatei zurueck. -

+
Returns:
-str() mit Logdaten +Binary() der Logdatei
-
+

-LogReader.get_plclines

-get_plclines() +LogReader.load_plclog +load_plclog(start, count)

-Gibt neue Zeilen ab letzen Aufruf zurueck. +Uebertraegt Logdaten Binaer.

-
Returns:
+
start:
-list() mit neuen Zeilen +Startbyte +
count:
+
+Max. Byteanzahl zum uebertragen
-
-

-LogReader.get_plclog

-get_plclog() -

-Gibt die gesamte Logdatei zurueck. -

+
Returns:
-str() mit Logdaten +Binary() der Logdatei
@@ -794,6 +782,8 @@ Statuscode: -1 Kann JSON-Datei nicht laden -2 piCtory Elemente in JSON-Datei nicht gefunden -3 Konnte Konfiguraiton nicht schreiben + -4 Module in Konfiguration enthalten, die es nicht gibt + -5 Kein RAP Katalog zur Ueberpruefung gefunden Positive Zahl ist exitcode von piControlReset diff --git a/eric-revpipyload.api b/eric-revpipyload.api index e42cade..8b39e80 100644 --- a/eric-revpipyload.api +++ b/eric-revpipyload.api @@ -15,10 +15,8 @@ proginit.logplc?7 proginit.pargs?7 proginit.startdir?7 revpipyload.LogReader.closeall?4() -revpipyload.LogReader.get_applines?4() -revpipyload.LogReader.get_applog?4() -revpipyload.LogReader.get_plclines?4() -revpipyload.LogReader.get_plclog?4() +revpipyload.LogReader.load_applog?4(start, count) +revpipyload.LogReader.load_plclog?4(start, count) revpipyload.LogReader?1() revpipyload.PipeLogwriter.__del__?6() revpipyload.PipeLogwriter._configurefh?5() @@ -65,3 +63,4 @@ revpipyload.configrsc?7 revpipyload.picontrolreset?7 revpipyload.procimg?7 revpipyload.pyloadverion?7 +revpipyload.rapcatalog?7 diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index 9861d8f..ff19dc9 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -107,27 +107,37 @@ class ProcimgServer(): @param device: Device Position oder Name @param io: IO Name fuer neuen Wert @param value: Neuer Wert + @returns: list() [device, io, status, msg] """ # Zugriffsrechte prüfen if self.acl < 3: - raise PermissionError( + return [ + device, io, False, "not allowed in XML-RPC permission mode {}".format(self.acl) - ) + ] + + # Binary() in bytes() umwandeln + if type(value) == Binary: + value = value.data self.rpi.devices.syncoutputs(device=device) - # Neuen Wert übernehmen - if type(value) == bytes or type(value) == bool: - self.rpi.devices[device][io].set_value(value) - else: - self.rpi.devices[device][io].set_value( - value.to_bytes( - self.rpi.devices[device][io].length, byteorder="little" + try: + # Neuen Wert übernehmen + if type(value) == bytes or type(value) == bool: + self.rpi.devices[device][io].set_value(value) + else: + self.rpi.devices[device][io].set_value( + value.to_bytes( + self.rpi.devices[device][io].length, byteorder="little" + ) ) - ) + except Exception as e: + return [device, io, False, str(e)] self.rpi.devices.writeprocimg(device=device) + return [device, io, True, ""] def values(self): """Liefert Prozessabbild an Client. diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 6a86d1c..c0d38b9 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -54,6 +54,7 @@ configrsc = None picontrolreset = "/opt/KUNBUS/piControlReset" procimg = "/dev/piControl0" pyloadverion = "0.4.1" +rapcatalog = None class LogReader(): @@ -443,11 +444,8 @@ class RevPiPyLoad(): """Instantiiert RevPiPyLoad-Klasse.""" proginit.configure() - # Globale Werte anpassen - global configrsc - global picontrolreset - # piCtory Konfiguration an bekannten Stellen prüfen + global configrsc lst_rsc = ["/etc/revpi/config.rsc", "/opt/KUNBUS/config.rsc"] for rscfile in lst_rsc: if os.access(rscfile, os.F_OK | os.R_OK): @@ -459,7 +457,18 @@ class RevPiPyLoad(): "".format(", ".join(lst_rsc)) ) + # rap Katalog an bekannten Stellen prüfen und laden + global rapcatalog + lst_rap = [ + "/opt/KUNBUS/pictory/resources/data/rap", + "/var/www/pictory/resources/data/rap" + ] + for rapfolder in lst_rap: + if os.path.isdir(rapfolder): + rapcatalog = os.listdir(rapfolder) + # piControlReset suchen + global picontrolreset if not os.access(picontrolreset, os.F_OK | os.X_OK): picontrolreset = "/usr/bin/piTest -x" @@ -668,7 +677,8 @@ class RevPiPyLoad(): @returns: Dateinamen des Archivs """ - filename = mkstemp(suffix=".packed", prefix="plc") + tup_file = mkstemp(suffix="_packed", prefix="plc_") + filename = tup_file[1] if mode == "zip": fh_pack = zipfile.ZipFile(filename, mode="w") @@ -968,6 +978,8 @@ class RevPiPyLoad(): -1 Kann JSON-Datei nicht laden -2 piCtory Elemente in JSON-Datei nicht gefunden -3 Konnte Konfiguraiton nicht schreiben + -4 Module in Konfiguration enthalten, die es nicht gibt + -5 Kein RAP Katalog zur Ueberpruefung gefunden Positive Zahl ist exitcode von piControlReset """ @@ -985,7 +997,22 @@ class RevPiPyLoad(): if chk not in jconfigrsc: return -2 - # TODO: Module prüfen, ob sie existieren + # Prüfen ob Modulkatalog vorhanden ist + if rapcatalog is None: + return -5 + else: + + # piCtory Device in Katalog suchen + for picdev in jconfigrsc["Devices"]: + found = False + picdev = picdev["id"][7:-4] + for rapdev in rapcatalog: + if rapdev.find(picdev) >= 0: + found = True + + # Device im Katalog nicht gefunden + if not found: + return -4 try: with open(configrsc, "wb") as fh: From abb2cb951227205fd2ac5bf49cbf716dd9a7cbf2 Mon Sep 17 00:00:00 2001 From: NaruX Date: Sat, 1 Jul 2017 13:17:09 +0200 Subject: [PATCH 4/9] debug lognachrichten angepasst docstrings angepasst --- doc/procimgserver.html | 18 ++--- doc/revpipyload.html | 34 ++++----- revpipyload/procimgserver.py | 26 +++---- revpipyload/revpipyload.py | 129 +++++++++++++++++++++-------------- 4 files changed, 117 insertions(+), 90 deletions(-) diff --git a/doc/procimgserver.html b/doc/procimgserver.html index 6b7e157..0f398e2 100644 --- a/doc/procimgserver.html +++ b/doc/procimgserver.html @@ -94,19 +94,19 @@ ProcimgServer (Constructor)

Instantiiert RevPiCheckServer()-Klasse.

-
xmlserver:
+
xmlserver
XML-RPC Server -
procimg:
+
procimg
Pfad zum Prozessabbild -
configrsc:
+
configrsc
Pfad zur piCtory Konfigurationsdatei -
logger:
+
logger
Loggerinstanz -
aclmode:
+
aclmode
Zugriffsrechte
@@ -128,7 +128,7 @@ ProcimgServer.ios

Generiert ein dict() der Devices und IOs.

-
type:
+
type
IO Typ inp/out
@@ -144,13 +144,13 @@ ProcimgServer.setvalue

Setzt einen Wert auf dem RevPi.

-
device:
+
device
Device Position oder Name -
io:
+
io
IO Name fuer neuen Wert -
value:
+
value
Neuer Wert
diff --git a/doc/revpipyload.html b/doc/revpipyload.html index 4c67169..f19aa87 100644 --- a/doc/revpipyload.html +++ b/doc/revpipyload.html @@ -123,10 +123,10 @@ LogReader.load_applog

Uebertraegt Logdaten Binaer.

-
start:
+
start
Startbyte -
count:
+
count
Max. Byteanzahl zum uebertragen
@@ -142,10 +142,10 @@ LogReader.load_plclog

Uebertraegt Logdaten Binaer.

-
start:
+
start
Startbyte -
count:
+
count
Max. Byteanzahl zum uebertragen
@@ -220,7 +220,7 @@ PipeLogwriter (Constructor)

Instantiiert PipeLogwriter-Klasse.

-
logfilename:
+
logfilename
Dateiname fuer Logdatei
@@ -248,7 +248,7 @@ PipeLogwriter.logline

Schreibt eine Zeile in die Logdatei oder stdout.

-
message:
+
message
Logzeile zum Schreiben
@@ -362,7 +362,7 @@ RevPiPlc._spopen

Startet das PLC Programm.

-
lst_proc:
+
lst_proc
Prozessliste
@@ -486,7 +486,7 @@ Methods Loescht das gesamte plcworkdir Verzeichnis. xml_psstart -Starten den Prozessabbildserver. +Startet den Prozessabbildserver. xml_psstop Stoppt den Prozessabbildserver. @@ -554,10 +554,10 @@ RevPiPyLoad.packapp

Erzeugt aus dem PLC-Programm ein TAR-File.

-
mode:
+
mode
Packart 'tar' oder 'zip' -
pictory:
+
pictory
piCtory Konfiguration mit einpacken
@@ -629,10 +629,10 @@ RevPiPyLoad.xml_plcdownload

Uebertraegt ein Archiv vom plcworkdir.

-
mode:
+
mode
Archivart 'tar' 'zip' -
pictory:
+
pictory
piCtory Konfiguraiton mit einpacken
@@ -698,10 +698,10 @@ RevPiPyLoad.xml_plcupload

Empfaengt Dateien fuer das PLC Programm.

-
filedata:
+
filedata
GZIP Binary data der datei -
filename:
+
filename
Name inkl. Unterverzeichnis der Datei
@@ -726,7 +726,7 @@ True, wenn erfolgreich RevPiPyLoad.xml_psstart xml_psstart()

-Starten den Prozessabbildserver. +Startet den Prozessabbildserver.

Returns:
@@ -767,10 +767,10 @@ RevPiPyLoad.xml_setpictoryrsc

Schreibt die config.rsc Datei von piCotry.

-
filebytes:
+
filebytes
xmlrpc.client.Binary()-Objekt -
reset:
+
reset
Reset piControl Device
diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index ff19dc9..0248908 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -30,11 +30,11 @@ class ProcimgServer(): def __init__(self, logger, xmlserver, configrsc, procimg, aclmode): """Instantiiert RevPiCheckServer()-Klasse. - @param xmlserver: XML-RPC Server - @param procimg: Pfad zum Prozessabbild - @param configrsc: Pfad zur piCtory Konfigurationsdatei - @param logger: Loggerinstanz - @param aclmode: Zugriffsrechte + @param xmlserver XML-RPC Server + @param procimg Pfad zum Prozessabbild + @param configrsc Pfad zur piCtory Konfigurationsdatei + @param logger Loggerinstanz + @param aclmode Zugriffsrechte """ # Logger übernehmen @@ -68,15 +68,15 @@ class ProcimgServer(): def devices(self): """Generiert Deviceliste mit Position und Namen. - @returns: list() mit Tuple (pos, name)""" + @return list() mit Tuple (pos, name)""" return [ (dev.position, dev.name) for dev in self.rpi.devices ] def ios(self, type): """Generiert ein dict() der Devices und IOs. - @param type: IO Typ inp/out - @returns: pickled dict()""" + @param type IO Typ inp/out + @return pickled dict()""" dict_ios = {} for dev in self.rpi.devices: dict_ios[dev.position] = [] @@ -104,10 +104,10 @@ class ProcimgServer(): def setvalue(self, device, io, value): """Setzt einen Wert auf dem RevPi. - @param device: Device Position oder Name - @param io: IO Name fuer neuen Wert - @param value: Neuer Wert - @returns: list() [device, io, status, msg] + @param device Device Position oder Name + @param io IO Name fuer neuen Wert + @param value Neuer Wert + @return list() [device, io, status, msg] """ # Zugriffsrechte prüfen @@ -141,7 +141,7 @@ class ProcimgServer(): def values(self): """Liefert Prozessabbild an Client. - @returns: Binary() bytes or None""" + @return Binary() bytes or None""" if self.rpi.devices.readprocimg() and self.rpi.devices.syncoutputs(): bytebuff = b'' for dev in self.rpi.devices: diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index c0d38b9..912ea3e 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -85,9 +85,9 @@ class LogReader(): def load_applog(self, start, count): """Uebertraegt Logdaten Binaer. - @param start: Startbyte - @param count: Max. Byteanzahl zum uebertragen - @returns: Binary() der Logdatei + @param start Startbyte + @param count Max. Byteanzahl zum uebertragen + @return Binary() der Logdatei """ if not os.access(proginit.logapp, os.R_OK): @@ -105,9 +105,9 @@ class LogReader(): def load_plclog(self, start, count): """Uebertraegt Logdaten Binaer. - @param start: Startbyte - @param count: Max. Byteanzahl zum uebertragen - @returns: Binary() der Logdatei + @param start Startbyte + @param count Max. Byteanzahl zum uebertragen + @return Binary() der Logdatei """ if not os.access(proginit.logplc, os.R_OK): @@ -136,7 +136,7 @@ class PipeLogwriter(Thread): def __init__(self, logfilename): """Instantiiert PipeLogwriter-Klasse. - @param logfilename: Dateiname fuer Logdatei""" + @param logfilename Dateiname fuer Logdatei""" super().__init__() self._exit = Event() self._fh = None @@ -159,11 +159,10 @@ class PipeLogwriter(Thread): def _configurefh(self): """Konfiguriert den FileHandler fuer Ausgaben der PLCAPP. - @returns: FileHandler-Objekt""" + @return FileHandler-Objekt""" proginit.logger.debug("enter PipeLogwriter._configurefh()") dirname = os.path.dirname(self.logfile) - proginit.logger.debug("dirname = {}".format(os.path.abspath(dirname))) if os.access(dirname, os.R_OK | os.W_OK): @@ -176,7 +175,7 @@ class PipeLogwriter(Thread): def logline(self, message): """Schreibt eine Zeile in die Logdatei oder stdout. - @param message: Logzeile zum Schreiben""" + @param message Logzeile zum Schreiben""" with self._lckfh: self._fh.write("{}\n".format(message)) self._fh.flush() @@ -194,7 +193,6 @@ class PipeLogwriter(Thread): proginit.logger.debug("enter PipeLogwriter.run()") fhread = os.fdopen(self._fdr) - proginit.logger.debug("enter logreader pipe loop") while not self._exit.is_set(): line = fhread.readline() self._lckfh.acquire() @@ -258,7 +256,7 @@ class RevPiPlc(Thread): def _configureplw(self): """Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP. - @returns: PipeLogwriter()""" + @return PipeLogwriter()""" proginit.logger.debug("enter RevPiPlc._configureplw()") logfile = None if proginit.pargs.daemon: @@ -282,8 +280,8 @@ class RevPiPlc(Thread): def _spopen(self, lst_proc): """Startet das PLC Programm. - @param lst_proc: Prozessliste - @returns: subprocess""" + @param lst_proc Prozessliste + @return subprocess""" proginit.logger.debug("enter RevPiPlc._spopen({})".format(lst_proc)) sp = subprocess.Popen( lst_proc, @@ -379,6 +377,12 @@ class RevPiPlc(Thread): self._evt_exit.wait(1) + if self._plw is not None: + self._plw.logline("-" * 55) + self._plw.logline("plc: {} stopped: {}".format( + os.path.basename(self._program), asctime() + )) + proginit.logger.debug("leave RevPiPlc.run()") def stop(self): @@ -391,9 +395,8 @@ class RevPiPlc(Thread): if self._procplc is None: if self._plw is not None: self._plw.stop() - proginit.logger.debug("join after NONE pipe thread") self._plw.join() - proginit.logger.debug("joined after NONE pipe thread") + proginit.logger.debug("log pipes successfully closed") proginit.logger.debug("leave RevPiPlc.stop()") return @@ -424,9 +427,8 @@ class RevPiPlc(Thread): if self._plw is not None: self._plw.stop() - proginit.logger.debug("join pipe thread") self._plw.join() - proginit.logger.debug("joined pipe thread") + proginit.logger.debug("log pipes successfully closed") proginit.logger.debug("leave RevPiPlc.stop()") @@ -443,6 +445,7 @@ class RevPiPyLoad(): def __init__(self): """Instantiiert RevPiPyLoad-Klasse.""" proginit.configure() + proginit.logger.debug("enter RevPiPyLoad.__init__()") # piCtory Konfiguration an bekannten Stellen prüfen global configrsc @@ -492,8 +495,12 @@ class RevPiPyLoad(): signal.signal(signal.SIGHUP, self._sigloadconfig) signal.signal(signal.SIGUSR1, self._signewlogfile) + proginit.logger.debug("leave RevPiPyLoad.__init__()") + def _loadconfig(self): """Load configuration file and setup modul.""" + proginit.logger.debug("enter RevPiPyLoad._loadconfig()") + self.evt_loadconfig.clear() pauseproc = False @@ -614,9 +621,12 @@ class RevPiPyLoad(): ) self.start() + proginit.logger.debug("leave RevPiPyLoad._loadconfig()") + def _plcthread(self): """Konfiguriert den PLC-Thread fuer die Ausfuehrung. - @returns: PLC-Thread Object or None""" + @return PLC-Thread Object or None""" + proginit.logger.debug("enter RevPiPyLoad._plcthread()") # Prüfen ob Programm existiert if not os.path.exists(os.path.join(self.plcworkdir, self.plcprog)): @@ -636,27 +646,29 @@ class RevPiPyLoad(): th_plc.uid = int(self.globalconfig["DEFAULT"].get("plcuid", 65534)) th_plc.zeroonerror = self.zeroonerror th_plc.zeroonexit = self.zeroonexit - proginit.logger.debug("created PLC watcher") + + proginit.logger.debug("leave RevPiPyLoad._plcthread()") return th_plc def _sigexit(self, signum, frame): """Signal handler to clean and exit program.""" - proginit.logger.debug("got exit signal") - self.stop() + proginit.logger.debug("enter RevPiPyLoad._sigexit()") - # Programm aufräumen + # Programm stoppen und aufräumen + self.stop() proginit.cleanup() - proginit.logger.debug("end revpipyload program") + proginit.logger.debug("leave RevPiPyLoad._sigexit()") def _sigloadconfig(self, signum, frame): """Signal handler to load configuration.""" - proginit.logger.debug("got reload config signal") + proginit.logger.debug("enter RevPiPyLoad._sigloadconfig()") self.evt_loadconfig.set() + proginit.logger.debug("leave RevPiPyLoad._sigloadconfig()") def _signewlogfile(self, signum, frame): """Signal handler to start new logfile.""" - proginit.logger.debug("got new logfile signal") + proginit.logger.debug("enter RevPiPyLoad._signewlogfile()") # Logger neu konfigurieren proginit.configure() @@ -669,14 +681,18 @@ class RevPiPyLoad(): # Logreader schließen self.logr.closeall() + proginit.logger.debug("leave RevPiPyLoad._signewlogfile()") + def packapp(self, mode="tar", pictory=False): """Erzeugt aus dem PLC-Programm ein TAR-File. - @param mode: Packart 'tar' oder 'zip' - @param pictory: piCtory Konfiguration mit einpacken - @returns: Dateinamen des Archivs + @param mode Packart 'tar' oder 'zip' + @param pictory piCtory Konfiguration mit einpacken + @return Dateinamen des Archivs """ + proginit.logger.debug("enter RevPiPyLoad.packapp()") + tup_file = mkstemp(suffix="_packed", prefix="plc_") filename = tup_file[1] @@ -713,10 +729,13 @@ class RevPiPyLoad(): finally: fh_pack.close() + proginit.logger.debug("leave RevPiPyLoad.packapp()") return filename def start(self): """Start plcload and PLC python program.""" + proginit.logger.debug("enter RevPiPyLoad.start()") + proginit.logger.info("starting revpipyload") self._exit = False @@ -738,8 +757,12 @@ class RevPiPyLoad(): proginit.logger.info("exit python plc program to reload config") self._loadconfig() + proginit.logger.debug("leave RevPiPyLoad.start()") + def stop(self): """Stop PLC python program and plcload.""" + proginit.logger.debug("enter RevPiPyLoad.stop()") + proginit.logger.info("stopping revpipyload") self._exit = True @@ -747,6 +770,7 @@ class RevPiPyLoad(): proginit.logger.debug("stopping revpiplc-thread") self.plc.stop() self.plc.join() + proginit.logger.debug("revpiplc-thread successfully closed") if self.xmlrpc >= 1: proginit.logger.info("shutting down xmlrpc-server") @@ -754,9 +778,11 @@ class RevPiPyLoad(): self.tpe.shutdown() self.xsrv.server_close() + proginit.logger.debug("leave RevPiPyLoad.stop()") + def xml_getconfig(self): """Uebertraegt die RevPiPyLoad Konfiguration. - @returns: dict() der Konfiguration""" + @return dict() der Konfiguration""" proginit.logger.debug("xmlrpc call getconfig") dc = {} dc["autoreload"] = self.autoreload @@ -775,7 +801,7 @@ class RevPiPyLoad(): def xml_getfilelist(self): """Uebertraegt die Dateiliste vom plcworkdir. - @returns: list() mit Dateinamen""" + @return list() mit Dateinamen""" proginit.logger.debug("xmlrpc call getfilelist") lst_file = [] wd = os.walk("./") @@ -786,7 +812,7 @@ class RevPiPyLoad(): def xml_getpictoryrsc(self): """Gibt die config.rsc Datei von piCotry zurueck. - @returns: xmlrpc.client.Binary()""" + @return xmlrpc.client.Binary()""" proginit.logger.debug("xmlrpc call getpictoryrsc") with open(configrsc, "rb") as fh: buff = fh.read() @@ -794,7 +820,7 @@ class RevPiPyLoad(): def xml_getprocimg(self): """Gibt die Rohdaten aus piControl0 zurueck. - @returns: xmlrpc.client.Binary()""" + @return xmlrpc.client.Binary()""" proginit.logger.debug("xmlrpc call getprocimg") with open(procimg, "rb") as fh: buff = fh.read() @@ -803,9 +829,9 @@ class RevPiPyLoad(): def xml_plcdownload(self, mode="tar", pictory=False): """Uebertraegt ein Archiv vom plcworkdir. - @param mode: Archivart 'tar' 'zip' - @param pictory: piCtory Konfiguraiton mit einpacken - @returns: Binary() mit Archivdatei + @param mode Archivart 'tar' 'zip' + @param pictory piCtory Konfiguraiton mit einpacken + @return Binary() mit Archivdatei """ proginit.logger.debug("xmlrpc call plcdownload") @@ -824,7 +850,7 @@ class RevPiPyLoad(): def xml_plcexitcode(self): """Gibt den aktuellen exitcode vom PLC Programm zurueck. - @returns: int() exitcode oder: + @return int() exitcode oder: -1 laeuft noch -2 Datei nicht gefunden -3 Lief nie @@ -840,14 +866,14 @@ class RevPiPyLoad(): def xml_plcrunning(self): """Prueft ob das PLC Programm noch lauft. - @returns: True, wenn das PLC Programm noch lauft""" + @return True, wenn das PLC Programm noch lauft""" proginit.logger.debug("xmlrpc call plcrunning") return False if self.plc is None else self.plc.is_alive() def xml_plcstart(self): """Startet das PLC Programm. - @returns: int() Status: + @return int() Status: -1 Programm lauft noch -2 Datei nicht gefunden @@ -866,7 +892,7 @@ class RevPiPyLoad(): def xml_plcstop(self): """Stoppt das PLC Programm. - @returns: int() Exitcode vom PLC Programm + @return int() Exitcode vom PLC Programm -1 PLC Programm lief nicht """ @@ -874,6 +900,7 @@ class RevPiPyLoad(): if self.plc is not None and self.plc.is_alive(): self.plc.stop() self.plc.join() + proginit.logger.debug("revpiplc-thread successfully closed") return self.plc.exitcode else: return -1 @@ -881,9 +908,9 @@ class RevPiPyLoad(): def xml_plcupload(self, filedata, filename): """Empfaengt Dateien fuer das PLC Programm. - @param filedata: GZIP Binary data der datei - @param filename: Name inkl. Unterverzeichnis der Datei - @returns: Ture, wenn Datei erfolgreich gespeichert wurde + @param filedata GZIP Binary data der datei + @param filename Name inkl. Unterverzeichnis der Datei + @return Ture, wenn Datei erfolgreich gespeichert wurde """ proginit.logger.debug("xmlrpc call plcupload") @@ -913,7 +940,7 @@ class RevPiPyLoad(): def xml_plcuploadclean(self): """Loescht das gesamte plcworkdir Verzeichnis. - @returns: True, wenn erfolgreich""" + @return True, wenn erfolgreich""" proginit.logger.debug("xmlrpc call plcuploadclean") try: rmtree(".", ignore_errors=True) @@ -928,7 +955,7 @@ class RevPiPyLoad(): def xml_setconfig(self, dc, loadnow=False): """Empfaengt die RevPiPyLoad Konfiguration. - @returns: True, wenn erfolgreich angewendet""" + @return True, wenn erfolgreich angewendet""" proginit.logger.debug("xmlrpc call setconfig") keys = { "autoreload": "[01]", @@ -971,9 +998,9 @@ class RevPiPyLoad(): def xml_setpictoryrsc(self, filebytes, reset=False): """Schreibt die config.rsc Datei von piCotry. - @param filebytes: xmlrpc.client.Binary()-Objekt - @param reset: Reset piControl Device - @returns: Statuscode: + @param filebytes xmlrpc.client.Binary()-Objekt + @param reset Reset piControl Device + @return Statuscode: 0 Alles erfolgreich -1 Kann JSON-Datei nicht laden -2 piCtory Elemente in JSON-Datei nicht gefunden @@ -1026,8 +1053,8 @@ class RevPiPyLoad(): return 0 def xml_psstart(self): - """Starten den Prozessabbildserver. - @returns: True, wenn start erfolgreich""" + """Startet den Prozessabbildserver. + @return True, wenn start erfolgreich""" if self.xml_ps is not None: self.xml_ps.start() return True @@ -1036,7 +1063,7 @@ class RevPiPyLoad(): def xml_psstop(self): """Stoppt den Prozessabbildserver. - @returns: True, wenn stop erfolgreich""" + @return True, wenn stop erfolgreich""" if self.xml_ps is not None: self.xml_ps.stop() return True From 029dda5f1ab4ebd550c0365a219dacafb9a5169e Mon Sep 17 00:00:00 2001 From: NaruX Date: Sun, 2 Jul 2017 22:16:34 +0200 Subject: [PATCH 5/9] =?UTF-8?q?ProcimgServer.loadrevpimodio()=20erstellt?= =?UTF-8?q?=20um=20Ver=C3=A4nderungen=20an=20piCtory=20zu=20laden=20RevPiP?= =?UTF-8?q?yLoad=20pr=C3=BCft=20=C3=84nderungsdatum=20von=20piCtory=20und?= =?UTF-8?q?=20beendet=20ggf.=20ProcimgServer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/index.html | 26 ++++++++++++++++++++++++++ doc/procimgserver.html | 11 ++++++++++- eric-revpipyload.api | 1 + revpipyload.e4p | 8 +------- revpipyload/procimgserver.py | 26 ++++++++++++++++++-------- revpipyload/revpipyload.py | 13 ++++++++++++- 6 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 doc/index.html diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..418bfe4 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,26 @@ + + +Table of contents + + + +

+Table of contents

+ + + +

+Modules

+ + + + + + + + + + + +
procimgserverStellt Funktionen bereit um das Prozessabbild zu ueberwachen.
proginitMain functions of our program.
revpipyloadRevolution Pi Python PLC Loader.
+ \ No newline at end of file diff --git a/doc/procimgserver.html b/doc/procimgserver.html index 0f398e2..4c37d09 100644 --- a/doc/procimgserver.html +++ b/doc/procimgserver.html @@ -69,6 +69,9 @@ Methods ios Generiert ein dict() der Devices und IOs. +loadrevpimodio +Instantiiert das RevPiModIO Modul. + setvalue Setzt einen Wert auf dem RevPi. @@ -137,7 +140,13 @@ IO Typ inp/out
pickled dict()
-
+
+

+ProcimgServer.loadrevpimodio

+loadrevpimodio() +

+Instantiiert das RevPiModIO Modul. +

ProcimgServer.setvalue

setvalue(device, io, value) diff --git a/eric-revpipyload.api b/eric-revpipyload.api index 8b39e80..bdcbe29 100644 --- a/eric-revpipyload.api +++ b/eric-revpipyload.api @@ -1,5 +1,6 @@ procimgserver.ProcimgServer.devices?4() procimgserver.ProcimgServer.ios?4(type) +procimgserver.ProcimgServer.loadrevpimodio?4() procimgserver.ProcimgServer.setvalue?4(device, io, value) procimgserver.ProcimgServer.start?4() procimgserver.ProcimgServer.stop?4() diff --git a/revpipyload.e4p b/revpipyload.e4p index b090706..cbbcf57 100644 --- a/revpipyload.e4p +++ b/revpipyload.e4p @@ -1,7 +1,7 @@ - + en_US @@ -212,12 +212,6 @@ setup.py - - noindex - - - True - outputDirectory diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index 0248908..06f4c71 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -41,6 +41,9 @@ class ProcimgServer(): self.logger = logger self.logger.debug("enter ProcimgServer.__init__()") self.acl = aclmode + self.configrsc = configrsc + self.procimg = procimg + self.rpi = None # XML-Server übernehmen self.xmlsrv = xmlserver @@ -55,14 +58,7 @@ class ProcimgServer(): "ps_setvalue": self.setvalue, } - # RevPiModIO-Modul Instantiieren - self.logger.debug("create revpimodio class") - self.rpi = revpimodio.RevPiModIO( - configrsc=configrsc, - procimg=procimg, - ) - self.rpi.devices.syncoutputs(device=0) - self.logger.debug("created revpimodio class") + self.loadrevpimodio() self.logger.debug("leave ProcimgServer.__init__()") @@ -101,6 +97,20 @@ class ProcimgServer(): ]) return Binary(pickle.dumps(dict_ios)) + def loadrevpimodio(self): + """Instantiiert das RevPiModIO Modul.""" + # RevPiModIO-Modul Instantiieren + if self.rpi is not None: + self.rpi.cleanup() + + self.logger.debug("create revpimodio class") + self.rpi = revpimodio.RevPiModIO( + configrsc=self.configrsc, + procimg=self.procimg, + ) + self.rpi.devices.syncoutputs(device=0) + self.logger.debug("created revpimodio class") + def setvalue(self, device, io, value): """Setzt einen Wert auf dem RevPi. diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 912ea3e..270d11f 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -477,6 +477,7 @@ class RevPiPyLoad(): # Klassenattribute self._exit = True + self.pictorymtime = os.path.getmtime(configrsc) self.evt_loadconfig = Event() self.globalconfig = ConfigParser() self.logr = LogReader() @@ -580,7 +581,7 @@ class RevPiPyLoad(): self.xml_ps = None proginit.logger.warning( "can not load revpimodio module. maybe its not installed " - "or an old version (required at least 0.11.0). if you " + "or an old version (required at least 0.15.0). if you " "like to use the process monitor feature, update/install " "revpimodio: 'apt-get install python3-revpimodio'" ) @@ -751,6 +752,16 @@ class RevPiPyLoad(): while not self._exit \ and not self.evt_loadconfig.is_set(): + + # piCtory auf Veränderung prüfen + if self.pictorymtime != os.path.getmtime(configrsc): + proginit.logger.warning("piCtory configuration was changed") + self.pictorymtime = os.path.getmtime(configrsc) + + if self.xml_ps is not None: + self.xml_psstop() + self.xml_ps.loadrevpimodio() + self.evt_loadconfig.wait(1) if not self._exit: From 97c352040873bae2acee7d6521c78021f9194dc9 Mon Sep 17 00:00:00 2001 From: NaruX Date: Mon, 3 Jul 2017 08:25:43 +0200 Subject: [PATCH 6/9] docstrings und codestyle --- doc/revpipyload.html | 30 +++++++++++++++--------------- revpipyload/revpipyload.py | 34 ++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/doc/revpipyload.html b/doc/revpipyload.html index f19aa87..8edc9dc 100644 --- a/doc/revpipyload.html +++ b/doc/revpipyload.html @@ -64,8 +64,6 @@ Ermoeglicht den Zugriff auf die Logdateien.

Beinhaltet Funktionen fuer den Abruf der gesamten Logdatei fuer das RevPiPyLoad-System und die Logdatei der PLC-Anwendung. - Ausserdem koennen nur neue Zeilen abgerufen werden, um eine dynamische - Logansicht zu ermoeglichen.

@@ -93,10 +91,10 @@ Methods Fuehrt close auf File Handler durch. load_applog -Uebertraegt Logdaten Binaer. +Uebertraegt Logdaten des PLC Programms Binaer. load_plclog -Uebertraegt Logdaten Binaer. +Uebertraegt Logdaten des Loaders Binaer.

@@ -121,7 +119,7 @@ Fuehrt close auf File Handler durch. LogReader.load_applog

load_applog(start, count)

-Uebertraegt Logdaten Binaer. +Uebertraegt Logdaten des PLC Programms Binaer.

start
@@ -140,7 +138,7 @@ Binary() der Logdatei LogReader.load_plclog load_plclog(start, count)

-Uebertraegt Logdaten Binaer. +Uebertraegt Logdaten des Loaders Binaer.

start
@@ -444,13 +442,13 @@ Methods Signal handler to start new logfile. packapp -Erzeugt aus dem PLC-Programm ein TAR-File. +Erzeugt aus dem PLC-Programm ein TAR/Zip-File. start -Start plcload and PLC python program. +Start revpipyload. stop -Stop PLC python program and plcload. +Stop revpipyload. xml_getconfig Uebertraegt die RevPiPyLoad Konfiguration. @@ -480,7 +478,7 @@ Methods Stoppt das PLC Programm. xml_plcupload -Empfaengt Dateien fuer das PLC Programm. +Empfaengt Dateien fuer das PLC Programm einzeln. xml_plcuploadclean Loescht das gesamte plcworkdir Verzeichnis. @@ -552,7 +550,7 @@ Signal handler to start new logfile. RevPiPyLoad.packapp packapp(mode="tar", pictory=False)

-Erzeugt aus dem PLC-Programm ein TAR-File. +Erzeugt aus dem PLC-Programm ein TAR/Zip-File.

mode
@@ -571,13 +569,13 @@ Dateinamen des Archivs RevPiPyLoad.start start()

-Start plcload and PLC python program. +Start revpipyload.

RevPiPyLoad.stop

stop()

-Stop PLC python program and plcload. +Stop revpipyload.

RevPiPyLoad.xml_getconfig

@@ -676,6 +674,7 @@ Startet das PLC Programm.
Returns:
int() Status: + -0 Erfolgreich -1 Programm lauft noch -2 Datei nicht gefunden
@@ -689,6 +688,7 @@ Stoppt das PLC Programm.
Returns:
int() Exitcode vom PLC Programm + -0 Erfolgreich -1 PLC Programm lief nicht
@@ -696,7 +696,7 @@ int() Exitcode vom PLC Programm RevPiPyLoad.xml_plcupload xml_plcupload(filedata, filename)

-Empfaengt Dateien fuer das PLC Programm. +Empfaengt Dateien fuer das PLC Programm einzeln.

filedata
@@ -778,7 +778,7 @@ Reset piControl Device
Returns:
Statuscode: - 0 Alles erfolgreich + -0 Alles erfolgreich -1 Kann JSON-Datei nicht laden -2 piCtory Elemente in JSON-Datei nicht gefunden -3 Konnte Konfiguraiton nicht schreiben diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 270d11f..437c0b6 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -63,8 +63,6 @@ class LogReader(): Beinhaltet Funktionen fuer den Abruf der gesamten Logdatei fuer das RevPiPyLoad-System und die Logdatei der PLC-Anwendung. - Ausserdem koennen nur neue Zeilen abgerufen werden, um eine dynamische - Logansicht zu ermoeglichen. """ @@ -83,7 +81,7 @@ class LogReader(): self.fhplc.close() def load_applog(self, start, count): - """Uebertraegt Logdaten Binaer. + """Uebertraegt Logdaten des PLC Programms Binaer. @param start Startbyte @param count Max. Byteanzahl zum uebertragen @@ -103,7 +101,7 @@ class LogReader(): return Binary(self.fhapp.read(count)) def load_plclog(self, start, count): - """Uebertraegt Logdaten Binaer. + """Uebertraegt Logdaten des Loaders Binaer. @param start Startbyte @param count Max. Byteanzahl zum uebertragen @@ -200,7 +198,7 @@ class PipeLogwriter(Thread): self._fh.write(line) self._fh.flush() except: - proginit.logger.exception("PipeLogwriter write log line") + proginit.logger.exception("PipeLogwriter in write log line") finally: self._lckfh.release() proginit.logger.debug("leave logreader pipe loop") @@ -273,8 +271,10 @@ class RevPiPlc(Thread): def _setuppopen(self): """Setzt UID und GID fuer das PLC Programm.""" - proginit.logger.debug( - "set uid {} and gid {}".format(self.uid, self.gid)) + proginit.logger.info( + "set uid {} and gid {} for plc program".format( + self.uid, self.gid) + ) os.setgid(self.gid) os.setuid(self.uid) @@ -343,7 +343,7 @@ class RevPiPlc(Thread): if self.exitcode > 0: # PLC Python Programm abgestürzt proginit.logger.error( - "plc program chrashed - exitcode: {}".format( + "plc program crashed - exitcode: {}".format( self.exitcode ) ) @@ -456,7 +456,7 @@ class RevPiPyLoad(): break if configrsc is None: raise RuntimeError( - "can not access known pictory configurations at {}" + "can not find known pictory configurations at {}" "".format(", ".join(lst_rsc)) ) @@ -685,7 +685,7 @@ class RevPiPyLoad(): proginit.logger.debug("leave RevPiPyLoad._signewlogfile()") def packapp(self, mode="tar", pictory=False): - """Erzeugt aus dem PLC-Programm ein TAR-File. + """Erzeugt aus dem PLC-Programm ein TAR/Zip-File. @param mode Packart 'tar' oder 'zip' @param pictory piCtory Konfiguration mit einpacken @@ -734,7 +734,7 @@ class RevPiPyLoad(): return filename def start(self): - """Start plcload and PLC python program.""" + """Start revpipyload.""" proginit.logger.debug("enter RevPiPyLoad.start()") proginit.logger.info("starting revpipyload") @@ -771,7 +771,7 @@ class RevPiPyLoad(): proginit.logger.debug("leave RevPiPyLoad.start()") def stop(self): - """Stop PLC python program and plcload.""" + """Stop revpipyload.""" proginit.logger.debug("enter RevPiPyLoad.stop()") proginit.logger.info("stopping revpipyload") @@ -781,7 +781,7 @@ class RevPiPyLoad(): proginit.logger.debug("stopping revpiplc-thread") self.plc.stop() self.plc.join() - proginit.logger.debug("revpiplc-thread successfully closed") + proginit.logger.debug("revpiplc thread successfully closed") if self.xmlrpc >= 1: proginit.logger.info("shutting down xmlrpc-server") @@ -885,6 +885,7 @@ class RevPiPyLoad(): """Startet das PLC Programm. @return int() Status: + -0 Erfolgreich -1 Programm lauft noch -2 Datei nicht gefunden @@ -904,6 +905,7 @@ class RevPiPyLoad(): """Stoppt das PLC Programm. @return int() Exitcode vom PLC Programm + -0 Erfolgreich -1 PLC Programm lief nicht """ @@ -911,13 +913,13 @@ class RevPiPyLoad(): if self.plc is not None and self.plc.is_alive(): self.plc.stop() self.plc.join() - proginit.logger.debug("revpiplc-thread successfully closed") + proginit.logger.debug("revpiplc thread successfully closed") return self.plc.exitcode else: return -1 def xml_plcupload(self, filedata, filename): - """Empfaengt Dateien fuer das PLC Programm. + """Empfaengt Dateien fuer das PLC Programm einzeln. @param filedata GZIP Binary data der datei @param filename Name inkl. Unterverzeichnis der Datei @@ -1012,7 +1014,7 @@ class RevPiPyLoad(): @param filebytes xmlrpc.client.Binary()-Objekt @param reset Reset piControl Device @return Statuscode: - 0 Alles erfolgreich + -0 Alles erfolgreich -1 Kann JSON-Datei nicht laden -2 piCtory Elemente in JSON-Datei nicht gefunden -3 Konnte Konfiguraiton nicht schreiben From 9f7e3cc5a4cf9d888d355dd2dd570744593bf733 Mon Sep 17 00:00:00 2001 From: NaruX Date: Thu, 6 Jul 2017 12:50:26 +0200 Subject: [PATCH 8/9] =?UTF-8?q?Wenn=20keine=20piCtory=20Konfiguration=20vo?= =?UTF-8?q?rhanden=20ist,=20dennoch=20Modul=20laden=20Bei=20RevPiModIO=20I?= =?UTF-8?q?nstantiierung=20R=C3=BCckgabewert=20False,=20sollte=20piCtory?= =?UTF-8?q?=20leer=20sein=20description=20Text=20angepasst?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/procimgserver.html | 14 +++++++++++-- revpipyload.e4p | 4 ++-- revpipyload/procimgserver.py | 40 +++++++++++++++++++++++++----------- revpipyload/revpipyload.py | 5 ++--- setup.py | 14 ++++++------- 5 files changed, 51 insertions(+), 26 deletions(-) diff --git a/doc/procimgserver.html b/doc/procimgserver.html index 4c37d09..12a44e9 100644 --- a/doc/procimgserver.html +++ b/doc/procimgserver.html @@ -146,7 +146,12 @@ ProcimgServer.loadrevpimodio loadrevpimodio()

Instantiiert das RevPiModIO Modul. -

+

+
Returns:
+
+True, wenn erfolgreich, sonst False +
+

ProcimgServer.setvalue

setvalue(device, io, value) @@ -174,7 +179,12 @@ ProcimgServer.start start()

Registriert XML Funktionen. -

+

+
Returns:
+
+True, wenn erfolgreich +
+

ProcimgServer.stop

stop() diff --git a/revpipyload.e4p b/revpipyload.e4p index cbbcf57..eff7f78 100644 --- a/revpipyload.e4p +++ b/revpipyload.e4p @@ -1,7 +1,7 @@ - + en_US @@ -9,7 +9,7 @@ Python3 Console Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten. - 0.4.1 + 0.4.2 Sven Sager akira@narux.de diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index 06f4c71..c135843 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -98,18 +98,26 @@ class ProcimgServer(): return Binary(pickle.dumps(dict_ios)) def loadrevpimodio(self): - """Instantiiert das RevPiModIO Modul.""" + """Instantiiert das RevPiModIO Modul. + @return True, wenn erfolgreich, sonst False""" # RevPiModIO-Modul Instantiieren if self.rpi is not None: self.rpi.cleanup() self.logger.debug("create revpimodio class") - self.rpi = revpimodio.RevPiModIO( - configrsc=self.configrsc, - procimg=self.procimg, - ) + try: + self.rpi = revpimodio.RevPiModIO( + configrsc=self.configrsc, + procimg=self.procimg, + ) + except: + self.rpi = None + self.logger.error("piCtory configuration not loadable") + return False + self.rpi.devices.syncoutputs(device=0) self.logger.debug("created revpimodio class") + return True def setvalue(self, device, io, value): """Setzt einen Wert auf dem RevPi. @@ -161,19 +169,27 @@ class ProcimgServer(): return None def start(self): - """Registriert XML Funktionen.""" + """Registriert XML Funktionen. + @return True, wenn erfolgreich""" self.logger.debug("enter ProcimgServer.start()") + ec = False - # Registriere Funktionen - for xmlfunc in self.xmlreadfuncs: - self.xmlsrv.register_function(self.xmlreadfuncs[xmlfunc], xmlfunc) - if self.acl >= 3: - for xmlfunc in self.xmlwritefuncs: + if self.rpi is not None: + + # Registriere Funktionen + for xmlfunc in self.xmlreadfuncs: self.xmlsrv.register_function( - self.xmlwritefuncs[xmlfunc], xmlfunc + self.xmlreadfuncs[xmlfunc], xmlfunc ) + if self.acl >= 3: + for xmlfunc in self.xmlwritefuncs: + self.xmlsrv.register_function( + self.xmlwritefuncs[xmlfunc], xmlfunc + ) + ec = True self.logger.debug("leave ProcimgServer.start()") + return ec def stop(self): """Entfernt XML-Funktionen.""" diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 437c0b6..15938a4 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -53,7 +53,7 @@ from xmlrpc.server import SimpleXMLRPCServer configrsc = None picontrolreset = "/opt/KUNBUS/piControlReset" procimg = "/dev/piControl0" -pyloadverion = "0.4.1" +pyloadverion = "0.4.2" rapcatalog = None @@ -1069,8 +1069,7 @@ class RevPiPyLoad(): """Startet den Prozessabbildserver. @return True, wenn start erfolgreich""" if self.xml_ps is not None: - self.xml_ps.start() - return True + return self.xml_ps.start() else: return False diff --git a/setup.py b/setup.py index e0a6495..64cce8f 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ setup( license="LGPLv3", name="revpipyload", - version="0.4.1", + version="0.4.2", scripts=["data/revpipyload"], @@ -42,12 +42,12 @@ setup( 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 Absturz kann das gesamte /dev/piControl0 auf 0x00 gesetzt 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.", + "Dieses Programm startet beim Systemstart ein angegebenes Python PLC \n" + "Programm. Es überwacht das Programm und startet es im Fehlerfall neu. \n" + "Bei Absturz kann das gesamte /dev/piControl0 auf 0x00 gesetzt 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 \n" + "Tool zur Laufzeit überwacht werden.", classifiers=[ "License :: OSI Approved :: "