Berechnung von Bit-IOs über mehr als 2 Bytes angepasst

wd und x2out Ansteuerung verbessert
Connect Funkscheiben werden als Devices ignoriert
Alle Cores werden bei syncoutputs nicht mehr mit \x00 vorbelegt
issubclass gegen isinstance getauscht
.exitsignal-Event für den Benutzer hinzugefügt
Bei Core-Klasse a*green / a*red als echte IOs hinzugefügt
This commit is contained in:
2018-08-01 12:43:49 +02:00
parent c10f36001f
commit 5cb806bbc5
5 changed files with 74 additions and 28 deletions

View File

@@ -1,7 +1,7 @@
<?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 revpimodio2 --> <!-- eric project file for project revpimodio2 -->
<!-- Saved: 2018-07-25, 14:56:58 --> <!-- Saved: 2018-08-01, 12:41:53 -->
<!-- Copyright (C) 2018 Sven Sager, akira@narux.de --> <!-- Copyright (C) 2018 Sven Sager, akira@narux.de -->
<Project version="5.1"> <Project version="5.1">
<Language>en_US</Language> <Language>en_US</Language>
@@ -38,6 +38,7 @@
<Source>test/web_startseite.py</Source> <Source>test/web_startseite.py</Source>
<Source>test/web_rpidaten.py</Source> <Source>test/web_rpidaten.py</Source>
<Source>test/web_rpii2c.py</Source> <Source>test/web_rpii2c.py</Source>
<Source>test/test_unit_fh.py</Source>
</Sources> </Sources>
<Forms/> <Forms/>
<Translations/> <Translations/>

View File

@@ -55,7 +55,7 @@ class DeviceList(object):
def __delitem__(self, key): def __delitem__(self, key):
"""Entfernt Device an angegebener Position. """Entfernt Device an angegebener Position.
@param key Deviceposition zum entfernen""" @param key Deviceposition zum entfernen"""
if issubclass(type(key), Device): if isinstance(key, Device):
key = key._position key = key._position
self.__delattr__(key) self.__delattr__(key)
@@ -91,7 +91,7 @@ class DeviceList(object):
"""Setzt Attribute nur wenn Device. """Setzt Attribute nur wenn Device.
@param key Attributname @param key Attributname
@param value Attributobjekt""" @param value Attributobjekt"""
if issubclass(type(value), Device): if isinstance(value, Device):
object.__setattr__(self, key, value) object.__setattr__(self, key, value)
self.__dict_position[value._position] = value self.__dict_position[value._position] = value
elif key == "_DeviceList__dict_position": elif key == "_DeviceList__dict_position":
@@ -178,7 +178,7 @@ class Device(object):
"""Prueft ob IO auf diesem Device liegt. """Prueft ob IO auf diesem Device liegt.
@param key IO-Name <class 'str'> / IO-Bytenummer <class 'int'> @param key IO-Name <class 'str'> / IO-Bytenummer <class 'int'>
@return True, wenn IO auf Device vorhanden""" @return True, wenn IO auf Device vorhanden"""
if issubclass(type(key), IOBase): if isinstance(key, IOBase):
# Umwandlung für key # Umwandlung für key
key = key._name key = key._name
@@ -432,18 +432,23 @@ class Core(Device):
self._ioerrorlimit1 = lst_io[6] self._ioerrorlimit1 = lst_io[6]
self._ioerrorlimit2 = lst_io[7] self._ioerrorlimit2 = lst_io[7]
if not (self._modio._monitoring or self._modio._simulator): # Echte IOs erzeugen
# Für RS485 errors defaults laden sollte procimg NULL sein self.a1green = IOBase(self, [
if self._ioerrorlimit1 is not None: "a1green", 0, 1, self._ioled.address,
self._ioerrorlimit1.set_value( False, None, "LED_A1_GREEN", "0"
self._ioerrorlimit1._defaultvalue ], OUT, "little", False)
) self.a1red = IOBase(self, [
if self._ioerrorlimit2 is not None: "a1red", 0, 1, self._ioled.address,
self._ioerrorlimit2.set_value( False, None, "LED_A1_RED", "1"
self._ioerrorlimit2._defaultvalue ], OUT, "little", False)
) self.a2green = IOBase(self, [
# RS485 errors schreiben "a2green", 0, 1, self._ioled.address,
self._modio.writeprocimg(self) False, None, "LED_A2_GREEN", "2"
], OUT, "little", False)
self.a2red = IOBase(self, [
"a2red", 0, 1, self._ioled.address,
False, None, "LED_A2_RED", "3"
], OUT, "little", False)
def __errorlimit(self, io, errorlimit): def __errorlimit(self, io, errorlimit):
"""Verwaltet das Lesen und Schreiben der ErrorLimits. """Verwaltet das Lesen und Schreiben der ErrorLimits.
@@ -648,10 +653,20 @@ class Connect(Core):
"""Connect-Klasse vorbereiten.""" """Connect-Klasse vorbereiten."""
super()._devconfigure() super()._devconfigure()
# Echte IOs erzeugen
self.a3green = IOBase(self, [
"a3green", 0, 1, self._ioled.address,
False, None, "LED_A3_GREEN", "4"
], OUT, "little", False)
self.a3red = IOBase(self, [
"a3red", 0, 1, self._ioled.address,
False, None, "LED_A3_RED", "5"
], OUT, "little", False)
# IO Objekte für WD und X2 in/out erzeugen # IO Objekte für WD und X2 in/out erzeugen
self.wd = IOBase(self, [ self.wd = IOBase(self, [
"wd", 0, 1, self._ioled.address, "wd", 0, 1, self._ioled.address,
False, None, "Connect_WatchDog", "6" False, None, "Connect_WatchDog", "7"
], OUT, "little", False) ], OUT, "little", False)
self.x2in = IOBase(self, [ self.x2in = IOBase(self, [
"x2in", 0, 1, self._iostatusbyte.address, "x2in", 0, 1, self._iostatusbyte.address,
@@ -659,7 +674,7 @@ class Connect(Core):
], INP, "little", False) ], INP, "little", False)
self.x2out = IOBase(self, [ self.x2out = IOBase(self, [
"x2out", 0, 1, self._ioled.address, "x2out", 0, 1, self._ioled.address,
False, None, "Connect_X2_OUT", "7" False, None, "Connect_X2_OUT", "6"
], OUT, "little", False) ], OUT, "little", False)
def _get_leda3(self): def _get_leda3(self):

View File

@@ -191,7 +191,7 @@ class IOList(object):
def _private_register_new_io_object(self, new_io): def _private_register_new_io_object(self, new_io):
"""Registriert neues IO Objekt unabhaenging von __setattr__. """Registriert neues IO Objekt unabhaenging von __setattr__.
@param new_io Neues IO Objekt""" @param new_io Neues IO Objekt"""
if issubclass(type(new_io), IOBase): if isinstance(new_io, IOBase):
if hasattr(self, new_io._name): if hasattr(self, new_io._name):
raise AttributeError( raise AttributeError(
"attribute {} already exists - can not set io".format( "attribute {} already exists - can not set io".format(
@@ -317,7 +317,7 @@ class IOBase(object):
else: else:
# Höhere Bits als 7 auf nächste Bytes umbrechen # Höhere Bits als 7 auf nächste Bytes umbrechen
int_startaddress += int((int(valuelist[7]) % 16) / 8) int_startaddress += int(int(valuelist[7]) / 8)
self._slc_address = slice( self._slc_address = slice(
int_startaddress, int_startaddress + 1 int_startaddress, int_startaddress + 1
) )
@@ -519,7 +519,7 @@ class IOBase(object):
>Python3 struct</a> >Python3 struct</a>
""" """
if not issubclass(type(self._parentdevice), Gateway): if not isinstance(self._parentdevice, Gateway):
raise RuntimeError( raise RuntimeError(
"this function can be used for ios on gatway or virtual " "this function can be used for ios on gatway or virtual "
"devices only" "devices only"

View File

@@ -79,6 +79,9 @@ class RevPiModIO(object):
self.io = None self.io = None
self.summary = None self.summary = None
# Event für Benutzeraktionen
self.exitsignal = Event()
# Nur Konfigurieren, wenn nicht vererbt # Nur Konfigurieren, wenn nicht vererbt
if type(self) == RevPiModIO: if type(self) == RevPiModIO:
self._configure(self.get_jconfigrsc()) self._configure(self.get_jconfigrsc())
@@ -177,6 +180,9 @@ class RevPiModIO(object):
dev_new = devicemodule.Gateway( dev_new = devicemodule.Gateway(
self, device, simulator=self._simulator self, device, simulator=self._simulator
) )
elif device["type"] == "RIGHT":
# Connectdevice
dev_new = None
else: else:
# Device-Type nicht gefunden # Device-Type nicht gefunden
warnings.warn( warnings.warn(
@@ -216,6 +222,20 @@ class RevPiModIO(object):
if self._syncoutputs: if self._syncoutputs:
self.syncoutputs() self.syncoutputs()
# Für RS485 errors am core defaults laden sollte procimg NULL sein
if not (self.core is None or self._monitoring or self._simulator):
if self.core._ioerrorlimit1 is not None:
self.core._ioerrorlimit1.set_value(
self.core._ioerrorlimit1._defaultvalue
)
if self.core._ioerrorlimit2 is not None:
self.core._ioerrorlimit2.set_value(
self.core._ioerrorlimit2._defaultvalue
)
# RS485 errors schreiben
self.writeprocimg(self.core)
# Optional ins autorefresh aufnehmen # Optional ins autorefresh aufnehmen
if self._autorefresh: if self._autorefresh:
self.autorefresh_all() self.autorefresh_all()
@@ -374,6 +394,9 @@ class RevPiModIO(object):
# Zeitänderung in _imgwriter neuladen # Zeitänderung in _imgwriter neuladen
self._imgwriter.newdata.clear() self._imgwriter.newdata.clear()
# Benutzerevent
self.exitsignal.clear()
# Cycleloop starten # Cycleloop starten
self._exit.clear() self._exit.clear()
self._looprunning = True self._looprunning = True
@@ -423,6 +446,10 @@ class RevPiModIO(object):
wird dann gestoppt und das Programm kann sauber beendet werden. wird dann gestoppt und das Programm kann sauber beendet werden.
@param full Entfernt auch alle Devices aus autorefresh""" @param full Entfernt auch alle Devices aus autorefresh"""
# Benutzerevent
self.exitsignal.set()
self._exit.set() self._exit.set()
self._waitexit.set() self._waitexit.set()
@@ -544,6 +571,9 @@ class RevPiModIO(object):
self._th_mainloop.start() self._th_mainloop.start()
return return
# Benutzerevent
self.exitsignal.clear()
# Event säubern vor Eintritt in Mainloop # Event säubern vor Eintritt in Mainloop
self._exit.clear() self._exit.clear()
self._looprunning = True self._looprunning = True
@@ -592,7 +622,7 @@ class RevPiModIO(object):
if device is None: if device is None:
mylist = self.device mylist = self.device
else: else:
dev = device if issubclass(type(device), devicemodule.Device) \ dev = device if isinstance(device, devicemodule.Device) \
else self.device.__getitem__(device) else self.device.__getitem__(device)
if dev._selfupdate: if dev._selfupdate:
@@ -647,7 +677,7 @@ class RevPiModIO(object):
if device is None: if device is None:
mylist = self.device mylist = self.device
else: else:
dev = device if issubclass(type(device), devicemodule.Device) \ dev = device if isinstance(device, devicemodule.Device) \
else self.device.__getitem__(device) else self.device.__getitem__(device)
mylist = [dev] mylist = [dev]
@@ -667,12 +697,12 @@ class RevPiModIO(object):
if device is None: if device is None:
mylist = self.device mylist = self.device
else: else:
dev = device if issubclass(type(device), devicemodule.Device) \ dev = device if isinstance(device, devicemodule.Device) \
else self.device.__getitem__(device) else self.device.__getitem__(device)
if dev._selfupdate: if dev._selfupdate:
raise RuntimeError( raise RuntimeError(
"can not sync process image, while device '{}|{}'" "can not sync outputs, while device '{}|{}'"
"is in autorefresh mode".format(dev._position, dev._name) "is in autorefresh mode".format(dev._position, dev._name)
) )
mylist = [dev] mylist = [dev]
@@ -710,7 +740,7 @@ class RevPiModIO(object):
if device is None: if device is None:
mylist = self.device mylist = self.device
else: else:
dev = device if issubclass(type(device), devicemodule.Device) \ dev = device if isinstance(device, devicemodule.Device) \
else self.device.__getitem__(device) else self.device.__getitem__(device)
if dev._selfupdate: if dev._selfupdate:

View File

@@ -466,7 +466,7 @@ class RevPiNetIO(_RevPiModIO):
if device is None: if device is None:
self._myfh.clear_dirtybytes() self._myfh.clear_dirtybytes()
else: else:
dev = device if issubclass(type(device), Device) \ dev = device if isinstance(device, Device) \
else self.device.__getitem__(device) else self.device.__getitem__(device)
mylist = [dev] mylist = [dev]
@@ -486,7 +486,7 @@ class RevPiNetIO(_RevPiModIO):
if device is None: if device is None:
mylist = self.device mylist = self.device
else: else:
dev = device if issubclass(type(device), Device) \ dev = device if isinstance(device, Device) \
else self.device.__getitem__(device) else self.device.__getitem__(device)
mylist = [dev] mylist = [dev]