diff --git a/doc/revpimodio2.device.html b/doc/revpimodio2.device.html
index 3c2bb08..3872073 100644
--- a/doc/revpimodio2.device.html
+++ b/doc/revpimodio2.device.html
@@ -358,7 +358,7 @@ object
Class Attributes
-| None |
+| length |
| name |
| offset |
| position |
| producttype |
Class Methods
@@ -396,6 +396,12 @@ Methods
_devconfigure |
Funktion zum ueberschreiben von abgeleiteten Klassen. |
+| _get_offset |
+Gibt den Deviceoffset im Prozessabbild zurueck. |
+
+| _get_producttype |
+Gibt den Produkttypen des device zurueck. |
+
| autorefresh |
Registriert dieses Device fuer die automatische Synchronisierung. |
@@ -542,7 +548,29 @@ Device._devconfigure
_devconfigure()
Funktion zum ueberschreiben von abgeleiteten Klassen.
-
+
+
+Device._get_offset
+_get_offset()
+
+Gibt den Deviceoffset im Prozessabbild zurueck.
+
+- Returns:
+-
+Deviceoffset
+
+
+
+Device._get_producttype
+_get_producttype()
+
+Gibt den Produkttypen des device zurueck.
+
+- Returns:
+-
+Deviceprodukttyp
+
+
Device.autorefresh
autorefresh(activate=True)
diff --git a/doc/revpimodio2.io.html b/doc/revpimodio2.io.html
index 6a4d96d..2b9c16f 100644
--- a/doc/revpimodio2.io.html
+++ b/doc/revpimodio2.io.html
@@ -141,6 +141,9 @@ Methods
__bool__ |
-Wert der Klasse. |
+| __len__ |
+Gibt die Bytelaenge des IO zurueck. |
+
| __str__ |
-Wert der Klasse. |
@@ -153,12 +156,6 @@ Methods
| _get_iotype |
Gibt io.Type zurueck. |
-| _get_length |
-Gibt die Bytelaenge des IO zurueck. |
-
-| _get_name |
-Gibt den Namen des IOs zurueck. |
-
| get_defaultvalue |
Gibt die Defaultvalue von piCtory zurueck. |
@@ -220,6 +217,17 @@ IOBase.__bool__
Nur False wenn False oder 0 sonst True
+
+
+IOBase.__len__
+__len__()
+
+Gibt die Bytelaenge des IO zurueck.
+
+- Returns:
+-
+Bytelaenge des IO - 0 bei BITs
+
IOBase.__str__
@@ -264,28 +272,6 @@ Gibt io.Type zurueck.
io.Type
-
-
-IOBase._get_length
-_get_length()
-
-Gibt die Bytelaenge des IO zurueck.
-
-- Returns:
--
-Bytelaenge des IO
-
-
-
-IOBase._get_name
-_get_name()
-
-Gibt den Namen des IOs zurueck.
-
-- Returns:
--
-IO Name
-
IOBase.get_defaultvalue
@@ -832,10 +818,10 @@ struct formatierung (1 Zeichen)
kwargs
Weitere Parameter:
- - bmk: Bezeichnung fuer Output
+ - bmk: Bezeichnung fuer IO
- bit: Registriert IO als am angegebenen Bit im Byte
- - byteorder: Byteorder fuer den Input, Standardwert=little
- - defaultvalue: Standardwert fuer Output, Standard ist 0
+ - byteorder: Byteorder fuer IO, Standardwert vom ersetzter IO
+ - defaultvalue: Standardwert fuer IO, Standard vom ersetzter IO
diff --git a/eric-revpimodio2.api b/eric-revpimodio2.api
index 49b6e46..6c11d5c 100644
--- a/eric-revpimodio2.api
+++ b/eric-revpimodio2.api
@@ -28,11 +28,18 @@ revpimodio2.device.Core.temperatur?4()
revpimodio2.device.Core.unconfdevice?4()
revpimodio2.device.Device._buildio?5(dict_io, iotype)
revpimodio2.device.Device._devconfigure?5()
+revpimodio2.device.Device._get_offset?5()
+revpimodio2.device.Device._get_producttype?5()
revpimodio2.device.Device.autorefresh?4(activate=True)
revpimodio2.device.Device.get_allios?4()
revpimodio2.device.Device.get_inputs?4()
revpimodio2.device.Device.get_memmories?4()
revpimodio2.device.Device.get_outputs?4()
+revpimodio2.device.Device.length?7
+revpimodio2.device.Device.name?7
+revpimodio2.device.Device.offset?7
+revpimodio2.device.Device.position?7
+revpimodio2.device.Device.producttype?7
revpimodio2.device.Device.readprocimg?4()
revpimodio2.device.Device.setdefaultvalues?4()
revpimodio2.device.Device.syncoutputs?4()
@@ -70,8 +77,6 @@ revpimodio2.io.DeadIO?1(deadio)
revpimodio2.io.IOBase._get_address?5()
revpimodio2.io.IOBase._get_byteorder?5()
revpimodio2.io.IOBase._get_iotype?5()
-revpimodio2.io.IOBase._get_length?5()
-revpimodio2.io.IOBase._get_name?5()
revpimodio2.io.IOBase.address?7
revpimodio2.io.IOBase.byteorder?7
revpimodio2.io.IOBase.defaultvalue?7
diff --git a/revpimodio2/device.py b/revpimodio2/device.py
index c75d664..3433812 100644
--- a/revpimodio2/device.py
+++ b/revpimodio2/device.py
@@ -37,15 +37,15 @@ class DeviceList(object):
# Reinigungsjobs
dev_del.autorefresh(False)
for io in dev_del:
- delattr(dev_del._modio.io, io.name)
+ delattr(dev_del._modio.io, io._name)
- del self.__dict_position[dev_del.position]
+ del self.__dict_position[dev_del._position]
object.__delattr__(self, key)
def __delitem__(self, key):
"""Entfernt Device an angegebener Position.
@param key Deviceposition zum entfernen"""
- self.__delattr__(self[key].name)
+ self.__delattr__(self[key]._name)
def __getitem__(self, key):
"""Gibt angegebenes Device zurueck.
@@ -75,7 +75,7 @@ class DeviceList(object):
@param value Attributobjekt"""
if issubclass(type(value), Device):
object.__setattr__(self, key, value)
- self.__dict_position[value.position] = value
+ self.__dict_position[value._position] = value
elif key == "_DeviceList__dict_position":
object.__setattr__(self, key, value)
@@ -106,10 +106,10 @@ class Device(object):
self._selfupdate = False
# Wertzuweisung aus dict_device
- self.name = dict_device.pop("name")
- self.offset = int(dict_device.pop("offset"))
- self.position = int(dict_device.pop("position"))
- self.producttype = int(dict_device.pop("productType"))
+ self._name = dict_device.pop("name")
+ self._offset = int(dict_device.pop("offset"))
+ self._position = int(dict_device.pop("position"))
+ self._producttype = int(dict_device.pop("productType"))
# IOM-Objekte erstellen und Adressen in SLCs speichern
if simulator:
@@ -127,15 +127,18 @@ class Device(object):
)
# SLCs mit offset berechnen
- self._slc_devoff = slice(self.offset, self.offset + self._length)
+ self._slc_devoff = slice(self._offset, self._offset + self._length)
self._slc_inpoff = slice(
- self._slc_inp.start + self.offset, self._slc_inp.stop + self.offset
+ self._slc_inp.start + self._offset,
+ self._slc_inp.stop + self._offset
)
self._slc_outoff = slice(
- self._slc_out.start + self.offset, self._slc_out.stop + self.offset
+ self._slc_out.start + self._offset,
+ self._slc_out.stop + self._offset
)
self._slc_memoff = slice(
- self._slc_mem.start + self.offset, self._slc_mem.stop + self.offset
+ self._slc_mem.start + self._offset,
+ self._slc_mem.stop + self._offset
)
# Neues bytearray und Kopie für mainloop anlegen
@@ -172,7 +175,7 @@ class Device(object):
def __int__(self):
"""Gibt die Positon im RevPi Bus zurueck.
@return Positionsnummer"""
- return self.position
+ return self._position
def __iter__(self):
"""Gibt Iterator aller IOs zurueck.
@@ -189,7 +192,7 @@ class Device(object):
def __str__(self):
"""Gibt den Namen des Devices zurueck.
@return Devicename"""
- return self.name
+ return self._name
def _buildio(self, dict_io, iotype):
"""Erstellt aus der piCtory-Liste die IOs fuer dieses Device.
@@ -206,7 +209,7 @@ class Device(object):
for key in sorted(dict_io, key=lambda x: int(x)):
# Neuen IO anlegen
- if bool(dict_io[key][7]) or self.producttype == 95:
+ if bool(dict_io[key][7]) or self._producttype == 95:
# Bei Bitwerten oder Core RevPiIOBase verwenden
io_new = iomodule.IOBase(
self, dict_io[key], iotype, "little", False
@@ -216,7 +219,7 @@ class Device(object):
self, dict_io[key],
iotype,
"little",
- self.producttype == 103
+ self._producttype == 103
)
# IO registrieren
@@ -236,6 +239,16 @@ class Device(object):
"""Funktion zum ueberschreiben von abgeleiteten Klassen."""
pass
+ def _get_offset(self):
+ """Gibt den Deviceoffset im Prozessabbild zurueck.
+ @return Deviceoffset"""
+ return self._offset
+
+ def _get_producttype(self):
+ """Gibt den Produkttypen des device zurueck.
+ @return Deviceprodukttyp"""
+ return self._producttype
+
def autorefresh(self, activate=True):
"""Registriert dieses Device fuer die automatische Synchronisierung.
@param activate Default True fuegt Device zur Synchronisierung hinzu"""
@@ -336,6 +349,12 @@ class Device(object):
RevPiModIO.writeprocimg()"""
self._modio.writeprocimg(self)
+ length = property(__len__)
+ name = property(__str__)
+ offset = property(_get_offset)
+ position = property(__int__)
+ producttype = property(_get_producttype)
+
class Core(Device):
@@ -380,11 +399,11 @@ class Core(Device):
# Für RS485 errors defaults laden sollte procimg NULL sein
if self._ioerrorlimit1 is not None:
self.__lst_io[self._ioerrorlimit1].set_value(
- self.__lst_io[self._ioerrorlimit1].defaultvalue
+ self.__lst_io[self._ioerrorlimit1]._defaultvalue
)
if self._ioerrorlimit2 is not None:
self.__lst_io[self._ioerrorlimit2].set_value(
- self.__lst_io[self._ioerrorlimit2].defaultvalue
+ self.__lst_io[self._ioerrorlimit2]._defaultvalue
)
# RS485 errors schreiben
self._modio.writeprocimg(self)
diff --git a/revpimodio2/io.py b/revpimodio2/io.py
index 617ddfd..33769ea 100644
--- a/revpimodio2/io.py
+++ b/revpimodio2/io.py
@@ -127,8 +127,19 @@ class IOList(object):
def __private_replace_oldio_with_newio(self, io):
"""Ersetzt bestehende IOs durch den neu Registrierten.
@param io Neuer IO der eingefuegt werden soll"""
- int_length = 1 if io._length == 0 else io._length
- for i in range(io.address, io.address + int_length):
+
+ # Scanbereich festlegen
+ if io._bitaddress < 0:
+ scan_start = io.address
+ scan_stop = scan_start + (1 if io._length == 0 else io._length)
+ else:
+ scan_start = io._parentio_address
+ scan_stop = scan_start + io._parentio_length
+
+ # Defaultvalue über mehrere Bytes sammeln
+ calc_defaultvalue = b''
+
+ for i in range(scan_start, scan_stop):
for oldio in self.__dict_iobyte[i]:
if type(oldio) == StructIO:
@@ -151,26 +162,42 @@ class IOList(object):
# IOs im Speicherbereich des neuen IO merken
if io._bitaddress >= 0:
# ios für ref bei bitaddress speichern
- self.__dict_iorefname[oldio.name] = DeadIO(oldio)
+ self.__dict_iorefname[oldio._name] = DeadIO(oldio)
+ else:
+ # Defaultwert berechnen
+ oldio.byteorder = io._byteorder
+ if io._byteorder == "little":
+ calc_defaultvalue += oldio._defaultvalue
+ else:
+ calc_defaultvalue = \
+ oldio._defaultvalue + calc_defaultvalue
# ios aus listen entfernen
- delattr(self, oldio.name)
+ delattr(self, oldio._name)
+
+ if io._defaultvalue is None:
+ if io._bitaddress < 0:
+ io._defaultvalue = calc_defaultvalue
+ else:
+ io._defaultvalue = bool(io._parentio_defaultvalue[
+ io._parentio_address - io.address
+ ] & (1 << io._bitaddress))
def _private_register_new_io_object(self, new_io):
"""Registriert neues IO Objekt unabhaenging von __setattr__.
@param new_io Neues IO Objekt"""
if issubclass(type(new_io), IOBase):
- if hasattr(self, new_io.name):
+ if hasattr(self, new_io._name):
raise AttributeError(
"attribute {} already exists - can not set io".format(
- new_io.name
+ new_io._name
)
)
if type(new_io) is StructIO:
self.__private_replace_oldio_with_newio(new_io)
- object.__setattr__(self, new_io.name, new_io)
+ object.__setattr__(self, new_io._name, new_io)
# Bytedict für Adresszugriff anpassen
if new_io._bitaddress < 0:
@@ -251,19 +278,20 @@ class IOBase(object):
self._defaultvalue = int(valuelist[1]).to_bytes(
self._length, byteorder=self._byteorder
)
- else:
+ elif valuelist[1] is None and type(self) == StructIO:
+ self._defaultvalue = None
+ elif type(valuelist[1]) == bytes:
# Defaultvalue direkt von bytes übernehmen
- if type(valuelist[1]) == bytes:
- if len(valuelist[1]) != self._length:
- raise ValueError(
- "given bytes for default value must have a length "
- "of {} but {} was given"
- "".format(self._length, len(valuelist[1]))
- )
- else:
- self._defaultvalue = valuelist[1]
+ if len(valuelist[1]) == self._length:
+ self._defaultvalue = valuelist[1]
else:
- self._defaultvalue = bytes(self._length)
+ raise ValueError(
+ "given bytes for default value must have a length "
+ "of {} but {} was given"
+ "".format(self._length, len(valuelist[1]))
+ )
+ else:
+ self._defaultvalue = bytes(self._length)
else:
# Höhere Bits als 7 auf nächste Bytes umbrechen
@@ -271,7 +299,8 @@ class IOBase(object):
self._slc_address = slice(
int_startaddress, int_startaddress + 1
)
- self._defaultvalue = bool(int(valuelist[1]))
+ self._defaultvalue = None if valuelist[1] is None \
+ else bool(int(valuelist[1]))
def __bool__(self):
"""-Wert der Klasse.
@@ -285,6 +314,11 @@ class IOBase(object):
else:
return bool(self._parentdevice._ba_devdata[self._slc_address])
+ def __len__(self):
+ """Gibt die Bytelaenge des IO zurueck.
+ @return Bytelaenge des IO - 0 bei BITs"""
+ return 0 if self._bitaddress > 0 else self._length
+
def __str__(self):
"""-Wert der Klasse.
@return Namen des IOs"""
@@ -293,7 +327,7 @@ class IOBase(object):
def _get_address(self):
"""Gibt die absolute Byteadresse im Prozessabbild zurueck.
@return Absolute Byteadresse"""
- return self._parentdevice.offset + self._slc_address.start
+ return self._parentdevice._offset + self._slc_address.start
def _get_byteorder(self):
"""Gibt konfigurierte Byteorder zurueck.
@@ -305,16 +339,6 @@ class IOBase(object):
@return io.Type"""
return self._iotype
- def _get_length(self):
- """Gibt die Bytelaenge des IO zurueck.
- @return Bytelaenge des IO"""
- return self._length
-
- def _get_name(self):
- """Gibt den Namen des IOs zurueck.
- @return IO Name"""
- return self._name
-
def get_defaultvalue(self):
"""Gibt die Defaultvalue von piCtory zurueck.
@return Defaultvalue als oder """
@@ -404,6 +428,10 @@ class IOBase(object):
"this function can be used for ios on gatway or virtual "
"devices only"
)
+ if type(self) == StructIO:
+ raise RuntimeError(
+ "this io is already a replaced one"
+ )
# StructIO erzeugen
io_new = StructIO(
@@ -555,7 +583,7 @@ class IOBase(object):
raise RuntimeError(
"autorefresh is not activated for device '{}|{}' - there "
"will never be new data".format(
- self._parentdevice.position, self._parentdevice.name
+ self._parentdevice._position, self._parentdevice._name
)
)
@@ -612,8 +640,8 @@ class IOBase(object):
address = property(_get_address)
byteorder = property(_get_byteorder)
defaultvalue = property(get_defaultvalue)
- length = property(_get_length)
- name = property(_get_name)
+ length = property(__len__)
+ name = property(__str__)
type = property(_get_iotype)
value = property(get_value, set_value)
@@ -649,8 +677,9 @@ class IntIO(IOBase):
@param value 'little' or 'big'"""
if not (value == "little" or value == "big"):
raise ValueError("byteorder must be 'little' or 'big'")
- self._byteorder = value
- self._defaultvalue = self._defaultvalue[::-1]
+ if self._byteorder != value:
+ self._byteorder = value
+ self._defaultvalue = self._defaultvalue[::-1]
def _set_signed(self, value):
"""Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll.
@@ -713,41 +742,51 @@ class StructIO(IOBase):
@param name Name des neuen IO
@param frm struct formatierung (1 Zeichen)
@param kwargs Weitere Parameter:
- - bmk: Bezeichnung fuer Output
+ - bmk: Bezeichnung fuer IO
- bit: Registriert IO als am angegebenen Bit im Byte
- - byteorder: Byteorder fuer den Input, Standardwert=little
- - defaultvalue: Standardwert fuer Output, Standard ist 0
+ - byteorder: Byteorder fuer IO, Standardwert vom ersetzter IO
+ - defaultvalue: Standardwert fuer IO, Standard vom ersetzter IO
"""
if len(frm) == 1:
# Byteorder prüfen und übernehmen
- byteorder = kwargs.get("byteorder", "little")
+ byteorder = kwargs.get("byteorder", parentio._byteorder)
if not (byteorder == "little" or byteorder == "big"):
raise ValueError("byteorder must be 'little' or 'big'")
bofrm = "<" if byteorder == "little" else ">"
- bitaddress = "" if frm != "?" else str(kwargs.get("bit", 0))
- if bitaddress == "" or (0 <= int(bitaddress) < 8):
-
- bitlength = "1" if bitaddress.isdigit() else \
- struct.calcsize(bofrm + frm) * 8
-
- # [name,default,anzbits,adressbyte,export,adressid,bmk,bitaddress]
- valuelist = [
- name,
- kwargs.get("defaultvalue", 0),
- bitlength,
- parentio._slc_address.start,
- False,
- str(parentio._slc_address.start).rjust(4, "0"),
- kwargs.get("bmk", ""),
- bitaddress
- ]
+ if frm == "?":
+ bitaddress = kwargs.get("bit", 0)
+ max_bits = parentio._length * 8
+ if not (0 <= bitaddress < max_bits):
+ raise AttributeError(
+ "bitaddress must be a value between 0 and {}"
+ "".format(max_bits - 1)
+ )
+ bitlength = 1
+ # Bitweise Ersetzung erfordert diese Informationen zusätzlich
+ if parentio._byteorder == byteorder:
+ self._parentio_defaultvalue = parentio._defaultvalue
+ else:
+ self._parentio_defaultvalue = parentio._defaultvalue[::-1]
+ self._parentio_address = parentio.address
+ self._parentio_length = parentio._length
else:
- raise AttributeError(
- "bitaddress must be a value between 0 and 7"
- )
+ bitaddress = ""
+ bitlength = struct.calcsize(bofrm + frm) * 8
+
+ # [name,default,anzbits,adressbyte,export,adressid,bmk,bitaddress]
+ valuelist = [
+ name,
+ kwargs.get("defaultvalue", None),
+ bitlength,
+ parentio._slc_address.start,
+ False,
+ str(parentio._slc_address.start).rjust(4, "0"),
+ kwargs.get("bmk", ""),
+ bitaddress
+ ]
else:
raise AttributeError("parameter frm has to be a single sign")
diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py
index cd751c7..c904153 100644
--- a/revpimodio2/modio.py
+++ b/revpimodio2/modio.py
@@ -177,17 +177,17 @@ class RevPiModIO(object):
if dev_new is not None:
# Offset prüfen, muss mit Länge übereinstimmen
- if self._length < dev_new.offset:
- self._length = dev_new.offset
+ if self._length < dev_new._offset:
+ self._length = dev_new._offset
self._length += dev_new._length
# Auf doppelte Namen prüfen, da piCtory dies zulässt
- if hasattr(self.device, dev_new.name):
- err_names.append(dev_new.name)
+ if hasattr(self.device, dev_new._name):
+ err_names.append(dev_new._name)
# DeviceList für direkten Zugriff aufbauen
- setattr(self.device, dev_new.name, dev_new)
+ setattr(self.device, dev_new._name, dev_new)
# Namenszugriff zerstören, wenn doppelte Namen vorhanden sind
for errdev in err_names:
@@ -561,13 +561,13 @@ class RevPiModIO(object):
or regfunc[1] == RISING and boolor \
or regfunc[1] == FALLING and not boolor:
lst_fire.append(
- (regfunc, io_event.name, io_event.value)
+ (regfunc, io_event._name, io_event.value)
)
else:
for regfunc in dev._dict_events[io_event]:
lst_fire.append(
- (regfunc, io_event.name, io_event.value)
+ (regfunc, io_event._name, io_event.value)
)
# Nach Verarbeitung aller IOs die Bytes kopieren
@@ -619,7 +619,7 @@ class RevPiModIO(object):
if dev._selfupdate:
raise RuntimeError(
"can not read process image, while device '{}|{}'"
- "is in autorefresh mode".format(dev.position, dev.name)
+ "is in autorefresh mode".format(dev._position, dev._name)
)
mylist = [dev]
@@ -694,7 +694,7 @@ class RevPiModIO(object):
if dev._selfupdate:
raise RuntimeError(
"can not sync process image, while device '{}|{}'"
- "is in autorefresh mode".format(dev.position, dev.name)
+ "is in autorefresh mode".format(dev._position, dev._name)
)
mylist = [dev]
@@ -737,7 +737,7 @@ class RevPiModIO(object):
if dev._selfupdate:
raise RuntimeError(
"can not write process image, while device '{}|{}'"
- "is in autorefresh mode".format(dev.position, dev.name)
+ "is in autorefresh mode".format(dev._position, dev._name)
)
mylist = [dev]