A portable Modbus RTU, ASCII, and TCP protocol stack with device simulation and gateway primitives for MoonBit.
moon update
moon check --target all --deny-warn
moon test --target all --deny-warn
moon run cmd/main///|
let request = @moonbit-modbus.read_holding(1, 0, 4)
///|
let rtu_bytes = @moonbit-modbus.encode_rtu(request)
///|
let parsed = @moonbit-modbus.decode_rtu(rtu_bytes)///|
let parser = @moonbit-modbus.IncrementalParser::new(@moonbit-modbus.rtu_mode())
///|
let frames = parser.feed(rtu_bytes)# 展示请求编码、虚拟设备处理和响应格式化
moon run --target native cmd/main
# 运行 1000 次 CRC、RTU、TCP 和设备读工作负载
moon run --target native cmd/benchmoon fmt --check
moon info
moon check --target all --deny-warn
moon test --target all --deny-warnfn AccessPolicy::allows(self : AccessPolicy, role : AccessRole, operation : AccessOperation, frame : Frame) -> Boolfn AccessPolicy::decision(self : AccessPolicy, role : AccessRole, operation : AccessOperation, frame : Frame) -> Result[Unit, ModbusError]pub(all) struct AccessRule {
name : String
role : AccessRole
operation : AccessOperation
unit_start : Byte
unit_end : Byte
functions : Array[Byte]
enabled : Bool
}fn AccessRule::matches(self : AccessRule, role : AccessRole, operation : AccessOperation, frame : Frame) -> Boolfn AccessRule::new(name : String, role : AccessRole, operation : AccessOperation, unit_start : Byte, unit_end : Byte, functions : Array[Byte]) -> Result[AccessRule, ModbusError]fn AddressAllocator::allocate(self : AddressAllocator, length : Int) -> Result[AddressRange, ModbusError]fn AddressAllocator::release(self : AddressAllocator, range : AddressRange) -> Result[Unit, ModbusError]pub(all) struct AddressRange {
start : UInt16
length : Int
}fn AddressRange::slice(self : AddressRange, offset : Int, length : Int) -> Result[AddressRange, ModbusError]fn AddressRange::split(self : AddressRange, segment_length : Int) -> Result[Array[AddressRange], ModbusError]pub(all) struct AlarmEngine {
instances : Array[AlarmInstance]
events : Array[AlarmEvent]
max_events : Int
next_sequence : Int
}fn AlarmEngine::acknowledge(self : AlarmEngine, rule_id : String, operator : String, timestamp : Int) -> Result[AlarmEvent, ModbusError]fn AlarmEngine::evaluate(self : AlarmEngine, point_id : String, value : Int, timestamp : Int) -> Result[Array[AlarmEvent], ModbusError]fn AlarmEngine::shelve(self : AlarmEngine, rule_id : String, timestamp : Int) -> Result[AlarmEvent, ModbusError]fn AlarmEngine::unshelve(self : AlarmEngine, rule_id : String, timestamp : Int) -> Result[AlarmEvent, ModbusError]pub(all) struct AlarmEvent {
sequence : Int
rule_id : String
point_id : String
state : AlarmState
value : Int
timestamp : Int
severity : AlarmSeverity
message : String
} derive(Debug)pub(all) struct AlarmInstance {
rule : AlarmRule
state : AlarmState
pending_since : Int?
clearing_since : Int?
last_value : Int
last_timestamp : Int
transitions : Int
acknowledger : String?
}fn AlarmInstance::evaluate(self : AlarmInstance, value : Int, timestamp : Int, sequence : Int) -> AlarmTransitionpub(all) struct AlarmMonitor {
threshold : Threshold
state : ThresholdState
transitions : Int
last_value : Int?
}pub(all) struct AlarmRule {
id : String
point_id : String
condition : AlarmCondition
low : Int
high : Int
severity : AlarmSeverity
activation_delay : Int
clear_delay : Int
hysteresis : Int
enabled : Bool
}fn AlarmRule::new(id : String, point_id : String, condition : AlarmCondition, low : Int, high : Int, severity : AlarmSeverity, activation_delay? : Int, clear_delay? : Int, hysteresis? : Int) -> Result[AlarmRule, ModbusError]pub(all) struct AnalyticsReport {
direction : TrendDirection
average : Int
minimum : Int
maximum : Int
slope : Int
anomalies : Int
p95 : Int
}pub(all) struct AnalyticsRule {
id : String
lower : Int?
upper : Int?
spike_delta : Int
flatline_delta : Int
flatline_count : Int
}fn AnalyticsRule::new(id : String, lower? : Int, upper? : Int, spike_delta? : Int, flatline_delta? : Int, flatline_count? : Int) -> Result[AnalyticsRule, ModbusError]fn AnalyticsSample::new(timestamp : Int, value : Int, quality? : ReadingQuality) -> Result[AnalyticsSample, ModbusError]pub(all) struct AnalyticsWindow {
id : String
capacity : Int
samples : Array[AnalyticsSample]
dropped : Int
}fn AnalyticsWindow::append(self : AnalyticsWindow, sample : AnalyticsSample) -> Result[Unit, ModbusError]fn AnalyticsWindow::direction(self : AnalyticsWindow, threshold : Int) -> Result[TrendDirection, ModbusError]pub(all) struct AuditEntry {
sequence : Int
direction : String
mode : Mode
transaction_id : UInt16
summary : FrameSummary
outcome : String
}pub(all) struct BenchmarkResult {
name : String
iterations : Int
successful : Int
failed : Int
bytes : Int
}fn BitVector::pack_range(self : BitVector, start : Int, quantity : Int) -> Result[Array[Byte], ModbusError]fn BitVector::unpack_into(self : BitVector, start : Int, quantity : Int, bytes : Array[Byte]) -> Result[Unit, ModbusError]pub(all) struct BridgeDecision {
rule_id : String?
action : BridgeAction
frame : Frame?
reason : String
matched : Bool
}fn BridgeDecision::matched(rule : ServiceBridgeRule, action : BridgeAction, frame : Frame?, reason : String) -> BridgeDecisionpub(all) struct CalibrationCurve {
samples : Array[CalibrationSample]
max_samples : Int
clamp : Bool
}fn CalibrationCurve::add(self : CalibrationCurve, sample : CalibrationSample) -> Result[Unit, ModbusError]fn CalibrationCurve::convert_many(self : CalibrationCurve, values : Array[Int]) -> Result[Array[Int], ModbusError]fn CalibrationCurve::new(max_samples? : Int, clamp? : Bool) -> Result[CalibrationCurve, ModbusError]fn CalibrationCurve::sample(self : CalibrationCurve, index : Int) -> Result[CalibrationSample, ModbusError]pub(all) struct CalibrationSample {
raw : Int
engineering : Int
}pub(all) struct CapacityLedger {
limits : Array[CapacityLimit]
reservations : Array[CapacityReservation]
max_reservations : Int
sequence : Int
}fn CapacityLedger::add_limit(self : CapacityLedger, limit : CapacityLimit) -> Result[Unit, ModbusError]fn CapacityLedger::release(self : CapacityLedger, reservation_id : String) -> Result[Unit, ModbusError]fn CapacityLedger::reserve(self : CapacityLedger, resource : CapacityResource, amount : Int, now : Int) -> Result[CapacityReservation, ModbusError]pub(all) struct CapacityLimit {
resource : CapacityResource
name : String
soft_limit : Int
hard_limit : Int
used : Int
}fn CapacityLimit::new(resource : CapacityResource, name : String, soft_limit : Int, hard_limit : Int) -> Result[CapacityLimit, ModbusError]pub(all) struct CapacityReservation {
id : String
resource : CapacityResource
amount : Int
created_at : Int
released : Bool
}fn CapacityReservation::new(id : String, resource : CapacityResource, amount : Int, created_at : Int) -> Result[CapacityReservation, ModbusError]pub(all) struct CaptureFilter {
mode : Mode?
unit_id : Byte?
function : Byte?
direction : CaptureDirection?
status : CaptureStatus?
start_time : Int?
end_time : Int?
}fn CaptureFilter::between(self : CaptureFilter, start : Int, end : Int) -> Result[CaptureFilter, ModbusError]fn CaptureFilter::with_direction(self : CaptureFilter, direction : CaptureDirection) -> CaptureFilterpub(all) struct CaptureRecord {
id : Int
timestamp : Int
mode : Mode
transaction_id : UInt16
direction : CaptureDirection
bytes : Array[Byte]
frame : Frame?
status : CaptureStatus
note : String
}fn CaptureRecord::from_frame(id : Int, timestamp : Int, mode : Mode, transaction_id : UInt16, direction : CaptureDirection, frame : Frame, note? : String) -> Result[CaptureRecord, ModbusError]fn CaptureRecord::new(id : Int, timestamp : Int, mode : Mode, transaction_id : UInt16, direction : CaptureDirection, bytes : Array[Byte], note? : String) -> Result[CaptureRecord, ModbusError]pub(all) struct CaptureRing {
records : Array[CaptureRecord]
max_records : Int
next_id : Int
lost : Int
}fn CaptureRing::push(self : CaptureRing, timestamp : Int, mode : Mode, transaction_id : UInt16, direction : CaptureDirection, bytes : Array[Byte], note? : String) -> Result[CaptureRecord, ModbusError]fn CaptureRing::push_frame(self : CaptureRing, timestamp : Int, mode : Mode, transaction_id : UInt16, direction : CaptureDirection, frame : Frame, note? : String) -> Result[CaptureRecord, ModbusError]pub(all) struct CircuitGuard {
name : String
failure_threshold : Int
recovery_after : Int
probe_limit : Int
state : CircuitGuardState
consecutive_failures : Int
opened_at : Int?
probes : Int
}fn CircuitGuard::new(name : String, failure_threshold : Int, recovery_after : Int, probe_limit? : Int) -> Result[CircuitGuard, ModbusError]pub struct Client {
mode : Mode
config : ClientConfig
next_transaction : UInt16
pending : Array[PendingExchange]
}fn Client::accept(self : Client, request : ClientRequest, bytes : Array[Byte]) -> Result[Frame, ModbusError]fn Client::accept_frame(self : Client, request : ClientRequest, transaction_id : UInt16, response : Frame) -> Result[Frame, ModbusError]pub(all) struct ClientConfig {
timeout_ticks : Int
retries : Int
max_pending : Int
strict_unit : Bool
}fn CoilBank::read(self : CoilBank, address : UInt16, quantity : Int) -> Result[Array[Bool], ModbusError]fn CoilBank::write(self : CoilBank, address : UInt16, values : Array[Bool]) -> Result[Unit, ModbusError]pub(all) struct CommandArgument {
key : String
value : String
}pub(all) struct CommandAuditEntry {
sequence : Int
command_id : String
principal : String
device_id : String
operation : String
state : DeviceCommandState
timestamp : Int
detail : String
}fn CommandAuditEntry::new(sequence : Int, command : DeviceCommand, state : DeviceCommandState, timestamp : Int, detail? : String) -> Result[CommandAuditEntry, ModbusError]pub(all) struct CommandCenter {
queue : Array[DeviceCommand]
completed : Array[CommandExecution]
audit : Array[CommandAuditEntry]
max_queue : Int
max_audit : Int
sequence : Int
}fn CommandCenter::cancel(self : CommandCenter, command_id : String, timestamp : Int) -> Result[Unit, ModbusError]fn CommandCenter::finish(self : CommandCenter, command : DeviceCommand, execution : CommandExecution) -> Result[Unit, ModbusError]fn CommandCenter::recent(self : CommandCenter, limit : Int) -> Result[Array[CommandAuditEntry], ModbusError]fn CommandCenter::submit(self : CommandCenter, command : DeviceCommand, timestamp : Int) -> Result[Unit, ModbusError]pub(all) struct CommandExecution {
command_id : String
state : DeviceCommandState
started_at : Int
finished_at : Int
response : Frame?
error : ModbusError?
message : String
}fn CommandExecution::new(command_id : String, state : DeviceCommandState, started_at : Int, finished_at : Int, response? : Frame, error? : ModbusError, message? : String) -> Result[CommandExecution, ModbusError]fn ConfigEntry::new(key : String, value : ConfigValue, source? : String, revision? : Int) -> Result[ConfigEntry, ModbusError]fn ConfigSchema::validate_values(self : ConfigSchema, values : Array[ConfigEntry]) -> Result[Unit, ModbusError]pub(all) struct ConfigSpec {
key : String
kind : ConfigKind
required : Bool
default_value : ConfigValue?
min_integer : Int?
max_integer : Int?
min_length : Int
max_length : Int
secret : Bool
description : String
}fn ConfigSpec::new(key : String, kind : ConfigKind, required? : Bool, default_value? : ConfigValue, min_integer? : Int, max_integer? : Int, min_length? : Int, max_length? : Int, secret? : Bool, description? : String) -> Result[ConfigSpec, ModbusError]pub(all) struct ConformanceResult {
name : String
passed : Bool
detail : String
}pub(all) struct ConformanceVector {
name : String
mode : Mode
bytes : Array[Byte]
expected_function : Byte?
expected_error : ModbusError?
}fn ConformanceVector::invalid(name : String, mode : Mode, bytes : Array[Byte], expected_error : ModbusError) -> ConformanceVectorfn ConformanceVector::valid(name : String, mode : Mode, bytes : Array[Byte], expected_function : Byte) -> ConformanceVectorpub(all) struct Counter {
name : String
value : Int
}pub(all) struct Crc16State {
value : UInt16
}pub struct Device {
unit_id : Byte
memory : DeviceMemory
file_store : FileRecordStore
server_id : Array[Byte]
event_count : UInt16
busy : Bool
exception_count : Int
}fn Device::new(unit_id : Byte, coil_capacity? : Int, register_capacity? : Int) -> Result[Device, ModbusError]pub(all) struct DeviceCommand {
id : String
device_id : String
unit_id : Byte
kind : DeviceCommandKind
function : Byte
address : UInt16
quantity : Int
arguments : Array[CommandArgument]
principal : String
reason : String
timeout : Int
state : DeviceCommandState
created_at : Int
}fn DeviceCommand::add_argument(self : DeviceCommand, argument : CommandArgument) -> Result[Unit, ModbusError]fn DeviceCommand::new(id : String, device_id : String, unit_id : Byte, kind : DeviceCommandKind, function : Byte, address : UInt16, quantity : Int, principal : String, reason : String, created_at : Int, timeout? : Int) -> Result[DeviceCommand, ModbusError]fn DeviceCommand::set_state(self : DeviceCommand, state : DeviceCommandState) -> Result[Unit, ModbusError]pub(all) struct DeviceHealth {
unit_id : Byte
event_count : UInt16
exception_count : Int
busy : Bool
}pub(all) struct DeviceIdObject {
object_id : Byte
value : String
}pub(all) struct DeviceIdentification {
category : DeviceIdCategory
conformity : Byte
more_follows : Bool
next_object_id : Byte
objects : Array[DeviceIdObject]
}pub struct DeviceIdentityCatalog {
category : DeviceIdCategory
objects : Array[DeviceIdObject]
conformity : Byte
}fn DeviceIdentityCatalog::add(self : DeviceIdentityCatalog, object : DeviceIdObject) -> Result[Unit, ModbusError]fn DeviceIdentityCatalog::response(self : DeviceIdentityCatalog, request : Frame) -> Result[Frame, ModbusError]pub(all) struct DeviceInventory {
devices : Array[InventoryDevice]
max_devices : Int
revision : Int
}fn DeviceInventory::add(self : DeviceInventory, device : InventoryDevice) -> Result[Unit, ModbusError]fn DeviceInventory::mark_stale(self : DeviceInventory, now : Int, timeout : Int) -> Result[Int, ModbusError]fn DeviceInventory::remove(self : DeviceInventory, id : String) -> Result[InventoryDevice, ModbusError]pub(all) struct DeviceMemory {
coils : CoilBank
discrete_inputs : CoilBank
input_registers : RegisterBank
holding_registers : RegisterBank
}fn DeviceMemory::load_discrete(self : DeviceMemory, address : UInt16, values : Array[Bool]) -> Result[Unit, ModbusError]fn DeviceMemory::load_holding(self : DeviceMemory, address : UInt16, values : Array[UInt16]) -> Result[Unit, ModbusError]fn DeviceMemory::load_input(self : DeviceMemory, address : UInt16, values : Array[UInt16]) -> Result[Unit, ModbusError]fn DeviceMemory::new(coil_capacity? : Int, register_capacity? : Int) -> Result[DeviceMemory, ModbusError]pub(all) struct DeviceProfile {
name : String
model : String
unit_id : Byte
revision : String
points : Array[ProfilePoint]
max_points : Int
}fn DeviceProfile::add_point(self : DeviceProfile, point : ProfilePoint) -> Result[Unit, ModbusError]fn DeviceProfile::new(name : String, model : String, unit_id : Byte, revision? : String, max_points? : Int) -> Result[DeviceProfile, ModbusError]fn DeviceProfile::remove_point(self : DeviceProfile, id : String) -> Result[ProfilePoint, ModbusError]pub(all) struct DeviceReliability {
device_id : String
window : ReliabilityWindow
circuit : CircuitGuard
last_seen : Int?
total_requests : Int
total_successes : Int
}fn DeviceReliability::allow_request(self : DeviceReliability, now : Int) -> Result[Bool, ModbusError]fn DeviceReliability::new(device_id : String, window_width : Int, failure_threshold : Int, recovery_after : Int) -> Result[DeviceReliability, ModbusError]fn DeviceReliability::record(self : DeviceReliability, sample : ReliabilitySample) -> Result[Unit, ModbusError]pub(all) struct DeviceService {
id : String
device_id : String
kind : DeviceServiceKind
endpoint : String
state : DeviceServiceState
started_at : Int?
stopped_at : Int?
restart_count : Int
tags : Array[String]
}fn DeviceService::new(id : String, device_id : String, kind : DeviceServiceKind, endpoint : String) -> Result[DeviceService, ModbusError]pub(all) struct DeviceServiceRegistry {
services : Array[DeviceService]
snapshots : Array[DeviceSnapshot]
max_services : Int
max_snapshots : Int
}fn DeviceServiceRegistry::for_device(self : DeviceServiceRegistry, device_id : String) -> Array[DeviceService]fn DeviceServiceRegistry::new(max_services? : Int, max_snapshots? : Int) -> Result[DeviceServiceRegistry, ModbusError]fn DeviceServiceRegistry::put_snapshot(self : DeviceServiceRegistry, snapshot : DeviceSnapshot) -> Result[Unit, ModbusError]fn DeviceServiceRegistry::register(self : DeviceServiceRegistry, service : DeviceService) -> Result[Unit, ModbusError]fn DeviceServiceRegistry::snapshot(self : DeviceServiceRegistry, device_id : String) -> DeviceSnapshot?pub(all) struct DeviceSnapshot {
device_id : String
captured_at : Int
values : Array[SnapshotValue]
sequence : Int
complete : Bool
}fn DeviceSnapshot::new(device_id : String, captured_at : Int, sequence : Int) -> Result[DeviceSnapshot, ModbusError]pub(all) struct DiagnosticIssue {
code : String
category : DiagnosticCategory
severity : DiagnosticSeverity
message : String
context : String
suggestion : String
}fn DiagnosticIssue::new(code : String, category : DiagnosticCategory, severity : DiagnosticSeverity, message : String, context? : String, suggestion? : String) -> Result[DiagnosticIssue, ModbusError]pub(all) struct DiagnosticReport {
name : String
issues : Array[DiagnosticIssue]
max_issues : Int
inspected : Int
}fn DiagnosticReport::add(self : DiagnosticReport, issue : DiagnosticIssue) -> Result[Unit, ModbusError]fn DiagnosticReport::inspect_one(self : DiagnosticReport, frame : Frame) -> Result[Unit, ModbusError]fn DiagnosticReport::inspect_wire(self : DiagnosticReport, mode : Mode, bytes : Array[Byte]) -> Unitfn DiagnosticReport::new(name? : String, max_issues? : Int) -> Result[DiagnosticReport, ModbusError]fn EncodedAdu::new(mode : Mode, transaction_id : UInt16, frame : Frame) -> Result[EncodedAdu, ModbusError]pub(all) struct EndpointHealth {
unit_id : Byte
ready : Bool
event_count : UInt16
exceptions : Int
requests : Int
responses : Int
errors : Int
}pub(all) struct EndpointRuntime {
config : EndpointConfig
state : EndpointState
opened_at : Int
last_error : ModbusError?
reconnects : Int
frames_in : Int
frames_out : Int
}pub(all) struct EventSubscription {
id : String
source : String?
kind : ServiceEventKind?
enabled : Bool
}fn EventSubscription::new(id : String, source? : String, kind? : ServiceEventKind) -> Result[EventSubscription, ModbusError]fn ExchangeEnvelope::new(source : String, destination : String, adu : EncodedAdu) -> ExchangeEnvelopepub(all) struct FileRecordReference {
reference_type : Byte
file_number : UInt16
record_number : UInt16
record_length : UInt16
}fn FileRecordReference::new(file_number : UInt16, record_number : UInt16, record_length : UInt16, reference_type? : Byte) -> Result[FileRecordReference, ModbusError]fn FileRecordStore::get(self : FileRecordStore, reference : FileRecordReference) -> Result[Array[UInt16], ModbusError]fn FileRecordStore::put(self : FileRecordStore, record : FileRecordWrite) -> Result[Unit, ModbusError]fn FileRecordWrite::new(reference : FileRecordReference, values : Array[UInt16]) -> Result[FileRecordWrite, ModbusError]pub(all) struct FirmwareConstraint {
vendor : String
model : String
minimum : String
recommended : String
}fn FirmwareConstraint::new(vendor : String, model : String, minimum : String, recommended : String) -> Result[FirmwareConstraint, ModbusError]pub(all) struct FleetHealthRollup {
contributions : Array[HealthContribution]
score : Int
state : FleetHealthState
timestamp : Int
}fn FleetHealthRollup::add(self : FleetHealthRollup, contribution : HealthContribution) -> Result[Unit, ModbusError]fn FleetHealthRollup::contribution(self : FleetHealthRollup, source : String) -> HealthContribution?fn FleetHealthRollup::remove(self : FleetHealthRollup, source : String) -> Result[HealthContribution, ModbusError]pub(all) struct FrameContract {
id : String
function : Byte
request_min : Int
request_max : Int
response_min : Int
response_max : Int
require_echo : Bool
}fn FrameContract::new(id : String, function : Byte, request_min : Int, request_max : Int, response_min : Int, response_max : Int, require_echo? : Bool) -> Result[FrameContract, ModbusError]fn FrameContractCatalog::add(self : FrameContractCatalog, contract : FrameContract) -> Result[Unit, ModbusError]fn FrameContractCatalog::check(self : FrameContractCatalog, request : Frame, response : Frame) -> Result[ContractResult, ModbusError]fn FrameContractCatalog::check_all(self : FrameContractCatalog, pairs : Array[(Frame, Frame)]) -> Array[ContractResult]pub(all) struct FrameFingerprint {
unit_id : Byte
function : Byte
data_length : Int
checksum : Int
}fn FrameSequence::validate(self : FrameSequence, allow_broadcast : Bool) -> Result[Unit, ModbusError]pub struct FrameStream {
mode : Mode
parser : IncrementalParser
queue : ByteQueue
chunks : Int
frames : Int
}fn FrameStream::new(mode : Mode, role? : ParserRole, max_buffer? : Int, max_frame? : Int) -> Result[FrameStream, ModbusError]pub(all) struct FrameSummary {
unit_id : Byte
function : Byte
data_length : Int
exception : Bool
}fn FrameTextLog::record_wire(self : FrameTextLog, direction : String, mode : Mode, transaction_id : UInt16, frame : Frame) -> Unitpub(all) enum FunctionCode {
ReadCoils
ReadDiscreteInputs
ReadHoldingRegisters
ReadInputRegisters
WriteSingleCoil
WriteSingleRegister
ReadExceptionStatus
Diagnostics
GetCommEventCounter
GetCommEventLog
ReportServerId
WriteMultipleCoils
WriteMultipleRegisters
ReportServerIdExtended
ReadFileRecord
WriteFileRecord
MaskWriteRegister
ReadWriteMultipleRegisters
ReadFifoQueue
EncapsulatedInterface
Unknown(Byte)
} derive(Eq, Debug)pub(all) struct FunctionDescriptor {
function : Byte
name : String
request_min : Int
request_max : Int
response_variable : Bool
writable : Bool
description : String
}fn GatewayPolicyTable::add(self : GatewayPolicyTable, policy : ServiceGatewayPolicy) -> Result[Unit, ModbusError]fn GatewayPolicyTable::evaluate(self : GatewayPolicyTable, source : String, destination : String, frame : Frame) -> Result[BridgeDecision, ModbusError]fn GatewayPolicyTable::find(self : GatewayPolicyTable, source : String, destination : String) -> ServiceGatewayPolicy?pub(all) struct GatewayRule {
source_unit : Byte
target_unit : Byte
function : Byte
source_start : UInt16
target_start : UInt16
span : Int
enabled : Bool
}fn GatewayRule::new(source_unit : Byte, target_unit : Byte, function : Byte, source_start : UInt16, target_start : UInt16, span : Int) -> Result[GatewayRule, ModbusError]pub(all) struct GuardEvent {
sequence : Int
timestamp : Int
peer : String
decision : GuardDecision
reason : GuardReason
unit_id : Byte
function : Byte
frame_bytes : Int
fingerprint : FrameFingerprint
}fn GuardEvent::new(sequence : Int, timestamp : Int, peer : String, decision : GuardDecision, reason : GuardReason, frame : Frame) -> Result[GuardEvent, ModbusError]pub(all) struct HealthContribution {
source : String
score : Int
weight : Int
detail : String
}fn HealthContribution::new(source : String, score : Int, weight : Int, detail : String) -> Result[HealthContribution, ModbusError]fn Historian::aggregate(self : Historian, point_id : String, start : Int, end : Int, aggregation : Aggregation) -> Result[Int, ModbusError]fn Historian::query(self : Historian, point_id : String, start : Int, end : Int) -> Result[Array[TagSample], ModbusError]pub(all) struct HistoryBucket {
start : Int
end : Int
count : Int
minimum : Int
maximum : Int
sum : Int
}pub struct IncrementalParser {
mode : Mode
role : ParserRole
buffer : Array[Byte]
max_frame : Int
frames_seen : Int
errors_seen : Int
}fn IncrementalParser::feed(self : IncrementalParser, input : Array[Byte]) -> Result[Array[Frame], ModbusError]fn IncrementalParser::feed_byte(self : IncrementalParser, byte : Byte) -> Result[Array[Frame], ModbusError]fn IncrementalParser::set_max_frame(self : IncrementalParser, max_frame : Int) -> Result[Unit, ModbusError]pub(all) struct InventoryDevice {
id : String
label : String
vendor : String
model : String
serial : String
firmware : String
unit_id : Byte
transport : String
state : InventoryState
last_seen : Int?
tags : Array[String]
}fn InventoryDevice::new(id : String, label : String, vendor : String, model : String, serial : String, firmware : String, unit_id : Byte, transport : String) -> Result[InventoryDevice, ModbusError]fn InventoryDevice::stale(self : InventoryDevice, now : Int, timeout : Int) -> Result[Bool, ModbusError]pub(all) struct JobScheduler {
jobs : Array[ScheduledJob]
max_jobs : Int
now : Int
dispatched : Int
completed : Int
failed : Int
cancelled : Int
}fn JobScheduler::fail(self : JobScheduler, id : String, error : ModbusError, now : Int) -> Result[Bool, ModbusError]fn JobScheduler::reschedule(self : JobScheduler, id : String, due_at : Int) -> Result[Unit, ModbusError]pub(all) struct LeaseManager {
leases : Array[ResourceLease]
max_leases : Int
default_duration : Int
sequence : Int
}fn LeaseManager::acquire(self : LeaseManager, resource : String, owner : String, now : Int, priority? : Int) -> Result[ResourceLease, ModbusError]fn LeaseManager::active_resources(self : LeaseManager, now : Int) -> Result[Array[String], ModbusError]fn LeaseManager::new(max_leases? : Int, default_duration? : Int) -> Result[LeaseManager, ModbusError]fn LeaseManager::owned_by(self : LeaseManager, owner : String, now : Int) -> Result[Array[String], ModbusError]fn LeaseManager::release(self : LeaseManager, lease_id : String, owner : String) -> Result[Unit, ModbusError]fn LeaseManager::renew(self : LeaseManager, lease_id : String, owner : String, now : Int, duration? : Int) -> Result[Unit, ModbusError]pub(all) struct MaintenancePlanner {
plans : Array[ServicePlan]
records : Array[ServiceRecord]
work_orders : Array[MaintenanceWorkOrder]
max_records : Int
max_orders : Int
}fn MaintenancePlanner::add_plan(self : MaintenancePlanner, plan : ServicePlan) -> Result[Unit, ModbusError]fn MaintenancePlanner::add_record(self : MaintenancePlanner, record : ServiceRecord) -> Result[Unit, ModbusError]fn MaintenancePlanner::add_work_order(self : MaintenancePlanner, order : MaintenanceWorkOrder) -> Result[Unit, ModbusError]fn MaintenancePlanner::complete_order(self : MaintenancePlanner, order_id : String, timestamp : Int, note? : String) -> Result[Unit, ModbusError]fn MaintenancePlanner::due_plans(self : MaintenancePlanner, now : Int) -> Result[Array[String], ModbusError]fn MaintenancePlanner::generate_due(self : MaintenancePlanner, now : Int) -> Result[Int, ModbusError]fn MaintenancePlanner::history_count(self : MaintenancePlanner, asset_id : String, start : Int, end : Int) -> Result[Int, ModbusError]fn MaintenancePlanner::new(max_records? : Int, max_orders? : Int) -> Result[MaintenancePlanner, ModbusError]fn MaintenancePlanner::open_orders(self : MaintenancePlanner, now : Int, overdue_only? : Bool) -> Result[Array[String], ModbusError]fn MaintenancePlanner::summary(self : MaintenancePlanner, now : Int) -> Result[MaintenanceSummary, ModbusError]pub(all) struct MaintenanceSummary {
plans : Int
due : Int
overdue : Int
completed : Int
open : Int
records : Int
}pub(all) struct MaintenanceWorkOrder {
id : String
asset_id : String
plan_id : String?
title : String
priority : MaintenancePriority
state : WorkOrderState
created_at : Int
due_at : Int
assigned_to : String?
started_at : Int?
finished_at : Int?
note : String
}fn MaintenanceWorkOrder::assign(self : MaintenanceWorkOrder, technician : String) -> Result[Unit, ModbusError]fn MaintenanceWorkOrder::block(self : MaintenanceWorkOrder, note : String) -> Result[Unit, ModbusError]fn MaintenanceWorkOrder::cancel(self : MaintenanceWorkOrder, reason : String) -> Result[Unit, ModbusError]fn MaintenanceWorkOrder::complete(self : MaintenanceWorkOrder, timestamp : Int, note? : String) -> Result[Unit, ModbusError]fn MaintenanceWorkOrder::new(id : String, asset_id : String, title : String, priority : MaintenancePriority, created_at : Int, due_at : Int, plan_id? : String) -> Result[MaintenanceWorkOrder, ModbusError]