Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions snap7/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,9 @@ def db_get(self, db_number: int, size: int = 0) -> bytearray:
Get entire DB.
Uses get_block_info() to determine the DB size automatically.
If the PLC does not support get_block_info(), pass the size
parameter explicitly.
If the PLC does not support get_block_info() or reports an
incorrect size (common on S7-1200/1500), pass the size parameter
explicitly.
Args:
db_number: DB number to read
Expand All @@ -283,15 +284,23 @@ def db_get(self, db_number: int, size: int = 0) -> bytearray:
if size <= 0:
block_info = self.get_block_info(Block.DB, db_number)
size = block_info.MC7Size if block_info.MC7Size > 0 else 65536
return self.db_read(db_number, 0, size)
try:
return self.db_read(db_number, 0, size)
except S7Error:
raise S7Error(
f"db_get failed for DB{db_number} with auto-detected size {size}. "
f"Some PLCs (e.g. S7-1200) report incorrect MC7Size in block info. "
f"Try passing the actual DB size explicitly: client.db_get({db_number}, size=<actual_size>)"
)

def db_fill(self, db_number: int, filler: int, size: int = 0) -> int:
"""
Fill a DB with a filler byte.
Uses get_block_info() to determine the DB size automatically.
If the PLC does not support get_block_info(), pass the size
parameter explicitly.
If the PLC does not support get_block_info() or reports an
incorrect size (common on S7-1200/1500), pass the size parameter
explicitly.
Args:
db_number: DB number to fill
Expand All @@ -306,7 +315,14 @@ def db_fill(self, db_number: int, filler: int, size: int = 0) -> int:
block_info = self.get_block_info(Block.DB, db_number)
size = block_info.MC7Size if block_info.MC7Size > 0 else 65536
data = bytearray([filler] * size)
return self.db_write(db_number, 0, data)
try:
return self.db_write(db_number, 0, data)
except S7Error:
raise S7Error(
f"db_fill failed for DB{db_number} with auto-detected size {size}. "
f"Some PLCs (e.g. S7-1200) report incorrect MC7Size in block info. "
f"Try passing the actual DB size explicitly: client.db_fill({db_number}, {filler}, size=<actual_size>)"
)

def read_area(self, area: Area, db_number: int, start: int, size: int, word_len: Optional[WordLen] = None) -> bytearray:
"""
Expand Down
5 changes: 3 additions & 2 deletions tests/test_client_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,9 @@ def test_db_get(self) -> None:
try:
data = self.client.db_get(DB_READ_ONLY)
except Exception as e:
if "does not exist" in str(e).lower() or "block info failed" in str(e).lower():
pytest.skip(f"get_block_info not supported on this PLC: {e}")
err_msg = str(e).lower()
if "does not exist" in err_msg or "block info failed" in err_msg or "auto-detected size" in err_msg:
pytest.skip(f"db_get with auto-detect not supported on this PLC: {e}")
raise
self.assertIsInstance(data, bytearray)
self.assertGreater(len(data), 0)
Expand Down