evcc-io/util/modbus/connection.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)
})
}