Closed nikyred1978 closed 1 year ago
Documentation says:
The Datatype STRING defines a string of maximal 254 characters. The field reserved for a standard string is 256 Bytes. This space is required in order to save 254 characters and a string-head of 2 bytes. The string-head contains the maximal and the actual length of the string. In a string all characters of the ASCII-Code can be used. A string can even contain special characters like control keys and non printable characters.
The first two bytes are consumed by the header. To avoid this, you can use helper functions from the Snap7 library: snap7.util.get_string
and snap7.util.set_string
, or you can write your own class to handle this data type, something like this:
import struct
class S7String:
def __init__(self, value: str, max_length: int = 254) -> None:
self.value = value
self.max_length = max_length
@classmethod
def from_buffer(cls, buffer: bytes) -> str:
max_length, actual_length = struct.unpack("!BB", buffer[:2])
value = struct.unpack_from(f"{actual_length}s", buffer, 2)[0].decode()
return cls(value=value, max_length=max_length)
def to_buffer(self) -> bytearray:
value = self.value.encode()
actual_length = len(self.value)
rest = (self.max_length - actual_length) * b"\x00"
return struct.pack(f"BB{actual_length}s{len(rest)}s", self.max_length, actual_length, value, rest)
data_str = "001;+293.50;+58.00;+150.00;+000.01;+003.14;+000.01;08;080;01;"
s7_str = S7String(value=data_str, max_length=65)
client = snap7.client.Client()
client.connect('128.0.0.1', 0, 1)
client.db_write(db_number=34, start=0, data=s7_str.to_buffer())
buffer_rcv = client.db_read(db_number=34, start=0, size=65)
str_from_plc = S7String.from_buffer(buffer_rcv).value
assert data_str == str_from_plc
client.disconnect()
result:
Fantastic! Thanks a lot, I've tried them all
I have a problem, I have to write this string:('001;+293.50;+58.00;+150.00;+000.01;+003.14;+000.01;08;080;01;') on a DB32 in offset 0 format STRING[65], but when I run the code it transfers me this string:('1;+293.50;+58.00;+150.00;+000.01;+003.14;+000.01;' ), then it removes the first 2 zeros and also removes the last part of the string .
This is code, below:
`import snap7 from snap7.util import * import time
plc = snap7.client.Client()
try: plc.connect('128.0.0.1', 0, 1) except snap7.snap7exceptions.Snap7Exception as e: print("Error PLC:", e) exit()
data_str = '001;+293.50;+58.00;+150.00;+000.01;+003.14;+000.01;08;080;01;'
try: plc.db_write(34, 0, data_str) except snap7.snap7exceptions.Snap7Exception as e:
print('Error DB32:', e)
plc.disconnect()
`