优化逻辑
This commit is contained in:
@@ -2,6 +2,7 @@ package common
|
|||||||
|
|
||||||
import "sync"
|
import "sync"
|
||||||
|
|
||||||
|
// CtrlWait 待机暂停控制器
|
||||||
type CtrlWait struct {
|
type CtrlWait struct {
|
||||||
C chan int8
|
C chan int8
|
||||||
|
|
||||||
|
|||||||
@@ -19,15 +19,15 @@ func switchPoint(ctx context.Context, point int) leaf.HandlerFunc {
|
|||||||
switch point {
|
switch point {
|
||||||
case 2: // 镇水塔点位
|
case 2: // 镇水塔点位
|
||||||
return play.OnlyVideo
|
return play.OnlyVideo
|
||||||
|
case 5:
|
||||||
|
// 登龙云台(激光秀)
|
||||||
|
return play.LaserShow
|
||||||
case 10:
|
case 10:
|
||||||
// 10号点位(发卡机)
|
// 10号点位(发卡机)
|
||||||
return play.PushCard(ctx)
|
return play.PushCard(ctx)
|
||||||
case 11:
|
case 11:
|
||||||
// 11号点位(等待插卡)
|
// 11号点位(等待插卡)
|
||||||
return play.WaitCard(ctx)
|
return play.WaitCard(ctx)
|
||||||
case 5:
|
|
||||||
// 登龙云台(激光秀)
|
|
||||||
return play.LaserShow
|
|
||||||
default:
|
default:
|
||||||
return play.Default
|
return play.Default
|
||||||
}
|
}
|
||||||
|
|||||||
35
internal/routes/standby/laser.go
Normal file
35
internal/routes/standby/laser.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package standby
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"game-driver/config/game"
|
||||||
|
"game-driver/internal/schema"
|
||||||
|
"game-driver/pkg/oscx"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LaserShow(item schema.WaitItemModel) func(c context.Context) error {
|
||||||
|
cfg := (game.C).(game.LaserConfig)
|
||||||
|
|
||||||
|
return func(c context.Context) error {
|
||||||
|
zap.S().Infoln("开始播放大型激光秀")
|
||||||
|
|
||||||
|
o := oscx.New(cfg.Host, cfg.Port)
|
||||||
|
err := o.EnableLaserOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("激光打开异常: %w", err)
|
||||||
|
} else {
|
||||||
|
defer zap.S().Infoln("大型激光秀播放结束:", item.Data)
|
||||||
|
defer o.DisableLaserOutput()
|
||||||
|
|
||||||
|
err = o.StartCue(item.Data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("播放大型激光节目异常: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<-c.Done()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"game-driver/pkg/audio"
|
"game-driver/pkg/audio"
|
||||||
"game-driver/pkg/tts"
|
"game-driver/pkg/tts"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TTS(item schema.WaitItemModel) func(c context.Context) error {
|
func TTS(item schema.WaitItemModel) func(c context.Context) error {
|
||||||
@@ -20,13 +19,8 @@ func TTS(item schema.WaitItemModel) func(c context.Context) error {
|
|||||||
zap.S().Infoln("播放待机 TTS 语音")
|
zap.S().Infoln("播放待机 TTS 语音")
|
||||||
defer zap.S().Infoln("结束待机 TTS 语音")
|
defer zap.S().Infoln("结束待机 TTS 语音")
|
||||||
|
|
||||||
for {
|
audio.PlayWav(c, reader)
|
||||||
audio.PlayWav(c, reader)
|
|
||||||
select {
|
return nil
|
||||||
case <-c.Done():
|
|
||||||
return nil
|
|
||||||
case <-time.After(time.Duration(item.Interval) * time.Second):
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"game-driver/pkg/utils"
|
"game-driver/pkg/utils"
|
||||||
"game-driver/pkg/video"
|
"game-driver/pkg/video"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Video(item schema.WaitItemModel) func(c context.Context) error {
|
func Video(item schema.WaitItemModel) func(c context.Context) error {
|
||||||
@@ -23,16 +22,10 @@ func Video(item schema.WaitItemModel) func(c context.Context) error {
|
|||||||
utils.BlankOpen()
|
utils.BlankOpen()
|
||||||
defer utils.BlankClose()
|
defer utils.BlankClose()
|
||||||
|
|
||||||
for {
|
err = video.Play(c, path, local)
|
||||||
err := video.Play(c, path, local)
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("视频播放异常: %w", err)
|
||||||
return fmt.Errorf("视频播放异常: %w", err)
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case <-c.Done():
|
|
||||||
return nil
|
|
||||||
case <-time.After(time.Duration(item.Interval) * time.Second):
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Time 时间控制器
|
// Cron 时间控制器
|
||||||
func Time(rootRules []cronrange.Rule, cron string, play func(c context.Context) error) func(c context.Context) error {
|
func Cron(rootRules []cronrange.Rule, cron string, play func(c context.Context) error) func(c context.Context) error {
|
||||||
// 设定默认时间规则
|
// 设定默认时间规则
|
||||||
if cron == "" {
|
if cron == "" {
|
||||||
cron = "* * * *"
|
cron = "* * * *"
|
||||||
21
internal/routes/standby_ctrl/device.go
Normal file
21
internal/routes/standby_ctrl/device.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package standby_ctrl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"game-driver/internal/common"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Device(d *common.Device, lock bool, play func(c context.Context) error) func(c context.Context) error {
|
||||||
|
return func(c context.Context) error {
|
||||||
|
if lock {
|
||||||
|
zap.S().Infoln("待机任务锁定设备")
|
||||||
|
defer zap.S().Infoln("待机任务解锁设备")
|
||||||
|
|
||||||
|
d.Lock()
|
||||||
|
defer d.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
return play(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
23
internal/routes/standby_ctrl/duration.go
Normal file
23
internal/routes/standby_ctrl/duration.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package standby_ctrl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Duration 持续时长控制器
|
||||||
|
func Duration(duration int64, play func(c context.Context) error) func(c context.Context) error {
|
||||||
|
return func(c context.Context) error {
|
||||||
|
zap.S().Infoln("待机持续时长控制器: ", duration)
|
||||||
|
defer zap.S().Infoln("待机持续时长控制器结束: ", duration)
|
||||||
|
|
||||||
|
if duration > 0 {
|
||||||
|
ctx, cancel := context.WithTimeout(c, time.Duration(duration)*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
c = ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
return play(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
34
internal/routes/standby_ctrl/interval.go
Normal file
34
internal/routes/standby_ctrl/interval.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package standby_ctrl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Interval(interval int64, play func(c context.Context) error) func(c context.Context) error {
|
||||||
|
return func(c context.Context) error {
|
||||||
|
zap.S().Infoln("待机间隔控制器: ", interval)
|
||||||
|
defer zap.S().Infoln("待机间隔控制器结束: ", interval)
|
||||||
|
|
||||||
|
for {
|
||||||
|
err := play(c)
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Errorln("执行后续操作异常: ", err)
|
||||||
|
}
|
||||||
|
if interval > 0 {
|
||||||
|
select {
|
||||||
|
case <-c.Done():
|
||||||
|
return nil
|
||||||
|
case <-time.After(time.Duration(interval) * time.Second):
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
select {
|
||||||
|
case <-c.Done():
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WaitAction(ctrl *common.CtrlWait) leaf.HandlerFunc {
|
// WaitAction 待机任务,支持音乐、TTS、继电器、视频、网页、投影仪、大型激光秀 ctrl
|
||||||
|
func WaitAction(ctrl *common.CtrlWait, device *common.Device) leaf.HandlerFunc {
|
||||||
ps := common.NewPauseSub(ctrl)
|
ps := common.NewPauseSub(ctrl)
|
||||||
|
|
||||||
return func(c *leaf.Context) {
|
return func(c *leaf.Context) {
|
||||||
@@ -49,7 +50,15 @@ func WaitAction(ctrl *common.CtrlWait) leaf.HandlerFunc {
|
|||||||
if f == nil {
|
if f == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f = standby_ctrl.Time(rules, item.Cron, f)
|
f = standby_ctrl.Duration(item.Duration, f)
|
||||||
|
if f == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f = standby_ctrl.Device(device, item.Lock, f)
|
||||||
|
if f == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f = standby_ctrl.Interval(item.Interval, f)
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -57,6 +66,10 @@ func WaitAction(ctrl *common.CtrlWait) leaf.HandlerFunc {
|
|||||||
if f == nil {
|
if f == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
f = standby_ctrl.Cron(rules, item.Cron, f)
|
||||||
|
if f == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
e := f(c)
|
e := f(c)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
zap.S().Errorf("%s异常: %s\n", title, e)
|
zap.S().Errorf("%s异常: %s\n", title, e)
|
||||||
@@ -75,9 +88,11 @@ func WaitAction(ctrl *common.CtrlWait) leaf.HandlerFunc {
|
|||||||
case schema.WaitVideo:
|
case schema.WaitVideo:
|
||||||
handleItem("视频待机控制", item, standby.Video(item))
|
handleItem("视频待机控制", item, standby.Video(item))
|
||||||
case schema.WaitWeb:
|
case schema.WaitWeb:
|
||||||
handleItem("视频待机控制", item, standby.Web(item))
|
handleItem("网页待机控制", item, standby.Web(item))
|
||||||
case schema.WaitPJLink:
|
case schema.WaitPJLink:
|
||||||
handleItem("视频待机控制", item, standby.PJLink(item))
|
handleItem("投影仪待机控制", item, standby.PJLink(item))
|
||||||
|
case schema.WaitLaserShow:
|
||||||
|
handleItem("大型激光秀控制", item, standby.LaserShow(item))
|
||||||
default:
|
default:
|
||||||
zap.S().Infof("不支持的类型: %d\n", item.Type)
|
zap.S().Infof("不支持的类型: %d\n", item.Type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,17 @@ const (
|
|||||||
WaitRelay
|
WaitRelay
|
||||||
WaitWeb
|
WaitWeb
|
||||||
WaitPJLink
|
WaitPJLink
|
||||||
|
WaitLaserShow
|
||||||
)
|
)
|
||||||
|
|
||||||
type WaitItemModel struct {
|
type WaitItemModel struct {
|
||||||
Cron string `json:"cron"`
|
Cron string `json:"cron"` // 时间规则
|
||||||
Type WaitType `json:"type"`
|
Type WaitType `json:"type"` // 类型
|
||||||
Data string `json:"data"`
|
Data string `json:"data"` // 执行数据
|
||||||
Interval int64 `json:"interval"`
|
Duration int64 `json:"duration"` // 持续时长
|
||||||
Pause bool `json:"pause"`
|
Interval int64 `json:"interval"` // 间隔时间
|
||||||
|
Pause bool `json:"pause"` // 是否暂停
|
||||||
|
Lock bool `json:"lock"` // 是否锁定
|
||||||
}
|
}
|
||||||
|
|
||||||
type WaitModel struct {
|
type WaitModel struct {
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ func Run() {
|
|||||||
middleware.PayloadJSON[schema.WaitModel](),
|
middleware.PayloadJSON[schema.WaitModel](),
|
||||||
middleware.Unique(common.GlobalBgStopper),
|
middleware.Unique(common.GlobalBgStopper),
|
||||||
middleware.EmergencyStop(common.GlobalBgStopper),
|
middleware.EmergencyStop(common.GlobalBgStopper),
|
||||||
routes.WaitAction(common.PassCtrl),
|
routes.WaitAction(common.PassCtrl, device),
|
||||||
)
|
)
|
||||||
// 处理指令
|
// 处理指令
|
||||||
router.RegisterHandler(topicPrefix+"command",
|
router.RegisterHandler(topicPrefix+"command",
|
||||||
|
|||||||
27
json.md
27
json.md
@@ -20,6 +20,24 @@ url: `server/wushan/0/play`
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 点位1(击缶台)
|
||||||
|
|
||||||
|
### 待机
|
||||||
|
|
||||||
|
url: `server/wushan/1/wait`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cron": "08:00-22:00 * * *",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": 3,
|
||||||
|
"data": "/dev/ttyUSB0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Game
|
### Game
|
||||||
|
|
||||||
url: `server/wushan/1/play`
|
url: `server/wushan/1/play`
|
||||||
@@ -140,7 +158,14 @@ url: `server/wushan/5/wait`
|
|||||||
"cron": "08:00-22:00 * * *",
|
"cron": "08:00-22:00 * * *",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"data": "file://./三峡龙脊BGM.mp3"
|
"data": "file://./三峡龙脊BGM.mp3",
|
||||||
|
"pause": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cron": "12:05-12:10 * * *",
|
||||||
|
"type": 6,
|
||||||
|
"data": "wushan",
|
||||||
|
"lock": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,10 +136,14 @@ Payload:
|
|||||||
"cron": "17:20-21:35 1-5 * *",
|
"cron": "17:20-21:35 1-5 * *",
|
||||||
// 间隔时间(s), 类型>2时, 该项无效, default 0
|
// 间隔时间(s), 类型>2时, 该项无效, default 0
|
||||||
"interval": 0,
|
"interval": 0,
|
||||||
// 事件类型(0: 音频; 1: 视频; 2: TTS; 3: 继电器; 4: 网页), default 0
|
// 持续时长(s), 待机任务执行时持续的时长。为 0 表示 音频、视频、TTS 按播放时长,继电器、网页、投影仪、激光秀持续整个时间段。 default 0
|
||||||
|
"duration": 0,
|
||||||
|
// 事件类型(0: 音频; 1: 视频; 2: TTS; 3: 继电器; 4: 网页; 5: 投影仪; 6: 激光秀;), default 0
|
||||||
"type": 2,
|
"type": 2,
|
||||||
// Game 指令执行时是否暂停(默认 false)
|
// Game 指令执行时是否暂停(默认 false)
|
||||||
"pause": true,
|
"pause": true,
|
||||||
|
// 待机任务执行时,是否锁定设备(默认 false)
|
||||||
|
"lock": false,
|
||||||
// 事件数据(TTS为文字, 继电器为端口号, 其他都为地址链接。支持 file:// 本地文件地址、 http(s):// 远程文件地址)
|
// 事件数据(TTS为文字, 继电器为端口号, 其他都为地址链接。支持 file:// 本地文件地址、 http(s):// 远程文件地址)
|
||||||
"data": "",
|
"data": "",
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user