Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 59 additions & 25 deletions src/xeto/ph.protocols/modbus.xeto
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,43 @@
//
// History:
// 5 Feb 2025 James Gessel Creation
//
// 22 Jun 2026 Will Stephens Revised: Updated to 6-digit extended Modicon addressing, added ModbusScaleExpr, and updated documentation

// ModbusAddr contains all info required to connect to a modbus point
// Only supports decimal format (no hex or modicon)
// Fields:
// - **addr**: Modbus address (0=Coil, 1=Input, 3=Holding Reg, 4=Input Reg). Must follow `0xxxx`-'4xxxx' pattern.
// - **encoding**: Data format for interpretation.
// - **bitIndex**: (0-15) Optional bit position within a register.
// - **access**: `"r"` (default) or `"rw"` (Read/Write).
// - **scale**: Multiplier for raw values (default 1).
// - **offset**: Optional offset value applied after scaling.
// - **byteOrder**: Optional, defines endianness for multi-register values.
// ModbusAddr contains all info required to connect to a modbus point.
// Only supports 6-digit extended Modicon format (no hex or decimal).
//
// Example: `{ "addr": "40001", "encoding": "u2", "scale": 10, "access": "rw" }`
// Example: `{ "addr": "400001", "encoding": "u2", "scale": "+32768 /10", "access": "rw" , "dis": "Run Cmd"}`

ModbusAddr: ProtocolAddr {
addr: Str <pattern:"[0-4](\\d{4})"> // Must follow standard Modbus addressing rules (0xxxx-4xxxx)
encoding: ModbusEncoding // Specifies data representation format
bitIndex: Int? <minVal:0, maxVal:15> // Optional bit index within a register
access: ModbusAccess "r" // Read/write access
scale: Number "1" // Scaling factor for raw values
offset: Number? // Optional offset applied after scaling
byteOrder: ModbusByteOrder? // Defines byte ordering for multi-register values

// Must follow 6-digit extended Modicon address format. Leading digit selects the
// type/function; the remaining 5 digits are the 1-based register number.
// Only the following register values are allowed:
// ```
// 0xxxxx Coil 000001-065536
// 1xxxxx Discrete Input 100001-165536
// 3xxxxx Input Register 300001-365536
// 4xxxxx Holding Register 400001-465536
// ```
addr: Str <pattern: "[0134]\\d{5}">

// Specifies data representation format
encoding: ModbusEncoding

// Optional bit index within a register
bitIndex: Int? <minVal: 0, maxVal: 15>

// `"r"` (default), `"rw"` (Read/Write), or `"w"` (Write Only)
access: ModbusAccess "r"

// Optional ordered op chain applied to the raw value.
scale: ModbusScaleExpr?

// Optional - defines byte ordering and endianness
byteOrder: ModbusByteOrder?

// Optional but preferred vendor human-readable point name
dis: Str?
}

// ModbusAccess specifies read/write access for a modbus point
Expand All @@ -49,11 +64,30 @@ ModbusEncoding: Enum {
f8 // 64-bit Float
}

// Specifies byte and word order for a modbus point
ModbusByteOrder: Enum {
be // Big endian or network byte order
le // Little endian both byte and word order
leb // Little endian byte order
lew // Little endian word order
// Specifies byte and word order for multi-register values
ModbusByteOrder: Enum {
be // Big-Endian (ABCD) - big endian byte and word order
le // Little-Endian (DCBA) - little endian byte and word order
leb // Byte-Swap (BADC) - little endian byte order only
lew // Word-Swap (CDAB) - little endian word order only
}

// Optional ordered op chain applied to the raw value, evaluated
// left-to-right with NO operator precedence. Format is `"[op] [number]"`
// with op choices (`+ - * /`).
//
// Examples: `"*10"`, `"/1000"`, `"+1.5"`, `"+32768 /10"`.
//
// `"+32768 /10"` means (raw + 32768) / 10.
//
// The formal grammar is defined below:
// ```
// <expr> := <term> (" " <term>)*
// <term> := <op> <number>
// <op> := "+" | "-" | "*" | "/"
// <number> := <digits> ["." <digits>] [<exp>]
// <exp> := ("e" | "E") ["+" | "-"] <digits>
// <digits> := <digit>+
// <digit> := ('0' - '9')
// ```
ModbusScaleExpr: Scalar