Mit replace_ios zusammenführen

This commit is contained in:
2019-06-17 14:18:12 +02:00
17 changed files with 483 additions and 35 deletions

View File

@@ -0,0 +1,9 @@
# Replace IO
# [NewIoName]
# replace = OldIoName
# frm = StructFormat
# bit = 0-n (Only with '?' struct)
# byteorder = little/big
# bmk = JustText

View File

@@ -8,6 +8,7 @@ plcarguments =
plcuid = 1000 plcuid = 1000
plcgid = 1000 plcgid = 1000
pythonversion = 3 pythonversion = 3
replace_ios = /etc/revpipyload/replace_ios.conf
rtlevel = 0 rtlevel = 0
zeroonerror = 0 zeroonerror = 0
zeroonexit = 0 zeroonexit = 0

View File

@@ -31,6 +31,9 @@ Functions</h3>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#refullmatch">refullmatch</a></td> <td><a style="color:#0000FF" href="#refullmatch">refullmatch</a></td>
<td>re.fullmatch wegen alter python version aus wheezy nachgebaut.</td> <td>re.fullmatch wegen alter python version aus wheezy nachgebaut.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#revpimodio_replaceio">revpimodio_replaceio</a></td>
<td>Importiert und ersetzt IOs in RevPiModIO.</td>
</tr> </tr>
</table> </table>
<hr /><hr /> <hr /><hr />
@@ -80,5 +83,26 @@ True, wenn komplett passt sonst False
</dd> </dd>
</dl> </dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div> <div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="revpimodio_replaceio" ID="revpimodio_replaceio"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">revpimodio_replaceio</h2>
<b>revpimodio_replaceio</b>(<i>revpi, filename</i>)
<p>
Importiert und ersetzt IOs in RevPiModIO.
</p><dl>
<dt><i>revpi</i></dt>
<dd>
RevPiModIO Instanz
</dd><dt><i>filename</i></dt>
<dd>
Dateiname der Ersetzungsdatei
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn alle IOs ersetzt werden konnten
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /> <hr />
</body></html> </body></html>

View File

@@ -45,6 +45,9 @@ Modules</h3>
<td><a style="color:#0000FF" href="revpipyload.html">revpipyload</a></td> <td><a style="color:#0000FF" href="revpipyload.html">revpipyload</a></td>
<td>Revolution Pi Python PLC Loader.</td> <td>Revolution Pi Python PLC Loader.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="testsystem.html">testsystem</a></td>
<td>Test all config files and print results.</td>
</tr><tr>
<td><a style="color:#0000FF" href="xrpcserver.html">xrpcserver</a></td> <td><a style="color:#0000FF" href="xrpcserver.html">xrpcserver</a></td>
<td>XML-RPC Server anpassungen fuer Absicherung.</td> <td>XML-RPC Server anpassungen fuer Absicherung.</td>
</tr> </tr>

View File

@@ -92,7 +92,7 @@ Static Methods</h3>
<a NAME="MqttServer.__init__" ID="MqttServer.__init__"></a> <a NAME="MqttServer.__init__" ID="MqttServer.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer (Constructor)</h3> MqttServer (Constructor)</h3>
<b>MqttServer</b>(<i>basetopic, sendinterval, broker_address, port=1883, tls_set=False, username="", password=None, client_id="", send_events=False, write_outputs=False</i>) <b>MqttServer</b>(<i>basetopic, sendinterval, broker_address, port=1883, tls_set=False, username="", password=None, client_id="", send_events=False, write_outputs=False, replace_ios=None</i>)
<p> <p>
Init MqttServer class. Init MqttServer class.
</p><dl> </p><dl>
@@ -126,6 +126,9 @@ Sendet Werte bei IO Wertaenderung
</dd><dt><i>write_outputs</i></dt> </dd><dt><i>write_outputs</i></dt>
<dd> <dd>
Per MQTT auch Outputs schreiben Per MQTT auch Outputs schreiben
</dd><dt><i>replace_ios</i></dt>
<dd>
Replace IOs of RevPiModIO
</dd> </dd>
</dl><a NAME="MqttServer._evt_io" ID="MqttServer._evt_io"></a> </dl><a NAME="MqttServer._evt_io" ID="MqttServer._evt_io"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">

View File

@@ -93,13 +93,16 @@ Static Methods</h3>
<a NAME="ProcimgServer.__init__" ID="ProcimgServer.__init__"></a> <a NAME="ProcimgServer.__init__" ID="ProcimgServer.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgServer (Constructor)</h3> ProcimgServer (Constructor)</h3>
<b>ProcimgServer</b>(<i>xmlserver</i>) <b>ProcimgServer</b>(<i>xmlserver, replace_ios=None</i>)
<p> <p>
Instantiiert RevPiCheckServer()-Klasse. Instantiiert RevPiCheckServer()-Klasse.
</p><dl> </p><dl>
<dt><i>xmlserver</i></dt> <dt><i>xmlserver</i></dt>
<dd> <dd>
XML-RPC Server XML-RPC Server
</dd><dt><i>replace_ios</i></dt>
<dd>
Replace IOs of RevPiModIO
</dd> </dd>
</dl><a NAME="ProcimgServer.devices" ID="ProcimgServer.devices"></a> </dl><a NAME="ProcimgServer.devices" ID="ProcimgServer.devices"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">

View File

@@ -66,7 +66,7 @@ None
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3> Class Attributes</h3>
<table> <table>
<tr><td>root</td></tr> <tr><td>None</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3> Class Methods</h3>

108
doc/testsystem.html Normal file
View File

@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html><head>
<title>testsystem</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
testsystem</h1>
<p>
Test all config files and print results.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr><tr><td>newline</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#TestSystem">TestSystem</a></td>
<td>Main class for test system of revpipyload.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="TestSystem" ID="TestSystem"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">TestSystem</h2>
<p>
Main class for test system of revpipyload.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
None
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#TestSystem.__init__">TestSystem</a></td>
<td>Init TestSystem class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#TestSystem.start">start</a></td>
<td>Start test program and run tests.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#TestSystem.test_replace_io">test_replace_io</a></td>
<td>Test replace_io file.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#TestSystem.test_sections">test_sections</a></td>
<td>Test config file.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="TestSystem.__init__" ID="TestSystem.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
TestSystem (Constructor)</h3>
<b>TestSystem</b>(<i></i>)
<p>
Init TestSystem class.
</p><a NAME="TestSystem.start" ID="TestSystem.start"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
TestSystem.start</h3>
<b>start</b>(<i></i>)
<p>
Start test program and run tests.
</p><a NAME="TestSystem.test_replace_io" ID="TestSystem.test_replace_io"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
TestSystem.test_replace_io</h3>
<b>test_replace_io</b>(<i></i>)
<p>
Test replace_io file.
</p><dl>
<dt>Returns:</dt>
<dd>
0 if successful testet
</dd>
</dl><a NAME="TestSystem.test_sections" ID="TestSystem.test_sections"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
TestSystem.test_sections</h3>
<b>test_sections</b>(<i></i>)
<p>
Test config file.
</p><dl>
<dt>Returns:</dt>
<dd>
0 if successful testet
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -4,6 +4,7 @@ helper.__license__?9
helper._setuprt?5(pid, evt_exit) helper._setuprt?5(pid, evt_exit)
helper._zeroprocimg?5() helper._zeroprocimg?5()
helper.refullmatch?4(regex, string) helper.refullmatch?4(regex, string)
helper.revpimodio_replaceio?4(revpi, filename)
logsystem.LogReader.closeall?4() logsystem.LogReader.closeall?4()
logsystem.LogReader.load_applog?4(start, count) logsystem.LogReader.load_applog?4(start, count)
logsystem.LogReader.load_plclog?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.reload_revpimodio?4()
mqttserver.MqttServer.run?4() mqttserver.MqttServer.run?4()
mqttserver.MqttServer.stop?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.__author__?9
mqttserver.__copyright__?9 mqttserver.__copyright__?9
mqttserver.__license__?9 mqttserver.__license__?9
@@ -63,7 +64,7 @@ procimgserver.ProcimgServer.setvalue?4(device, io, value)
procimgserver.ProcimgServer.start?4() procimgserver.ProcimgServer.start?4()
procimgserver.ProcimgServer.stop?4() procimgserver.ProcimgServer.stop?4()
procimgserver.ProcimgServer.values?4() procimgserver.ProcimgServer.values?4()
procimgserver.ProcimgServer?1(xmlserver) procimgserver.ProcimgServer?1(xmlserver, replace_ios=None)
procimgserver.__author__?9 procimgserver.__author__?9
procimgserver.__copyright__?9 procimgserver.__copyright__?9
procimgserver.__license__?9 procimgserver.__license__?9
@@ -92,7 +93,6 @@ revpipyload.RevPiPyLoad._sigexit?5(signum, frame)
revpipyload.RevPiPyLoad._sigloadconfig?5(signum, frame) revpipyload.RevPiPyLoad._sigloadconfig?5(signum, frame)
revpipyload.RevPiPyLoad._signewlogfile?5(signum, frame) revpipyload.RevPiPyLoad._signewlogfile?5(signum, frame)
revpipyload.RevPiPyLoad.packapp?4(mode="tar", pictory=False) revpipyload.RevPiPyLoad.packapp?4(mode="tar", pictory=False)
revpipyload.RevPiPyLoad.root?7
revpipyload.RevPiPyLoad.start?4() revpipyload.RevPiPyLoad.start?4()
revpipyload.RevPiPyLoad.stop?4() revpipyload.RevPiPyLoad.stop?4()
revpipyload.RevPiPyLoad.stop_plcmqtt?4() revpipyload.RevPiPyLoad.stop_plcmqtt?4()
@@ -148,6 +148,14 @@ revpipyload.shared.ipaclmanager.__copyright__?9
revpipyload.shared.ipaclmanager.__license__?9 revpipyload.shared.ipaclmanager.__license__?9
revpipyload.shared.ipaclmanager.__version__?9 revpipyload.shared.ipaclmanager.__version__?9
revpipyload.shared.ipaclmanager.refullmatch?4(regex, string) 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.SaveXMLRPCRequestHandler.parse_request?4()
xrpcserver.SaveXMLRPCServer._dispatch?5(method, params) xrpcserver.SaveXMLRPCServer._dispatch?5(method, params)
xrpcserver.SaveXMLRPCServer.is_alive?4() xrpcserver.SaveXMLRPCServer.is_alive?4()

View File

@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd"> <!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipyload --> <!-- eric project file for project revpipyload -->
<!-- Saved: 2018-12-21, 12:21:56 --> <!-- Saved: 2019-06-16, 15:47:42 -->
<!-- Copyright (C) 2018 Sven Sager, akira@narux.de --> <!-- Copyright (C) 2019 Sven Sager, akira@narux.de -->
<Project version="5.1"> <Project version="5.1">
<Language>en_US</Language> <Language>en_US</Language>
<Hash>89ddb4e70b339f832ee277085202b38acc6a125c</Hash> <Hash>89ddb4e70b339f832ee277085202b38acc6a125c</Hash>
<ProgLanguage mixed="0">Python3</ProgLanguage> <ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType> <ProjectType>Console</ProjectType>
<Description>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.</Description> <Description>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.</Description>
<Version>0.7.5</Version> <Version>0.7.6</Version>
<Author>Sven Sager</Author> <Author>Sven Sager</Author>
<Email>akira@narux.de</Email> <Email>akira@narux.de</Email>
<Eol index="1"/> <Eol index="1"/>
@@ -24,6 +24,7 @@
<Source>revpipyload/revpipyload.py</Source> <Source>revpipyload/revpipyload.py</Source>
<Source>revpipyload/shared/__init__.py</Source> <Source>revpipyload/shared/__init__.py</Source>
<Source>revpipyload/shared/ipaclmanager.py</Source> <Source>revpipyload/shared/ipaclmanager.py</Source>
<Source>revpipyload/testsystem.py</Source>
<Source>revpipyload/xrpcserver.py</Source> <Source>revpipyload/xrpcserver.py</Source>
<Source>setup.py</Source> <Source>setup.py</Source>
</Sources> </Sources>

View File

@@ -5,6 +5,7 @@ __copyright__ = "Copyright (C) 2018 Sven Sager"
__license__ = "GPLv3" __license__ = "GPLv3"
import os import os
import proginit import proginit
from configparser import ConfigParser
from re import match as rematch from re import match as rematch
from subprocess import Popen, PIPE 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): def refullmatch(regex, string):
"""re.fullmatch wegen alter python version aus wheezy nachgebaut. """re.fullmatch wegen alter python version aus wheezy nachgebaut.

View File

@@ -18,7 +18,7 @@ class MqttServer(Thread):
def __init__( def __init__(
self, basetopic, sendinterval, broker_address, port=1883, self, basetopic, sendinterval, broker_address, port=1883,
tls_set=False, username="", password=None, client_id="", 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. """Init MqttServer class.
@param basetopic Basis-Topic fuer Datenaustausch @param basetopic Basis-Topic fuer Datenaustausch
@@ -31,6 +31,7 @@ class MqttServer(Thread):
@param client_id MQTT ClientID, wenn leer automatisch random erzeugung @param client_id MQTT ClientID, wenn leer automatisch random erzeugung
@param send_events Sendet Werte bei IO Wertaenderung @param send_events Sendet Werte bei IO Wertaenderung
@param write_outputs Per MQTT auch Outputs schreiben @param write_outputs Per MQTT auch Outputs schreiben
@param replace_ios Replace IOs of RevPiModIO
""" """
if not isinstance(basetopic, str): if not isinstance(basetopic, str):
@@ -59,6 +60,8 @@ class MqttServer(Thread):
raise ValueError("parameter send_events must be <class 'bool'>") raise ValueError("parameter send_events must be <class 'bool'>")
if not isinstance(write_outputs, bool): if not isinstance(write_outputs, bool):
raise ValueError("parameter write_outputs must be <class 'bool'>") raise ValueError("parameter write_outputs must be <class 'bool'>")
if not (replace_ios is None or isinstance(replace_ios, str)):
raise ValueError("parameter replace_ios must be <class 'str'>")
super().__init__() super().__init__()
@@ -69,6 +72,7 @@ class MqttServer(Thread):
self._broker_address = broker_address self._broker_address = broker_address
self._port = port self._port = port
self._reloadmodio = False self._reloadmodio = False
self._replace_ios = replace_ios
self._rpi = None self._rpi = None
self._rpi_write = None self._rpi_write = None
self._send_events = send_events self._send_events = send_events
@@ -136,23 +140,47 @@ class MqttServer(Thread):
autorefresh=self._send_events, autorefresh=self._send_events,
monitoring=True, monitoring=True,
configrsc=proginit.pargs.configrsc, configrsc=proginit.pargs.configrsc,
procimg=proginit.pargs.procimg procimg=proginit.pargs.procimg,
replace_io_file=self._replace_ios
) )
# Schreibenen Zugriff # Schreibenen Zugriff
if self._write_outputs: if self._write_outputs:
self._rpi_write = revpimodio2.RevPiModIO( self._rpi_write = revpimodio2.RevPiModIO(
configrsc=proginit.pargs.configrsc, configrsc=proginit.pargs.configrsc,
procimg=proginit.pargs.procimg procimg=proginit.pargs.procimg,
replace_io_file=self._replace_ios
) )
if self._replace_ios:
proginit.logger.info("loaded replace_ios to MQTT")
except Exception as e: except Exception as e:
self._rpi = None try:
self._rpi_write = None # Lesend und Eventüberwachung
proginit.logger.error( self._rpi = revpimodio2.RevPiModIO(
"piCtory configuration not loadable for MQTT" autorefresh=self._send_events,
) monitoring=True,
raise e 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 # Exportierte IOs laden
for dev in self._rpi.device: for dev in self._rpi.device:

View File

@@ -25,13 +25,15 @@ class ProcimgServer():
""" """
def __init__(self, xmlserver): def __init__(self, xmlserver, replace_ios=None):
"""Instantiiert RevPiCheckServer()-Klasse. """Instantiiert RevPiCheckServer()-Klasse.
@param xmlserver XML-RPC Server""" @param xmlserver XML-RPC Server
@param replace_ios Replace IOs of RevPiModIO"""
# Logger übernehmen # Logger übernehmen
proginit.logger.debug("enter ProcimgServer.__init__()") proginit.logger.debug("enter ProcimgServer.__init__()")
self.rpi = None self.rpi = None
self.replace_ios = replace_ios
# XML-Server übernehmen # XML-Server übernehmen
self.xmlsrv = xmlserver self.xmlsrv = xmlserver
@@ -96,14 +98,29 @@ class ProcimgServer():
try: try:
self.rpi = revpimodio2.RevPiModIO( self.rpi = revpimodio2.RevPiModIO(
configrsc=proginit.pargs.configrsc, configrsc=proginit.pargs.configrsc,
procimg=proginit.pargs.procimg 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: except Exception as e:
self.rpi = None try:
proginit.logger.error( self.rpi = revpimodio2.RevPiModIO(
"piCtory configuration not loadable for ProcimgServer" configrsc=proginit.pargs.configrsc,
) procimg=proginit.pargs.procimg,
return e )
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? # NOTE: Warum das?
self.rpi.syncoutputs(device=0) self.rpi.syncoutputs(device=0)

View File

@@ -63,6 +63,10 @@ def configure():
"--pictory", dest="configrsc", "--pictory", dest="configrsc",
help="piCtory file to use" 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( parser.add_argument(
"-v", "--verbose", action="count", dest="verbose", "-v", "--verbose", action="count", dest="verbose",
help="Switch on verbose logging: info -v debug -vv" help="Switch on verbose logging: info -v debug -vv"

View File

@@ -28,7 +28,7 @@ begrenzt werden!
__author__ = "Sven Sager" __author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2018 Sven Sager" __copyright__ = "Copyright (C) 2018 Sven Sager"
__license__ = "GPLv3" __license__ = "GPLv3"
__version__ = "0.7.5" __version__ = "0.7.6"
import gzip import gzip
import logsystem import logsystem
import picontrolserver import picontrolserver
@@ -49,7 +49,7 @@ from time import asctime
from xmlrpc.client import Binary from xmlrpc.client import Binary
from xrpcserver import SaveXMLRPCServer from xrpcserver import SaveXMLRPCServer
min_revpimodio = "2.5.0" min_revpimodio = "2.3.3"
class RevPiPyLoad(): class RevPiPyLoad():
@@ -68,6 +68,7 @@ class RevPiPyLoad():
# Klassenattribute # Klassenattribute
self._exit = True self._exit = True
self.pictorymtime = os.path.getmtime(proginit.pargs.configrsc) self.pictorymtime = os.path.getmtime(proginit.pargs.configrsc)
self.replaceiosmtime = 0
self.evt_loadconfig = Event() self.evt_loadconfig = Event()
self.globalconfig = ConfigParser() self.globalconfig = ConfigParser()
self.logr = logsystem.LogReader() self.logr = logsystem.LogReader()
@@ -107,6 +108,8 @@ class RevPiPyLoad():
return True return True
else: else:
return ( return (
self.replace_ios_config !=
self.globalconfig["DEFAULT"].get("replace_ios", "") or
self.mqtt != self.mqtt !=
self.globalconfig["MQTT"].getboolean("mqtt", False) or self.globalconfig["MQTT"].getboolean("mqtt", False) or
self.mqttbasetopic != self.mqttbasetopic !=
@@ -219,6 +222,8 @@ class RevPiPyLoad():
self.globalconfig["DEFAULT"].getint("plcgid", 65534) self.globalconfig["DEFAULT"].getint("plcgid", 65534)
self.pythonversion = \ self.pythonversion = \
self.globalconfig["DEFAULT"].getint("pythonversion", 3) self.globalconfig["DEFAULT"].getint("pythonversion", 3)
self.replace_ios_config = \
self.globalconfig["DEFAULT"].get("replace_ios", "")
self.rtlevel = \ self.rtlevel = \
self.globalconfig["DEFAULT"].getint("rtlevel", 0) self.globalconfig["DEFAULT"].getint("rtlevel", 0)
self.zeroonerror = \ self.zeroonerror = \
@@ -226,6 +231,24 @@ class RevPiPyLoad():
self.zeroonexit = \ self.zeroonexit = \
self.globalconfig["DEFAULT"].getboolean("zeroonexit", True) 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] # Konfiguration verarbeiten [MQTT]
self.mqtt = 0 self.mqtt = 0
if "MQTT" in self.globalconfig: if "MQTT" in self.globalconfig:
@@ -390,9 +413,6 @@ class RevPiPyLoad():
# Erweiterte Funktionen anmelden # Erweiterte Funktionen anmelden
try: try:
import procimgserver import procimgserver
self.xml_ps = procimgserver.ProcimgServer(self.xsrv)
self.xsrv.register_function(1, self.xml_psstart, "psstart")
self.xsrv.register_function(1, self.xml_psstop, "psstop")
except Exception: except Exception:
self.xml_ps = None self.xml_ps = None
proginit.logger.warning( proginit.logger.warning(
@@ -402,6 +422,17 @@ class RevPiPyLoad():
"revpimodio2: 'apt-get install python3-revpimodio2'" "revpimodio2: 'apt-get install python3-revpimodio2'"
"".format(min_revpimodio) "".format(min_revpimodio)
) )
try:
self.xml_ps = procimgserver.ProcimgServer(
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")
except Exception as e:
self.xml_ps = None
proginit.logger.error(e)
# XML Modus 2 Einstellungen lesen und Programm herunterladen # XML Modus 2 Einstellungen lesen und Programm herunterladen
self.xsrv.register_function( self.xsrv.register_function(
@@ -482,6 +513,8 @@ class RevPiPyLoad():
self.mqttclient_id, self.mqttclient_id,
self.mqttsend_on_event, self.mqttsend_on_event,
self.mqttwrite_outputs, self.mqttwrite_outputs,
None if not self.replace_ios_config
else self.replace_ios_config,
) )
except Exception as e: except Exception as e:
proginit.logger.error(e) proginit.logger.error(e)
@@ -761,6 +794,7 @@ class RevPiPyLoad():
dc["plcuid"] = self.plcuid dc["plcuid"] = self.plcuid
dc["plcgid"] = self.plcgid dc["plcgid"] = self.plcgid
dc["pythonversion"] = self.pythonversion dc["pythonversion"] = self.pythonversion
dc["replace_ios"] = self.replace_ios_config
dc["rtlevel"] = self.rtlevel dc["rtlevel"] = self.rtlevel
dc["zeroonerror"] = int(self.zeroonerror) dc["zeroonerror"] = int(self.zeroonerror)
dc["zeroonexit"] = int(self.zeroonexit) dc["zeroonexit"] = int(self.zeroonexit)
@@ -996,6 +1030,7 @@ class RevPiPyLoad():
# "plcuid": "[0-9]{,5}", # "plcuid": "[0-9]{,5}",
# "plcgid": "[0-9]{,5}", # "plcgid": "[0-9]{,5}",
"pythonversion": "[23]", "pythonversion": "[23]",
"replace_ios": ".*",
"rtlevel": "[0-1]", "rtlevel": "[0-1]",
"zeroonerror": "[01]", "zeroonerror": "[01]",
"zeroonexit": "[01]", "zeroonexit": "[01]",
@@ -1205,8 +1240,13 @@ if __name__ == "__main__":
# Programmeinstellungen konfigurieren # Programmeinstellungen konfigurieren
proginit.configure() proginit.configure()
if proginit.pargs.test:
from testsystem import TestSystem
root = TestSystem()
else:
root = RevPiPyLoad()
# Programm starten # Programm starten
root = RevPiPyLoad()
root.start() root.start()
# Aufräumen # Aufräumen

88
revpipyload/testsystem.py Normal file
View File

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

View File

@@ -27,11 +27,11 @@ setup(
license="LGPLv3", license="LGPLv3",
name="revpipyload", name="revpipyload",
version="0.7.5", version="0.7.6",
scripts=["data/revpipyload"], scripts=["data/revpipyload"],
install_requires=["revpimodio2 >= 2.3.1"], install_requires=["revpimodio2 >= 2.3.3"],
python_requires=">=3.2", python_requires=">=3.2",
data_files=[ data_files=[
@@ -41,6 +41,7 @@ setup(
("/etc/revpipyload", [ ("/etc/revpipyload", [
"data/etc/revpipyload/aclplcslave.conf", "data/etc/revpipyload/aclplcslave.conf",
"data/etc/revpipyload/aclxmlrpc.conf", "data/etc/revpipyload/aclxmlrpc.conf",
"data/etc/revpipyload/replace_ios.conf",
"data/etc/revpipyload/revpipyload.conf", "data/etc/revpipyload/revpipyload.conf",
]), ]),
("share/revpipyload", glob("revpipyload/*.*")), ("share/revpipyload", glob("revpipyload/*.*")),