refactor: 重构,修复包引用问题;添加rtu相关连接封装
parent
ebcbd0f88f
commit
e99030b919
@ -0,0 +1,39 @@
|
||||
package connection
|
||||
|
||||
import (
|
||||
"github.com/goburrow/serial"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RTUConn rtu connection wrapper
|
||||
type RTUConn struct {
|
||||
serial.Port
|
||||
config *serial.Config
|
||||
}
|
||||
|
||||
// NewRTUConn 新建 RTUConn
|
||||
func NewRTUConn(port serial.Port, cfg *serial.Config) net.Conn {
|
||||
return &RTUConn{Port: port, config: cfg}
|
||||
}
|
||||
|
||||
func (c *RTUConn) LocalAddr() net.Addr {
|
||||
cfg := c.config
|
||||
return NewRTUAddr(cfg.Address, cfg.BaudRate, cfg.DataBits, cfg.StopBits, cfg.Parity)
|
||||
}
|
||||
|
||||
func (c *RTUConn) RemoteAddr() net.Addr {
|
||||
return c.LocalAddr()
|
||||
}
|
||||
|
||||
func (c *RTUConn) SetDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RTUConn) SetReadDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RTUConn) SetWriteDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package connection
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
const RTUNetwork = "rtu"
|
||||
|
||||
type RTUAddr struct {
|
||||
Address string
|
||||
BaudRate int
|
||||
DataBits int
|
||||
StopBits int
|
||||
Parity string
|
||||
}
|
||||
|
||||
func NewRTUAddr(addr string, rate int, dataBits int, stopBits int, parity string) net.Addr {
|
||||
return &RTUAddr{
|
||||
Address: addr,
|
||||
BaudRate: rate,
|
||||
DataBits: dataBits,
|
||||
StopBits: stopBits,
|
||||
Parity: parity,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RTUAddr) Network() string {
|
||||
return RTUNetwork
|
||||
}
|
||||
|
||||
// String form of address (for example, "/dev/ttyS0|19200|8|1|N", "com1|19200|8|1|N")
|
||||
func (r *RTUAddr) String() string {
|
||||
return fmt.Sprintf("%s|%d|%d|%d", r.Address, r.BaudRate, r.DataBits, r.StopBits)
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package modbus
|
||||
|
||||
import "sync"
|
||||
|
||||
var crcTable []uint16
|
||||
var mu sync.Mutex
|
||||
|
||||
// crcModbus 计算modbus的crc
|
||||
func crcModbus(data []byte) (crc uint16) {
|
||||
if crcTable == nil {
|
||||
mu.Lock()
|
||||
if crcTable == nil {
|
||||
initCrcTable()
|
||||
}
|
||||
mu.Unlock()
|
||||
}
|
||||
crc = 0xffff
|
||||
for _, v := range data {
|
||||
crc = (crc >> 8) ^ crcTable[(crc^uint16(v))&0x00FF]
|
||||
}
|
||||
return crc
|
||||
}
|
||||
|
||||
// initCrcTable 初始化crcTable
|
||||
func initCrcTable() {
|
||||
crc16IBM := uint16(0xA001)
|
||||
crcTable = make([]uint16, 256)
|
||||
|
||||
for i := uint16(0); i < 256; i++ {
|
||||
crc := uint16(0)
|
||||
c := i
|
||||
|
||||
for j := uint16(0); j < 8; j++ {
|
||||
if ((crc ^ c) & 0x0001) > 0 {
|
||||
crc = (crc >> 1) ^ crc16IBM
|
||||
} else {
|
||||
crc = crc >> 1
|
||||
}
|
||||
c = c >> 1
|
||||
}
|
||||
crcTable[i] = crc
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package modbus
|
||||
|
||||
import (
|
||||
"git.noahlan.cn/noahlan/nnet/protocol/modbus/internal"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCRC(t *testing.T) {
|
||||
got := crcModbus([]byte{0x01, 0x04, 0x02, 0xFF, 0xFF})
|
||||
expect := uint16(0x80B8)
|
||||
|
||||
assert := internal.NewAssert(t, "TestCRC")
|
||||
assert.Equal(expect, got)
|
||||
}
|
@ -1,167 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
compareNotEqual int = iota - 2
|
||||
compareLess
|
||||
compareEqual
|
||||
compareGreater
|
||||
)
|
||||
|
||||
// Assert is a simple implementation of assertion, only for internal usage
|
||||
type Assert struct {
|
||||
T *testing.T
|
||||
CaseName string
|
||||
}
|
||||
|
||||
// NewAssert return instance of Assert
|
||||
func NewAssert(t *testing.T, caseName string) *Assert {
|
||||
return &Assert{T: t, CaseName: caseName}
|
||||
}
|
||||
|
||||
// Equal check if expected is equal with actual
|
||||
func (a *Assert) Equal(expected, actual any) {
|
||||
if compare(expected, actual) != compareEqual {
|
||||
makeTestFailed(a.T, a.CaseName, expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// NotEqual check if expected is not equal with actual
|
||||
func (a *Assert) NotEqual(expected, actual any) {
|
||||
if compare(expected, actual) == compareEqual {
|
||||
expectedInfo := fmt.Sprintf("not %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// Greater check if expected is greate than actual
|
||||
func (a *Assert) Greater(expected, actual any) {
|
||||
if compare(expected, actual) != compareGreater {
|
||||
expectedInfo := fmt.Sprintf("> %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// GreaterOrEqual check if expected is greate than or equal with actual
|
||||
func (a *Assert) GreaterOrEqual(expected, actual any) {
|
||||
isGreatOrEqual := compare(expected, actual) == compareGreater || compare(expected, actual) == compareEqual
|
||||
if !isGreatOrEqual {
|
||||
expectedInfo := fmt.Sprintf(">= %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// Less check if expected is less than actual
|
||||
func (a *Assert) Less(expected, actual any) {
|
||||
if compare(expected, actual) != compareLess {
|
||||
expectedInfo := fmt.Sprintf("< %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// LessOrEqual check if expected is less than or equal with actual
|
||||
func (a *Assert) LessOrEqual(expected, actual any) {
|
||||
isLessOrEqual := compare(expected, actual) == compareLess || compare(expected, actual) == compareEqual
|
||||
if !isLessOrEqual {
|
||||
expectedInfo := fmt.Sprintf("<= %v", expected)
|
||||
makeTestFailed(a.T, a.CaseName, expectedInfo, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// IsNil check if value is nil
|
||||
func (a *Assert) IsNil(value any) {
|
||||
if value != nil {
|
||||
makeTestFailed(a.T, a.CaseName, nil, value)
|
||||
}
|
||||
}
|
||||
|
||||
// IsNotNil check if value is not nil
|
||||
func (a *Assert) IsNotNil(value any) {
|
||||
if value == nil {
|
||||
makeTestFailed(a.T, a.CaseName, "not nil", value)
|
||||
}
|
||||
}
|
||||
|
||||
// compare x and y return :
|
||||
// x > y -> 1, x < y -> -1, x == y -> 0, x != y -> -2
|
||||
func compare(x, y any) int {
|
||||
vx := reflect.ValueOf(x)
|
||||
vy := reflect.ValueOf(y)
|
||||
|
||||
if vx.Type() != vy.Type() {
|
||||
return compareNotEqual
|
||||
}
|
||||
|
||||
switch vx.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
xInt := vx.Int()
|
||||
yInt := vy.Int()
|
||||
if xInt > yInt {
|
||||
return compareGreater
|
||||
}
|
||||
if xInt == yInt {
|
||||
return compareEqual
|
||||
}
|
||||
if xInt < yInt {
|
||||
return compareLess
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
xUint := vx.Uint()
|
||||
yUint := vy.Uint()
|
||||
if xUint > yUint {
|
||||
return compareGreater
|
||||
}
|
||||
if xUint == yUint {
|
||||
return compareEqual
|
||||
}
|
||||
if xUint < yUint {
|
||||
return compareLess
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
xFloat := vx.Float()
|
||||
yFloat := vy.Float()
|
||||
if xFloat > yFloat {
|
||||
return compareGreater
|
||||
}
|
||||
if xFloat == yFloat {
|
||||
return compareEqual
|
||||
}
|
||||
if xFloat < yFloat {
|
||||
return compareLess
|
||||
}
|
||||
case reflect.String:
|
||||
xString := vx.String()
|
||||
yString := vy.String()
|
||||
if xString > yString {
|
||||
return compareGreater
|
||||
}
|
||||
if xString == yString {
|
||||
return compareEqual
|
||||
}
|
||||
if xString < yString {
|
||||
return compareLess
|
||||
}
|
||||
default:
|
||||
if reflect.DeepEqual(x, y) {
|
||||
return compareEqual
|
||||
}
|
||||
return compareNotEqual
|
||||
}
|
||||
|
||||
return compareNotEqual
|
||||
|
||||
}
|
||||
|
||||
// logFailedInfo make test failed and log error info
|
||||
func makeTestFailed(t *testing.T, caseName string, expected, actual any) {
|
||||
_, file, line, _ := runtime.Caller(2)
|
||||
errInfo := fmt.Sprintf("Case %v failed. file: %v, line: %v, expected: %v, actual: %v.", caseName, file, line, expected, actual)
|
||||
t.Error(errInfo)
|
||||
t.FailNow()
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAssert(t *testing.T) {
|
||||
assert := NewAssert(t, "TestAssert")
|
||||
assert.Equal(0, 0)
|
||||
assert.NotEqual(1, 0)
|
||||
|
||||
assert.NotEqual("1", 1)
|
||||
var uInt1 uint
|
||||
var uInt2 uint
|
||||
var uInt8 uint8
|
||||
var uInt16 uint16
|
||||
var uInt32 uint32
|
||||
var uInt64 uint64
|
||||
assert.NotEqual(uInt1, uInt8)
|
||||
assert.NotEqual(uInt8, uInt16)
|
||||
assert.NotEqual(uInt16, uInt32)
|
||||
assert.NotEqual(uInt32, uInt64)
|
||||
|
||||
assert.Equal(uInt1, uInt2)
|
||||
|
||||
uInt1 = 1
|
||||
uInt2 = 2
|
||||
assert.Less(uInt1, uInt2)
|
||||
|
||||
assert.Greater(1, 0)
|
||||
assert.GreaterOrEqual(1, 1)
|
||||
assert.Less(0, 1)
|
||||
assert.LessOrEqual(0, 0)
|
||||
|
||||
assert.Equal(0.1, 0.1)
|
||||
assert.Greater(1.1, 0.1)
|
||||
assert.Less(0.1, 1.1)
|
||||
|
||||
assert.Equal("abc", "abc")
|
||||
assert.NotEqual("abc", "abd")
|
||||
assert.Less("abc", "abd")
|
||||
assert.Greater("abd", "abc")
|
||||
|
||||
assert.Equal([]int{1, 2, 3}, []int{1, 2, 3})
|
||||
assert.NotEqual([]int{1, 2, 3}, []int{1, 2})
|
||||
|
||||
assert.IsNil(nil)
|
||||
assert.IsNotNil("abc")
|
||||
|
||||
}
|
Loading…
Reference in New Issue