You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

342 lines
7.4 KiB
Go

package FLXCheckInController
import (
"fmt"
"io"
"reflect"
"time"
log "github.com/sirupsen/logrus"
)
type FlxCheckInCmdReader struct {
BufferMaxLength int
SerialPort *io.ReadWriteCloser
tmpRecDataBuffer []byte
IsRunning bool
//记录最后一次接收数据时间
dtLastRecivedDateTime time.Time
InvokeOnBusinessDataReviceData func([]byte)
OnConnectStatusHandler func(time.Time)
}
func (para *FlxCheckInCmdReader) InitPara(serialPortt *io.ReadWriteCloser) {
defer func() {
if r := recover(); r != nil {
log.Error("InitPara:", r)
}
}()
fmt.Println("初始化串口驱动参数 ")
para.SerialPort = serialPortt
// Make sure to close it later.
// defer port.Close()
// // Write 4 bytes to the port.
// b := []byte{0x00, 0x01, 0x02, 0x03}
// n, err := port.Write(b)
// port.Read()
// if err != nil {
// fmt.Println("port.Write: %v", err)
// }
// fmt.Println("Wrote", n, "bytes.")
}
// /// <summary>接收到业务数据后触发事件</summary>
// public event BusinessDataReciveEventHandler OnBusinessDataReciveEventHandler;
// /// <summary>读串口数据时发生的日志信息</summary>
// public event DataReciveLogHandler OnDataReciveLogHandler;
// /// <summary>
// /// 判断串口设备的连接状态事件
// /// </summary>
// public event DataReciveHandler OnConnectStatusHandler;
func (para *FlxCheckInCmdReader) InvokeOnDataReciveLogHandler(logMessage string) {
defer func() {
if r := recover(); r != nil {
log.Error("InvokeOnDataReciveLogHandler:", r)
}
}()
// if OnDataReciveLogHandler != nil {
// OnDataReciveLogHandler(logMessage)
// }
fmt.Println("串口消息:" + logMessage)
}
func (para *FlxCheckInCmdReader) InvokeOnConnectStatusHandler(dtLastRecived time.Time) {
defer func() {
if r := recover(); r != nil {
log.Error("InvokeOnConnectStatusHandler:", r)
}
}()
para.OnConnectStatusHandler(dtLastRecived)
}
func (para *FlxCheckInCmdReader) ProcessRecvBuff(RecvBuffer []byte) {
defer func() {
if r := recover(); r != nil {
log.Error("ProcessRecvBuff:", r)
}
}()
var PackLen int = 0
var PackBuff []byte
var startIndex int = 0
var curIndex int = 0
for curIndex < len(RecvBuffer) {
//应该判断7E 06 或02
if RecvBuffer[curIndex] == CMD_HEAD {
if startIndex != curIndex && (curIndex-startIndex) >= 5 {
PackLen = curIndex + 1 - startIndex
PackBuff = make([]byte, PackLen)
PackBuff = RecvBuffer[startIndex : startIndex+PackLen]
para.InvokeOnBusinessDataReviceData(PackBuff) //外发事件。
startIndex = curIndex + 1
}
}
curIndex++
}
if startIndex != curIndex {
para.tmpRecDataBuffer = append(para.tmpRecDataBuffer, RecvBuffer[curIndex:]...)
}
}
func (para *FlxCheckInCmdReader) TimerCallbackHandler() {
defer func() {
if r := recover(); r != nil {
log.Error("TimerCallbackHandler:", r)
}
}()
var waitReadPackLen int = 0 //待读的字节长度
// var length int = 0 //放入缓冲区的长度。
for para.IsRunning {
reciveData := make([]byte, 51200)
clen, err := (*(para.SerialPort)).Read(reciveData)
if err != nil {
fmt.Println(err)
if err == io.EOF {
// time.Sleep(2000)
// para.IsRunning = false
// go para.CloseDevice()
// go para.TimerCallbackHandler()
return
}
continue
}
if clen >= DataPacketMinLength {
waitReadPackLen = clen
if waitReadPackLen == 0 {
fmt.Println(err)
}
data := make([]byte, waitReadPackLen)
data = reciveData[:waitReadPackLen]
//当前包接收长度 加上 上次接收半包的长度
recvBuffer := make([]byte, len(para.tmpRecDataBuffer)+waitReadPackLen) //从端口读取数据的缓冲区
//上次如果为半包
if len(para.tmpRecDataBuffer) > 0 {
recvBuffer = insertToSlice(0, para.tmpRecDataBuffer, recvBuffer)
// id = PersonIDs[j]
}
recvBuffer = insertToSlice(len(para.tmpRecDataBuffer), data, recvBuffer)
para.tmpRecDataBuffer = para.tmpRecDataBuffer[0:0]
// recvBuffer = append(para.tmpRecDataBuffer, data...)
//读取当前包的数据
//Array.Copy(data, 0, recvBuffer, index, waitReadPackLen) //读来的数据先零时放入这个缓冲区
para.ProcessRecvBuff(recvBuffer)
para.dtLastRecivedDateTime = time.Now()
} else {
para.tmpRecDataBuffer = append(para.tmpRecDataBuffer, reciveData[:clen]...)
}
}
}
func (para *FlxCheckInCmdReader) Start() bool {
defer func() {
if r := recover(); r != nil {
log.Error("Start:", r)
}
}()
// id = PersonIDs[j]
//此处 para.IsRunning 如不设置,则程序无法接收签到门信息
para.IsRunning = true
fmt.Println("中控机接收开启")
go para.TimerCallbackHandler()
return true
}
func (para *FlxCheckInCmdReader) Stop() bool {
defer func() {
if r := recover(); r != nil {
log.Error("Stop:", r)
}
}()
para.IsRunning = false
return true
}
func (para *FlxCheckInCmdReader) ReadResponseData() []byte {
defer func() {
if r := recover(); r != nil {
log.Error("ReadResponseData:", r)
}
}()
if para.SerialPort == nil {
return nil
}
reciveData := make([]byte, 51200)
clen, err := (*(para.SerialPort)).Read(reciveData)
if err != nil {
fmt.Println("串口报错消息:" + err.Error())
return nil
}
if clen <= 0 {
return nil
}
// data := make([]byte, clen)
data := reciveData[:clen]
return data
}
// 截取字符串 start 起点下标 length 需要截取的长度
func Substr(str string, start int, length int) string {
defer func() {
if r := recover(); r != nil {
log.Error("Substr:", r)
}
}()
rs := []rune(str)
rl := len(rs)
end := 0
if start < 0 {
start = rl - 1 + start
}
end = start + length
if start > end {
start, end = end, start
}
if start < 0 {
start = 0
}
if start > rl {
start = rl
}
if end < 0 {
end = 0
}
if end > rl {
end = rl
}
return string(rs[start:end])
}
// insertSlice 插入
func insertSlice(index int, newstr []byte, src []byte) (ns []byte) {
defer func() {
if r := recover(); r != nil {
log.Error("insertSlice:", r)
}
}()
ns = append(ns, src[:index]...) // 切片后加..., 相当于拆包成单个元素
ns = append(ns, newstr...)
ns = append(ns, src[index+len(newstr):]...)
return
}
func insertToSlice(index int, newstr []byte, src []byte) (ns []byte) {
defer func() {
if r := recover(); r != nil {
log.Error("insertToSlice:", r)
}
}()
ns = append(ns, src[:index]...) // 切片后加..., 相当于拆包成单个元素
ns = append(ns, newstr...)
ns = append(ns, src[index:]...)
return
}
func Contain(obj interface{}, target interface{}) bool {
defer func() {
if r := recover(); r != nil {
log.Error("Contain:", r)
}
}()
targetValue := reflect.ValueOf(target)
switch reflect.TypeOf(target).Kind() {
case reflect.Slice, reflect.Array:
for i := 0; i < targetValue.Len(); i++ {
if targetValue.Index(i).Interface() == obj {
return true
}
}
case reflect.Map:
if targetValue.MapIndex(reflect.ValueOf(obj)).IsValid() {
return true
}
}
return false
}
// RemoveElementToint32 移除数组内的指定元素
func RemoveElementStrings(list []string, value string) []string {
defer func() {
if r := recover(); r != nil {
log.Error("RemoveElementStrings:", r)
}
}()
var result = make([]string, 0)
index := 0
endIndex := len(list) - 1
for i, s := range list {
if s == value {
result = append(result, list[index:i]...)
index = i + 1
} else if i == endIndex {
result = append(result, list[index:endIndex+1]...)
}
}
return result
}