Skip to content

Commit 0333e45

Browse files
gijzelaerrclaude
andauthored
Fix db_get/db_fill failing on S7-1200 PLCs with incorrect MC7Size (#608)
Some PLCs (e.g. S7-1200) report MC7Size as the load memory allocation (1024) rather than the actual data area size (e.g. 37 bytes) in block info responses. This caused db_get() to attempt reading more bytes than exist, resulting in "No data in response" errors. Wrap the auto-sized read/write in db_get and db_fill with error handling that provides a clear message suggesting the user pass the size parameter explicitly. Also update the e2e test to skip gracefully on affected PLCs. Fixes #569 (comment by @razour08) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0bfc883 commit 0333e45

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

snap7/client.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,9 @@ def db_get(self, db_number: int, size: int = 0) -> bytearray:
269269
Get entire DB.
270270
271271
Uses get_block_info() to determine the DB size automatically.
272-
If the PLC does not support get_block_info(), pass the size
273-
parameter explicitly.
272+
If the PLC does not support get_block_info() or reports an
273+
incorrect size (common on S7-1200/1500), pass the size parameter
274+
explicitly.
274275
275276
Args:
276277
db_number: DB number to read
@@ -283,15 +284,23 @@ def db_get(self, db_number: int, size: int = 0) -> bytearray:
283284
if size <= 0:
284285
block_info = self.get_block_info(Block.DB, db_number)
285286
size = block_info.MC7Size if block_info.MC7Size > 0 else 65536
286-
return self.db_read(db_number, 0, size)
287+
try:
288+
return self.db_read(db_number, 0, size)
289+
except S7Error:
290+
raise S7Error(
291+
f"db_get failed for DB{db_number} with auto-detected size {size}. "
292+
f"Some PLCs (e.g. S7-1200) report incorrect MC7Size in block info. "
293+
f"Try passing the actual DB size explicitly: client.db_get({db_number}, size=<actual_size>)"
294+
)
287295

288296
def db_fill(self, db_number: int, filler: int, size: int = 0) -> int:
289297
"""
290298
Fill a DB with a filler byte.
291299
292300
Uses get_block_info() to determine the DB size automatically.
293-
If the PLC does not support get_block_info(), pass the size
294-
parameter explicitly.
301+
If the PLC does not support get_block_info() or reports an
302+
incorrect size (common on S7-1200/1500), pass the size parameter
303+
explicitly.
295304
296305
Args:
297306
db_number: DB number to fill
@@ -306,7 +315,14 @@ def db_fill(self, db_number: int, filler: int, size: int = 0) -> int:
306315
block_info = self.get_block_info(Block.DB, db_number)
307316
size = block_info.MC7Size if block_info.MC7Size > 0 else 65536
308317
data = bytearray([filler] * size)
309-
return self.db_write(db_number, 0, data)
318+
try:
319+
return self.db_write(db_number, 0, data)
320+
except S7Error:
321+
raise S7Error(
322+
f"db_fill failed for DB{db_number} with auto-detected size {size}. "
323+
f"Some PLCs (e.g. S7-1200) report incorrect MC7Size in block info. "
324+
f"Try passing the actual DB size explicitly: client.db_fill({db_number}, {filler}, size=<actual_size>)"
325+
)
310326

311327
def read_area(self, area: Area, db_number: int, start: int, size: int, word_len: Optional[WordLen] = None) -> bytearray:
312328
"""

tests/test_client_e2e.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,9 @@ def test_db_get(self) -> None:
492492
try:
493493
data = self.client.db_get(DB_READ_ONLY)
494494
except Exception as e:
495-
if "does not exist" in str(e).lower() or "block info failed" in str(e).lower():
496-
pytest.skip(f"get_block_info not supported on this PLC: {e}")
495+
err_msg = str(e).lower()
496+
if "does not exist" in err_msg or "block info failed" in err_msg or "auto-detected size" in err_msg:
497+
pytest.skip(f"db_get with auto-detect not supported on this PLC: {e}")
497498
raise
498499
self.assertIsInstance(data, bytearray)
499500
self.assertGreater(len(data), 0)

0 commit comments

Comments
 (0)