replace_io kann Bits >7 bei längeren Datentypen festlegen

Klassenattribute für Device angelegt
Intern nur auf interne _Variablen zugreifen
StructIO berechnet _defaultvalue aus gelöschten IOs
This commit is contained in:
2017-08-27 14:46:28 +02:00
parent 4e9abf794b
commit dcc8c22428
6 changed files with 199 additions and 122 deletions

View File

@@ -358,7 +358,7 @@ object
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3> Class Attributes</h3>
<table> <table>
<tr><td>None</td></tr> <tr><td>length</td></tr><tr><td>name</td></tr><tr><td>offset</td></tr><tr><td>position</td></tr><tr><td>producttype</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3> Class Methods</h3>
@@ -396,6 +396,12 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Device._devconfigure">_devconfigure</a></td> <td><a style="color:#0000FF" href="#Device._devconfigure">_devconfigure</a></td>
<td>Funktion zum ueberschreiben von abgeleiteten Klassen.</td> <td>Funktion zum ueberschreiben von abgeleiteten Klassen.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Device._get_offset">_get_offset</a></td>
<td>Gibt den Deviceoffset im Prozessabbild zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device._get_producttype">_get_producttype</a></td>
<td>Gibt den Produkttypen des device zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.autorefresh">autorefresh</a></td> <td><a style="color:#0000FF" href="#Device.autorefresh">autorefresh</a></td>
<td>Registriert dieses Device fuer die automatische Synchronisierung.</td> <td>Registriert dieses Device fuer die automatische Synchronisierung.</td>
</tr><tr> </tr><tr>
@@ -542,7 +548,29 @@ Device._devconfigure</h3>
<b>_devconfigure</b>(<i></i>) <b>_devconfigure</b>(<i></i>)
<p> <p>
Funktion zum ueberschreiben von abgeleiteten Klassen. Funktion zum ueberschreiben von abgeleiteten Klassen.
</p><a NAME="Device.autorefresh" ID="Device.autorefresh"></a> </p><a NAME="Device._get_offset" ID="Device._get_offset"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device._get_offset</h3>
<b>_get_offset</b>(<i></i>)
<p>
Gibt den Deviceoffset im Prozessabbild zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Deviceoffset
</dd>
</dl><a NAME="Device._get_producttype" ID="Device._get_producttype"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device._get_producttype</h3>
<b>_get_producttype</b>(<i></i>)
<p>
Gibt den Produkttypen des device zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Deviceprodukttyp
</dd>
</dl><a NAME="Device.autorefresh" ID="Device.autorefresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.autorefresh</h3> Device.autorefresh</h3>
<b>autorefresh</b>(<i>activate=True</i>) <b>autorefresh</b>(<i>activate=True</i>)

View File

@@ -141,6 +141,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IOBase.__bool__">__bool__</a></td> <td><a style="color:#0000FF" href="#IOBase.__bool__">__bool__</a></td>
<td><class 'bool'>-Wert der Klasse.</td> <td><class 'bool'>-Wert der Klasse.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#IOBase.__len__">__len__</a></td>
<td>Gibt die Bytelaenge des IO zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.__str__">__str__</a></td> <td><a style="color:#0000FF" href="#IOBase.__str__">__str__</a></td>
<td><class 'str'>-Wert der Klasse.</td> <td><class 'str'>-Wert der Klasse.</td>
</tr><tr> </tr><tr>
@@ -153,12 +156,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IOBase._get_iotype">_get_iotype</a></td> <td><a style="color:#0000FF" href="#IOBase._get_iotype">_get_iotype</a></td>
<td>Gibt io.Type zurueck.</td> <td>Gibt io.Type zurueck.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#IOBase._get_length">_get_length</a></td>
<td>Gibt die Bytelaenge des IO zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase._get_name">_get_name</a></td>
<td>Gibt den Namen des IOs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.get_defaultvalue">get_defaultvalue</a></td> <td><a style="color:#0000FF" href="#IOBase.get_defaultvalue">get_defaultvalue</a></td>
<td>Gibt die Defaultvalue von piCtory zurueck.</td> <td>Gibt die Defaultvalue von piCtory zurueck.</td>
</tr><tr> </tr><tr>
@@ -220,6 +217,17 @@ IOBase.__bool__</h3>
<dd> <dd>
<class 'bool'> Nur False wenn False oder 0 sonst True <class 'bool'> Nur False wenn False oder 0 sonst True
</dd> </dd>
</dl><a NAME="IOBase.__len__" ID="IOBase.__len__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.__len__</h3>
<b>__len__</b>(<i></i>)
<p>
Gibt die Bytelaenge des IO zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Bytelaenge des IO - 0 bei BITs
</dd>
</dl><a NAME="IOBase.__str__" ID="IOBase.__str__"></a> </dl><a NAME="IOBase.__str__" ID="IOBase.__str__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.__str__</h3> IOBase.__str__</h3>
@@ -264,28 +272,6 @@ Gibt io.Type zurueck.
<dd> <dd>
<class 'int'> io.Type <class 'int'> io.Type
</dd> </dd>
</dl><a NAME="IOBase._get_length" ID="IOBase._get_length"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase._get_length</h3>
<b>_get_length</b>(<i></i>)
<p>
Gibt die Bytelaenge des IO zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Bytelaenge des IO
</dd>
</dl><a NAME="IOBase._get_name" ID="IOBase._get_name"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase._get_name</h3>
<b>_get_name</b>(<i></i>)
<p>
Gibt den Namen des IOs zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
IO Name
</dd>
</dl><a NAME="IOBase.get_defaultvalue" ID="IOBase.get_defaultvalue"></a> </dl><a NAME="IOBase.get_defaultvalue" ID="IOBase.get_defaultvalue"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.get_defaultvalue</h3> IOBase.get_defaultvalue</h3>
@@ -832,10 +818,10 @@ struct formatierung (1 Zeichen)
</dd><dt><i>kwargs</i></dt> </dd><dt><i>kwargs</i></dt>
<dd> <dd>
Weitere Parameter: Weitere Parameter:
- bmk: Bezeichnung fuer Output - bmk: Bezeichnung fuer IO
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte - bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
- byteorder: Byteorder fuer den Input, Standardwert=little - byteorder: Byteorder fuer IO, Standardwert vom ersetzter IO
- defaultvalue: Standardwert fuer Output, Standard ist 0 - defaultvalue: Standardwert fuer IO, Standard vom ersetzter IO
</dd> </dd>
</dl><a NAME="StructIO._get_frm" ID="StructIO._get_frm"></a> </dl><a NAME="StructIO._get_frm" ID="StructIO._get_frm"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">

View File

@@ -28,11 +28,18 @@ revpimodio2.device.Core.temperatur?4()
revpimodio2.device.Core.unconfdevice?4() revpimodio2.device.Core.unconfdevice?4()
revpimodio2.device.Device._buildio?5(dict_io, iotype) revpimodio2.device.Device._buildio?5(dict_io, iotype)
revpimodio2.device.Device._devconfigure?5() 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.autorefresh?4(activate=True)
revpimodio2.device.Device.get_allios?4() revpimodio2.device.Device.get_allios?4()
revpimodio2.device.Device.get_inputs?4() revpimodio2.device.Device.get_inputs?4()
revpimodio2.device.Device.get_memmories?4() revpimodio2.device.Device.get_memmories?4()
revpimodio2.device.Device.get_outputs?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.readprocimg?4()
revpimodio2.device.Device.setdefaultvalues?4() revpimodio2.device.Device.setdefaultvalues?4()
revpimodio2.device.Device.syncoutputs?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_address?5()
revpimodio2.io.IOBase._get_byteorder?5() revpimodio2.io.IOBase._get_byteorder?5()
revpimodio2.io.IOBase._get_iotype?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.address?7
revpimodio2.io.IOBase.byteorder?7 revpimodio2.io.IOBase.byteorder?7
revpimodio2.io.IOBase.defaultvalue?7 revpimodio2.io.IOBase.defaultvalue?7

View File

@@ -37,15 +37,15 @@ class DeviceList(object):
# Reinigungsjobs # Reinigungsjobs
dev_del.autorefresh(False) dev_del.autorefresh(False)
for io in dev_del: 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) object.__delattr__(self, key)
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"""
self.__delattr__(self[key].name) self.__delattr__(self[key]._name)
def __getitem__(self, key): def __getitem__(self, key):
"""Gibt angegebenes Device zurueck. """Gibt angegebenes Device zurueck.
@@ -75,7 +75,7 @@ class DeviceList(object):
@param value Attributobjekt""" @param value Attributobjekt"""
if issubclass(type(value), Device): if issubclass(type(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":
object.__setattr__(self, key, value) object.__setattr__(self, key, value)
@@ -106,10 +106,10 @@ class Device(object):
self._selfupdate = False self._selfupdate = False
# Wertzuweisung aus dict_device # Wertzuweisung aus dict_device
self.name = dict_device.pop("name") self._name = dict_device.pop("name")
self.offset = int(dict_device.pop("offset")) self._offset = int(dict_device.pop("offset"))
self.position = int(dict_device.pop("position")) self._position = int(dict_device.pop("position"))
self.producttype = int(dict_device.pop("productType")) self._producttype = int(dict_device.pop("productType"))
# IOM-Objekte erstellen und Adressen in SLCs speichern # IOM-Objekte erstellen und Adressen in SLCs speichern
if simulator: if simulator:
@@ -127,15 +127,18 @@ class Device(object):
) )
# SLCs mit offset berechnen # 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_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_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_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 # Neues bytearray und Kopie für mainloop anlegen
@@ -172,7 +175,7 @@ class Device(object):
def __int__(self): def __int__(self):
"""Gibt die Positon im RevPi Bus zurueck. """Gibt die Positon im RevPi Bus zurueck.
@return Positionsnummer""" @return Positionsnummer"""
return self.position return self._position
def __iter__(self): def __iter__(self):
"""Gibt Iterator aller IOs zurueck. """Gibt Iterator aller IOs zurueck.
@@ -189,7 +192,7 @@ class Device(object):
def __str__(self): def __str__(self):
"""Gibt den Namen des Devices zurueck. """Gibt den Namen des Devices zurueck.
@return Devicename""" @return Devicename"""
return self.name return self._name
def _buildio(self, dict_io, iotype): def _buildio(self, dict_io, iotype):
"""Erstellt aus der piCtory-Liste die IOs fuer dieses Device. """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)): for key in sorted(dict_io, key=lambda x: int(x)):
# Neuen IO anlegen # 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 # Bei Bitwerten oder Core RevPiIOBase verwenden
io_new = iomodule.IOBase( io_new = iomodule.IOBase(
self, dict_io[key], iotype, "little", False self, dict_io[key], iotype, "little", False
@@ -216,7 +219,7 @@ class Device(object):
self, dict_io[key], self, dict_io[key],
iotype, iotype,
"little", "little",
self.producttype == 103 self._producttype == 103
) )
# IO registrieren # IO registrieren
@@ -236,6 +239,16 @@ class Device(object):
"""Funktion zum ueberschreiben von abgeleiteten Klassen.""" """Funktion zum ueberschreiben von abgeleiteten Klassen."""
pass 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): def autorefresh(self, activate=True):
"""Registriert dieses Device fuer die automatische Synchronisierung. """Registriert dieses Device fuer die automatische Synchronisierung.
@param activate Default True fuegt Device zur Synchronisierung hinzu""" @param activate Default True fuegt Device zur Synchronisierung hinzu"""
@@ -336,6 +349,12 @@ class Device(object):
RevPiModIO.writeprocimg()""" RevPiModIO.writeprocimg()"""
self._modio.writeprocimg(self) self._modio.writeprocimg(self)
length = property(__len__)
name = property(__str__)
offset = property(_get_offset)
position = property(__int__)
producttype = property(_get_producttype)
class Core(Device): class Core(Device):
@@ -380,11 +399,11 @@ class Core(Device):
# Für RS485 errors defaults laden sollte procimg NULL sein # Für RS485 errors defaults laden sollte procimg NULL sein
if self._ioerrorlimit1 is not None: if self._ioerrorlimit1 is not None:
self.__lst_io[self._ioerrorlimit1].set_value( 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: if self._ioerrorlimit2 is not None:
self.__lst_io[self._ioerrorlimit2].set_value( self.__lst_io[self._ioerrorlimit2].set_value(
self.__lst_io[self._ioerrorlimit2].defaultvalue self.__lst_io[self._ioerrorlimit2]._defaultvalue
) )
# RS485 errors schreiben # RS485 errors schreiben
self._modio.writeprocimg(self) self._modio.writeprocimg(self)

View File

@@ -127,8 +127,19 @@ class IOList(object):
def __private_replace_oldio_with_newio(self, io): def __private_replace_oldio_with_newio(self, io):
"""Ersetzt bestehende IOs durch den neu Registrierten. """Ersetzt bestehende IOs durch den neu Registrierten.
@param io Neuer IO der eingefuegt werden soll""" @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]: for oldio in self.__dict_iobyte[i]:
if type(oldio) == StructIO: if type(oldio) == StructIO:
@@ -151,26 +162,42 @@ class IOList(object):
# IOs im Speicherbereich des neuen IO merken # IOs im Speicherbereich des neuen IO merken
if io._bitaddress >= 0: if io._bitaddress >= 0:
# ios für ref bei bitaddress speichern # 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 # 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): 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 issubclass(type(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(
new_io.name new_io._name
) )
) )
if type(new_io) is StructIO: if type(new_io) is StructIO:
self.__private_replace_oldio_with_newio(new_io) 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 # Bytedict für Adresszugriff anpassen
if new_io._bitaddress < 0: if new_io._bitaddress < 0:
@@ -251,19 +278,20 @@ class IOBase(object):
self._defaultvalue = int(valuelist[1]).to_bytes( self._defaultvalue = int(valuelist[1]).to_bytes(
self._length, byteorder=self._byteorder 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 # Defaultvalue direkt von bytes übernehmen
if type(valuelist[1]) == bytes: if len(valuelist[1]) == self._length:
if len(valuelist[1]) != self._length: self._defaultvalue = valuelist[1]
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]
else: 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: else:
# Höhere Bits als 7 auf nächste Bytes umbrechen # Höhere Bits als 7 auf nächste Bytes umbrechen
@@ -271,7 +299,8 @@ class IOBase(object):
self._slc_address = slice( self._slc_address = slice(
int_startaddress, int_startaddress + 1 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): def __bool__(self):
"""<class 'bool'>-Wert der Klasse. """<class 'bool'>-Wert der Klasse.
@@ -285,6 +314,11 @@ class IOBase(object):
else: else:
return bool(self._parentdevice._ba_devdata[self._slc_address]) 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): def __str__(self):
"""<class 'str'>-Wert der Klasse. """<class 'str'>-Wert der Klasse.
@return Namen des IOs""" @return Namen des IOs"""
@@ -293,7 +327,7 @@ class IOBase(object):
def _get_address(self): def _get_address(self):
"""Gibt die absolute Byteadresse im Prozessabbild zurueck. """Gibt die absolute Byteadresse im Prozessabbild zurueck.
@return Absolute Byteadresse""" @return Absolute Byteadresse"""
return self._parentdevice.offset + self._slc_address.start return self._parentdevice._offset + self._slc_address.start
def _get_byteorder(self): def _get_byteorder(self):
"""Gibt konfigurierte Byteorder zurueck. """Gibt konfigurierte Byteorder zurueck.
@@ -305,16 +339,6 @@ class IOBase(object):
@return <class 'int'> io.Type""" @return <class 'int'> io.Type"""
return self._iotype 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): def get_defaultvalue(self):
"""Gibt die Defaultvalue von piCtory zurueck. """Gibt die Defaultvalue von piCtory zurueck.
@return Defaultvalue als <class 'byte'> oder <class 'bool'>""" @return Defaultvalue als <class 'byte'> oder <class 'bool'>"""
@@ -404,6 +428,10 @@ class IOBase(object):
"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"
) )
if type(self) == StructIO:
raise RuntimeError(
"this io is already a replaced one"
)
# StructIO erzeugen # StructIO erzeugen
io_new = StructIO( io_new = StructIO(
@@ -555,7 +583,7 @@ class IOBase(object):
raise RuntimeError( raise RuntimeError(
"autorefresh is not activated for device '{}|{}' - there " "autorefresh is not activated for device '{}|{}' - there "
"will never be new data".format( "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) address = property(_get_address)
byteorder = property(_get_byteorder) byteorder = property(_get_byteorder)
defaultvalue = property(get_defaultvalue) defaultvalue = property(get_defaultvalue)
length = property(_get_length) length = property(__len__)
name = property(_get_name) name = property(__str__)
type = property(_get_iotype) type = property(_get_iotype)
value = property(get_value, set_value) value = property(get_value, set_value)
@@ -649,8 +677,9 @@ class IntIO(IOBase):
@param value <class 'str'> 'little' or 'big'""" @param value <class 'str'> 'little' or 'big'"""
if not (value == "little" or value == "big"): if not (value == "little" or value == "big"):
raise ValueError("byteorder must be 'little' or 'big'") raise ValueError("byteorder must be 'little' or 'big'")
self._byteorder = value if self._byteorder != value:
self._defaultvalue = self._defaultvalue[::-1] self._byteorder = value
self._defaultvalue = self._defaultvalue[::-1]
def _set_signed(self, value): def _set_signed(self, value):
"""Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll. """Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll.
@@ -713,41 +742,51 @@ class StructIO(IOBase):
@param name Name des neuen IO @param name Name des neuen IO
@param frm struct formatierung (1 Zeichen) @param frm struct formatierung (1 Zeichen)
@param kwargs Weitere Parameter: @param kwargs Weitere Parameter:
- bmk: Bezeichnung fuer Output - bmk: Bezeichnung fuer IO
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte - bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
- byteorder: Byteorder fuer den Input, Standardwert=little - byteorder: Byteorder fuer IO, Standardwert vom ersetzter IO
- defaultvalue: Standardwert fuer Output, Standard ist 0 - defaultvalue: Standardwert fuer IO, Standard vom ersetzter IO
""" """
if len(frm) == 1: if len(frm) == 1:
# Byteorder prüfen und übernehmen # Byteorder prüfen und übernehmen
byteorder = kwargs.get("byteorder", "little") byteorder = kwargs.get("byteorder", parentio._byteorder)
if not (byteorder == "little" or byteorder == "big"): if not (byteorder == "little" or byteorder == "big"):
raise ValueError("byteorder must be 'little' or 'big'") raise ValueError("byteorder must be 'little' or 'big'")
bofrm = "<" if byteorder == "little" else ">" bofrm = "<" if byteorder == "little" else ">"
bitaddress = "" if frm != "?" else str(kwargs.get("bit", 0)) if frm == "?":
if bitaddress == "" or (0 <= int(bitaddress) < 8): bitaddress = kwargs.get("bit", 0)
max_bits = parentio._length * 8
bitlength = "1" if bitaddress.isdigit() else \ if not (0 <= bitaddress < max_bits):
struct.calcsize(bofrm + frm) * 8 raise AttributeError(
"bitaddress must be a value between 0 and {}"
# [name,default,anzbits,adressbyte,export,adressid,bmk,bitaddress] "".format(max_bits - 1)
valuelist = [ )
name, bitlength = 1
kwargs.get("defaultvalue", 0),
bitlength,
parentio._slc_address.start,
False,
str(parentio._slc_address.start).rjust(4, "0"),
kwargs.get("bmk", ""),
bitaddress
]
# 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: else:
raise AttributeError( bitaddress = ""
"bitaddress must be a value between 0 and 7" 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: else:
raise AttributeError("parameter frm has to be a single sign") raise AttributeError("parameter frm has to be a single sign")

View File

@@ -177,17 +177,17 @@ class RevPiModIO(object):
if dev_new is not None: if dev_new is not None:
# Offset prüfen, muss mit Länge übereinstimmen # Offset prüfen, muss mit Länge übereinstimmen
if self._length < dev_new.offset: if self._length < dev_new._offset:
self._length = dev_new.offset self._length = dev_new._offset
self._length += dev_new._length self._length += dev_new._length
# Auf doppelte Namen prüfen, da piCtory dies zulässt # Auf doppelte Namen prüfen, da piCtory dies zulässt
if hasattr(self.device, dev_new.name): if hasattr(self.device, dev_new._name):
err_names.append(dev_new.name) err_names.append(dev_new._name)
# DeviceList für direkten Zugriff aufbauen # 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 # Namenszugriff zerstören, wenn doppelte Namen vorhanden sind
for errdev in err_names: for errdev in err_names:
@@ -561,13 +561,13 @@ class RevPiModIO(object):
or regfunc[1] == RISING and boolor \ or regfunc[1] == RISING and boolor \
or regfunc[1] == FALLING and not boolor: or regfunc[1] == FALLING and not boolor:
lst_fire.append( lst_fire.append(
(regfunc, io_event.name, io_event.value) (regfunc, io_event._name, io_event.value)
) )
else: else:
for regfunc in dev._dict_events[io_event]: for regfunc in dev._dict_events[io_event]:
lst_fire.append( lst_fire.append(
(regfunc, io_event.name, io_event.value) (regfunc, io_event._name, io_event.value)
) )
# Nach Verarbeitung aller IOs die Bytes kopieren # Nach Verarbeitung aller IOs die Bytes kopieren
@@ -619,7 +619,7 @@ class RevPiModIO(object):
if dev._selfupdate: if dev._selfupdate:
raise RuntimeError( raise RuntimeError(
"can not read process image, while device '{}|{}'" "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] mylist = [dev]
@@ -694,7 +694,7 @@ class RevPiModIO(object):
if dev._selfupdate: if dev._selfupdate:
raise RuntimeError( raise RuntimeError(
"can not sync process image, while device '{}|{}'" "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] mylist = [dev]
@@ -737,7 +737,7 @@ class RevPiModIO(object):
if dev._selfupdate: if dev._selfupdate:
raise RuntimeError( raise RuntimeError(
"can not write process image, while device '{}|{}'" "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] mylist = [dev]