[READ-ONLY] Mirror of https://github.com/SantaClaas/embedded-fan-control.

Add the modbus coil functions the bypass relay speaks master

The relay that opens the bypass is a coil device, not a register device: it takes its position through write single coil (0x05) and reports it through read coils (0x01), neither of which the client could speak. `WriteSingleCoil` is the same eight byte frame as `WriteHoldingRegister` and comes back as the same echo, so `transact_write` is now shared between them. The one thing that differed was how much of the echoed value has to match -- the fan quietly drops the four low bits of a set point, a coil has nothing to drop -- so that moved out of the function and into an argument. `ReadCoil` asks for exactly one coil for the same reason `ReadHoldingRegister` asks for exactly one register: it keeps the answer a fixed length. Coil addresses get their own newtype rather than reusing the register one. On this relay the two spaces genuinely collide: coil 0x0000 is the relay, while holding register 0x0000 is the device address of the whole module, and mixing them up would reassign the module instead of switching the bypass. The client is no longer talking only to fans, so `fan_identifier` is now `device_identifier` and the log lines and doc comments in the shared paths say device. The exception codes are the standard modbus ones and apply unchanged; their comments now say so, since only the fan documents them. All three frames the relay manual gives as examples reproduce byte for byte, CRC and its byte order included. Nothing calls any of this yet -- the routine that drives the bypass is the next layer -- so the new items carry `#[allow(dead_code)]` until it does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>


+352 -64
7 changed files