Documentation
¶
Index ¶
- Constants
- Variables
- func DecodeRegisters[T any](regs []uint16, codec Decoder[T]) (T, error)
- func DecodeRegistersAny(regs []uint16, codec RuntimeDecoder) (any, error)
- func DecodeWithDescriptor(regs []uint16, desc CodecDescriptor) (any, error)
- func EncodeRegisters[T any](value T, codec Encoder[T]) ([]uint16, error)
- func EncodeRegistersAny(value any, codec RuntimeEncoder) ([]uint16, error)
- func EncodeWithDescriptor(value any, desc CodecDescriptor) ([]uint16, error)
- func PermuteBytesDecode(raw []byte, layout RegisterLayout) ([]byte, error)
- func PermuteBytesEncode(canonical []byte, layout RegisterLayout) ([]byte, error)
- func ReadFromClient[T any](r RegisterReader, ctx context.Context, unitID uint8, addr uint16, ...) (T, error)
- func ReadRuntimeFromClient(r RegisterReader, ctx context.Context, unitID uint8, addr uint16, ...) (any, error)
- func ReadUint32FromClient(r RegisterReader, ctx context.Context, unitID uint8, addr uint16, ...) (uint32, error)
- func ValidateByteSpec(spec ByteSpec, b []byte, codecID string) error
- func ValidateRegisterSpec(spec RegisterSpec, regs []uint16, codecID string) error
- func WriteRuntimeToClient(w RegisterWriter, ctx context.Context, unitID uint8, addr uint16, value any, ...) error
- func WriteToClient[T any](w RegisterWriter, ctx context.Context, unitID uint8, addr uint16, value T, ...) error
- func WriteUint32ToClient(w RegisterWriter, ctx context.Context, unitID uint8, addr uint16, v uint32, ...) error
- type ByteSpec
- type Codec
- func MustNewFloat32Codec(layout RegisterLayout) Codec[float32]
- func MustNewFloat64Codec(layout RegisterLayout) Codec[float64]
- func MustNewInt16Codec(layout RegisterLayout) Codec[int16]
- func MustNewInt32Codec(layout RegisterLayout) Codec[int32]
- func MustNewInt32M10kCodec(order DecimalLimbOrder) Codec[int32]
- func MustNewInt48Codec(layout RegisterLayout) Codec[int64]
- func MustNewInt48M10kCodec(order DecimalLimbOrder) Codec[int64]
- func MustNewInt64Codec(layout RegisterLayout) Codec[int64]
- func MustNewInt64M10kCodec(order DecimalLimbOrder) Codec[int64]
- func MustNewUint16Codec(layout RegisterLayout) Codec[uint16]
- func MustNewUint32Codec(layout RegisterLayout) Codec[uint32]
- func MustNewUint32M10kCodec(order DecimalLimbOrder) Codec[uint32]
- func MustNewUint48Codec(layout RegisterLayout) Codec[uint64]
- func MustNewUint48M10kCodec(order DecimalLimbOrder) Codec[uint64]
- func MustNewUint64Codec(layout RegisterLayout) Codec[uint64]
- func MustNewUint64M10kCodec(order DecimalLimbOrder) Codec[uint64]
- func NewAsciiCodec(registerCount uint16) (Codec[string], error)
- func NewAsciiFixedCodec(registerCount uint16) (Codec[string], error)
- func NewAsciiReverseCodec(registerCount uint16) (Codec[string], error)
- func NewBCDCodec(registerCount uint16) (Codec[string], error)
- func NewBytesCodec(byteCount uint16) (Codec[[]byte], error)
- func NewDateTime2S2000Codec() Codec[time.Time]
- func NewDateTime3S2000Codec() Codec[time.Time]
- func NewDateTimeIEC870Codec() Codec[time.Time]
- func NewDateTimeIEC870LocalCodec() Codec[time.Time]
- func NewDateTimeIEC870UTCCodec() Codec[time.Time]
- func NewDateTimeYMDhmsCodec() Codec[time.Time]
- func NewDateTimeYMDhmsLocalCodec() Codec[time.Time]
- func NewDateTimeYMDhmsUTCCodec() Codec[time.Time]
- func NewEUI48Codec() Codec[net.HardwareAddr]
- func NewEUI64Codec() Codec[net.HardwareAddr]
- func NewFloat32Codec(layout RegisterLayout) (Codec[float32], error)
- func NewFloat64Codec(layout RegisterLayout) (Codec[float64], error)
- func NewIPAddrCodec() Codec[net.IP]
- func NewIPv6AddrCodec() Codec[net.IP]
- func NewInt16Codec(layout RegisterLayout) (Codec[int16], error)
- func NewInt16SignMagnitudeCodec() Codec[int16]
- func NewInt32Codec(layout RegisterLayout) (Codec[int32], error)
- func NewInt32M10kCodec(order DecimalLimbOrder) (Codec[int32], error)
- func NewInt48Codec(layout RegisterLayout) (Codec[int64], error)
- func NewInt48M10kCodec(order DecimalLimbOrder) (Codec[int64], error)
- func NewInt64Codec(layout RegisterLayout) (Codec[int64], error)
- func NewInt64M10kCodec(order DecimalLimbOrder) (Codec[int64], error)
- func NewPackedBCDCodec(registerCount uint16) (Codec[string], error)
- func NewPackedBCDReverseCodec(registerCount uint16) (Codec[string], error)
- func NewSignedPackedBCDCodec(registerCount uint16) (Codec[string], error)
- func NewUTF16BECodec(registerCount uint16) (Codec[string], error)
- func NewUTF16LECodec(registerCount uint16) (Codec[string], error)
- func NewUint8SliceCodec(byteCount uint16) (Codec[[]uint8], error)
- func NewUint16Codec(layout RegisterLayout) (Codec[uint16], error)
- func NewUint32Codec(layout RegisterLayout) (Codec[uint32], error)
- func NewUint32M10kCodec(order DecimalLimbOrder) (Codec[uint32], error)
- func NewUint48Codec(layout RegisterLayout) (Codec[uint64], error)
- func NewUint48M10kCodec(order DecimalLimbOrder) (Codec[uint64], error)
- func NewUint64Codec(layout RegisterLayout) (Codec[uint64], error)
- func NewUint64M10kCodec(order DecimalLimbOrder) (Codec[uint64], error)
- type CodecByteCountError
- type CodecCandidate
- type CodecDescriptor
- func AvailableCodecDescriptors() []CodecDescriptor
- func CodecDescriptorByID(id string) (CodecDescriptor, bool)
- func CodecDescriptorsForByteCount(count uint16) []CodecDescriptor
- func CodecDescriptorsForRegisterCount(count uint16) []CodecDescriptor
- func FindCodecDescriptors(q CodecQuery) []CodecDescriptor
- type CodecFamily
- type CodecLayoutError
- type CodecQuery
- type CodecRegisterCountError
- type CodecValueError
- type CodecValueKind
- type DecimalLimbOrder
- type Decoder
- type Encoder
- type Endianness
- type RegType
- type RegisterLayout
- type RegisterLayoutDescriptor
- type RegisterReader
- type RegisterSpec
- type RegisterWriter
- type RuntimeCodec
- func AsRuntimeCodec[T any](c Codec[T], kind CodecValueKind) RuntimeCodec
- func FindRuntimeCodecs(q CodecQuery) ([]RuntimeCodec, error)
- func MustRuntimeCodecByID(id string) RuntimeCodec
- func RuntimeCodecByID(id string) (RuntimeCodec, bool, error)
- func RuntimeCodecFromDescriptor(desc CodecDescriptor) (RuntimeCodec, error)
- func RuntimeCodecsForByteCount(count uint16) ([]RuntimeCodec, error)
- func RuntimeCodecsForRegisterCount(count uint16) ([]RuntimeCodec, error)
- type RuntimeDecoder
- type RuntimeEncoder
- type WordOrder
Constants ¶
const ( HoldingRegister = protocol.HoldingRegister InputRegister = protocol.InputRegister )
const ( BigEndian = adu.BigEndian LittleEndian = adu.LittleEndian )
Variables ¶
var ( ErrCodecRegisterCount = errors.New("modbus: codec register count mismatch") ErrCodecLayout = errors.New("modbus: invalid codec layout") ErrCodecValue = errors.New("modbus: invalid codec value") ErrCodecByteCount = errors.New("modbus: codec byte count mismatch") ErrUnknownCodec = errors.New("modbus: unknown codec") ErrEncodingError = errors.New("modbus: encoding error") )
var ( Layout16_21 = MustNewRegisterLayout(1, 2, 1) Layout16_12 = MustNewRegisterLayout(1, 1, 2) )
var ( Layout32_4321 = MustNewRegisterLayout(2, 4, 3, 2, 1) Layout32_3412 = MustNewRegisterLayout(2, 3, 4, 1, 2) Layout32_2143 = MustNewRegisterLayout(2, 2, 1, 4, 3) Layout32_1234 = MustNewRegisterLayout(2, 1, 2, 3, 4) )
var ( Layout48_654321 = MustNewRegisterLayout(3, 6, 5, 4, 3, 2, 1) Layout48_563412 = MustNewRegisterLayout(3, 5, 6, 3, 4, 1, 2) Layout48_214365 = MustNewRegisterLayout(3, 2, 1, 4, 3, 6, 5) Layout48_123456 = MustNewRegisterLayout(3, 1, 2, 3, 4, 5, 6) )
var ( Layout64_87654321 = MustNewRegisterLayout(4, 8, 7, 6, 5, 4, 3, 2, 1) Layout64_78563412 = MustNewRegisterLayout(4, 7, 8, 5, 6, 3, 4, 1, 2) Layout64_21436587 = MustNewRegisterLayout(4, 2, 1, 4, 3, 6, 5, 8, 7) Layout64_12345678 = MustNewRegisterLayout(4, 1, 2, 3, 4, 5, 6, 7, 8) )
var ErrInvalidLayout = errors.New("modbus: invalid register layout")
ErrInvalidLayout is returned when layout parameters are invalid (wrong length, duplicate or out-of-range positions).
Functions ¶
func DecodeRegisters ¶
DecodeRegisters decodes raw registers using the given codec. It validates register count against the codec's RegisterSpec before calling the codec.
func DecodeRegistersAny ¶
func DecodeRegistersAny(regs []uint16, codec RuntimeDecoder) (any, error)
DecodeRegistersAny decodes raw registers using the given runtime decoder. It validates register count against the codec's RegisterSpec before calling the codec.
func DecodeWithDescriptor ¶
func DecodeWithDescriptor(regs []uint16, desc CodecDescriptor) (any, error)
DecodeWithDescriptor builds a runtime codec from the descriptor and decodes the registers. Offline only (no client needed). Returns an error if the descriptor is unknown or if decode fails.
func EncodeRegisters ¶
EncodeRegisters encodes a value to raw registers using the given codec, then validates the result against the codec's RegisterSpec.
func EncodeRegistersAny ¶
func EncodeRegistersAny(value any, codec RuntimeEncoder) ([]uint16, error)
EncodeRegistersAny encodes a value to raw registers using the given runtime encoder. Wrong dynamic type returns *CodecValueError (never panics).
func EncodeWithDescriptor ¶
func EncodeWithDescriptor(value any, desc CodecDescriptor) ([]uint16, error)
EncodeWithDescriptor builds a runtime codec from the descriptor and encodes the value to registers. Offline only (no client needed). Returns an error if the descriptor is unknown, if the value type does not match the codec, or if encode fails.
func PermuteBytesDecode ¶
func PermuteBytesDecode(raw []byte, layout RegisterLayout) ([]byte, error)
PermuteBytesDecode converts raw register bytes (wire order) into canonical big-endian byte order using the layout permutation. Positions are 1-based: position 1 = LSB, position byteCount = MSB. len(raw) must equal layout.RegisterCount()*2.
func PermuteBytesEncode ¶
func PermuteBytesEncode(canonical []byte, layout RegisterLayout) ([]byte, error)
PermuteBytesEncode converts canonical big-endian bytes into raw register bytes (wire order) using the layout permutation. len(canonical) must equal layout.RegisterCount()*2.
func ReadFromClient ¶
func ReadFromClient[T any]( r RegisterReader, ctx context.Context, unitID uint8, addr uint16, regType RegType, dec Decoder[T], ) (T, error)
ReadFromClient reads registers at the given address and decodes them using the supplied typed codec. The number of registers read is dec.RegisterSpec().Count. Register data is read in wire order (big-endian per register); the codec applies any layout or interpretation.
func ReadRuntimeFromClient ¶
func ReadRuntimeFromClient( r RegisterReader, ctx context.Context, unitID uint8, addr uint16, regType RegType, dec RuntimeDecoder, ) (any, error)
ReadRuntimeFromClient reads registers and decodes them using a runtime decoder.
func ReadUint32FromClient ¶
func ReadUint32FromClient(r RegisterReader, ctx context.Context, unitID uint8, addr uint16, regType RegType, layout RegisterLayout) (uint32, error)
ReadUint32FromClient reads two registers at addr and decodes them as uint32 using the given layout. Convenience wrapper around NewUint32Codec + ReadFromClient.
func ValidateByteSpec ¶
ValidateByteSpec returns an error if the number of bytes in b does not match spec.Count. codecID is used in the error for diagnostics (e.g. codec.ID()); if empty, "codec" is used. Used for offline tooling and test helpers when working with byte-oriented views of codec data; transport remains register-native.
func ValidateRegisterSpec ¶
func ValidateRegisterSpec(spec RegisterSpec, regs []uint16, codecID string) error
ValidateRegisterSpec returns an error if the number of registers in regs does not match spec.Count. codecID is used in the error for diagnostics (e.g. codec.ID()); if empty, "codec" is used. Use this before calling DecodeRegisters or after EncodeRegisters to enforce the codec contract.
func WriteRuntimeToClient ¶
func WriteRuntimeToClient( w RegisterWriter, ctx context.Context, unitID uint8, addr uint16, value any, enc RuntimeEncoder, ) error
WriteRuntimeToClient encodes a value with the runtime encoder and writes the resulting registers. Wrong value type returns *CodecValueError.
func WriteToClient ¶
func WriteToClient[T any]( w RegisterWriter, ctx context.Context, unitID uint8, addr uint16, value T, enc Encoder[T], ) error
WriteToClient encodes value with the codec and writes the resulting registers at the given address. Register data is written in wire order (big-endian per register).
func WriteUint32ToClient ¶
func WriteUint32ToClient(w RegisterWriter, ctx context.Context, unitID uint8, addr uint16, v uint32, layout RegisterLayout) error
WriteUint32ToClient encodes v as two registers using the given layout and writes them at addr. Convenience wrapper around NewUint32Codec + WriteToClient.
Types ¶
type ByteSpec ¶
type ByteSpec struct {
Count uint16
}
ByteSpec declares the fixed byte count for a codec. Used for discovery and validation; transport remains register-native.
type Codec ¶
Codec is a combined decoder and encoder for type T. Transport uses Codec for ReadWithCodec / WriteWithCodec; internally Decoder and Encoder allow read-only or write-only use later if needed.
func MustNewFloat32Codec ¶
func MustNewFloat32Codec(layout RegisterLayout) Codec[float32]
func MustNewFloat64Codec ¶
func MustNewFloat64Codec(layout RegisterLayout) Codec[float64]
func MustNewInt16Codec ¶
func MustNewInt16Codec(layout RegisterLayout) Codec[int16]
func MustNewInt32Codec ¶
func MustNewInt32Codec(layout RegisterLayout) Codec[int32]
func MustNewInt32M10kCodec ¶
func MustNewInt32M10kCodec(order DecimalLimbOrder) Codec[int32]
MustNewInt32M10kCodec is like NewInt32M10kCodec but panics on error.
func MustNewInt48Codec ¶
func MustNewInt48Codec(layout RegisterLayout) Codec[int64]
func MustNewInt48M10kCodec ¶
func MustNewInt48M10kCodec(order DecimalLimbOrder) Codec[int64]
MustNewInt48M10kCodec is like NewInt48M10kCodec but panics on error.
func MustNewInt64Codec ¶
func MustNewInt64Codec(layout RegisterLayout) Codec[int64]
func MustNewInt64M10kCodec ¶
func MustNewInt64M10kCodec(order DecimalLimbOrder) Codec[int64]
MustNewInt64M10kCodec is like NewInt64M10kCodec but panics on error.
func MustNewUint16Codec ¶
func MustNewUint16Codec(layout RegisterLayout) Codec[uint16]
MustNewUint16Codec is like NewUint16Codec but panics on error.
func MustNewUint32Codec ¶
func MustNewUint32Codec(layout RegisterLayout) Codec[uint32]
func MustNewUint32M10kCodec ¶
func MustNewUint32M10kCodec(order DecimalLimbOrder) Codec[uint32]
MustNewUint32M10kCodec is like NewUint32M10kCodec but panics on error.
func MustNewUint48Codec ¶
func MustNewUint48Codec(layout RegisterLayout) Codec[uint64]
func MustNewUint48M10kCodec ¶
func MustNewUint48M10kCodec(order DecimalLimbOrder) Codec[uint64]
MustNewUint48M10kCodec is like NewUint48M10kCodec but panics on error.
func MustNewUint64Codec ¶
func MustNewUint64Codec(layout RegisterLayout) Codec[uint64]
func MustNewUint64M10kCodec ¶
func MustNewUint64M10kCodec(order DecimalLimbOrder) Codec[uint64]
MustNewUint64M10kCodec is like NewUint64M10kCodec but panics on error.
func NewAsciiCodec ¶
NewAsciiCodec returns a codec for ASCII text: high byte first per register, decode trims trailing spaces, encode right-pads with space. registerCount must be >= 1.
func NewAsciiFixedCodec ¶
NewAsciiFixedCodec returns a codec for fixed-width ASCII: no trim on decode, encode right-pads with NUL. registerCount must be >= 1.
func NewAsciiReverseCodec ¶
NewAsciiReverseCodec returns a codec for ASCII with low byte first per register; decode trims trailing spaces. registerCount must be >= 1.
func NewBCDCodec ¶
NewBCDCodec returns a codec for one-byte-per-digit BCD (0-9). Encode pads with leading zeros; non-digit input is rejected. registerCount must be >= 1.
func NewBytesCodec ¶
NewBytesCodec returns a codec for raw bytes in wire order. byteCount must be even (transport is register-based). Rejects 0 and odd byteCount.
func NewDateTime2S2000Codec ¶
NewDateTime2S2000Codec returns a codec for 2-register seconds-since-2000 (uint32). Uses layout 4321.
func NewDateTime3S2000Codec ¶
NewDateTime3S2000Codec returns a codec for 3-register seconds-since-2000 (48-bit). Uses layout 654321.
func NewDateTimeIEC870Codec ¶
NewDateTimeIEC870Codec returns a codec for 4-register IEC 60870-5 CP56Time2a: timezone-unspecified wire value interpreted by library in UTC.
func NewDateTimeIEC870LocalCodec ¶
NewDateTimeIEC870LocalCodec returns a codec for 4-register IEC 60870-5 CP56Time2a interpreted as local time.
func NewDateTimeIEC870UTCCodec ¶
NewDateTimeIEC870UTCCodec returns a codec for 4-register IEC 60870-5 CP56Time2a interpreted as UTC.
func NewDateTimeYMDhmsCodec ¶
NewDateTimeYMDhmsCodec returns a codec for 6-register YMDhms: naive Y/M/D/h/m/s tuple; library interprets it in UTC by default.
func NewDateTimeYMDhmsLocalCodec ¶
NewDateTimeYMDhmsLocalCodec returns a codec for 6-register YMDhms interpreted as local time.
func NewDateTimeYMDhmsUTCCodec ¶
NewDateTimeYMDhmsUTCCodec returns a codec for 6-register YMDhms interpreted as UTC.
func NewEUI48Codec ¶
func NewEUI48Codec() Codec[net.HardwareAddr]
NewEUI48Codec returns a codec for EUI-48/MAC (6 bytes, 3 registers) in raw wire order.
func NewEUI64Codec ¶
func NewEUI64Codec() Codec[net.HardwareAddr]
NewEUI64Codec returns a codec for EUI-64 (8 bytes, 4 registers) in raw wire order.
func NewFloat32Codec ¶
func NewFloat32Codec(layout RegisterLayout) (Codec[float32], error)
NewFloat32Codec returns a codec for two registers. Layout must have RegisterCount() == 2.
func NewFloat64Codec ¶
func NewFloat64Codec(layout RegisterLayout) (Codec[float64], error)
NewFloat64Codec returns a codec for four registers. Layout must have RegisterCount() == 4.
func NewIPAddrCodec ¶
NewIPAddrCodec returns a codec for IPv4 (4 bytes, 2 registers) in raw wire order.
func NewIPv6AddrCodec ¶
NewIPv6AddrCodec returns a codec for IPv6 (16 bytes, 8 registers) in raw wire order.
func NewInt16Codec ¶
func NewInt16Codec(layout RegisterLayout) (Codec[int16], error)
NewInt16Codec returns a codec for one register. Layout must have RegisterCount() == 1.
func NewInt16SignMagnitudeCodec ¶
NewInt16SignMagnitudeCodec returns a codec for one register as sign-magnitude: bit 15 = sign (1 = negative), bits 0–14 = magnitude. Not two's complement.
func NewInt32Codec ¶
func NewInt32Codec(layout RegisterLayout) (Codec[int32], error)
NewInt32Codec returns a codec for two registers. Layout must have RegisterCount() == 2.
func NewInt32M10kCodec ¶
func NewInt32M10kCodec(order DecimalLimbOrder) (Codec[int32], error)
NewInt32M10kCodec returns a signed 32-bit decimal-limb (M10k) codec. Only the most-significant limb is signed (-9999..9999); other limbs are 0..9999.
func NewInt48Codec ¶
func NewInt48Codec(layout RegisterLayout) (Codec[int64], error)
NewInt48Codec returns a codec for three registers (48-bit as int64). Layout must have RegisterCount() == 3.
func NewInt48M10kCodec ¶
func NewInt48M10kCodec(order DecimalLimbOrder) (Codec[int64], error)
NewInt48M10kCodec returns a signed 48-bit decimal-limb (M10k) codec; Go type int64. Only the MS limb is signed.
func NewInt64Codec ¶
func NewInt64Codec(layout RegisterLayout) (Codec[int64], error)
NewInt64Codec returns a codec for four registers. Layout must have RegisterCount() == 4.
func NewInt64M10kCodec ¶
func NewInt64M10kCodec(order DecimalLimbOrder) (Codec[int64], error)
NewInt64M10kCodec returns a signed 64-bit decimal-limb (M10k) codec. Only the MS limb is signed.
func NewPackedBCDCodec ¶
NewPackedBCDCodec returns a codec for packed BCD (two digits per byte). Encode pads with leading zeros; non-digit input is rejected. registerCount must be >= 1.
func NewPackedBCDReverseCodec ¶
NewPackedBCDReverseCodec returns a codec for packed BCD with low byte first per register (byte-swap within each word on wire). registerCount must be >= 1.
func NewSignedPackedBCDCodec ¶
NewSignedPackedBCDCodec returns a codec for signed packed BCD: trailing nibble 0xC/0xD/0xF = negative, 0x0-0x9 = positive. Decode returns e.g. "-1234" or "1234"; encode accepts optional leading "-". registerCount must be >= 1.
func NewUTF16BECodec ¶
NewUTF16BECodec returns a codec for fixed-width UTF-16 big-endian (one code unit per register, high byte first). registerCount must be >= 1.
func NewUTF16LECodec ¶
NewUTF16LECodec returns a codec for fixed-width UTF-16 little-endian (one code unit per register, low byte first on wire). registerCount must be >= 1.
func NewUint8SliceCodec ¶
NewUint8SliceCodec returns a codec for []uint8 in wire order. byteCount must be even. Rejects 0 and odd byteCount.
func NewUint16Codec ¶
func NewUint16Codec(layout RegisterLayout) (Codec[uint16], error)
NewUint16Codec returns a codec for one register. Layout must have RegisterCount() == 1.
func NewUint32Codec ¶
func NewUint32Codec(layout RegisterLayout) (Codec[uint32], error)
NewUint32Codec returns a codec for two registers. Layout must have RegisterCount() == 2.
func NewUint32M10kCodec ¶
func NewUint32M10kCodec(order DecimalLimbOrder) (Codec[uint32], error)
NewUint32M10kCodec returns a 32-bit decimal-limb (M10k) codec. Order controls whether the first register is the least- or most-significant limb.
func NewUint48Codec ¶
func NewUint48Codec(layout RegisterLayout) (Codec[uint64], error)
NewUint48Codec returns a codec for three registers (48-bit as uint64). Layout must have RegisterCount() == 3.
func NewUint48M10kCodec ¶
func NewUint48M10kCodec(order DecimalLimbOrder) (Codec[uint64], error)
NewUint48M10kCodec returns a 48-bit decimal-limb (M10k) codec; Go type uint64.
func NewUint64Codec ¶
func NewUint64Codec(layout RegisterLayout) (Codec[uint64], error)
NewUint64Codec returns a codec for four registers. Layout must have RegisterCount() == 4.
func NewUint64M10kCodec ¶
func NewUint64M10kCodec(order DecimalLimbOrder) (Codec[uint64], error)
NewUint64M10kCodec returns a 64-bit decimal-limb (M10k) codec.
type CodecByteCountError ¶
CodecByteCountError is returned when the number of bytes does not match the codec contract. Used by ValidateByteSpec for offline/byte-oriented tooling.
func (*CodecByteCountError) Error ¶
func (e *CodecByteCountError) Error() string
func (*CodecByteCountError) Unwrap ¶
func (e *CodecByteCountError) Unwrap() error
type CodecCandidate ¶
CodecCandidate is a lightweight concrete selectable option for discovery/CLI. CodecID must equal the CodecDescriptor.ID of the option it refers to (same namespace). LayoutName is empty for layout-less codecs. Candidates mirror the registered descriptors rather than expanding from a separate family list.
func CodecCandidatesForByteCount ¶
func CodecCandidatesForByteCount(count uint16) []CodecCandidate
CodecCandidatesForByteCount returns one candidate per descriptor whose ByteSpec.Count equals count.
func CodecCandidatesForRegisterCount ¶
func CodecCandidatesForRegisterCount(count uint16) []CodecCandidate
CodecCandidatesForRegisterCount returns one candidate per descriptor whose RegisterSpec.Count equals count. CodecID is the descriptor's ID; LayoutName is the layout name when the descriptor has exactly one layout, otherwise empty.
type CodecDescriptor ¶
type CodecDescriptor struct {
ID string
Name string
Family CodecFamily
ValueKind CodecValueKind
RegisterSpec RegisterSpec
ByteSpec ByteSpec
Layouts []RegisterLayoutDescriptor // nil for layout-less codecs
}
CodecDescriptor is metadata for a codec option. Descriptors are derived from the registration table (see codec_registration.go), not hand-authored. Layouts is nil for layout-less codecs (ASCII, BCD, IP, EUI48, etc.).
In the current implementation each concrete option (e.g. a specific layout or width) is registered as its own descriptor; CodecCandidate then provides a lightweight view (CodecID + LayoutName) for discovery/CLI without duplicating full descriptor data.
func AvailableCodecDescriptors ¶
func AvailableCodecDescriptors() []CodecDescriptor
AvailableCodecDescriptors returns a copy of all registered codec descriptors sorted by ID for deterministic discovery output. Layouts are deep-copied so returned descriptors are immutable to the caller.
func CodecDescriptorByID ¶
func CodecDescriptorByID(id string) (CodecDescriptor, bool)
CodecDescriptorByID returns the descriptor with the given ID, if registered. The returned descriptor is a deep copy.
func CodecDescriptorsForByteCount ¶
func CodecDescriptorsForByteCount(count uint16) []CodecDescriptor
CodecDescriptorsForByteCount returns descriptors whose ByteSpec.Count equals count. Returned descriptors are deep-copied.
func CodecDescriptorsForRegisterCount ¶
func CodecDescriptorsForRegisterCount(count uint16) []CodecDescriptor
CodecDescriptorsForRegisterCount returns descriptors whose RegisterSpec.Count equals count. Returned descriptors are deep-copied.
func FindCodecDescriptors ¶
func FindCodecDescriptors(q CodecQuery) []CodecDescriptor
FindCodecDescriptors returns descriptors matching the query. Zero values in CodecQuery mean "no filter" for that field. Returned descriptors are deep-copied.
type CodecFamily ¶
type CodecFamily uint8
CodecFamily classifies a codec for discovery and CLI grouping.
const ( CodecFamilyUnknown CodecFamily = iota CodecFamilyInteger CodecFamilyFloat CodecFamilyText CodecFamilyBCD CodecFamilyBytes CodecFamilyNetwork CodecFamilyHardwareAddress CodecFamilyDecimalLimb CodecFamilyTime CodecFamilyVendorSpecific )
func (CodecFamily) String ¶
func (f CodecFamily) String() string
type CodecLayoutError ¶
type CodecLayoutError struct {
Codec string
Layout RegisterLayout
Reason string
}
CodecLayoutError is returned when a layout is invalid for the codec.
func (*CodecLayoutError) Error ¶
func (e *CodecLayoutError) Error() string
func (*CodecLayoutError) Unwrap ¶
func (e *CodecLayoutError) Unwrap() error
type CodecQuery ¶
type CodecQuery struct {
RegisterCount uint16
ByteCount uint16
Family CodecFamily
ValueKind CodecValueKind
}
CodecQuery filters descriptors by register count, byte count, family, and value kind. Zero values mean "no filter" for that field.
type CodecRegisterCountError ¶
type CodecRegisterCountError struct {
Codec string
Expected RegisterSpec
Actual uint16
}
CodecRegisterCountError is returned when the number of registers does not match the codec contract.
func (*CodecRegisterCountError) Error ¶
func (e *CodecRegisterCountError) Error() string
func (*CodecRegisterCountError) Unwrap ¶
func (e *CodecRegisterCountError) Unwrap() error
type CodecValueError ¶
CodecValueError is returned when a value is invalid for encode or decode.
func (*CodecValueError) Error ¶
func (e *CodecValueError) Error() string
func (*CodecValueError) Unwrap ¶
func (e *CodecValueError) Unwrap() error
type CodecValueKind ¶
type CodecValueKind uint8
CodecValueKind is the type of value a codec produces or consumes.
const ( CodecValueUnknown CodecValueKind = iota CodecValueUint16 CodecValueInt16 CodecValueUint32 CodecValueInt32 CodecValueUint48 CodecValueInt48 CodecValueUint64 CodecValueInt64 CodecValueFloat32 CodecValueFloat64 CodecValueString CodecValueByteSlice CodecValueUint8Slice CodecValueIP CodecValueHardwareAddr CodecValueTime )
func (CodecValueKind) String ¶
func (k CodecValueKind) String() string
type DecimalLimbOrder ¶
type DecimalLimbOrder uint8
DecimalLimbOrder controls how base-10000 limbs are ordered across registers. Used by M10k (modulo-10000) codecs; distinct from byte-order RegisterLayout.
const ( // DecimalLimbLowToHigh: first register is least-significant limb. // Schneider equivalents: 2143, 21-65, 21-87. DecimalLimbLowToHigh DecimalLimbOrder = iota + 1 // DecimalLimbHighToLow: first register is most-significant limb. // Schneider equivalents: 4321, 65-21, 87-21. DecimalLimbHighToLow )
func (DecimalLimbOrder) String ¶
func (o DecimalLimbOrder) String() string
type Decoder ¶
type Decoder[T any] interface { ID() string Name() string RegisterSpec() RegisterSpec ByteSpec() ByteSpec DecodeRegisters(regs []uint16) (T, error) }
Decoder decodes raw registers into a typed value.
type Encoder ¶
type Encoder[T any] interface { ID() string Name() string RegisterSpec() RegisterSpec ByteSpec() ByteSpec EncodeRegisters(value T) ([]uint16, error) }
Encoder encodes a typed value into raw registers.
type Endianness ¶
type Endianness = adu.Endianness
type RegType ¶
RegType selects holding vs input registers for read operations. This is an alias for protocol.RegType, identical to modbus.RegType.
type RegisterLayout ¶
type RegisterLayout struct {
// contains filtered or unexported fields
}
RegisterLayout describes how the bytes of a multi-register value are permuted across Modbus registers. Positions are 1-based: 1 is the least-significant byte, and the highest position (e.g. 8 for 64-bit) is the most-significant byte. Layout is immutable; use NewRegisterLayout or MustNewRegisterLayout to construct.
func MustNewRegisterLayout ¶
func MustNewRegisterLayout(registerCount uint16, positions ...uint8) RegisterLayout
MustNewRegisterLayout is like NewRegisterLayout but panics on error. Use for known-good layouts (e.g. package-level vars).
func NewRegisterLayout ¶
func NewRegisterLayout(registerCount uint16, positions ...uint8) (RegisterLayout, error)
NewRegisterLayout builds a RegisterLayout from a register count and byte positions. Positions are 1-based (1 = least-significant byte). Each position 1..(registerCount*2) must appear exactly once. registerCount must be 1..4.
func (RegisterLayout) BytePositions ¶
func (l RegisterLayout) BytePositions() []uint8
BytePositions returns a copy of the byte position permutation. Callers must not mutate the result. Length equals RegisterCount()*2.
func (RegisterLayout) RegisterCount ¶
func (l RegisterLayout) RegisterCount() uint16
RegisterCount returns the number of 16-bit Modbus registers (1..4).
func (RegisterLayout) String ¶
func (l RegisterLayout) String() string
String returns the layout as a compact digit string for IDs and discovery, e.g. "21", "4321", "87654321", "21436587".
type RegisterLayoutDescriptor ¶
type RegisterLayoutDescriptor struct {
Name string
Common bool
Layout RegisterLayout
}
RegisterLayoutDescriptor describes a layout variant for discovery (e.g. "4321", "2143").
type RegisterReader ¶
type RegisterReader interface {
ReadRegisters(ctx context.Context, unitID uint8, addr uint16, quantity uint16, regType RegType) ([]uint16, error)
}
RegisterReader can read Modbus registers. *modbus.Client satisfies this.
type RegisterSpec ¶
type RegisterSpec struct {
Count uint16
}
RegisterSpec declares the fixed register count for a codec. v1 uses only fixed width; variable-width forms are a future extension.
type RegisterWriter ¶
type RegisterWriter interface {
WriteRegisters(ctx context.Context, unitID uint8, addr uint16, values []uint16) error
}
RegisterWriter can write Modbus registers. *modbus.Client satisfies this.
type RuntimeCodec ¶
type RuntimeCodec interface {
RuntimeDecoder
RuntimeEncoder
}
RuntimeCodec is a combined runtime decoder and encoder.
func AsRuntimeCodec ¶
func AsRuntimeCodec[T any](c Codec[T], kind CodecValueKind) RuntimeCodec
AsRuntimeCodec wraps a typed Codec[T] as a RuntimeCodec. Wrong type passed to EncodeRegistersAny returns *CodecValueError and never panics.
func FindRuntimeCodecs ¶
func FindRuntimeCodecs(q CodecQuery) ([]RuntimeCodec, error)
FindRuntimeCodecs returns runtime codecs for all descriptors matching the query. Zero values in CodecQuery mean "no filter" for that field.
func MustRuntimeCodecByID ¶
func MustRuntimeCodecByID(id string) RuntimeCodec
MustRuntimeCodecByID is like RuntimeCodecByID but panics if the ID is unknown or if construction fails. Use for known-good IDs (e.g. from config or tests).
func RuntimeCodecByID ¶
func RuntimeCodecByID(id string) (RuntimeCodec, bool, error)
RuntimeCodecByID looks up a registered codec by ID and returns a RuntimeCodec. Returns (nil, false, nil) when the ID is not registered. Returns (nil, false, err) when the codec is registered but construction fails.
func RuntimeCodecFromDescriptor ¶
func RuntimeCodecFromDescriptor(desc CodecDescriptor) (RuntimeCodec, error)
RuntimeCodecFromDescriptor builds a RuntimeCodec from a concrete codec descriptor. The descriptor must represent a fully concrete codec (e.g. "uint32/layout:4321", "ascii/registers:4", "ip_addr"). Unknown or abstract descriptors return an error. Descriptor metadata is used only to identify the codec; the actual layout/count comes from the descriptor's Layouts, RegisterSpec, or ByteSpec.
func RuntimeCodecsForByteCount ¶
func RuntimeCodecsForByteCount(count uint16) ([]RuntimeCodec, error)
RuntimeCodecsForByteCount returns runtime codecs for all registered descriptors whose ByteSpec.Count equals count.
func RuntimeCodecsForRegisterCount ¶
func RuntimeCodecsForRegisterCount(count uint16) ([]RuntimeCodec, error)
RuntimeCodecsForRegisterCount returns runtime codecs for all registered descriptors whose RegisterSpec.Count equals count. Returned codecs are directly usable for DecodeRegistersAny, EncodeRegistersAny, and runtime plan execution. Returns an error if any descriptor fails to instantiate.
type RuntimeDecoder ¶
type RuntimeDecoder interface {
ID() string
Name() string
RegisterSpec() RegisterSpec
ByteSpec() ByteSpec
ValueKind() CodecValueKind
DecodeRegistersAny(regs []uint16) (any, error)
}
RuntimeDecoder decodes raw registers into an any value. Used for discovery, CLI selection, and batch decode plans where the concrete type is not known at compile time.
func AsRuntimeDecoder ¶
func AsRuntimeDecoder[T any](d Decoder[T], kind CodecValueKind) RuntimeDecoder
AsRuntimeDecoder wraps a typed Decoder[T] as a RuntimeDecoder. The kind is stored for discovery/CLI.
type RuntimeEncoder ¶
type RuntimeEncoder interface {
ID() string
Name() string
RegisterSpec() RegisterSpec
ByteSpec() ByteSpec
ValueKind() CodecValueKind
EncodeRegistersAny(value any) ([]uint16, error)
}
RuntimeEncoder encodes an any value into raw registers. Callers must pass a value whose type matches the codec; otherwise EncodeRegistersAny returns a *CodecValueError (never panics). For interface types (e.g. net.IP), a typed nil (var ip net.IP = nil) may pass the type assertion while an untyped nil may not; CLI/runtime callers should be aware when passing nil.
func AsRuntimeEncoder ¶
func AsRuntimeEncoder[T any](e Encoder[T], kind CodecValueKind) RuntimeEncoder
AsRuntimeEncoder wraps a typed Encoder[T] as a RuntimeEncoder. Wrong type passed to EncodeRegistersAny returns *CodecValueError and never panics.