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
		
	
		
		
			
		
	
	
			342 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Go
		
	
| 
											5 months ago
										 | 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 | ||
|  | } |