Skip to content

Commit

Permalink
dev: new version v0.6.2
Browse files Browse the repository at this point in the history
dev: new version v0.6.2
  • Loading branch information
wwhai authored Aug 13, 2023
2 parents de7525f + 957313a commit fd5c9ef
Show file tree
Hide file tree
Showing 42 changed files with 1,919 additions and 332 deletions.
5 changes: 3 additions & 2 deletions common/common_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ package common
*
*/
type HostConfig struct {
Host string `json:"host" validate:"required" title:"服务地址"`
Port int `json:"port" validate:"required" title:"服务端口"`
Host string `json:"host" validate:"required" title:"服务地址"`
Port int `json:"port" validate:"required" title:"服务端口"`
Timeout int `json:"timeout"`
}

/*
Expand Down
143 changes: 65 additions & 78 deletions device/custom_protocol_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"time"

"github.com/hootrhino/rulex/common"
Expand All @@ -19,28 +20,14 @@ import (
const __DEFAULT_BUFFER_SIZE = 100

// 传输形式:
// `rawtcp`, `rawudp`, `rs485rawserial`, `rs485rawtcp`
// const rawtcp string = "rawtcp"
// const rawudp string = "rawudp"
// const rs485rawserial string = "rs485rawserial"
// const rs485rawtcp string = "rs485rawtcp"
// `rawtcp`, `rawudp`, `rawserial`
const rawtcp string = "rawtcp"
const rawudp string = "rawudp"
const rawserial string = "rawserial"

type _CPDCommonConfig struct {
Transport *string `json:"transport" validate:"required"` // 传输协议
RetryTime *int `json:"retryTime" validate:"required"` // 几次以后重启,0 表示不重启
}

type _CPDProtocol struct {
//---------------------------------------------------------------------
// 下面都是校验算法相关配置:
// -- 例如对[Byte1,Byte2,Byte3,Byte4,Byte5,Byte6,Byte7]用XOR算法比对
// 从第一个开始,第五个结束[Byte1,Byte2,Byte3,Byte4,Byte5], 比对值位置在第六个[Byte6]
// 伪代码:XOR(Byte[ChecksumBegin:ChecksumEnd]) == Byte[ChecksumValuePos]
//---------------------------------------------------------------------
CheckAlgorithm string `json:"checkAlgorithm" validate:"required" default:"NONECHECK"` // 校验算法,目前暂时支持: CRC16, XOR
ChecksumValuePos uint `json:"checksumValuePos" validate:"required"` // 校验值比对位
ChecksumBegin uint `json:"checksumBegin" validate:"required"` // 校验算法起始位置
ChecksumEnd uint `json:"checksumEnd" validate:"required"` // 校验算法结束位置
Transport string `json:"transport" validate:"required"` // 传输协议
RetryTime int `json:"retryTime" validate:"required"` // 几次以后重启,0 表示不重启
}

/*
Expand All @@ -51,12 +38,14 @@ type _CPDProtocol struct {
type _CustomProtocolConfig struct {
CommonConfig _CPDCommonConfig `json:"commonConfig" validate:"required"`
UartConfig common.CommonUartConfig `json:"uartConfig" validate:"required"`
HostConfig common.HostConfig `json:"hostConfig" validate:"required"`
}
type CustomProtocolDevice struct {
typex.XStatus
status typex.DeviceState
RuleEngine typex.RuleX
serialPort *serial.Port // 现阶段暂时支持串口
serialPort *serial.Port // 串口
tcpcon net.Conn // TCP
mainConfig _CustomProtocolConfig
errorCount int // 记录最大容错数,默认5次,出错超过5此就重启
}
Expand All @@ -67,6 +56,7 @@ func NewCustomProtocolDevice(e typex.RuleX) typex.XDevice {
mdev.mainConfig = _CustomProtocolConfig{
CommonConfig: _CPDCommonConfig{},
UartConfig: common.CommonUartConfig{},
HostConfig: common.HostConfig{Timeout: 50},
}
return mdev

Expand All @@ -81,9 +71,9 @@ func (mdev *CustomProtocolDevice) Init(devId string, configMap map[string]interf
if !utils.SContains([]string{"N", "E", "O"}, mdev.mainConfig.UartConfig.Parity) {
return errors.New("parity value only one of 'N','O','E'")
}
if !utils.SContains([]string{`rawtcp`, `rawudp`, `rs485rawserial`, `rs485rawtcp`},
*mdev.mainConfig.CommonConfig.Transport) {
return errors.New("option only one of 'rawtcp','rawudp','rs485rawserial','rs485rawserial'")
if !utils.SContains([]string{`rawtcp`, `rawudp`, `rawserial`},
mdev.mainConfig.CommonConfig.Transport) {
return errors.New("option only one of 'rawtcp','rawudp','rawserial','rawserial'")
}
return nil
}
Expand All @@ -92,8 +82,11 @@ func (mdev *CustomProtocolDevice) Init(devId string, configMap map[string]interf
func (mdev *CustomProtocolDevice) Start(cctx typex.CCTX) error {
mdev.Ctx = cctx.Ctx
mdev.CancelCTX = cctx.CancelCTX
mdev.errorCount = 0
mdev.status = typex.DEV_DOWN

// 现阶段暂时只支持RS485串口, 以后有需求再支持TCP、UDP
if *mdev.mainConfig.CommonConfig.Transport == "rs485rawserial" {
if mdev.mainConfig.CommonConfig.Transport == "rawserial" {
config := serial.Config{
Name: mdev.mainConfig.UartConfig.Uart,
Baud: mdev.mainConfig.UartConfig.BaudRate,
Expand All @@ -107,13 +100,25 @@ func (mdev *CustomProtocolDevice) Start(cctx typex.CCTX) error {
glogger.GLogger.Error("serialPort start failed:", err)
return err
}
mdev.errorCount = 0
mdev.serialPort = serialPort
mdev.status = typex.DEV_UP
return nil
}

return fmt.Errorf("unsupported transport:%s", *mdev.mainConfig.CommonConfig.Transport)
// rawtcp
if mdev.mainConfig.CommonConfig.Transport == "rawtcp" {
tcpcon, err := net.Dial("tcp",
fmt.Sprintf("%s:%d", mdev.mainConfig.HostConfig.Host,
mdev.mainConfig.HostConfig.Port))
if err != nil {
glogger.GLogger.Error("tcp connection start failed:", err)
return err
}
mdev.tcpcon = tcpcon
mdev.status = typex.DEV_UP
return nil
}
return fmt.Errorf("unsupported transport:%s", mdev.mainConfig.CommonConfig.Transport)
}

/*
Expand Down Expand Up @@ -149,14 +154,9 @@ func (mdev *CustomProtocolDevice) OnCtrl(cmd []byte, _ []byte) ([]byte, error) {

// 设备当前状态
func (mdev *CustomProtocolDevice) Status() typex.DeviceState {
if *mdev.mainConfig.CommonConfig.RetryTime == 0 {
mdev.status = typex.DEV_UP
}
if *mdev.mainConfig.CommonConfig.RetryTime > 0 {
if mdev.errorCount >= *mdev.mainConfig.CommonConfig.RetryTime {
mdev.CancelCTX()
mdev.status = typex.DEV_DOWN
}
if mdev.errorCount >= mdev.mainConfig.CommonConfig.RetryTime {
mdev.CancelCTX()
mdev.status = typex.DEV_DOWN
}
return mdev.status
}
Expand All @@ -165,8 +165,16 @@ func (mdev *CustomProtocolDevice) Status() typex.DeviceState {
func (mdev *CustomProtocolDevice) Stop() {
mdev.CancelCTX()
mdev.status = typex.DEV_DOWN
mdev.serialPort.Close()

if mdev.mainConfig.CommonConfig.Transport == rawtcp {
if mdev.tcpcon != nil {
mdev.tcpcon.Close()
}
}
if mdev.mainConfig.CommonConfig.Transport == rawserial {
if mdev.serialPort != nil {
mdev.serialPort.Close()
}
}
}

// 设备属性,是一系列属性描述
Expand Down Expand Up @@ -213,53 +221,32 @@ func (mdev *CustomProtocolDevice) ctrl(args []byte) ([]byte, error) {
result := [__DEFAULT_BUFFER_SIZE]byte{}
ctx, cancel := context.WithTimeout(context.Background(),
time.Duration(mdev.mainConfig.UartConfig.Timeout)*time.Millisecond)
count, err2 := utils.SliceRequest(ctx, mdev.serialPort,
hexs, result[:], false,
time.Duration(30)*time.Millisecond /*30ms wait*/)
var count int = 0
var errSliceRequest error = nil
if mdev.mainConfig.CommonConfig.Transport == rawserial {
count, errSliceRequest = utils.SliceRequest(ctx, mdev.serialPort,
hexs, result[:], false,
time.Duration(30)*time.Millisecond /*30ms wait*/)
}
if mdev.mainConfig.CommonConfig.Transport == rawtcp {
mdev.tcpcon.SetReadDeadline(
time.Now().Add((time.Duration(mdev.mainConfig.HostConfig.Timeout) * time.Millisecond)),
)
count, errSliceRequest = utils.SliceRequest(ctx, mdev.tcpcon,
hexs, result[:], false,
time.Duration(30)*time.Millisecond /*30ms wait*/)
mdev.tcpcon.SetReadDeadline(time.Time{})
}

cancel()
if err2 != nil {
glogger.GLogger.Error("Custom Protocol Device Request error: ", err2)
if errSliceRequest != nil {
glogger.GLogger.Error("Custom Protocol Device Request error: ", errSliceRequest)
mdev.errorCount++
return nil, err2
return nil, errSliceRequest
}
dataMap := map[string]string{}
dataMap["in"] = string(args)
dataMap["out"] = hex.EncodeToString(result[:count])
bytes, _ := json.Marshal(dataMap)
return []byte(bytes), nil
}

// func (mdev *CustomProtocolDevice) checkXOR(b []byte, v int) bool {
// return utils.XOR(b) == v
// }
// func (mdev *CustomProtocolDevice) checkCRC(b []byte, v int) bool {

// return int(utils.CRC16(b)) == v
// }

// /*
// *
// * Check hex string
// *
// */
// func (mdev *CustomProtocolDevice) checkHexs(p _CPDProtocol, result []byte) bool {
// checkOk := false
// if p.CheckAlgorithm == "CRC16" || p.CheckAlgorithm == "crc16" {
// glogger.GLogger.Debug("checkCRC:", result[:p.BufferSize],
// int(result[:p.BufferSize][p.ChecksumValuePos]))
// checkOk = mdev.checkCRC(result[:p.BufferSize],
// int(result[:p.BufferSize][p.ChecksumValuePos]))
// }
// //
// if p.CheckAlgorithm == "XOR" || p.CheckAlgorithm == "xor" {
// glogger.GLogger.Debug("checkCRC:", result[:p.BufferSize],
// int(result[:p.BufferSize][p.ChecksumValuePos]))
// checkOk = mdev.checkXOR(result[:p.BufferSize],
// int(result[:p.BufferSize][p.ChecksumValuePos]))
// }
// // NONECHECK: 不校验
// if p.CheckAlgorithm == "NONECHECK" {
// checkOk = true
// }
// return checkOk
// }
Loading

0 comments on commit fd5c9ef

Please sign in to comment.