127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
package modbus
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/volkszaehler/mbmd/meters"
|
|
)
|
|
|
|
// Connection is a logical modbus connection per slave ID sharing a physical connection
|
|
type Connection struct {
|
|
*logger
|
|
meters.Connection
|
|
physical *meterConnection
|
|
slaveID uint8 // duplicated from meters.Connection
|
|
logical meters.Logger
|
|
}
|
|
|
|
func (c *Connection) Addr() string {
|
|
return fmt.Sprintf("%s::%d", c.Connection.String(), c.slaveID)
|
|
}
|
|
|
|
func (c *Connection) Logger(logger meters.Logger) {
|
|
c.logical = logger
|
|
}
|
|
|
|
// Delay applies the delay to the shared physical connection
|
|
func (c *Connection) Delay(delay time.Duration) {
|
|
c.physical.setDelay(delay)
|
|
}
|
|
|
|
func (c *Connection) Clone(slaveID uint8) *Connection {
|
|
return &Connection{
|
|
slaveID: slaveID,
|
|
Connection: c.Connection.Clone(slaveID),
|
|
logger: c.logger,
|
|
physical: c.physical,
|
|
}
|
|
}
|
|
|
|
// ConnectDelay applies the connect delay to the shared physical connection
|
|
func (c *Connection) ConnectDelay(delay time.Duration) {
|
|
c.physical.setConnectDelay(delay)
|
|
}
|
|
|
|
// Timeout applies the timeout to the shared physical connection
|
|
func (c *Connection) Timeout(timeout time.Duration) {
|
|
c.physical.setTimeout(timeout)
|
|
}
|
|
|
|
func (c *Connection) exec(fun func() ([]byte, error)) ([]byte, error) {
|
|
return c.WithLogger(c.logical, func() ([]byte, error) {
|
|
time.Sleep(c.physical.getDelay())
|
|
|
|
b, err := fun()
|
|
if err != nil {
|
|
c.Connection.Close()
|
|
}
|
|
return b, err
|
|
})
|
|
}
|
|
|
|
func (c *Connection) ReadCoils(address, quantity uint16) ([]byte, error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().ReadCoils(address, quantity)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) WriteSingleCoil(address, value uint16) ([]byte, error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().WriteSingleCoil(address, value)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) ReadInputRegisters(address, quantity uint16) ([]byte, error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().ReadInputRegisters(address, quantity)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) ReadHoldingRegisters(address, quantity uint16) ([]byte, error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().ReadHoldingRegisters(address, quantity)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) WriteSingleRegister(address, value uint16) ([]byte, error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().WriteSingleRegister(address, value)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) WriteMultipleRegisters(address, quantity uint16, value []byte) ([]byte, error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().WriteMultipleRegisters(address, quantity, value)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) ReadDiscreteInputs(address, quantity uint16) (results []byte, err error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().ReadDiscreteInputs(address, quantity)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) WriteMultipleCoils(address, quantity uint16, value []byte) (results []byte, err error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().WriteMultipleCoils(address, quantity, value)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) ReadWriteMultipleRegisters(readAddress, readQuantity, writeAddress, writeQuantity uint16, value []byte) (results []byte, err error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().ReadWriteMultipleRegisters(readAddress, readQuantity, writeAddress, writeQuantity, value)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) MaskWriteRegister(address, andMask, orMask uint16) (results []byte, err error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().MaskWriteRegister(address, andMask, orMask)
|
|
})
|
|
}
|
|
|
|
func (c *Connection) ReadFIFOQueue(address uint16) (results []byte, err error) {
|
|
return c.exec(func() ([]byte, error) {
|
|
return c.ModbusClient().ReadFIFOQueue(address)
|
|
})
|
|
}
|