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