rk_devices library
Device protocols that carry their own timing — framed, parsed, and never waited on.
Weighing scales, customer displays, cash drawers and MDB vending framing: one implementation of each conversation, instead of one per transport.
The rule this package is shaped by
Timing that a peripheral controller owns stays there. MDB's five-millisecond reply window and a stepper's microsecond pulses are held by hardware timers and UARTs, not by a general-purpose host running a till. So this package speaks protocols and holds no deadlines: it frames, parses and reports.
Concretely, the native library performs no I/O, opens nothing, sleeps never and spawns no thread. Every call is a pure function of its arguments. That is what makes "no device failure may block taking money" structural here rather than promised — nothing that cannot wait can make anyone wait.
The one place time appears is Stabilizer, and it holds no clock either: the caller supplies the elapsed time on every offer, and its budget is a Duration rather than a number of attempts.
Getting a library
final devices = RkDevices.tryOpen();
if (devices == null) {
// No native library for this host. That is a third state, not an
// error — see DrawerPulseUnsupportedHere.
}
The native crate lives in rust/ inside this package and builds to a
cdylib/staticlib with a plain C ABI. Wiring it into a Flutter build is
deliberately not this package's business.
Classes
- DisplayBytes
- Bytes to send, and how many characters could not be sent as themselves.
- DisplayGeometry
- Lines and columns, fixed by the manufacturer.
- DrawerPulse
- The three outcomes of asking for a drawer pulse.
- DrawerPulseBytes
- Here are the bytes. Sending them is the caller's job, and whether the drawer physically opened is nobody's: see DrawerReporting.cannotReport.
- DrawerPulseRefused
- The request itself was wrong — a pulse longer than the protocol can carry, an unknown model.
- DrawerPulseUnsupportedHere
- There is no native rk_devices library on this host, so no drawer support at all. Distinct from a failure, and it must stay distinct.
- MdbAck
-
0x00with the mode bit set. - MdbBadChecksum
-
A complete block whose checksum does not add up. Ask for a retransmit —
which in MDB is what
RETis for. - MdbBlock
- A data block whose checksum verified. payload excludes the checksum.
- MdbIncomplete
- No word with the mode bit set yet. Nothing may be dropped.
- MdbNak
-
0xFFwith the mode bit set — heard and refused. - MdbReply
- What came back from a peripheral.
- MdbRet
-
0xAAwith the mode bit set — repeat the last block. - RkDevices
- A loaded rk_devices native library.
- ScaleFrame
- What one parse found in the buffer it was given.
- ScaleGarbageFrame
- A complete line this protocol cannot read. Skip consumed and keep going: reporting this apart from ScaleIncompleteFrame is what lets a caller resynchronise instead of stalling.
- ScaleIncompleteFrame
- No terminator yet. consumed is zero: keep the bytes and read more.
- ScaleReadingFrame
- A complete, understood line.
- Stabilizer
- The settling rule, holding native state the caller owns.
- WeightReading
- One weight, exactly as the scale sent it.
- WriteContinue
-
offset bytes reached the wire. Send
payload.sublist(offset)next — and only that. Starting over duplicates bytes the device has already acted on. - WriteDone
- Everything reached the wire.
- WriteResume
- What may be done after a write, and nothing more.
- WriteUnknown
- How much reached the device is not knowable. Neither continuing nor repeating is safe at the byte level; the decision belongs to whatever owns the job, and is safe there only because a print job is idempotent by identifier (И29).
Enums
- DisplayModel
- DisplayOp
- DrawerModel
- DrawerPin
- DrawerReporting
- Whether anything can be learned about the drawer over the same wire.
- Heard
- What the caller heard on the wire since the last offer to a Stabilizer.
- MdbAddress
- ScaleMeasure
- ScaleProtocol
- ScaleStability
- SettleVerdict
- The answer to "may I put this number on a receipt yet".
- WeightUnit
- The unit the scale itself named. Never converted by this package: a conversion is a rounding decision about a number that is about to be multiplied by a price.
- Wire
- The transports whose partial-write behaviour differs.
Constants
- rkDevicesVersion → const String
- The version this package reports about itself.
Properties
- hasNativeDevices → bool
-
Whether a native rk_devices library could be loaded on this host.
no setter
Functions
-
cashDrawerPulse(
{DrawerModel model = DrawerModel.escposKick, DrawerPin pin = DrawerPin.pin2, Duration? on, Duration? off}) → DrawerPulse - The cash-drawer pulse, with all three outcomes a drawer has ever had.
-
remainingAfterWrite(
{required RkDevices devices, required Wire wire, required Uint8List payload, required int? accepted}) → Uint8List? - A convenience over RkDevices.resolveWrite for the common shape: hand it the payload and what the wire said, get back the bytes still to send.
Exceptions / Errors
- RkDevicesException
- A native call that could not do what it was asked.
- The native library could not be loaded on this host.