|
37 | 37 | ) |
38 | 38 | from s7.protocol import PROTOCOL_ID, DataType, Opcode, FunctionCode, Ids |
39 | 39 | from s7.vlq import encode_uint32_vlq, encode_int32_vlq, encode_uint64_vlq, encode_int64_vlq |
| 40 | +from s7._s7commplus_client import _build_symbolic_read_payload, _build_symbolic_write_payload |
40 | 41 |
|
41 | 42 |
|
42 | 43 | class TestFrameHeader: |
@@ -357,6 +358,35 @@ def test_custom_symbol_crc(self) -> None: |
357 | 358 | assert field_count == 4 |
358 | 359 |
|
359 | 360 |
|
| 361 | +class TestControllerAreaSubArea: |
| 362 | + """Regression: I/Q/M symbolic access must use ControllerArea_ValueActual (3736). |
| 363 | +
|
| 364 | + The earlier value 2551 was DB_InitialChanged, not a controller-area sub-area, |
| 365 | + so the PLC rejected every I/Q/M symbolic read/write. |
| 366 | + """ |
| 367 | + |
| 368 | + # IArea/QArea/MArea native-object RIDs (all < 0x8A0E0000 → controller-area path) |
| 369 | + IAREA_RID = 0x50 |
| 370 | + |
| 371 | + def test_constant_value(self) -> None: |
| 372 | + assert Ids.CONTROLLER_AREA_VALUE_ACTUAL == 3736 |
| 373 | + assert Ids.CONTROLLER_AREA_VALUE_ACTUAL != Ids.DB_VALUE_ACTUAL |
| 374 | + |
| 375 | + def test_read_payload_uses_controller_sub_area(self) -> None: |
| 376 | + payload = _build_symbolic_read_payload(self.IAREA_RID, lids=[0x124]) |
| 377 | + assert encode_uint32_vlq(3736) in payload |
| 378 | + assert encode_uint32_vlq(2551) not in payload |
| 379 | + |
| 380 | + def test_write_payload_uses_controller_sub_area(self) -> None: |
| 381 | + payload = _build_symbolic_write_payload(self.IAREA_RID, lids=[0x124], data=b"\x01") |
| 382 | + assert encode_uint32_vlq(3736) in payload |
| 383 | + assert encode_uint32_vlq(2551) not in payload |
| 384 | + |
| 385 | + def test_db_area_still_uses_db_sub_area(self) -> None: |
| 386 | + payload = _build_symbolic_read_payload(0x8A0E012C, lids=[0x4E, 0x69]) |
| 387 | + assert encode_uint32_vlq(Ids.DB_VALUE_ACTUAL) in payload |
| 388 | + |
| 389 | + |
360 | 390 | class TestPValueBlob: |
361 | 391 | def test_basic_blob(self) -> None: |
362 | 392 | data = bytes([1, 2, 3, 4]) |
|
0 commit comments