{ "_comment": "DL205.json — AutomationDirect DirectLOGIC DL205/DL260 quirk simulator. Models each behavior in docs/v2/dl205.md as concrete register values so DL205_ integration tests can assert against this profile WITHOUT a live PLC. Loaded by `pymodbus.simulator`. See ../README.md. Per-quirk address layout matches the table in dl205.md exactly. `shared blocks: true` matches DL series behavior — coils/HR overlay the same word address space (a Y-output is both a discrete bit AND part of a system V-memory register).", "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, 16383] ], "_comment_uint16": "Holding-register seeds. Every quirky value is a raw uint16 with the byte math worked out in dl205.md so the simulator serves it verbatim — pymodbus does NOT decode strings, BCD, or float-CDAB on its own; that's the driver's job.", "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": "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. Real DL205/DL260 FC03 caps at 128 registers (above spec's 125). HR[1280..1407] is 128 contiguous registers; rest of block defaults to 0.", "addr": 1280, "value": 0}, {"addr": 1281, "value": 1}, {"addr": 1282, "value": 2}, {"addr": 1343, "value": 63, "_marker": "FC03Block_mid"}, {"addr": 1407, "value": 127, "_marker": "FC03Block_last"} ], "_comment_bits": "Coils — Y outputs at 2048+, C relays at 3072+, scratch C at 4000-4007 for write tests. DL260 X inputs would be at discrete-input addresses 0..511 but pymodbus's shared-blocks mode + same-table-as-coils means those would conflict with HR seeds; FC02 tests against this profile use a separate discrete-input block instead — that's why `di size` is large but the X-input markers live in `bits` only when `shared blocks=false`. Document trade-off in README.", "bits": [ {"_quirk": "Y0 marker. DL260 maps Y0 to coil 2048 (0-based). Coil 2048 = ON proves the mapping.", "addr": 2048, "value": 1}, {"addr": 2049, "value": 0}, {"addr": 2050, "value": 1}, {"_quirk": "C0 marker. DL260 maps C0 to coil 3072 (0-based). Coil 3072 = ON proves the mapping.", "addr": 3072, "value": 1}, {"addr": 3073, "value": 0}, {"addr": 3074, "value": 1}, {"_quirk": "Scratch C-relays for write-roundtrip tests against the writable C range.", "addr": 4000, "value": 0}, {"addr": 4001, "value": 0}, {"addr": 4002, "value": 0}, {"addr": 4003, "value": 0}, {"addr": 4004, "value": 0}, {"addr": 4005, "value": 0}, {"addr": 4006, "value": 0}, {"addr": 4007, "value": 0} ], "uint32": [], "float32": [], "string": [], "repeat": [] } } }