{ "_comment": "DL205.json — DirectLOGIC DL205/DL260 quirk simulator. Models docs/v2/dl205.md as concrete register values. NOTE: pymodbus rejects unknown keys at device-list / setup level; explanatory comments live at top-level _comment + in README + git. Inline _quirk keys WITHIN individual register entries are accepted by pymodbus 3.13.0 (it only validates addr / value / action / parameters per entry). Each quirky uint16 is a pre-computed raw 16-bit value; pymodbus serves it verbatim. shared blocks=true matches DL series memory model. write list mirrors each seeded block — pymodbus rejects sweeping write ranges that include undefined cells.", "server_list": { "srv": { "comm": "tcp", "host": "0.0.0.0", "port": 5020, "framer": "socket", "device_id": 1 } }, "device_list": { "dev": { "setup": { "co size": 16384, "di size": 8192, "hr size": 16384, "ir size": 1024, "shared blocks": true, "type exception": false, "defaults": { "value": {"bits": 0, "uint16": 0, "uint32": 0, "float32": 0.0, "string": " "}, "action": {"bits": null, "uint16": null, "uint32": null, "float32": null, "string": null} } }, "invalid": [], "write": [ [0, 0], [200, 209], [1024, 1024], [1040, 1042], [1056, 1057], [1072, 1072], [1280, 1282], [1343, 1343], [1407, 1407], [1, 1], [128, 128], [192, 192], [250, 250], [8448, 8448] ], "uint16": [ {"_quirk": "V0 marker. HR[0]=0xCAFE proves register 0 is valid on DL205/DL260 (rejects-register-0 was a DL05/DL06 relative-mode artefact). 0xCAFE = 51966.", "addr": 0, "value": 51966}, {"_quirk": "Scratch HR range 200..209 — mirrors the standard.json scratch range so the smoke test (DL205Profile.SmokeHoldingRegister=200) round-trips identically against either profile.", "addr": 200, "value": 0}, {"addr": 201, "value": 0}, {"addr": 202, "value": 0}, {"addr": 203, "value": 0}, {"addr": 204, "value": 0}, {"addr": 205, "value": 0}, {"addr": 206, "value": 0}, {"addr": 207, "value": 0}, {"addr": 208, "value": 0}, {"addr": 209, "value": 0}, {"_quirk": "V2000 marker. V2000 octal = decimal 1024 = PDU 0x0400. Marker 0x2000 = 8192.", "addr": 1024, "value": 8192}, {"_quirk": "V40400 marker. V40400 octal = decimal 8448 = PDU 0x2100 (NOT register 0). Marker 0x4040 = 16448.", "addr": 8448, "value": 16448}, {"_quirk": "String 'Hello' first char in LOW byte. HR[0x410] = 'H'(0x48) lo + 'e'(0x65) hi = 0x6548 = 25928.", "addr": 1040, "value": 25928}, {"_quirk": "String 'Hello' second char-pair: 'l'(0x6C) lo + 'l'(0x6C) hi = 0x6C6C = 27756.", "addr": 1041, "value": 27756}, {"_quirk": "String 'Hello' third char-pair: 'o'(0x6F) lo + null(0x00) hi = 0x006F = 111.", "addr": 1042, "value": 111}, {"_quirk": "Float32 1.5f in CDAB word order. IEEE 754 1.5 = 0x3FC00000. CDAB = low word first: HR[0x420]=0x0000, HR[0x421]=0x3FC0=16320.", "addr": 1056, "value": 0}, {"_quirk": "Float32 1.5f CDAB high word.", "addr": 1057, "value": 16320}, {"_quirk": "BCD register. Decimal 1234 stored as BCD nibbles 0x1234 = 4660. NOT binary 1234 (= 0x04D2).", "addr": 1072, "value": 4660}, {"_quirk": "FC03 cap test marker — first cell of a 128-register span the FC03 cap test reads. Other cells in the span aren't seeded explicitly, so reads of HR[1283..1342] / 1344..1406 return the default 0; the seeded markers at 1280, 1281, 1282, 1343, 1407 prove the span boundaries.", "addr": 1280, "value": 0}, {"addr": 1281, "value": 1}, {"addr": 1282, "value": 2}, {"addr": 1343, "value": 63}, {"addr": 1407, "value": 127} ], "bits": [ {"_quirk": "X-input bank marker cell. X0 -> DI 0 conflicts with uint16 V0 at cell 0, so this marker covers X20 octal (= decimal 16 = DI 16 = cell 1 bit 0). X20=ON, X23 octal (DI 19 = cell 1 bit 3)=ON -> cell 1 value = 0b00001001 = 9.", "addr": 1, "value": 9}, {"_quirk": "Y-output bank marker cell. pymodbus's simulator maps Modbus FC01/02/05 bit-addresses to cell index = bit_addr / 16; so Modbus coil 2048 lives at cell 128 bit 0. Y0=ON (bit 0), Y1=OFF (bit 1), Y2=ON (bit 2) -> value=0b00000101=5 proves DL260 mapping Y0 -> coil 2048.", "addr": 128, "value": 5}, {"_quirk": "C-relay bank marker cell. Modbus coil 3072 -> cell 192 bit 0. C0=ON (bit 0), C1=OFF (bit 1), C2=ON (bit 2) -> value=5 proves DL260 mapping C0 -> coil 3072.", "addr": 192, "value": 5}, {"_quirk": "Scratch cell for coil 4000..4015 write round-trip tests. Cell 250 holds Modbus coils 4000-4015; all bits start at 0 and tests set specific bits via FC05.", "addr": 250, "value": 0} ], "uint32": [], "float32": [], "string": [], "repeat": [] } } }