From f608d99d7d7da6c7f6509fa4f8cb6d30b192ad55 Mon Sep 17 00:00:00 2001 From: NaruX Date: Mon, 10 Jun 2019 22:49:23 +0200 Subject: [PATCH 1/4] =?UTF-8?q?Replace=20IOs=20aus=20Configfile=20=C3=BCbe?= =?UTF-8?q?rnehmen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/etc/revpipyload/replace_ios.conf | 7 +++++++ data/etc/revpipyload/revpipyload.conf | 1 + revpipyload.e4p | 4 ++-- revpipyload/mqttserver.py | 18 +++++++++++++++++- revpipyload/procimgserver.py | 16 ++++++++++++++-- revpipyload/revpipyload.py | 13 +++++++++++-- setup.py | 2 +- 7 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 data/etc/revpipyload/replace_ios.conf diff --git a/data/etc/revpipyload/replace_ios.conf b/data/etc/revpipyload/replace_ios.conf new file mode 100644 index 0000000..c5b331c --- /dev/null +++ b/data/etc/revpipyload/replace_ios.conf @@ -0,0 +1,7 @@ +# Replace IO + +# [NewIoName] +# parentio_name = OldIoName +# frm = StructFormat +# bitaddress = 0-7 (Only with '?' struct) +# byteorder = little/big diff --git a/data/etc/revpipyload/revpipyload.conf b/data/etc/revpipyload/revpipyload.conf index 0573bf6..3f346fe 100644 --- a/data/etc/revpipyload/revpipyload.conf +++ b/data/etc/revpipyload/revpipyload.conf @@ -8,6 +8,7 @@ plcarguments = plcuid = 1000 plcgid = 1000 pythonversion = 3 +replace_ios = /etc/revpipyload/replace_ios.conf rtlevel = 0 zeroonerror = 0 zeroonexit = 0 diff --git a/revpipyload.e4p b/revpipyload.e4p index a099a48..50c279a 100644 --- a/revpipyload.e4p +++ b/revpipyload.e4p @@ -1,8 +1,8 @@ - - + + en_US 89ddb4e70b339f832ee277085202b38acc6a125c diff --git a/revpipyload/mqttserver.py b/revpipyload/mqttserver.py index e95d047..5ef06ef 100644 --- a/revpipyload/mqttserver.py +++ b/revpipyload/mqttserver.py @@ -18,7 +18,7 @@ class MqttServer(Thread): def __init__( self, basetopic, sendinterval, broker_address, port=1883, tls_set=False, username="", password=None, client_id="", - send_events=False, write_outputs=False): + send_events=False, write_outputs=False, replace_ios=None): """Init MqttServer class. @param basetopic Basis-Topic fuer Datenaustausch @@ -31,6 +31,7 @@ class MqttServer(Thread): @param client_id MQTT ClientID, wenn leer automatisch random erzeugung @param send_events Sendet Werte bei IO Wertaenderung @param write_outputs Per MQTT auch Outputs schreiben + @param replace_ios Replace IOs of RevPiModIO """ if not isinstance(basetopic, str): @@ -59,6 +60,8 @@ class MqttServer(Thread): raise ValueError("parameter send_events must be ") if not isinstance(write_outputs, bool): raise ValueError("parameter write_outputs must be ") + if not (replace_ios is None or isinstance(replace_ios, str)): + raise ValueError("parameter replace_ios must be ") super().__init__() @@ -69,6 +72,7 @@ class MqttServer(Thread): self._broker_address = broker_address self._port = port self._reloadmodio = False + self._replace_ios = replace_ios self._rpi = None self._rpi_write = None self._send_events = send_events @@ -154,6 +158,18 @@ class MqttServer(Thread): ) raise e + # Replace IOs of RevPiModIO + if self._replace_ios: + try: + self._rpi.import_replaced_ios(self._replace_ios) + if self._write_outputs: + self._rpi_write.import_replaced_ios(self._replace_ios) + except Exception as e: + proginit.logger.error( + "could not load replaced ios into RevPiModIO - using " + "defaults | {0}".format(e) + ) + # Exportierte IOs laden for dev in self._rpi.device: for io in dev.get_allios(export=True): diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index 2029a80..ad55575 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -25,13 +25,15 @@ class ProcimgServer(): """ - def __init__(self, xmlserver): + def __init__(self, xmlserver, replace_ios=None): """Instantiiert RevPiCheckServer()-Klasse. - @param xmlserver XML-RPC Server""" + @param xmlserver XML-RPC Server + @param replace_ios Replace IOs of RevPiModIO""" # Logger übernehmen proginit.logger.debug("enter ProcimgServer.__init__()") self.rpi = None + self.replace_ios = replace_ios # XML-Server übernehmen self.xmlsrv = xmlserver @@ -105,6 +107,16 @@ class ProcimgServer(): ) return e + # Replace IOs of RevPiModIO + if self.replace_ios: + try: + self.rpi.import_replaced_ios(self.replace_ios) + except Exception as e: + proginit.logger.error( + "could not load replaced ios into RevPiModIO - using " + "defaults | {0}".format(e) + ) + # NOTE: Warum das? self.rpi.syncoutputs(device=0) diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index d35438f..33fe736 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -49,7 +49,7 @@ from time import asctime from xmlrpc.client import Binary from xrpcserver import SaveXMLRPCServer -min_revpimodio = "2.5.0" +min_revpimodio = "2.3.3" class RevPiPyLoad(): @@ -107,6 +107,8 @@ class RevPiPyLoad(): return True else: return ( + self.replace_ios_config != + self.globalconfig["DEFAULT"].get("replace_ios", "") or self.mqtt != self.globalconfig["MQTT"].getboolean("mqtt", False) or self.mqttbasetopic != @@ -219,6 +221,8 @@ class RevPiPyLoad(): self.globalconfig["DEFAULT"].getint("plcgid", 65534) self.pythonversion = \ self.globalconfig["DEFAULT"].getint("pythonversion", 3) + self.replace_ios_config = \ + self.globalconfig["DEFAULT"].get("replace_ios", "") self.rtlevel = \ self.globalconfig["DEFAULT"].getint("rtlevel", 0) self.zeroonerror = \ @@ -390,7 +394,9 @@ class RevPiPyLoad(): # Erweiterte Funktionen anmelden try: import procimgserver - self.xml_ps = procimgserver.ProcimgServer(self.xsrv) + self.xml_ps = procimgserver.ProcimgServer( + self.xsrv, self.replace_ios_config + ) self.xsrv.register_function(1, self.xml_psstart, "psstart") self.xsrv.register_function(1, self.xml_psstop, "psstop") except Exception: @@ -482,6 +488,7 @@ class RevPiPyLoad(): self.mqttclient_id, self.mqttsend_on_event, self.mqttwrite_outputs, + self.replace_ios_config, ) except Exception as e: proginit.logger.error(e) @@ -761,6 +768,7 @@ class RevPiPyLoad(): dc["plcuid"] = self.plcuid dc["plcgid"] = self.plcgid dc["pythonversion"] = self.pythonversion + dc["replace_ios"] = self.replace_ios_config dc["rtlevel"] = self.rtlevel dc["zeroonerror"] = int(self.zeroonerror) dc["zeroonexit"] = int(self.zeroonexit) @@ -996,6 +1004,7 @@ class RevPiPyLoad(): # "plcuid": "[0-9]{,5}", # "plcgid": "[0-9]{,5}", "pythonversion": "[23]", + "replace_ios": ".*", "rtlevel": "[0-1]", "zeroonerror": "[01]", "zeroonexit": "[01]", diff --git a/setup.py b/setup.py index f9566b7..3e5a623 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ setup( scripts=["data/revpipyload"], - install_requires=["revpimodio2 >= 2.3.1"], + install_requires=["revpimodio2 >= 2.3.3"], python_requires=">=3.2", data_files=[ From 5661217900be3c14dc48f431afeb6ba887b74659 Mon Sep 17 00:00:00 2001 From: NaruX Date: Sun, 16 Jun 2019 13:55:24 +0200 Subject: [PATCH 2/4] replace_io aus Datei importieren wird direkt vararbeitet --- doc/helper.html | 24 ++++++++ doc/mqttserver.html | 5 +- doc/procimgserver.html | 5 +- eric-revpipyload.api | 5 +- revpipyload.e4p | 4 +- revpipyload/helper.py | 110 +++++++++++++++++++++++++++++++++++ revpipyload/procimgserver.py | 15 +++-- revpipyload/revpipyload.py | 2 +- setup.py | 2 +- 9 files changed, 156 insertions(+), 16 deletions(-) diff --git a/doc/helper.html b/doc/helper.html index a58d308..e023644 100644 --- a/doc/helper.html +++ b/doc/helper.html @@ -31,6 +31,9 @@ Functions refullmatch re.fullmatch wegen alter python version aus wheezy nachgebaut. + +revpimodio_replaceio +Importiert und ersetzt IOs in RevPiModIO.

@@ -80,5 +83,26 @@ True, wenn komplett passt sonst False +

+ +

revpimodio_replaceio

+revpimodio_replaceio(revpi, filename) +

+Importiert und ersetzt IOs in RevPiModIO. +

+
revpi
+
+RevPiModIO Instanz +
filename
+
+Dateiname der Ersetzungsdatei +
+
+
Returns:
+
+True, wenn alle IOs ersetzt werden konnten +
+
+
\ No newline at end of file diff --git a/doc/mqttserver.html b/doc/mqttserver.html index 43edbd9..683aea1 100644 --- a/doc/mqttserver.html +++ b/doc/mqttserver.html @@ -92,7 +92,7 @@ Static Methods

MqttServer (Constructor)

-MqttServer(basetopic, sendinterval, broker_address, port=1883, tls_set=False, username="", password=None, client_id="", send_events=False, write_outputs=False) +MqttServer(basetopic, sendinterval, broker_address, port=1883, tls_set=False, username="", password=None, client_id="", send_events=False, write_outputs=False, replace_ios=None)

Init MqttServer class.

@@ -126,6 +126,9 @@ Sendet Werte bei IO Wertaenderung
write_outputs
Per MQTT auch Outputs schreiben +
replace_ios
+
+Replace IOs of RevPiModIO

diff --git a/doc/procimgserver.html b/doc/procimgserver.html index 39b5fcf..c4b3138 100644 --- a/doc/procimgserver.html +++ b/doc/procimgserver.html @@ -93,13 +93,16 @@ Static Methods

ProcimgServer (Constructor)

-ProcimgServer(xmlserver) +ProcimgServer(xmlserver, replace_ios=None)

Instantiiert RevPiCheckServer()-Klasse.

xmlserver
XML-RPC Server +
replace_ios
+
+Replace IOs of RevPiModIO

diff --git a/eric-revpipyload.api b/eric-revpipyload.api index a661233..c3374a7 100644 --- a/eric-revpipyload.api +++ b/eric-revpipyload.api @@ -4,6 +4,7 @@ helper.__license__?9 helper._setuprt?5(pid, evt_exit) helper._zeroprocimg?5() helper.refullmatch?4(regex, string) +helper.revpimodio_replaceio?4(revpi, filename) logsystem.LogReader.closeall?4() logsystem.LogReader.load_applog?4(start, count) logsystem.LogReader.load_plclog?4(start, count) @@ -28,7 +29,7 @@ mqttserver.MqttServer.newlogfile?4() mqttserver.MqttServer.reload_revpimodio?4() mqttserver.MqttServer.run?4() mqttserver.MqttServer.stop?4() -mqttserver.MqttServer?1(basetopic, sendinterval, broker_address, port=1883, tls_set=False, username="", password=None, client_id="", send_events=False, write_outputs=False) +mqttserver.MqttServer?1(basetopic, sendinterval, broker_address, port=1883, tls_set=False, username="", password=None, client_id="", send_events=False, write_outputs=False, replace_ios=None) mqttserver.__author__?9 mqttserver.__copyright__?9 mqttserver.__license__?9 @@ -63,7 +64,7 @@ procimgserver.ProcimgServer.setvalue?4(device, io, value) procimgserver.ProcimgServer.start?4() procimgserver.ProcimgServer.stop?4() procimgserver.ProcimgServer.values?4() -procimgserver.ProcimgServer?1(xmlserver) +procimgserver.ProcimgServer?1(xmlserver, replace_ios=None) procimgserver.__author__?9 procimgserver.__copyright__?9 procimgserver.__license__?9 diff --git a/revpipyload.e4p b/revpipyload.e4p index 50c279a..63c4f3d 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.7.5 + 0.7.6 Sven Sager akira@narux.de diff --git a/revpipyload/helper.py b/revpipyload/helper.py index 915f546..34c8f81 100644 --- a/revpipyload/helper.py +++ b/revpipyload/helper.py @@ -5,6 +5,7 @@ __copyright__ = "Copyright (C) 2018 Sven Sager" __license__ = "GPLv3" import os import proginit +from configparser import ConfigParser from re import match as rematch from subprocess import Popen, PIPE @@ -117,6 +118,115 @@ def _zeroprocimg(): ) +def revpimodio_replaceio(revpi, filename): + """Importiert und ersetzt IOs in RevPiModIO. + + @param revpi RevPiModIO Instanz + @param filename Dateiname der Ersetzungsdatei + @return True, wenn alle IOs ersetzt werden konnten + + """ + cp = ConfigParser() + try: + with open(filename, "r") as fh: + cp.read_file(fh) + except Exception as e: + proginit.logger.error( + "could not read replace_io file '{0}' | {1}".format(filename, e) + ) + return False + + # Pre-check + lst_replace = [] + rc = True + for io in cp: + if io == "DEFAULT": + continue + + dict_replace = { + "replace": cp[io].get("replace", ""), + "frm": cp[io].get("frm"), + "bmk": cp[io].get("bmk", ""), + "byteorder": cp[io].get("byteorder", "little"), + } + + if dict_replace["replace"] in revpi.io: + + # Byteorder prüfen + if not (dict_replace["byteorder"] == "little" or + dict_replace["byteorder"] == "big"): + proginit.logger.error( + "byteorder of '{0}' must be 'little' or 'big'".format(io) + ) + rc = False + continue + + if dict_replace["frm"] == "?": + + # Convert defaultvalue from config file + try: + dict_replace["default"] = cp[io].getboolean("defaultvalue") + except Exception: + proginit.logger.error( + "could not convert '{0}' defaultvalue '{1}' to boolean" + "".format(io, cp[io].get("defaultvalue")) + ) + rc = False + continue + + # Get bitaddress + try: + dict_replace["bitaddress"] = cp[io].getint("bitaddress", 0) + except Exception: + proginit.logger.error( + "could not convert '{0}' bitaddress '{1}' to integer" + "".format(io, cp[io].get("bitaddress")) + ) + rc = False + continue + + else: + # Convert defaultvalue from config file + try: + dict_replace["default"] = cp[io].getint("defaultvalue") + except Exception: + proginit.logger.error( + "could not convert '{0}' defaultvalue '{1}' to integer" + "".format(io, cp[io].get("defaultvalue")) + ) + rc = False + continue + + else: + proginit.logger.error( + "can not find io '{0}' to replace with '{1}'" + "".format(dict_replace["replace"], io) + ) + rc = False + continue + + # Replace_IO übernehmen + lst_replace.append(dict_replace) + + if not rc: + # Abbrechen, wenn IO-Verarbeitung einen Fehler hatte + return False + + # Replace IOs + for dict_replace in lst_replace: + + # FIXME: Hier können Fehler auftreten !!! + + revpi.io[dict_replace["replace"]].replace_io( + io, + frm=dict_replace["frm"], + bmk=dict_replace["bmk"], + bit=dict_replace["bitaddress"], + byteorder=dict_replace["byteorder"], + defaultvalue=dict_replace["default"] + ) + + def refullmatch(regex, string): """re.fullmatch wegen alter python version aus wheezy nachgebaut. diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index ad55575..25d3739 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -11,6 +11,7 @@ __license__ = "GPLv3" import pickle import proginit import revpimodio2 +from .helper import revpimodio_replaceio from xmlrpc.client import Binary @@ -108,14 +109,12 @@ class ProcimgServer(): return e # Replace IOs of RevPiModIO - if self.replace_ios: - try: - self.rpi.import_replaced_ios(self.replace_ios) - except Exception as e: - proginit.logger.error( - "could not load replaced ios into RevPiModIO - using " - "defaults | {0}".format(e) - ) + if self.replace_ios and \ + not revpimodio_replaceio(self.rpi, self.replace_ios): + proginit.logger.error( + "could not load all or some replaced ios into RevPiModIO - " + "see log file" + ) # NOTE: Warum das? self.rpi.syncoutputs(device=0) diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 33fe736..75818c3 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -28,7 +28,7 @@ begrenzt werden! __author__ = "Sven Sager" __copyright__ = "Copyright (C) 2018 Sven Sager" __license__ = "GPLv3" -__version__ = "0.7.5" +__version__ = "0.7.6" import gzip import logsystem import picontrolserver diff --git a/setup.py b/setup.py index 3e5a623..cef2511 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ setup( license="LGPLv3", name="revpipyload", - version="0.7.5", + version="0.7.6", scripts=["data/revpipyload"], From 09cb134f31fcdfbad9e5e14849252a765c31e380 Mon Sep 17 00:00:00 2001 From: NaruX Date: Sun, 16 Jun 2019 16:06:29 +0200 Subject: [PATCH 3/4] =?UTF-8?q?replace=5Fio=5Ffile=20wird=20von=20RevPiMod?= =?UTF-8?q?IO=20verarbeitet=20Parameter=20kann=20per=20XML-RPC=20=C3=BCber?= =?UTF-8?q?geben=20werden=20Argument=20--test=20hinzugef=C3=BCgt=20um=20re?= =?UTF-8?q?place=5Fio=5Ffile=20testen=20zu=20k=C3=B6nnen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/etc/revpipyload/replace_ios.conf | 6 +- doc/index.html | 3 + doc/revpipyload.html | 2 +- doc/testsystem.html | 108 ++++++++++++++++++++++++++ eric-revpipyload.api | 9 ++- revpipyload.e4p | 3 +- revpipyload/mqttserver.py | 18 +---- revpipyload/procimgserver.py | 12 +-- revpipyload/proginit.py | 4 + revpipyload/revpipyload.py | 21 +++-- revpipyload/testsystem.py | 88 +++++++++++++++++++++ 11 files changed, 239 insertions(+), 35 deletions(-) create mode 100644 doc/testsystem.html create mode 100644 revpipyload/testsystem.py diff --git a/data/etc/revpipyload/replace_ios.conf b/data/etc/revpipyload/replace_ios.conf index c5b331c..94376f0 100644 --- a/data/etc/revpipyload/replace_ios.conf +++ b/data/etc/revpipyload/replace_ios.conf @@ -1,7 +1,9 @@ # Replace IO # [NewIoName] -# parentio_name = OldIoName +# replace = OldIoName # frm = StructFormat -# bitaddress = 0-7 (Only with '?' struct) +# bit = 0-n (Only with '?' struct) # byteorder = little/big +# bmk = JustText + diff --git a/doc/index.html b/doc/index.html index 2e74c52..c6edd36 100644 --- a/doc/index.html +++ b/doc/index.html @@ -45,6 +45,9 @@ Modules

revpipyload Revolution Pi Python PLC Loader. +testsystem +Test all config files and print results. + xrpcserver XML-RPC Server anpassungen fuer Absicherung. diff --git a/doc/revpipyload.html b/doc/revpipyload.html index 625fb74..4ec59aa 100644 --- a/doc/revpipyload.html +++ b/doc/revpipyload.html @@ -66,7 +66,7 @@ None

Class Attributes

- +
root
None

Class Methods

diff --git a/doc/testsystem.html b/doc/testsystem.html new file mode 100644 index 0000000..dc7a974 --- /dev/null +++ b/doc/testsystem.html @@ -0,0 +1,108 @@ + + +testsystem + + + +

+testsystem

+

+Test all config files and print results. +

+

+Global Attributes

+ + +
__author__
__copyright__
__license__
newline
+

+Classes

+ + + + + +
TestSystemMain class for test system of revpipyload.
+

+Functions

+ + +
None
+

+ +

TestSystem

+

+Main class for test system of revpipyload. +

+

+Derived from

+None +

+Class Attributes

+ + +
None
+

+Class Methods

+ + +
None
+

+Methods

+ + + + + + + + + + + + + + +
TestSystemInit TestSystem class.
startStart test program and run tests.
test_replace_ioTest replace_io file.
test_sectionsTest config file.
+

+Static Methods

+ + +
None
+ +

+TestSystem (Constructor)

+TestSystem() +

+Init TestSystem class. +

+

+TestSystem.start

+start() +

+Start test program and run tests. +

+

+TestSystem.test_replace_io

+test_replace_io() +

+Test replace_io file. +

+
Returns:
+
+0 if successful testet +
+
+

+TestSystem.test_sections

+test_sections() +

+Test config file. +

+
Returns:
+
+0 if successful testet +
+
+ +
+ \ No newline at end of file diff --git a/eric-revpipyload.api b/eric-revpipyload.api index c3374a7..813f47c 100644 --- a/eric-revpipyload.api +++ b/eric-revpipyload.api @@ -93,7 +93,6 @@ revpipyload.RevPiPyLoad._sigexit?5(signum, frame) revpipyload.RevPiPyLoad._sigloadconfig?5(signum, frame) revpipyload.RevPiPyLoad._signewlogfile?5(signum, frame) revpipyload.RevPiPyLoad.packapp?4(mode="tar", pictory=False) -revpipyload.RevPiPyLoad.root?7 revpipyload.RevPiPyLoad.start?4() revpipyload.RevPiPyLoad.stop?4() revpipyload.RevPiPyLoad.stop_plcmqtt?4() @@ -149,6 +148,14 @@ revpipyload.shared.ipaclmanager.__copyright__?9 revpipyload.shared.ipaclmanager.__license__?9 revpipyload.shared.ipaclmanager.__version__?9 revpipyload.shared.ipaclmanager.refullmatch?4(regex, string) +testsystem.TestSystem.start?4() +testsystem.TestSystem.test_replace_io?4() +testsystem.TestSystem.test_sections?4() +testsystem.TestSystem?1() +testsystem.__author__?9 +testsystem.__copyright__?9 +testsystem.__license__?9 +testsystem.newline?7 xrpcserver.SaveXMLRPCRequestHandler.parse_request?4() xrpcserver.SaveXMLRPCServer._dispatch?5(method, params) xrpcserver.SaveXMLRPCServer.is_alive?4() diff --git a/revpipyload.e4p b/revpipyload.e4p index 63c4f3d..c4f6847 100644 --- a/revpipyload.e4p +++ b/revpipyload.e4p @@ -1,7 +1,7 @@ - + en_US @@ -24,6 +24,7 @@ revpipyload/revpipyload.py revpipyload/shared/__init__.py revpipyload/shared/ipaclmanager.py + revpipyload/testsystem.py revpipyload/xrpcserver.py setup.py diff --git a/revpipyload/mqttserver.py b/revpipyload/mqttserver.py index 5ef06ef..6c9fa65 100644 --- a/revpipyload/mqttserver.py +++ b/revpipyload/mqttserver.py @@ -140,14 +140,16 @@ class MqttServer(Thread): autorefresh=self._send_events, monitoring=True, configrsc=proginit.pargs.configrsc, - procimg=proginit.pargs.procimg + procimg=proginit.pargs.procimg, + replace_io_file=self._replace_ios ) # Schreibenen Zugriff if self._write_outputs: self._rpi_write = revpimodio2.RevPiModIO( configrsc=proginit.pargs.configrsc, - procimg=proginit.pargs.procimg + procimg=proginit.pargs.procimg, + replace_io_file=self._replace_ios ) except Exception as e: @@ -158,18 +160,6 @@ class MqttServer(Thread): ) raise e - # Replace IOs of RevPiModIO - if self._replace_ios: - try: - self._rpi.import_replaced_ios(self._replace_ios) - if self._write_outputs: - self._rpi_write.import_replaced_ios(self._replace_ios) - except Exception as e: - proginit.logger.error( - "could not load replaced ios into RevPiModIO - using " - "defaults | {0}".format(e) - ) - # Exportierte IOs laden for dev in self._rpi.device: for io in dev.get_allios(export=True): diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index 25d3739..d9d7953 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -11,7 +11,6 @@ __license__ = "GPLv3" import pickle import proginit import revpimodio2 -from .helper import revpimodio_replaceio from xmlrpc.client import Binary @@ -99,7 +98,8 @@ class ProcimgServer(): try: self.rpi = revpimodio2.RevPiModIO( configrsc=proginit.pargs.configrsc, - procimg=proginit.pargs.procimg + procimg=proginit.pargs.procimg, + replace_io_file=self.replace_ios ) except Exception as e: self.rpi = None @@ -108,14 +108,6 @@ class ProcimgServer(): ) return e - # Replace IOs of RevPiModIO - if self.replace_ios and \ - not revpimodio_replaceio(self.rpi, self.replace_ios): - proginit.logger.error( - "could not load all or some replaced ios into RevPiModIO - " - "see log file" - ) - # NOTE: Warum das? self.rpi.syncoutputs(device=0) diff --git a/revpipyload/proginit.py b/revpipyload/proginit.py index 1594107..a0bf0fd 100644 --- a/revpipyload/proginit.py +++ b/revpipyload/proginit.py @@ -63,6 +63,10 @@ def configure(): "--pictory", dest="configrsc", help="piCtory file to use" ) + parser.add_argument( + "--test", action="store_true", dest="test", + help="Test parameters of config files and print results" + ) parser.add_argument( "-v", "--verbose", action="count", dest="verbose", help="Switch on verbose logging: info -v debug -vv" diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 75818c3..8aed928 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -394,11 +394,6 @@ class RevPiPyLoad(): # Erweiterte Funktionen anmelden try: import procimgserver - self.xml_ps = procimgserver.ProcimgServer( - self.xsrv, self.replace_ios_config - ) - self.xsrv.register_function(1, self.xml_psstart, "psstart") - self.xsrv.register_function(1, self.xml_psstop, "psstop") except Exception: self.xml_ps = None proginit.logger.warning( @@ -408,6 +403,15 @@ class RevPiPyLoad(): "revpimodio2: 'apt-get install python3-revpimodio2'" "".format(min_revpimodio) ) + try: + self.xml_ps = procimgserver.ProcimgServer( + self.xsrv, self.replace_ios_config + ) + self.xsrv.register_function(1, self.xml_psstart, "psstart") + self.xsrv.register_function(1, self.xml_psstop, "psstop") + except Exception as e: + self.xml_ps = None + proginit.logger.error(e) # XML Modus 2 Einstellungen lesen und Programm herunterladen self.xsrv.register_function( @@ -1214,8 +1218,13 @@ if __name__ == "__main__": # Programmeinstellungen konfigurieren proginit.configure() + if proginit.pargs.test: + from testsystem import TestSystem + root = TestSystem() + else: + root = RevPiPyLoad() + # Programm starten - root = RevPiPyLoad() root.start() # Aufräumen diff --git a/revpipyload/testsystem.py b/revpipyload/testsystem.py new file mode 100644 index 0000000..5ef5a1f --- /dev/null +++ b/revpipyload/testsystem.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +"""Test all config files and print results.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2019 Sven Sager" +__license__ = "GPLv3" +import proginit +from configparser import ConfigParser + +newline = "\n------------------------------------------------------------\n" + + +class TestSystem: + + """Main class for test system of revpipyload.""" + + def __init__(self): + """Init TestSystem class.""" + self.gc = ConfigParser() + lst_file = self.gc.read(proginit.globalconffile) + if len(lst_file) <= 0: + proginit.logger.error("can not read config file") + + def test_replace_io(self): + """Test replace_io file. + @return 0 if successful testet""" + print("Test replace_io data:") + file = self.gc["DEFAULT"].get("replace_ios") + if file is None: + print("\tFile MISSING") + return 1 + + print("\tFile: {0}\n".format(file)) + + try: + import revpimodio2 + except Exception as e: + print("\tERROR: {0}".format(e)) + return 1 + + try: + rpi = revpimodio2.RevPiModIO( + configrsc=proginit.pargs.configrsc, + procimg=proginit.pargs.procimg, + monitoring=False, + debug=True, + replace_io_file=file, + ) + except Exception as e: + print(e) + return 1 + else: + print("\tPrinting replaced IOs:") + for io in rpi.io: + if isinstance(io, revpimodio2.io.StructIO): + print("\t\tNew io: {0}".format(io.name)) + + rpi.cleanup() + return 0 + + def test_sections(self): + """Test config file. + @return 0 if successful testet""" + print("Parse config file:") + print("\tSection DEFAULT : {0}".format("DEFAULT" in self.gc)) + print("\tSection PLCSLAVE: {0}".format("PLCSLAVE" in self.gc)) + print("\tSection XMLRPC : {0}".format("XMLRPC" in self.gc)) + print("\tSection MQTT : {0}".format("MQTT" in self.gc)) + return 0 + + def start(self): + """Start test program and run tests.""" + program_ec = 0 + + print("--- RevPiPyLoad Testsystem ---\n") + ec = self.test_sections() + program_ec += int(ec) << 0 + print(newline) + + # TODO: Test Values of each section + # print() + + ec = self.test_replace_io() + program_ec += (int(ec) << 7) + print(newline) + + if program_ec != 0: + print("result: {0}".format(program_ec)) + exit(program_ec) From 89f29b0496609a14200ab7e630f93cbdc7f87cd4 Mon Sep 17 00:00:00 2001 From: NaruX Date: Mon, 17 Jun 2019 14:17:56 +0200 Subject: [PATCH 4/4] =?UTF-8?q?ProcimgServer=20l=C3=A4dt=20standard=20IOs,?= =?UTF-8?q?=20wenn=20replace=5Fios=5Ffile=20nicht=20g=C3=BCltig=20ist=20MQ?= =?UTF-8?q?TT=20l=C3=A4dt=20standard=20IOs,=20wenn=20replace=5Fios=5Ffile?= =?UTF-8?q?=20nicht=20g=C3=BCltig=20ist=20replace=5Fios=5Ffile=20wird=20be?= =?UTF-8?q?im=20reload=20gepr=C3=BCft=20und=20ggf.=20neu=20geladen=20Start?= =?UTF-8?q?bar=20ohne=20replace=5Fios=20Parameter=20Bei=20fehlender=20repl?= =?UTF-8?q?ace=5Fios=20Datei=20werden=20standard=20IOs=20verwendet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- revpipyload/mqttserver.py | 36 +++++++++++++++++++++++++++++------- revpipyload/procimgserver.py | 24 +++++++++++++++++++----- revpipyload/revpipyload.py | 26 ++++++++++++++++++++++++-- setup.py | 1 + 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/revpipyload/mqttserver.py b/revpipyload/mqttserver.py index 6c9fa65..f4aa9dc 100644 --- a/revpipyload/mqttserver.py +++ b/revpipyload/mqttserver.py @@ -143,7 +143,6 @@ class MqttServer(Thread): procimg=proginit.pargs.procimg, replace_io_file=self._replace_ios ) - # Schreibenen Zugriff if self._write_outputs: self._rpi_write = revpimodio2.RevPiModIO( @@ -152,13 +151,36 @@ class MqttServer(Thread): replace_io_file=self._replace_ios ) + if self._replace_ios: + proginit.logger.info("loaded replace_ios to MQTT") + except Exception as e: - self._rpi = None - self._rpi_write = None - proginit.logger.error( - "piCtory configuration not loadable for MQTT" - ) - raise e + try: + # Lesend und Eventüberwachung + self._rpi = revpimodio2.RevPiModIO( + autorefresh=self._send_events, + monitoring=True, + configrsc=proginit.pargs.configrsc, + procimg=proginit.pargs.procimg + ) + # Schreibenen Zugriff + if self._write_outputs: + self._rpi_write = revpimodio2.RevPiModIO( + configrsc=proginit.pargs.configrsc, + procimg=proginit.pargs.procimg + ) + proginit.logger.warning( + "replace_ios_file not loadable for MQTT - using " + "defaults now | {0}".format(e) + ) + + except Exception: + self._rpi = None + self._rpi_write = None + proginit.logger.error( + "piCtory configuration not loadable for MQTT" + ) + raise e # Exportierte IOs laden for dev in self._rpi.device: diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py index d9d7953..b6fbc45 100644 --- a/revpipyload/procimgserver.py +++ b/revpipyload/procimgserver.py @@ -101,12 +101,26 @@ class ProcimgServer(): procimg=proginit.pargs.procimg, replace_io_file=self.replace_ios ) + + if self.replace_ios: + proginit.logger.info("loaded replace_ios to ProcimgServer") + except Exception as e: - self.rpi = None - proginit.logger.error( - "piCtory configuration not loadable for ProcimgServer" - ) - return e + try: + self.rpi = revpimodio2.RevPiModIO( + configrsc=proginit.pargs.configrsc, + procimg=proginit.pargs.procimg, + ) + proginit.logger.warning( + "replace_ios_file not loadable for ProcimgServer - using " + "defaults now | {0}".format(e) + ) + except Exception: + self.rpi = None + proginit.logger.error( + "piCtory configuration not loadable for ProcimgServer" + ) + return e # NOTE: Warum das? self.rpi.syncoutputs(device=0) diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index 8aed928..c25dcee 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -68,6 +68,7 @@ class RevPiPyLoad(): # Klassenattribute self._exit = True self.pictorymtime = os.path.getmtime(proginit.pargs.configrsc) + self.replaceiosmtime = 0 self.evt_loadconfig = Event() self.globalconfig = ConfigParser() self.logr = logsystem.LogReader() @@ -230,6 +231,24 @@ class RevPiPyLoad(): self.zeroonexit = \ self.globalconfig["DEFAULT"].getboolean("zeroonexit", True) + # MTime für replace io übernehmen + mtime = 0 + if self.replace_ios_config: + if os.access(self.replace_ios_config, os.R_OK | os.W_OK): + mtime = os.path.getmtime(self.replace_ios_config) + else: + proginit.logger.error( + "can not access (r/w) the replace_ios file '{0}' " + "using defaults".format(self.replace_ios_config) + ) + self.replace_ios_config = "" + + if self.replaceiosmtime != mtime: + # MQTT reload erforderlich + restart_plcmqtt = True + + self.replaceiosmtime = mtime + # Konfiguration verarbeiten [MQTT] self.mqtt = 0 if "MQTT" in self.globalconfig: @@ -405,7 +424,9 @@ class RevPiPyLoad(): ) try: self.xml_ps = procimgserver.ProcimgServer( - self.xsrv, self.replace_ios_config + self.xsrv, + None if not self.replace_ios_config + else self.replace_ios_config, ) self.xsrv.register_function(1, self.xml_psstart, "psstart") self.xsrv.register_function(1, self.xml_psstop, "psstop") @@ -492,7 +513,8 @@ class RevPiPyLoad(): self.mqttclient_id, self.mqttsend_on_event, self.mqttwrite_outputs, - self.replace_ios_config, + None if not self.replace_ios_config + else self.replace_ios_config, ) except Exception as e: proginit.logger.error(e) diff --git a/setup.py b/setup.py index cef2511..64dd099 100644 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ setup( ("/etc/revpipyload", [ "data/etc/revpipyload/aclplcslave.conf", "data/etc/revpipyload/aclxmlrpc.conf", + "data/etc/revpipyload/replace_ios.conf", "data/etc/revpipyload/revpipyload.conf", ]), ("share/revpipyload", glob("revpipyload/*.*")),