API Reference (freemdu)
This page outlines the core Rust API structures, traits, and enums provided by the freemdu protocol crate. The library is logically separated into a high-level abstraction (device) and a low-level protocol interface (Interface).
High-Level API (freemdu::device)
The high-level API should be used for all standard interactions. It maps proprietary memory addresses to strongly typed, safe Rust constructs.
Device Trait
Located at freemdu::device::Device.
This trait defines the standard asynchronous contract for seamlessly interacting with any supported appliance.
Core Methods:
connect(port: P) -> Result<Self, P::Error>: The primary entry point. It negotiates the connection over the provided serial port, identifies the appliance via its software ID, handles all memory unlocking, and returns a fully initialized device mapping.software_id() -> u16: Returns the specific 16-bit firmware identifier of the connected appliance.kind() -> DeviceKind: Returns the broad appliance category (e.g., Washing Machine).properties() -> &'static [Property]: Returns an array of diagnostic properties that this specific machine supports querying.actions() -> &'static [Action]: Returns an array of commands/actions that can be triggered.query_property(prop: &Property) -> Result<Value, P::Error>: Queries the live state of a given property, returning a strongly typedValueenum.trigger_action(action: &Action, param: Option<Value>) -> Result<(), P::Error>: Invokes an action. If the action metadata indicates a required parameter, a matchingValuevariant must be supplied.interface() -> &mut Interface<P>: An escape hatch. Returns a mutable reference to the underlying low-level interface for raw memory access.
Data Structures
DeviceKind Enum: Identifies the appliance category.
Variants include: WashingMachine, TumbleDryer, WasherDryer, Dishwasher, CoffeeMachine.
Property Struct & PropertyKind Enum:
A Property defines a queryable datapoint. It contains a kind, a unique string id, a human-readable name, and an optional unit.
Properties are classified into four categories (PropertyKind):
General: Static machine data (e.g., serial numbers, total operating hours).Fault: Diagnostic error logs (e.g., NTC thermistor shorts, drainage timeouts).Operation: Dynamic cycle state (e.g., active program, current phase, target water temperature).Io: Raw hardware I/O state (e.g., physical sensor readouts, relay statuses).
Value Enum:
Wraps the result returned when querying a property or providing a parameter for an action.
Bool(bool): Simple true/false states.Number(u32): Raw numeric data.Sensor { current: u32, target: u32 }: Complex telemetry containing both the active reading and the machine's internal target threshold.String(String): Textual data.Duration(Duration): Time-based values (e.g., remaining cycle time).Date(Date): Calendar dates (e.g., manufacturing date).Fault(Fault): The status of a specific error condition.
Fault Enum:
Ok: The fault condition is clear.Active(Option<FaultInfo>): The fault is currently triggered and actively hindering operation.Stored(Option<FaultInfo>): The fault triggered previously, was resolved, but remains stored in the non-volatile diagnostic log.
Low-Level API (freemdu::Interface)
Located at freemdu::Interface.
The low-level API is a direct implementation of the Miele serial wire protocol. It handles packet checksums, byte formatting, and addressing, but leaves the interpretation of data entirely to the user. Use this when reverse-engineering or interacting with unsupported models.
Core Methods:
new(port: P) -> Self: Wraps an async serial port stream.query_software_id() -> Result<u16, P::Error>: Retrieves the 16-bit software ID. This must always be the first command sent to a device.unlock_read_access(key: u16) -> Result<(), P::Error>: Unlocks read-only access to RAM and EEPROM using a model-specific 16-bit key.unlock_full_access(key: u16) -> Result<(), P::Error>: Unlocks write and execution access.unlock_read_accessmust be successfully executed prior to calling this.read_memory(addr: u32) -> Result<L, P::Error>: Reads binary data from the microcontroller's RAM. (Note: Legacy devices use 16-bit addresses; newer models support 32-bit).read_eeprom(addr: u16) -> Result<L, P::Error>: Reads persistent configuration data from the EEPROM.write_memory(addr: u32, payload: L) -> Result<(), P::Error>: DANGEROUS. Writes bytes directly to active RAM.write_eeprom(addr: u16, payload: L) -> Result<(), P::Error>: HIGHLY DANGEROUS. Writes persistent data to the EEPROM.query_max_baud_rate() -> Result<BaudRate, P::Error>: Checks the fastest communication speed the connected microcontroller can support.set_baud_rate(rate: BaudRate) -> Result<(), P::Error>: Negotiates and transitions the connection to a faster baud rate.halt() -> Result<(), P::Error>: Traps the microcontroller in an infinite loop, freezing all normal appliance operations. Useful for preventing background tasks from modifying memory while dumping.jump_to_subroutine(addr: u32) -> Result<(), P::Error>: Forces the microcontroller's program counter to jump to a specific memory address. Note: Executing this resets all diagnostic access locks upon return.