Documentation
¶
Index ¶
- Variables
- func WithSerialHooks(hooks ClientHooks) func(c *SerialClient)
- func WithSerialReadTimeout(readTimeout time.Duration) func(c *SerialClient)
- type BFielddeprecated
- func (f *BField) ByteOrder(byteOrder packet.ByteOrder) *BFielddeprecated
- func (f *BField) FunctionCode(functionCode uint8) *BFielddeprecated
- func (f *BField) Name(name string) *BFielddeprecated
- func (f *BField) Protocol(protocol ProtocolType) *BFielddeprecated
- func (f *BField) RequestInterval(requestInterval time.Duration) *BFielddeprecated
- func (f *BField) ServerAddress(serverAddress string) *BFielddeprecated
- func (f *BField) UnitID(unitID uint8) *BFielddeprecated
- type Builder
- func (b *Builder) Add(field *BField) *Builderdeprecated
- func (b *Builder) AddAll(fields Fields) *Builder
- func (b *Builder) AddField(field Field) *Builder
- func (b *Builder) Bit(registerAddress uint16, bit uint8) *BFielddeprecated
- func (b *Builder) Byte(registerAddress uint16, fromHighByte bool) *BFielddeprecated
- func (b *Builder) Bytes(registerAddress uint16, byteLength uint8) *BFielddeprecated
- func (b *Builder) Coil(address uint16) *BFielddeprecated
- func (b *Builder) Float32(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Float64(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Int16(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Int32(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Int64(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Int8(registerAddress uint16, fromHighByte bool) *BFielddeprecated
- func (b *Builder) ReadCoilsRTU() ([]BuilderRequest, error)
- func (b *Builder) ReadCoilsTCP() ([]BuilderRequest, error)
- func (b *Builder) ReadDiscreteInputsRTU() ([]BuilderRequest, error)
- func (b *Builder) ReadDiscreteInputsTCP() ([]BuilderRequest, error)
- func (b *Builder) ReadHoldingRegistersRTU() ([]BuilderRequest, error)
- func (b *Builder) ReadHoldingRegistersTCP() ([]BuilderRequest, error)
- func (b *Builder) ReadInputRegistersRTU() ([]BuilderRequest, error)
- func (b *Builder) ReadInputRegistersTCP() ([]BuilderRequest, error)
- func (b *Builder) Split() ([]BuilderRequest, error)
- func (b *Builder) String(registerAddress uint16, length uint8) *BFielddeprecated
- func (b *Builder) Uint16(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Uint32(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Uint64(registerAddress uint16) *BFielddeprecated
- func (b *Builder) Uint8(registerAddress uint16, fromHighByte bool) *BFielddeprecated
- type BuilderDefaults
- type BuilderRequest
- type Client
- type ClientConfig
- type ClientError
- type ClientHooks
- type CoilsResponse
- type Duration
- type Field
- type FieldType
- type FieldValue
- type Fields
- type Flusher
- type Invalid
- type ProtocolType
- type RegistersResponse
- type SerialClient
- type SerialClientOptionFunc
Constants ¶
This section is empty.
Variables ¶
var ErrClientNotConnected = &ClientError{Err: errors.New("client is not connected")}
ErrClientNotConnected is error indicating that Client has not yet connected to the modbus server
var ErrInvalidValue = errors.New("invalid value")
ErrInvalidValue is returned when extracted value for Field resulted invalid value (Field.Invalid).
var ErrPacketTooLong = &ClientError{Err: errors.New("received more bytes than valid Modbus packet size can be")}
ErrPacketTooLong is error indicating that modbus server sent amount of data that is bigger than any modbus packet could be
var ErrorFieldExtractHadError = errors.New("field extraction had an error. check FieldValue.Error for details")
ErrorFieldExtractHadError is returned when ExtractFields could not extract value from Field
Functions ¶
func WithSerialHooks ¶
func WithSerialHooks(hooks ClientHooks) func(c *SerialClient)
WithSerialHooks is option to set hooks for SerialClient
func WithSerialReadTimeout ¶
func WithSerialReadTimeout(readTimeout time.Duration) func(c *SerialClient)
WithSerialReadTimeout is option to for setting total timeout for reading the whole packet
Types ¶
type BField
deprecated
type BField struct {
Field
}
BField is distinct field be requested and extracted from response
Deprecated: use `modbus.Field` struct and methods `Builder.AddAll(fields Fields)` and `Builder.AddField(field Field)`
func (*BField) ByteOrder
deprecated
func (*BField) FunctionCode
deprecated
func (*BField) Name
deprecated
func (*BField) Protocol
deprecated
func (f *BField) Protocol(protocol ProtocolType) *BField
Protocol sets Protocol for Field
Deprecated: use `modbus.Field` struct and methods `Builder.AddAll(fields Fields)` and `Builder.AddField(field Field)`
func (*BField) RequestInterval
deprecated
func (*BField) ServerAddress
deprecated
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder helps to group extractable field values of different types into modbus requests with minimal amount of separate requests produced
func NewRequestBuilder ¶
NewRequestBuilder creates new instance of Builder
func NewRequestBuilderWithConfig ¶
func NewRequestBuilderWithConfig(config BuilderDefaults) *Builder
NewRequestBuilderWithConfig creates new instance of Builder with given defaults. Arguments can be left empty and ServerAddress+UnitID provided for each field separately
func (*Builder) AddAll ¶
AddAll adds field into Builder. AddAll does not set ServerAddress and UnitID values.
func (*Builder) Bytes
deprecated
Bytes add raw bytes field to Builder to be requested and extracted. byteLength is length in bytes (1 register is 2 bytes)
Deprecated: use `modbus.Field` struct and methods `Builder.AddAll(fields Fields)` and `Builder.AddField(field Field)`
func (*Builder) ReadCoilsRTU ¶
func (b *Builder) ReadCoilsRTU() ([]BuilderRequest, error)
ReadCoilsRTU combines fields into RTU Read Coils (FC1) requests
func (*Builder) ReadCoilsTCP ¶
func (b *Builder) ReadCoilsTCP() ([]BuilderRequest, error)
ReadCoilsTCP combines fields into TCP Read Coils (FC1) requests
func (*Builder) ReadDiscreteInputsRTU ¶
func (b *Builder) ReadDiscreteInputsRTU() ([]BuilderRequest, error)
ReadDiscreteInputsRTU combines fields into RTU Read Discrete Inputs (FC2) requests
func (*Builder) ReadDiscreteInputsTCP ¶
func (b *Builder) ReadDiscreteInputsTCP() ([]BuilderRequest, error)
ReadDiscreteInputsTCP combines fields into TCP Read Discrete Inputs (FC2) requests
func (*Builder) ReadHoldingRegistersRTU ¶
func (b *Builder) ReadHoldingRegistersRTU() ([]BuilderRequest, error)
ReadHoldingRegistersRTU combines fields into RTU Read Holding Registers (FC3) requests
func (*Builder) ReadHoldingRegistersTCP ¶
func (b *Builder) ReadHoldingRegistersTCP() ([]BuilderRequest, error)
ReadHoldingRegistersTCP combines fields into TCP Read Holding Registers (FC3) requests
func (*Builder) ReadInputRegistersRTU ¶
func (b *Builder) ReadInputRegistersRTU() ([]BuilderRequest, error)
ReadInputRegistersRTU combines fields into RTU Read Input Registers (FC4) requests
func (*Builder) ReadInputRegistersTCP ¶
func (b *Builder) ReadInputRegistersTCP() ([]BuilderRequest, error)
ReadInputRegistersTCP combines fields into TCP Read Input Registers (FC4) requests
func (*Builder) Split ¶
func (b *Builder) Split() ([]BuilderRequest, error)
Split combines fields into requests by their ServerAddress+FunctionCode+UnitID+Protocol+RequestInterval
type BuilderDefaults ¶
type BuilderDefaults struct { // Should be formatted as url.URL scheme `[scheme:][//[userinfo@]host][/]path[?query]` // Example: // * `127.0.0.1:502` (library defaults to `tcp` as scheme) // * `udp://127.0.0.1:502` // * `/dev/ttyS0?BaudRate=4800` // * `file:///dev/ttyUSB?BaudRate=4800` ServerAddress string `json:"server_address" mapstructure:"server_address"` FunctionCode uint8 `json:"function_code" mapstructure:"function_code"` // UnitID default value for added field. Note: if non zero is set as default it will overwrite zero on Field. UnitID uint8 `json:"unit_id" mapstructure:"unit_id"` Protocol ProtocolType `json:"protocol" mapstructure:"protocol"` Interval Duration `json:"interval" mapstructure:"interval"` }
BuilderDefaults holds Builder default values for adding/creating Fields
type BuilderRequest ¶
type BuilderRequest struct { packet.Request // ServerAddress is modbus server address where request should be sent ServerAddress string // UnitID is unit identifier of modbus slave device UnitID uint8 // StartAddress is start register address for request StartAddress uint16 // Quantity is amount of registers/coils to return with request Quantity uint16 Protocol ProtocolType RequestInterval time.Duration // Fields is slice of field use to construct the request and to be extracted from response Fields Fields }
BuilderRequest helps to connect requested fields to responses
func (BuilderRequest) AsRegisters ¶
func (r BuilderRequest) AsRegisters(response RegistersResponse) (*packet.Registers, error)
AsRegisters returns response data as Register to more convenient access
func (BuilderRequest) ExtractFields ¶
func (r BuilderRequest) ExtractFields(response packet.Response, continueOnExtractionErrors bool) ([]FieldValue, error)
ExtractFields extracts Field values from given response. When continueOnExtractionErrors is true and error occurs during extraction, this method does not end but continues to extract all Fields and returns ErrorFieldExtractHadError at the end. To distinguish errors check FieldValue.Error field.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client provides mechanisms to send requests to modbus server over network connection
func NewClient ¶
func NewClient(conf ClientConfig) *Client
NewClient creates new instance of Modbus Client with given configuration options
func NewRTUClient ¶
func NewRTUClient() *Client
NewRTUClient creates new instance of Modbus Client for Modbus RTU protocol
func NewRTUClientWithConfig ¶
func NewRTUClientWithConfig(conf ClientConfig) *Client
NewRTUClientWithConfig creates new instance of Modbus Client for Modbus RTU protocol with given configuration options
func NewTCPClient ¶
func NewTCPClient() *Client
NewTCPClient creates new instance of Modbus Client for Modbus TCP protocol
func NewTCPClientWithConfig ¶
func NewTCPClientWithConfig(conf ClientConfig) *Client
NewTCPClientWithConfig creates new instance of Modbus Client for Modbus TCP protocol with given configuration options
func (*Client) Connect ¶
Connect opens network connection to Client to server. Context lifetime is only meant for this call. ctx is to be used for to cancel connection attempt.
`address` should be formatted as url.URL scheme `[scheme:][//[userinfo@]host][/]path[?query]` Example: * `127.0.0.1:502` (library defaults to `tcp` as scheme) * `udp://127.0.0.1:502` * `/dev/ttyS0?BaudRate=4800` * `file:///dev/ttyUSB?BaudRate=4800`
func (*Client) Do ¶
Do sends given Modbus request to modbus server and returns parsed Response. ctx is to be used for to cancel connection attempt. On modbus exception nil is returned as response and error wraps value of type packet.ErrorResponseTCP or packet.ErrorResponseRTU User errors.Is and errors.As to check if error wraps packet.ErrorResponseTCP or packet.ErrorResponseRTU
type ClientConfig ¶
type ClientConfig struct { // WriteTimeout is total amount of time writing the request can take after client returns error WriteTimeout time.Duration // ReadTimeout is total amount of time reading the response can take before client returns error ReadTimeout time.Duration DialContextFunc func(ctx context.Context, address string) (net.Conn, error) AsProtocolErrorFunc func(data []byte) error ParseResponseFunc func(data []byte) (packet.Response, error) Hooks ClientHooks }
ClientConfig is configuration for Client
type ClientError ¶
type ClientError struct {
Err error
}
ClientError indicates errors returned by Client that network related and are possibly retryable
func (*ClientError) Error ¶
func (e *ClientError) Error() string
Error returns contained error message
func (*ClientError) Unwrap ¶
func (e *ClientError) Unwrap() error
Unwrap allows unwrapping errors with errors.Is and errors.As
type ClientHooks ¶
type ClientHooks interface { BeforeWrite(toWrite []byte) AfterEachRead(received []byte, n int, err error) BeforeParse(received []byte) }
ClientHooks allows to log bytes send/received by client. NB: Do not modify given slice - it is not a copy.
type CoilsResponse ¶
type CoilsResponse interface { packet.Response IsCoilSet(startAddress uint16, coilAddress uint16) (bool, error) }
CoilsResponse is marker interface for responses returning coil/discrete data
type Duration ¶
A Duration represents the elapsed time between two instants. This library type extends time.Duration with JSON marshalling and unmarshalling support to/from string. i.e. "1s" unmarshalled to `1 * time.Second`
func (Duration) MarshalJSON ¶
MarshalJSON converts Duration to JSON bytes
func (*Duration) UnmarshalJSON ¶
UnmarshalJSON converts raw bytes from JSON to Duration
type Field ¶
type Field struct { Name string `json:"name" mapstructure:"name"` // ServerAddress is Modbus server location as URL. // URL: `scheme://host:port` or file `/dev/ttyS0?BaudRate=4800` // Query parameters are used to pass information about network connection or how to split // fields into request batches. // // Splitter logic know following query parameters: // - `max_quantity_per_request` maximum quantity (uint16) that request can have. How many // registers/coils requests will be limited to. // - `invalid_addr=70,100-120` - addresses or address range that splitter will avoid to include in request // when creating batches. ServerAddress string `json:"server_address" mapstructure:"server_address"` FunctionCode uint8 `json:"function_code" mapstructure:"function_code"` UnitID uint8 `json:"unit_id" mapstructure:"unit_id"` Protocol ProtocolType `json:"protocol" mapstructure:"protocol"` RequestInterval Duration `json:"request_interval" mapstructure:"request_interval"` // Address of the register (first register of that data type) or discrete/coil address in modbus. // Addresses are 0-based. Address uint16 `json:"address" mapstructure:"address"` Type FieldType `json:"type" mapstructure:"type"` // Only relevant to register function fields Bit uint8 `json:"bit" mapstructure:"bit"` // FromHighByte is for single byte data types stored in single register (e.g. byte,uint8,int8) // // In Modbus (which uses big-endian format), the most significant byte is // sent first and is therefore considered the 0th byte. The least significant byte // is sent second and is considered the 1st byte. // // Modbus register with value `0x1234`. // - 0x12 is High Byte, 0th byte // - 0x34 is Low byte, is the 1st byte FromHighByte bool `json:"from_high_byte" mapstructure:"from_high_byte"` // Length is length of string and raw bytes data types. Length uint8 `json:"length" mapstructure:"length"` ByteOrder packet.ByteOrder `json:"byte_order" mapstructure:"byte_order"` // Invalid that represents not existent value in modbus. Given value (presented in hex) when encountered is converted to ErrInvalidValue error. // for example your energy meter ac power is uint32 value of which `0xffffffff` should be treated as error/invalid value. // // Usually invalid value is largest unsigned or smallest signed value per data type. Example: // - uint8 = 0xff (255) // - int8 = 0x80 (-127) // - uint16 = 0xff, 0xff (65535) // - int16 = 0x80, 0x00 (-32768) // - uint32 = 0xff, 0xff, 0xff, 0xff (4294967295) // - int32 = 0x80, 0x0, 0x0, 0x0 (-2147483648) // - uint64 = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff (18446744073709551615) // - int64 = 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 (-9223372036854775808) // - float32 is same as uint32 // - float64 is same as uint64 // - bit, boolean - can not have invalid values Invalid Invalid `json:"invalid,omitempty" mapstructure:"invalid"` }
Field is distinct field be requested and extracted from response Tag `mapstructure` allows you to marshal https://github.com/spf13/viper supported configuration format to the Field
func (*Field) CheckInvalid ¶
CheckInvalid compares Invalid value to bytes in fields registers. When raw data in response equal to Invalid the ErrInvalidValue error is returned. Nil return value means no problems occurred.
func (*Field) ExtractFrom ¶
ExtractFrom extracts field value from given registers data
func (*Field) MarshalBytes ¶
MarshalBytes converts given value to suitable Modbus bytes (in big endian) that can be used as request data. This method will truncate/limit value to max/min value of field being marshalled. In case field type is Float32 or Float64 providing bigger int (e.g. uint64) conversion will have loss of precision
Accepted types for given value are: - bool - uint8,int8,byte - uint16,int16 - uint32,int32 - uint64,int64 - float32,float64 - string (Note: raw utf8 bytes. If you need ASCII, convert the string before) - []byte
type FieldType ¶
type FieldType uint8
FieldType is enum type for data types that Field can represent
const ( // FieldTypeBit represents single bit out 16 bit register. Use `Field.Bit` (0-15) to indicate which bit is meant. FieldTypeBit FieldType = 1 // FieldTypeByte represents single byte of 16 bit, 2 byte, single register. Use `Field.FromHighByte` to indicate is high or low byte is meant. FieldTypeByte FieldType = 2 // FieldTypeUint8 represents uint8 value of 2 byte, single register. Use `Field.FromHighByte` to indicate is high or low byte value is meant. FieldTypeUint8 FieldType = 3 // FieldTypeInt8 represents int8 value of 2 byte, single register. Use `Field.FromHighByte` to indicate is high or low byte value is meant. FieldTypeInt8 FieldType = 4 // FieldTypeUint16 represents single register (16 bit) as uint16 value FieldTypeUint16 FieldType = 5 // FieldTypeInt16 represents single register (16 bit) as int16 value FieldTypeInt16 FieldType = 6 // FieldTypeUint32 represents 2 registers (32 bit) as uint32 value. Use `Field.ByteOrder` to indicate byte and word order of register data. FieldTypeUint32 FieldType = 7 // FieldTypeInt32 represents 2 registers (32 bit) as int32 value. Use `Field.ByteOrder` to indicate byte and word order of register data. FieldTypeInt32 FieldType = 8 // FieldTypeUint64 represents 4 registers (64 bit) as uint64 value. Use `Field.ByteOrder` to indicate byte and word order of register data. FieldTypeUint64 FieldType = 9 // FieldTypeInt64 represents 4 registers (64 bit) as int64 value. Use `Field.ByteOrder` to indicate byte and word order of register data. FieldTypeInt64 FieldType = 10 // FieldTypeFloat32 represents 2 registers (32 bit) as float32 value. Use `Field.ByteOrder` to indicate byte and word order of register data. FieldTypeFloat32 FieldType = 11 // FieldTypeFloat64 represents 4 registers (64 bit) as float64 value. Use `Field.ByteOrder` to indicate byte and word order of register data. FieldTypeFloat64 FieldType = 12 // FieldTypeString represents N registers as string value. Use `Field.Length` to length of string. FieldTypeString FieldType = 13 // FieldTypeCoil represents single discrete/coil value (used by FC1/FC2). FieldTypeCoil FieldType = 14 // FieldTypeRawBytes represents N registers contents as byte slice. FieldTypeRawBytes FieldType = 15 )
func ParseFieldType ¶
ParseFieldType parses given string to FieldType
func (*FieldType) UnmarshalJSON ¶
UnmarshalJSON converts raw bytes from JSON to FieldType
type FieldValue ¶
type FieldValue struct { Field Field // Value contains extracted value // possible types: // * bool // * byte // * []byte // * uint[8/16/32/64] // * int[8/16/32/64] // * float[32/64] // * string Value any // Error contains error that occurred during extracting field from response. // In case Field.Invalid was set and response data contained it the Error is set to modbus.ErrInvalidValue Error error }
FieldValue is concrete value extracted from register data using field data type and byte order
type Flusher ¶
type Flusher interface {
Flush() error
}
Flusher is interface for flushing unread/unwritten data from serial port buffer
type Invalid ¶
type Invalid []byte
Invalid that represents not existent value in modbus. Given value (presented in hex) when encountered is converted to ErrInvalidValue error. for example your energy meter ac power is uint32 value of which `0xffffffff` should be treated as error/invalid value.
func (Invalid) MarshalJSON ¶
MarshalJSON converts Invalid to JSON bytes
func (*Invalid) UnmarshalJSON ¶
UnmarshalJSON converts raw bytes from JSON to Invalid
type ProtocolType ¶
type ProtocolType uint8
ProtocolType represents which Modbus encoding is being used.
const ( // ProtocolTCP represents Modbus TCP encoding which could be transferred over TCP/UDP connection. ProtocolTCP ProtocolType = 1 // ProtocolRTU represents Modbus RTU encoding with a Cyclic-Redundant Checksum. Could be transferred // over TCP/UDP and serial connection. ProtocolRTU ProtocolType = 2 )
func (*ProtocolType) UnmarshalJSON ¶
func (pt *ProtocolType) UnmarshalJSON(raw []byte) error
UnmarshalJSON converts raw bytes from JSON to Invalid
type RegistersResponse ¶
type RegistersResponse interface { packet.Response AsRegisters(requestStartAddress uint16) (*packet.Registers, error) }
RegistersResponse is marker interface for responses returning register data
type SerialClient ¶
type SerialClient struct {
// contains filtered or unexported fields
}
SerialClient provides mechanisms to send requests to modbus server over serial port
func NewSerialClient ¶
func NewSerialClient(serialPort io.ReadWriteCloser, opts ...SerialClientOptionFunc) *SerialClient
NewSerialClient creates new instance of Modbus SerialClient for Modbus RTU protocol
func (*SerialClient) Close ¶
func (c *SerialClient) Close() error
Close closes serial connection to the device
func (*SerialClient) Do ¶
Do sends given Modbus request to modbus server and returns parsed Response. ctx is to be used for to cancel connection attempt. On modbus exception nil is returned as response and error wraps value of type packet.ErrorResponseRTU User errors.Is and errors.As to check if error wraps packet.ErrorResponseRTU
type SerialClientOptionFunc ¶
type SerialClientOptionFunc func(c *SerialClient)
SerialClientOptionFunc is options type for NewSerialClient function