|
|
package FLXCheckInController
|
|
|
|
|
|
import (
|
|
|
"encoding/hex"
|
|
|
"flx/Common"
|
|
|
FLXDevice "flx/Device"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
"time"
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
serial "github.com/tarm/goserial"
|
|
|
)
|
|
|
|
|
|
type FlxCheckInDeviceController struct {
|
|
|
FirstRun bool
|
|
|
IsRunning bool
|
|
|
IsOpen bool
|
|
|
IsOnline bool
|
|
|
OldSData string
|
|
|
SerialPort *io.ReadWriteCloser
|
|
|
Reader FlxCheckInCmdReader
|
|
|
Sender FlxCheckInCmdSender
|
|
|
ComPackets chan []byte
|
|
|
previousBuffer []byte
|
|
|
HasDataIsReturned bool
|
|
|
deviceGUID string
|
|
|
regsterEvent_SeatInfos []FLXDevice.SeatChangeEventArg
|
|
|
DataReciveSave []string
|
|
|
InvokeDeviceEventHandler func(FLXDevice.EventArgSource, FLXDevice.EventArgType, []FLXDevice.SeatChangeEventArg)
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) FlxCheckInDeviceController() {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("FlxCheckInDeviceController:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
para.InitControllerBusnissInfo()
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) InitControllerBusnissInfo() {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("InitControllerBusnissInfo:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
para.ComPackets = make(chan []byte, 600)
|
|
|
para.Sender.init(para.SerialPort)
|
|
|
// Sender.defualtDelayed = configKeys.OneTimeDataPackedDelayed;
|
|
|
// Sender.OnDataSendLogHandler += Sender_OnDataSendLogHandler;
|
|
|
|
|
|
para.Reader.InitPara(para.SerialPort)
|
|
|
para.Reader.InvokeOnBusinessDataReviceData = para.Reader_OnDataReciveEventHandler
|
|
|
|
|
|
para.Reader.OnConnectStatusHandler = para.Reader_OnConnectStatusHandler
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) Reader_OnConnectStatusHandler(dtLastRecived time.Time) {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("Reader_OnConnectStatusHandler:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
ts := time.Now().Sub(dtLastRecived)
|
|
|
//判断报到机是否已达3秒没有向上位机发送数据
|
|
|
if ts.Seconds() >= 3 {
|
|
|
//尝试获取报到机系统信息,如果报到机无数据返回,视为离线,否则,作在线处理
|
|
|
para.Sender.SendHeartBeat()
|
|
|
revBuffer := para.Reader.ReadResponseData()
|
|
|
if revBuffer == nil {
|
|
|
if para.IsOnline {
|
|
|
para.IsOnline = false
|
|
|
}
|
|
|
} else {
|
|
|
para.Reader.dtLastRecivedDateTime = time.Now()
|
|
|
if !para.IsOnline {
|
|
|
if para.FirstRun {
|
|
|
para.FirstRun = false
|
|
|
} else {
|
|
|
//发送蜂鸣指令
|
|
|
para.Sender.SendBeep(1)
|
|
|
}
|
|
|
para.IsOnline = true
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// / <summary>
|
|
|
// /D7-D6:表示控制蜂鸣器操作模式
|
|
|
// /00:表示不对蜂鸣器进行控制操作
|
|
|
// /01:表示有人通过即提示
|
|
|
// /10:表示有人无卡提示
|
|
|
// /11:表示有人有卡提示
|
|
|
// /D5-D4:表示控制灯的操作模式
|
|
|
// /00:表示不对灯进行控制操作
|
|
|
// /01:表示有人通过即提示
|
|
|
// /10:表示有人无卡提示
|
|
|
// /11:表示有人有卡提示
|
|
|
// /D3-D0:表示时钟周期
|
|
|
// / </summary>
|
|
|
func (para *FlxCheckInDeviceController) InitEStatus() byte {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("InitEStatus:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
var eTmp byte = 0
|
|
|
|
|
|
eTmp += 0xC0
|
|
|
eTmp += 0x30
|
|
|
|
|
|
return eTmp
|
|
|
}
|
|
|
|
|
|
// func Sender_OnDataSendLogHandler(string logMessage) {
|
|
|
// RequestDebugMessage(this, logMessage);
|
|
|
// }
|
|
|
|
|
|
// func Reader_OnDataReciveLogHandler(string logMessage) {
|
|
|
// RequestDebugMessage(this, logMessage);
|
|
|
// }
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) OpenDevice() bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("OpenDevice:", r)
|
|
|
}
|
|
|
}()
|
|
|
// getCommlist2()
|
|
|
|
|
|
// c := &serial.Config{Name: "COM3", Baud: 19200}
|
|
|
// s, err := serial.OpenPort(c)
|
|
|
// if err != nil {
|
|
|
// fmt.Println(err)
|
|
|
// }
|
|
|
// n, err := s.Write([]byte("012345"))
|
|
|
// if err != nil {
|
|
|
// fmt.Println(err)
|
|
|
// }
|
|
|
// fmt.Printf("Read %d Bytes\r\n", n)
|
|
|
|
|
|
cfig := Common.LoadConfig()
|
|
|
c := &serial.Config{Name: cfig.CheckInDoor.PortName, Baud: cfig.CheckInDoor.BaudRate}
|
|
|
// var err error
|
|
|
fmt.Println("enterging OpenDevice ")
|
|
|
cport, err := serial.OpenPort(c)
|
|
|
|
|
|
if err != nil {
|
|
|
fmt.Println("打开串口驱动报错:")
|
|
|
fmt.Println(err)
|
|
|
return false
|
|
|
} else {
|
|
|
para.IsOpen = true
|
|
|
}
|
|
|
para.SerialPort = &cport
|
|
|
para.Sender.init(para.SerialPort)
|
|
|
para.Reader.InitPara(para.SerialPort)
|
|
|
para.Sender.InitDoor()
|
|
|
// para.Sender.SendBeep(1)
|
|
|
// if nil != para.Reader.ReadResponseData() {
|
|
|
para.Sender.DownLoadEStatus(para.InitEStatus())
|
|
|
para.Sender.SendBeep(1)
|
|
|
para.Reader.Start()
|
|
|
time.Sleep(500)
|
|
|
para.CreatEventHandleThread()
|
|
|
fmt.Println(OpenSerialPort_Success)
|
|
|
return true
|
|
|
// }
|
|
|
// fmt.Println(ReciveDataFromCOM_Error)
|
|
|
|
|
|
// return false
|
|
|
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) CloseDevice() bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("CloseDevice:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
if para.IsOpen {
|
|
|
para.Sender.SendBeep(1)
|
|
|
|
|
|
para.Reader.Stop()
|
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
para.KillEventHandleThread()
|
|
|
// (*para.SerialPort).Close()
|
|
|
if err := (*para.SerialPort).Close(); err != nil {
|
|
|
fmt.Println(CloseSerialPort_Faild, ":", err)
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
para.IsOpen = false
|
|
|
if !para.IsOpen {
|
|
|
fmt.Println(CloseSerialPort_Success)
|
|
|
return true
|
|
|
} else {
|
|
|
fmt.Println(CloseSerialPort_Faild)
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) CheckInStartAll() {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("CheckInStartAll:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
if !para.IsOpen {
|
|
|
para.OpenDevice()
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) CheckInStopAll() {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("CheckInStopAll:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
para.CloseDevice()
|
|
|
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) StartCardReadIn() {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("StartCardReadIn:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
para.Reader.Start()
|
|
|
time.Sleep(5 * time.Microsecond)
|
|
|
para.CreatEventHandleThread()
|
|
|
|
|
|
}
|
|
|
func (para *FlxCheckInDeviceController) StopCardReadIn() {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("StopCardReadIn:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
para.Reader.Stop()
|
|
|
time.Sleep(500)
|
|
|
para.KillEventHandleThread()
|
|
|
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) BeepOn(msec int) bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("BeepOn:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
var bRetValue bool = false
|
|
|
|
|
|
if para.IsOpen {
|
|
|
//Sender.SendAlarm(msec);
|
|
|
for index := 0; index < msec; index++ {
|
|
|
para.Sender.SendAlarm(1)
|
|
|
time.Sleep(1 * time.Microsecond)
|
|
|
}
|
|
|
bRetValue = true
|
|
|
}
|
|
|
|
|
|
return bRetValue
|
|
|
|
|
|
//return true;
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) BeepOff() bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("BeepOff:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) LightOn() bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("LightOn:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) LightOff() bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("LightOff:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) Reader_OnDataReciveEventHandler(compacket []byte) {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("Reader_OnDataReciveEventHandler:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
fmt.Println(compacket)
|
|
|
for i := 0; i < len(para.DataReciveSave); i++ {
|
|
|
if para.DataReciveSave[i] == string(compacket) {
|
|
|
//避免返回相同卡号
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
para.DataReciveSave = append(para.DataReciveSave, string(compacket))
|
|
|
para.HasDataIsReturned = true
|
|
|
if compacket != nil && len(compacket) > 5 {
|
|
|
if compacket[0] == CMD_HEAD && compacket[len(compacket)-1] == CMD_Tail {
|
|
|
para.ComPackets <- compacket
|
|
|
}
|
|
|
}
|
|
|
go func() {
|
|
|
time.Sleep(time.Second * 5)
|
|
|
para.DataReciveSave = para.DataReciveSave[1:]
|
|
|
}()
|
|
|
}
|
|
|
|
|
|
// / <summary>消息队列</summary>
|
|
|
func (para *FlxCheckInDeviceController) TimerCallbackHandler() {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("TimerCallbackHandler:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
for para.IsRunning {
|
|
|
|
|
|
para.regsterEvent_SeatInfos = para.regsterEvent_SeatInfos[0:0]
|
|
|
comPacket := <-para.ComPackets
|
|
|
if para.OldSData == hex.EncodeToString(comPacket) {
|
|
|
continue
|
|
|
}
|
|
|
var seatInfo FLXDevice.SeatChangeEventArg
|
|
|
if len(comPacket) > 2 {
|
|
|
seatInfo.DeviceGUID = para.deviceGUID
|
|
|
switch comPacket[1] {
|
|
|
case Read_Reader_State:
|
|
|
seatInfo.EventValue = FLXDevice.EventArgValue_RegistrStatus
|
|
|
seatInfo.Value_ExtraInt = int(comPacket[2])
|
|
|
para.InvokeDeviceEventHandler(FLXDevice.EventArgSource_SivtChecker, FLXDevice.EventArgType_DeviceQueryEvent, []FLXDevice.SeatChangeEventArg{seatInfo})
|
|
|
|
|
|
case Read_SeriaNo:
|
|
|
if !EqualsByteArray(para.previousBuffer, comPacket) {
|
|
|
|
|
|
if comPacket[2] != 2 && comPacket[2] != 1 {
|
|
|
para.previousBuffer = comPacket
|
|
|
// Console.WriteLine("1赋值" + DeviceUtil.ByteArrayToString(previousBuffer, 0, previousBuffer.Length))
|
|
|
// Console.WriteLine("1 " + DeviceUtil.ByteArrayToString(comPacket, 0, comPacket.Length))
|
|
|
}
|
|
|
// var cardNo string
|
|
|
// for i := 3; i < len(comPacket)-1; i++ {
|
|
|
// cardNo += comPacket[i].ToString("X2")
|
|
|
// }
|
|
|
cardNo := hex.EncodeToString(comPacket[3:])
|
|
|
seatInfo.EventValue = FLXDevice.EventArgValue_Register //不论进出检测到卡即为报到。
|
|
|
switch comPacket[2] {
|
|
|
case 2:
|
|
|
seatInfo.Value_ExtraInt = CheckInDirection_Out
|
|
|
|
|
|
case 1:
|
|
|
seatInfo.Value_ExtraInt = CheckInDirection_In
|
|
|
|
|
|
default:
|
|
|
seatInfo.Value_ExtraInt = CheckInDirection_In
|
|
|
|
|
|
}
|
|
|
seatInfo.Value_ExtraStr = cardNo
|
|
|
var isExist bool = false
|
|
|
for _, arg := range para.regsterEvent_SeatInfos {
|
|
|
if arg.Value_ExtraStr == seatInfo.Value_ExtraStr {
|
|
|
isExist = true
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
if !isExist {
|
|
|
para.regsterEvent_SeatInfos = append(para.regsterEvent_SeatInfos, seatInfo)
|
|
|
}
|
|
|
fmt.Println(InvokeCaredNo_Processed)
|
|
|
}
|
|
|
|
|
|
case Read_In_State:
|
|
|
if !EqualsByteArray(para.previousBuffer, comPacket) {
|
|
|
seatInfo.EventValue = FLXDevice.EventArgValue_Register //不论进出检测到卡即为报到。
|
|
|
switch comPacket[2] {
|
|
|
case 2:
|
|
|
seatInfo.Value_ExtraInt = CheckInDirection_Out
|
|
|
|
|
|
case 1:
|
|
|
seatInfo.Value_ExtraInt = CheckInDirection_In
|
|
|
|
|
|
default:
|
|
|
seatInfo.Value_ExtraInt = CheckInDirection_Unkown
|
|
|
|
|
|
}
|
|
|
seatInfo.Value_ExtraStr = ""
|
|
|
para.regsterEvent_SeatInfos = append(para.regsterEvent_SeatInfos, seatInfo)
|
|
|
fmt.Println(InvokeCaredNo_Processed)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
if seatInfo.Value_ExtraInt != 2 && seatInfo.Value_ExtraInt != 1 {
|
|
|
para.previousBuffer = comPacket
|
|
|
// Console.WriteLine("2赋值" + DeviceUtil.ByteArrayToString(previousBuffer, 0, previousBuffer.Length))
|
|
|
// Console.WriteLine("2 " + DeviceUtil.ByteArrayToString(comPacket, 0, comPacket.Length))
|
|
|
}
|
|
|
|
|
|
if len(para.regsterEvent_SeatInfos) > 0 {
|
|
|
|
|
|
// Console.WriteLine("触发事件" + regsterEvent_SeatInfos.Count + "个数据")
|
|
|
para.InvokeDeviceEventHandler(FLXDevice.EventArgSource_SivtChecker, FLXDevice.EventArgType_RegisterEvent, para.regsterEvent_SeatInfos)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func EqualsByteArray(sorBuf []byte, argBuf []byte) bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("EqualsByteArray:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
if len(sorBuf) != len(argBuf) {
|
|
|
return false
|
|
|
} else {
|
|
|
for i := 0; i < len(sorBuf); i++ {
|
|
|
if sorBuf[i] != argBuf[i] {
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) CreatEventHandleThread() bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("CreatEventHandleThread:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
para.IsRunning = true
|
|
|
go para.TimerCallbackHandler()
|
|
|
|
|
|
fmt.Println("串口创建线程:" + CreateThread)
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
func (para *FlxCheckInDeviceController) KillEventHandleThread() bool {
|
|
|
|
|
|
defer func() {
|
|
|
if r := recover(); r != nil {
|
|
|
log.Error("KillEventHandleThread:", r)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
para.IsRunning = false
|
|
|
fmt.Println("串口消毁线程:" + ClosedThread)
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|