继电器、读卡器,都用统一的modbus协议
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
location: wushan
|
location: wushan
|
||||||
point: 5
|
point: 5
|
||||||
relay: COM7
|
relay: /dev/ttyUSB0
|
||||||
maxTimeout: 60 # 单位 s,必须大于 0
|
maxTimeout: 60 # 单位 s,必须大于 0
|
||||||
log:
|
log:
|
||||||
level: debug
|
level: debug
|
||||||
@@ -19,7 +19,7 @@ aliyun:
|
|||||||
timeout: 10 # 单位 s
|
timeout: 10 # 单位 s
|
||||||
voice: zhifeng_emo
|
voice: zhifeng_emo
|
||||||
game:
|
game:
|
||||||
url: rtu:///dev/ttyUSB0 # 点位 5 的串口地址
|
addr: /dev/ttyUSB0 # 点位 5 的串口地址
|
||||||
# pushGroups: # 点位 4 的发卡器配置
|
# pushGroups: # 点位 4 的发卡器配置
|
||||||
# - name: gpiochip0
|
# - name: gpiochip0
|
||||||
# outOK: 6
|
# outOK: 6
|
||||||
@@ -29,4 +29,4 @@ game:
|
|||||||
# push: 11
|
# push: 11
|
||||||
# reset: 22
|
# reset: 22
|
||||||
# pull: 27
|
# pull: 27
|
||||||
# readUrl: rtu:///dev/ttyUSB0 # 点位 4 的读卡器配置
|
# readAddr: /dev/ttyUSB0 # 点位 4 的读卡器配置
|
||||||
@@ -4,5 +4,5 @@ import "game-driver/internal/routes/play/card_pusher"
|
|||||||
|
|
||||||
type ConfigPush struct {
|
type ConfigPush struct {
|
||||||
PushGroups []*card_pusher.LineGroup
|
PushGroups []*card_pusher.LineGroup
|
||||||
ReadURL string
|
ReadAddr string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
type ConfigWait struct {
|
type ConfigWait struct {
|
||||||
URL string
|
Addr string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func main() {
|
|||||||
logger.DefaultLogger()
|
logger.DefaultLogger()
|
||||||
defer logger.Sync()
|
defer logger.Sync()
|
||||||
|
|
||||||
reader, err := card_reader.NewReader("rtu:///dev/ttyUSB0")
|
reader, err := card_reader.NewReader("/dev/ttyUSB0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Panicln(err)
|
zap.S().Panicln(err)
|
||||||
}
|
}
|
||||||
|
|||||||
31
demo/relay/main.go
Normal file
31
demo/relay/main.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"game-driver/logger"
|
||||||
|
"game-driver/pkg/relay"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
logger.DefaultLogger()
|
||||||
|
defer logger.Sync()
|
||||||
|
|
||||||
|
r, err := relay.New("/dev/ttyUSB0")
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Panicln(err)
|
||||||
|
}
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
r.On(0)
|
||||||
|
defer r.Off(0)
|
||||||
|
|
||||||
|
sig := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
|
<-sig
|
||||||
|
zap.S().Infoln("接收到关闭命令 - 正在关闭程序")
|
||||||
|
zap.S().Infoln("关闭完成")
|
||||||
|
}
|
||||||
5
go.mod
5
go.mod
@@ -6,22 +6,21 @@ require (
|
|||||||
github.com/aliyun/alibabacloud-nls-go-sdk v1.1.1
|
github.com/aliyun/alibabacloud-nls-go-sdk v1.1.1
|
||||||
github.com/eclipse/paho.golang v0.22.0
|
github.com/eclipse/paho.golang v0.22.0
|
||||||
github.com/gopxl/beep/v2 v2.1.0
|
github.com/gopxl/beep/v2 v2.1.0
|
||||||
github.com/munnik/modbus v1.6.6
|
github.com/grid-x/modbus v0.0.0-20241004123532-f6c6fb5201b3
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/spf13/viper v1.19.0
|
github.com/spf13/viper v1.19.0
|
||||||
github.com/warthog618/go-gpiocdev v0.9.1
|
github.com/warthog618/go-gpiocdev v0.9.1
|
||||||
go.bug.st/serial v1.6.2
|
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.53 // indirect
|
github.com/aliyun/alibaba-cloud-sdk-go v1.63.53 // indirect
|
||||||
github.com/creack/goselect v0.1.2 // indirect
|
|
||||||
github.com/ebitengine/oto/v3 v3.3.1 // indirect
|
github.com/ebitengine/oto/v3 v3.3.1 // indirect
|
||||||
github.com/ebitengine/purego v0.8.1 // indirect
|
github.com/ebitengine/purego v0.8.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
github.com/grid-x/serial v0.0.0-20211107191517-583c7356b3aa // indirect
|
||||||
github.com/hajimehoshi/go-mp3 v0.3.4 // indirect
|
github.com/hajimehoshi/go-mp3 v0.3.4 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
|||||||
14
go.sum
14
go.sum
@@ -8,8 +8,6 @@ github.com/aliyun/alibaba-cloud-sdk-go v1.63.53/go.mod h1:SOSDHfe1kX91v3W5QiBsWS
|
|||||||
github.com/aliyun/alibabacloud-nls-go-sdk v1.1.1 h1:LjItoNZuu5xHlsByFo+kr3nGa4LRIESCGWhfurayxBg=
|
github.com/aliyun/alibabacloud-nls-go-sdk v1.1.1 h1:LjItoNZuu5xHlsByFo+kr3nGa4LRIESCGWhfurayxBg=
|
||||||
github.com/aliyun/alibabacloud-nls-go-sdk v1.1.1/go.mod h1:4BDMUKpEaP/Ct79w0ozR0nbnEj49g1k3mrgX/IKG5I4=
|
github.com/aliyun/alibabacloud-nls-go-sdk v1.1.1/go.mod h1:4BDMUKpEaP/Ct79w0ozR0nbnEj49g1k3mrgX/IKG5I4=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
|
||||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -39,6 +37,10 @@ github.com/gopxl/beep/v2 v2.1.0/go.mod h1:sQvj2oSsu8fmmDWH3t0DzIe0OZzTW6/TJEHW4K
|
|||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/grid-x/modbus v0.0.0-20241004123532-f6c6fb5201b3 h1:TfBJ561lUg0i0GLsxKeRaWoBGN8nyCLNt0OMGRx7R2M=
|
||||||
|
github.com/grid-x/modbus v0.0.0-20241004123532-f6c6fb5201b3/go.mod h1:WpbUAyptAAi0VAriSRopZa6uhiJOJCTz7KFvgGtNRXc=
|
||||||
|
github.com/grid-x/serial v0.0.0-20211107191517-583c7356b3aa h1:Rsn6ARgNkXrsXJIzhkE4vQr5Gbx2LvtEMv4BJOK4LyU=
|
||||||
|
github.com/grid-x/serial v0.0.0-20211107191517-583c7356b3aa/go.mod h1:kdOd86/VGFWRrtkNwf1MPk0u1gIjc4Y7R2j7nhwc7Rk=
|
||||||
github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68=
|
github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68=
|
||||||
github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo=
|
github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo=
|
||||||
github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo=
|
github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo=
|
||||||
@@ -73,8 +75,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
|||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/munnik/modbus v1.6.6 h1:QRAR+04bivKSzPN5qi5g9Wyzh+e3oQVFMUOhv35ya5Q=
|
|
||||||
github.com/munnik/modbus v1.6.6/go.mod h1:p8PIBjiZgsY82MiZPrkAGkrDomL1tBNGGQIwyAm4Vp0=
|
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
|
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
|
||||||
@@ -126,8 +126,6 @@ github.com/warthog618/go-gpiocdev v0.9.1 h1:pwHPaqjJfhCipIQl78V+O3l9OKHivdRDdmgX
|
|||||||
github.com/warthog618/go-gpiocdev v0.9.1/go.mod h1:dN3e3t/S2aSNC+hgigGE/dBW8jE1ONk9bDSEYfoPyl8=
|
github.com/warthog618/go-gpiocdev v0.9.1/go.mod h1:dN3e3t/S2aSNC+hgigGE/dBW8jE1ONk9bDSEYfoPyl8=
|
||||||
github.com/warthog618/go-gpiosim v0.1.1 h1:MRAEv+T+itmw+3GeIGpQJBfanUVyg0l3JCTwHtwdre4=
|
github.com/warthog618/go-gpiosim v0.1.1 h1:MRAEv+T+itmw+3GeIGpQJBfanUVyg0l3JCTwHtwdre4=
|
||||||
github.com/warthog618/go-gpiosim v0.1.1/go.mod h1:YXsnB+I9jdCMY4YAlMSRrlts25ltjmuIsrnoUrBLdqU=
|
github.com/warthog618/go-gpiosim v0.1.1/go.mod h1:YXsnB+I9jdCMY4YAlMSRrlts25ltjmuIsrnoUrBLdqU=
|
||||||
go.bug.st/serial v1.6.2 h1:kn9LRX3sdm+WxWKufMlIRndwGfPWsH1/9lCWXQCasq8=
|
|
||||||
go.bug.st/serial v1.6.2/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
@@ -160,8 +158,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -195,4 +191,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw=
|
||||||
|
pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// RelayMaster 继电器中间件
|
// RelayMaster 继电器中间件
|
||||||
func RelayMaster(r *relay.Device) leaf.HandlerFunc {
|
func RelayMaster(r relay.Relay) leaf.HandlerFunc {
|
||||||
return func(c *leaf.Context) {
|
return func(c *leaf.Context) {
|
||||||
pm := leaf.Value[*schema.PlayModal](c, PayloadJSONKey)
|
pm := leaf.Value[*schema.PlayModal](c, PayloadJSONKey)
|
||||||
if r != nil && pm.Power {
|
if r != nil && pm.Power {
|
||||||
r.On(1)
|
r.On(0)
|
||||||
defer r.Off(1)
|
defer r.Off(0)
|
||||||
|
|
||||||
zap.S().Infoln("开启电源")
|
zap.S().Infoln("开启电源")
|
||||||
defer zap.S().Infoln("关闭电源")
|
defer zap.S().Infoln("关闭电源")
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ func PushCard(ctx context.Context) leaf.HandlerFunc {
|
|||||||
g := (game.G).(game.ConfigPush)
|
g := (game.G).(game.ConfigPush)
|
||||||
|
|
||||||
// 开始初始化读卡器
|
// 开始初始化读卡器
|
||||||
reader, err := card_reader.NewReader(g.ReadURL)
|
reader, err := card_reader.NewReader(g.ReadAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
zap.S().Errorf("读卡器串口文件不存在: %s", g.ReadURL)
|
zap.S().Errorf("读卡器串口文件不存在: %s", g.ReadAddr)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
zap.S().Panicf("读卡器串口连接失败 [%T]: %q", err, err)
|
zap.S().Panicf("读卡器串口连接失败 [%T]: %q", err, err)
|
||||||
@@ -48,7 +48,7 @@ func PushCard(ctx context.Context) leaf.HandlerFunc {
|
|||||||
devices := make([]*card_pusher.Device, 0)
|
devices := make([]*card_pusher.Device, 0)
|
||||||
for i, group := range g.PushGroups {
|
for i, group := range g.PushGroups {
|
||||||
// 对读卡器初始化配置
|
// 对读卡器初始化配置
|
||||||
reader.SetUnitID(uint8(i + 1))
|
reader.SetSlave(uint8(i + 1))
|
||||||
err = reader.Init()
|
err = reader.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Panicln("读卡器初始配置失败", err)
|
zap.S().Panicln("读卡器初始配置失败", err)
|
||||||
@@ -114,7 +114,7 @@ func PushCard(ctx context.Context) leaf.HandlerFunc {
|
|||||||
if body.num != 0 {
|
if body.num != 0 {
|
||||||
// 若卡片就位,读取卡片信息
|
// 若卡片就位,读取卡片信息
|
||||||
if devices[body.num-1].GetOutOk() == 1 {
|
if devices[body.num-1].GetOutOk() == 1 {
|
||||||
reader.SetUnitID(uint8(body.num))
|
reader.SetSlave(uint8(body.num))
|
||||||
if info := reader.GetCardInfo(); info != nil {
|
if info := reader.GetCardInfo(); info != nil {
|
||||||
body.CardId = info.ID
|
body.CardId = info.ID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ import (
|
|||||||
func WaitCard(ctx context.Context) leaf.HandlerFunc {
|
func WaitCard(ctx context.Context) leaf.HandlerFunc {
|
||||||
g := (game.G).(game.ConfigWait)
|
g := (game.G).(game.ConfigWait)
|
||||||
|
|
||||||
reader, err := card_reader.NewReader(g.URL)
|
reader, err := card_reader.NewReader(g.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
zap.S().Errorf("读卡器串口文件不存在: %s", g.URL)
|
zap.S().Errorf("读卡器串口文件不存在: %s", g.Addr)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
zap.S().Panicf("读卡器串口连接失败 [%T]: %q", err, err)
|
zap.S().Panicf("读卡器串口连接失败 [%T]: %q", err, err)
|
||||||
|
|||||||
@@ -177,12 +177,12 @@ func relayAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeMod
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
device, err := relay.New(item.Data, nil)
|
r, err := relay.New(item.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Errorln("继电器初始化异常: ", err)
|
zap.S().Errorln("继电器初始化异常: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer device.Close()
|
defer r.Close()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
@@ -191,9 +191,9 @@ func relayAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeMod
|
|||||||
zap.S().Infoln("待机继电器供电")
|
zap.S().Infoln("待机继电器供电")
|
||||||
defer zap.S().Infoln("待机继电器断电")
|
defer zap.S().Infoln("待机继电器断电")
|
||||||
|
|
||||||
device.On(1)
|
r.On(0)
|
||||||
<-c.Done()
|
<-c.Done()
|
||||||
device.Off(1)
|
r.Off(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"game-driver/internal/schema"
|
"game-driver/internal/schema"
|
||||||
"game-driver/leaf"
|
"game-driver/leaf"
|
||||||
"game-driver/logger"
|
"game-driver/logger"
|
||||||
|
"game-driver/pkg/relay"
|
||||||
"game-driver/pkg/tts"
|
"game-driver/pkg/tts"
|
||||||
"game-driver/pkg/utils"
|
"game-driver/pkg/utils"
|
||||||
"github.com/eclipse/paho.golang/autopaho"
|
"github.com/eclipse/paho.golang/autopaho"
|
||||||
@@ -108,13 +109,11 @@ func Run() {
|
|||||||
tts.DefaultTTS = tts.New(ctx, config.C.Aliyun)
|
tts.DefaultTTS = tts.New(ctx, config.C.Aliyun)
|
||||||
|
|
||||||
// 构建继电器对象
|
// 构建继电器对象
|
||||||
//r, err := relay.New(config.C.Relay, func(msg string) {
|
r, err := relay.New(config.C.Relay)
|
||||||
// zap.S().Infoln("串口返回: ", msg)
|
if err != nil {
|
||||||
//})
|
zap.S().Panicln("串口连接异常: ", err)
|
||||||
//if err != nil {
|
}
|
||||||
// zap.S().Panicln("串口连接异常: ", err)
|
defer r.Close()
|
||||||
//}
|
|
||||||
//defer r.Close()
|
|
||||||
|
|
||||||
// 构建全局设备变量
|
// 构建全局设备变量
|
||||||
device := common.DefaultDevice(ctx, publishTopic)
|
device := common.DefaultDevice(ctx, publishTopic)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package card_reader
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/munnik/modbus"
|
"github.com/grid-x/modbus"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
type Reader interface {
|
type Reader interface {
|
||||||
io.Closer
|
io.Closer
|
||||||
SetUnitID(uint8)
|
SetSlave(uint8)
|
||||||
// WriteUnitId 写入读卡器的 UnitID
|
// WriteUnitId 写入读卡器的 UnitID
|
||||||
WriteUnitId(uint16) error
|
WriteUnitId(uint16) error
|
||||||
// Init 初始化读卡器配置
|
// Init 初始化读卡器配置
|
||||||
@@ -24,40 +24,42 @@ type Reader interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CardInfo struct {
|
type CardInfo struct {
|
||||||
Type uint16
|
Type []byte
|
||||||
ID string
|
ID string
|
||||||
}
|
}
|
||||||
|
|
||||||
type reader struct {
|
type reader struct {
|
||||||
c *modbus.Client
|
h modbus.ClientHandler
|
||||||
|
c modbus.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteUnitId 写入读卡器的 UnitID
|
// WriteUnitId 写入读卡器的 UnitID
|
||||||
func (r *reader) WriteUnitId(id uint16) error {
|
func (r *reader) WriteUnitId(id uint16) error {
|
||||||
v := id<<8 + 1
|
v := id<<8 + 1
|
||||||
zap.S().Infof("WriteRegister 40007 %#x", v)
|
zap.S().Infof("WriteRegister 40007 %#x", v)
|
||||||
return r.c.WriteRegister(6, v)
|
_, err := r.c.WriteSingleRegister(6, v)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init 初始化读卡器配置
|
// Init 初始化读卡器配置
|
||||||
func (r *reader) Init() error {
|
func (r *reader) Init() error {
|
||||||
// 配置读卡间隔时间为 50 毫秒
|
// 配置读卡间隔时间为 50 毫秒
|
||||||
err := r.c.WriteRegister(8, 0x0511)
|
_, err := r.c.WriteSingleRegister(8, 0x0511)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 由低到高输出 500 毫秒
|
// 由低到高输出 500 毫秒
|
||||||
err = r.c.WriteRegister(9, 0xF20A)
|
_, err = r.c.WriteSingleRegister(9, 0xF20A)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 读取后自动清空,高字节:00 不清空 01 清空
|
// 读取后自动清空,高字节:00 不清空 01 清空
|
||||||
err = r.c.WriteRegister(10, 0x0103)
|
_, err = r.c.WriteSingleRegister(10, 0x0103)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 自动读卡号,高字节高4位:0 读一次 1 连续读
|
// 自动读卡号,高字节高4位:0 读一次 1 连续读
|
||||||
err = r.c.WriteRegister(11, 0x0301)
|
_, err = r.c.WriteSingleRegister(11, 0x0301)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -67,31 +69,31 @@ func (r *reader) Init() error {
|
|||||||
// GetCardInfo 获取卡号信息
|
// GetCardInfo 获取卡号信息
|
||||||
func (r *reader) GetCardInfo() *CardInfo {
|
func (r *reader) GetCardInfo() *CardInfo {
|
||||||
// 读取状态寄存器确认是否信息已经准备好
|
// 读取状态寄存器确认是否信息已经准备好
|
||||||
status, err := r.c.ReadRegister(29, modbus.HoldingRegister)
|
status, err := r.c.ReadHoldingRegisters(29, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Errorln("ReadRegister 40030 error:", err)
|
zap.S().Errorln("ReadRegister 40030 error:", err)
|
||||||
return nil
|
return nil
|
||||||
} else if status == 0x0000 {
|
} else if len(status) != 2 || status[1] == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取卡号长度
|
// 读取卡号长度
|
||||||
cardLength, err := r.c.ReadRegister(30, modbus.HoldingRegister)
|
cardLength, err := r.c.ReadHoldingRegisters(30, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Errorln("ReadRegister 40031 error:", err)
|
zap.S().Errorln("ReadRegister 40031 error:", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
dataLength := cardLength >> 8
|
dataLength := cardLength[0]
|
||||||
|
|
||||||
// 读取卡类型
|
// 读取卡类型
|
||||||
cardType, err := r.c.ReadRegister(31, modbus.HoldingRegister)
|
cardType, err := r.c.ReadHoldingRegisters(31, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Errorln("ReadRegister 40032 error:", err)
|
zap.S().Errorln("ReadRegister 40032 error:", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取卡号数据
|
// 读取卡号数据
|
||||||
cardData, err := r.c.ReadRegisters(32, uint16(math.Round(float64(dataLength)/2)), modbus.HoldingRegister)
|
cardData, err := r.c.ReadHoldingRegisters(32, uint16(math.Round(float64(dataLength)/2)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Errorln("ReadRegister 40033~ error:", err)
|
zap.S().Errorln("ReadRegister 40033~ error:", err)
|
||||||
return nil
|
return nil
|
||||||
@@ -99,11 +101,7 @@ func (r *reader) GetCardInfo() *CardInfo {
|
|||||||
|
|
||||||
s := make([]string, dataLength)
|
s := make([]string, dataLength)
|
||||||
for i := 0; i < int(dataLength); i++ {
|
for i := 0; i < int(dataLength); i++ {
|
||||||
if i%2 == 0 {
|
s[i] = fmt.Sprintf("%02X", cardData[i])
|
||||||
s[i] = fmt.Sprintf("%02X", cardData[i/2]>>8)
|
|
||||||
} else {
|
|
||||||
s[i] = fmt.Sprintf("%02X", cardData[i/2]&0xFF)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &CardInfo{
|
return &CardInfo{
|
||||||
@@ -127,30 +125,30 @@ func (r *reader) OnCardInfo(ctx context.Context, f func(info *CardInfo)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *reader) SetUnitID(unitID uint8) {
|
func (r *reader) SetSlave(unitID byte) {
|
||||||
_ = r.c.SetUnitID(unitID)
|
r.h.SetSlave(unitID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *reader) Close() error {
|
func (r *reader) Close() error {
|
||||||
return r.c.Close()
|
return r.h.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReader 创建一个新的读卡器
|
// NewReader 创建一个新的读卡器
|
||||||
func NewReader(URL string) (Reader, error) {
|
func NewReader(address string) (Reader, error) {
|
||||||
// 配置串口客户端
|
// 配置串口客户端
|
||||||
c, _ := modbus.NewClient(&modbus.Configuration{
|
h := modbus.NewRTUClientHandler(address)
|
||||||
URL: URL,
|
h.SlaveID = 1
|
||||||
Speed: 9600,
|
h.BaudRate = 9600
|
||||||
DataBits: 8,
|
h.DataBits = 8
|
||||||
Timeout: 2 * time.Second,
|
h.Parity = "N"
|
||||||
Logger: zap.NewStdLog(zap.L()),
|
h.StopBits = 1
|
||||||
})
|
|
||||||
|
|
||||||
// 打开串口连接
|
// 连接串口
|
||||||
err := c.Open()
|
if err := h.Connect(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// 创建 modbus 客户端
|
||||||
|
c := modbus.NewClient(h)
|
||||||
|
|
||||||
return &reader{c}, nil
|
return &reader{h, c}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
package relay
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"go.bug.st/serial/enumerator"
|
|
||||||
)
|
|
||||||
|
|
||||||
func PrintPorts() {
|
|
||||||
ports, err := enumerator.GetDetailedPortsList()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(ports) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, port := range ports {
|
|
||||||
fmt.Printf("Port: %s\n", port.Name)
|
|
||||||
if port.Product != "" {
|
|
||||||
fmt.Printf(" Product Name: %s\n", port.Product)
|
|
||||||
}
|
|
||||||
if port.IsUSB {
|
|
||||||
fmt.Printf(" USB ID : %s:%s\n", port.VID, port.PID)
|
|
||||||
fmt.Printf(" USB serial : %s\n", port.SerialNumber)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +1,64 @@
|
|||||||
package relay
|
package relay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"github.com/grid-x/modbus"
|
||||||
"fmt"
|
|
||||||
"go.bug.st/serial"
|
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Device struct {
|
type Relay interface {
|
||||||
port serial.Port
|
io.Closer
|
||||||
|
SetSlave(slaveID byte)
|
||||||
|
On(num int) error
|
||||||
|
Off(num int) error
|
||||||
|
OnAll() error
|
||||||
|
OffAll() error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Device) Close() error {
|
type device struct {
|
||||||
return r.port.Close()
|
h modbus.ClientHandler
|
||||||
|
c modbus.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Device) On(num int) error {
|
func (r *device) SetSlave(slaveID byte) {
|
||||||
_, err := io.WriteString(r.port, fmt.Sprintf("AT+OUT%v+1=ON\r\n", num))
|
r.h.SetSlave(slaveID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *device) Close() error {
|
||||||
|
return r.h.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *device) OnAll() error {
|
||||||
|
_, err := r.c.WriteMultipleCoils(uint16(0), 16, []byte{0xFF, 0xFF})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Device) Off(num int) error {
|
func (r *device) OffAll() error {
|
||||||
_, err := io.WriteString(r.port, fmt.Sprintf("AT+OUT%v+1=OFF\r\n", num))
|
_, err := r.c.WriteMultipleCoils(uint16(0), 16, []byte{0x00, 0x00})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(portName string, reader func(msg string)) (*Device, error) {
|
func (r *device) On(num int) error {
|
||||||
port, err := serial.Open(portName, &serial.Mode{
|
_, err := r.c.WriteSingleCoil(uint16(num), 0xFF00)
|
||||||
BaudRate: 9600,
|
return err
|
||||||
DataBits: 8,
|
}
|
||||||
})
|
|
||||||
if err != nil {
|
func (r *device) Off(num int) error {
|
||||||
|
_, err := r.c.WriteSingleCoil(uint16(num), 0x0000)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(address string) (Relay, error) {
|
||||||
|
h := modbus.NewRTUClientHandler(address)
|
||||||
|
h.SlaveID = 1
|
||||||
|
h.BaudRate = 9600
|
||||||
|
h.DataBits = 8
|
||||||
|
h.Parity = "N"
|
||||||
|
h.StopBits = 1
|
||||||
|
|
||||||
|
if err := h.Connect(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
go func() {
|
c := modbus.NewClient(h)
|
||||||
for {
|
|
||||||
r := bufio.NewReader(port)
|
return &device{h, c}, nil
|
||||||
line, _, _ := r.ReadLine()
|
|
||||||
if reader != nil {
|
|
||||||
reader(string(line))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return &Device{port: port}, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user