发卡关卡的读卡流程完成
This commit is contained in:
@@ -14,9 +14,13 @@ import (
|
||||
type Reader interface {
|
||||
io.Closer
|
||||
SetUnitID(uint8)
|
||||
// WriteUnitId 写入读卡器的 UnitID
|
||||
WriteUnitId(uint16) error
|
||||
// Init 初始化读卡器配置
|
||||
Init() error
|
||||
// OnCardInfo 会在卡号信息发生变化时调用回调函数,直到上下文被取消,或者 Reader 被关闭。需要在 goroutine 中调用。
|
||||
OnCardInfo(context.Context, func(CardInfo))
|
||||
OnCardInfo(context.Context, func(*CardInfo))
|
||||
GetCardInfo() *CardInfo
|
||||
}
|
||||
|
||||
type CardInfo struct {
|
||||
@@ -28,6 +32,14 @@ type reader struct {
|
||||
c *modbus.Client
|
||||
}
|
||||
|
||||
// WriteUnitId 写入读卡器的 UnitID
|
||||
func (r *reader) WriteUnitId(id uint16) error {
|
||||
v := id<<8 + 1
|
||||
zap.S().Infof("WriteRegister 40007 %#x", v)
|
||||
return r.c.WriteRegister(6, v)
|
||||
}
|
||||
|
||||
// Init 初始化读卡器配置
|
||||
func (r *reader) Init() error {
|
||||
// 配置读卡间隔时间为 50 毫秒
|
||||
err := r.c.WriteRegister(8, 0x0511)
|
||||
@@ -52,57 +64,64 @@ func (r *reader) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *reader) OnCardInfo(ctx context.Context, f func(info CardInfo)) {
|
||||
// GetCardInfo 获取卡号信息
|
||||
func (r *reader) GetCardInfo() *CardInfo {
|
||||
// 读取状态寄存器确认是否信息已经准备好
|
||||
status, err := r.c.ReadRegister(29, modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40030 error:", err)
|
||||
return nil
|
||||
} else if status == 0x0000 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 读取卡号长度
|
||||
cardLength, err := r.c.ReadRegister(30, modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40031 error:", err)
|
||||
return nil
|
||||
}
|
||||
dataLength := cardLength >> 8
|
||||
|
||||
// 读取卡类型
|
||||
cardType, err := r.c.ReadRegister(31, modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40032 error:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 读取卡号数据
|
||||
cardData, err := r.c.ReadRegisters(32, uint16(math.Round(float64(dataLength)/2)), modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40033~ error:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
s := make([]string, dataLength)
|
||||
for i := 0; i < int(dataLength); i++ {
|
||||
if i%2 == 0 {
|
||||
s[i] = fmt.Sprintf("%02X", cardData[i/2]>>8)
|
||||
} else {
|
||||
s[i] = fmt.Sprintf("%02X", cardData[i/2]&0xFF)
|
||||
}
|
||||
}
|
||||
|
||||
return &CardInfo{
|
||||
Type: cardType,
|
||||
ID: strings.Join(s, ""),
|
||||
}
|
||||
}
|
||||
|
||||
// OnCardInfo 会在卡号信息发生变化时调用回调函数,直到上下文被取消,或者 Reader 被关闭。需要在 goroutine 中调用。
|
||||
func (r *reader) OnCardInfo(ctx context.Context, f func(info *CardInfo)) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
{
|
||||
// 读取状态寄存器确认是否信息已经准备好
|
||||
status, err := r.c.ReadRegister(29, modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40030 error:", err)
|
||||
break
|
||||
} else if status == 0x0000 {
|
||||
break
|
||||
}
|
||||
|
||||
// 读取卡号长度
|
||||
cardLength, err := r.c.ReadRegister(30, modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40031 error:", err)
|
||||
break
|
||||
}
|
||||
dataLength := cardLength >> 8
|
||||
|
||||
// 读取卡类型
|
||||
cardType, err := r.c.ReadRegister(31, modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40032 error:", err)
|
||||
break
|
||||
}
|
||||
|
||||
// 读取卡号数据
|
||||
cardData, err := r.c.ReadRegisters(32, uint16(math.Round(float64(dataLength)/2)), modbus.HoldingRegister)
|
||||
if err != nil {
|
||||
zap.S().Errorln("ReadRegister 40033~ error:", err)
|
||||
break
|
||||
}
|
||||
|
||||
s := make([]string, dataLength)
|
||||
for i := 0; i < int(dataLength); i++ {
|
||||
if i%2 == 0 {
|
||||
s[i] = fmt.Sprintf("%02X", cardData[i/2]>>8)
|
||||
} else {
|
||||
s[i] = fmt.Sprintf("%02X", cardData[i/2]&0xFF)
|
||||
}
|
||||
}
|
||||
|
||||
f(CardInfo{
|
||||
Type: cardType,
|
||||
ID: strings.Join(s, ""),
|
||||
})
|
||||
info := r.GetCardInfo()
|
||||
if info != nil {
|
||||
f(info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user