支持实时报警信息显示配置

main
wangqiyang 3 days ago
parent 65ba621c91
commit cd67652c9c

@ -135,8 +135,9 @@ type DeviceStatusLoop struct {
} }
type DeviceStatus struct { type DeviceStatus struct {
m9z.DeviceStatus m9z.DeviceStatus
ScanDeviceCount int `json:"scan_device_count"` ScanDeviceCount int `json:"scan_device_count"`
Loops []DeviceStatusLoop `json:"Loops"` AlarmDisplayEnabled bool `json:"alarm_display_enabled"`
Loops []DeviceStatusLoop `json:"Loops"`
} }
// 实时监控数据 // 实时监控数据
@ -158,6 +159,7 @@ func getDeviceStatus2Real(rpc towgo.JsonRpcConnection) {
scanLoopCount := configuredLoopCount() scanLoopCount := configuredLoopCount()
displayLoopCount := monitorDisplayLoopCount() displayLoopCount := monitorDisplayLoopCount()
d.ScanDeviceCount = scanLoopCount d.ScanDeviceCount = scanLoopCount
d.AlarmDisplayEnabled = scanConfigManager.GetAlarmDisplayEnabled()
loops := make([]DeviceStatusLoop, displayLoopCount) loops := make([]DeviceStatusLoop, displayLoopCount)
var wg sync.WaitGroup var wg sync.WaitGroup
for i := 0; i < displayLoopCount; i++ { for i := 0; i < displayLoopCount; i++ {
@ -206,8 +208,9 @@ func buildDemoDeviceStatus2() *DeviceStatus {
displayLoopCount := monitorDisplayLoopCount() displayLoopCount := monitorDisplayLoopCount()
scanLoopCount := configuredLoopCount() scanLoopCount := configuredLoopCount()
d := &DeviceStatus{ d := &DeviceStatus{
ScanDeviceCount: scanLoopCount, ScanDeviceCount: scanLoopCount,
Loops: make([]DeviceStatusLoop, displayLoopCount), AlarmDisplayEnabled: scanConfigManager.GetAlarmDisplayEnabled(),
Loops: make([]DeviceStatusLoop, displayLoopCount),
} }
d.Mode = 0 d.Mode = 0
d.DeviceTime = time.Now().UTC() d.DeviceTime = time.Now().UTC()

@ -12,16 +12,20 @@ import (
"github.com/towgo/towgo/towgo" "github.com/towgo/towgo/towgo"
) )
const defaultAlarmDisplayEnabled = true
type ScanConfigManager struct { type ScanConfigManager struct {
mu sync.RWMutex mu sync.RWMutex
loopCount int loopCount int
alarmDisplayEnabled bool
} }
type ScanConfigData struct { type ScanConfigData struct {
LoopCount int `json:"loop_count"` LoopCount int `json:"loop_count"`
AlarmDisplayEnabled *bool `json:"alarm_display_enabled,omitempty"`
} }
var scanConfigManager = &ScanConfigManager{} var scanConfigManager = &ScanConfigManager{alarmDisplayEnabled: defaultAlarmDisplayEnabled}
func getScanConfigFilePath() string { func getScanConfigFilePath() string {
return filepath.Join(system.GetPathOfProgram(), "data", "scanConfig.json") return filepath.Join(system.GetPathOfProgram(), "data", "scanConfig.json")
@ -33,15 +37,38 @@ func (m *ScanConfigManager) GetLoopCount() int {
return normalizeLoopCount(m.loopCount) return normalizeLoopCount(m.loopCount)
} }
func (m *ScanConfigManager) GetAlarmDisplayEnabled() bool {
m.mu.RLock()
defer m.mu.RUnlock()
return m.alarmDisplayEnabled
}
func (m *ScanConfigManager) SetLoopCount(loopCount int) error { func (m *ScanConfigManager) SetLoopCount(loopCount int) error {
m.mu.Lock() m.mu.Lock()
defer m.mu.Unlock() defer m.mu.Unlock()
m.loopCount = loopCount m.loopCount = normalizeLoopCount(loopCount)
if err := m.saveToFile(); err != nil {
return err
}
g.GVA_Config.DeviceInfo.LoopCount = m.loopCount
return nil
}
func (m *ScanConfigManager) SetConfig(loopCount int, alarmDisplayEnabled *bool) error {
m.mu.Lock()
defer m.mu.Unlock()
if loopCount > 0 {
m.loopCount = normalizeLoopCount(loopCount)
g.GVA_Config.DeviceInfo.LoopCount = m.loopCount
}
if alarmDisplayEnabled != nil {
m.alarmDisplayEnabled = *alarmDisplayEnabled
}
if err := m.saveToFile(); err != nil { if err := m.saveToFile(); err != nil {
return err return err
} }
g.GVA_Config.DeviceInfo.LoopCount = loopCount
return nil return nil
} }
@ -54,6 +81,7 @@ func (m *ScanConfigManager) loadFromFile() error {
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
m.loopCount = normalizeLoopCount(g.Config().DeviceInfo.LoopCount) m.loopCount = normalizeLoopCount(g.Config().DeviceInfo.LoopCount)
m.alarmDisplayEnabled = defaultAlarmDisplayEnabled
return m.saveToFile() return m.saveToFile()
} }
return err return err
@ -64,6 +92,11 @@ func (m *ScanConfigManager) loadFromFile() error {
return err return err
} }
m.loopCount = normalizeLoopCount(data.LoopCount) m.loopCount = normalizeLoopCount(data.LoopCount)
if data.AlarmDisplayEnabled == nil {
m.alarmDisplayEnabled = defaultAlarmDisplayEnabled
} else {
m.alarmDisplayEnabled = *data.AlarmDisplayEnabled
}
g.GVA_Config.DeviceInfo.LoopCount = m.loopCount g.GVA_Config.DeviceInfo.LoopCount = m.loopCount
return nil return nil
} }
@ -76,7 +109,8 @@ func (m *ScanConfigManager) saveToFile() error {
} }
jsonData, err := json.Marshal(ScanConfigData{ jsonData, err := json.Marshal(ScanConfigData{
LoopCount: normalizeLoopCount(m.loopCount), LoopCount: normalizeLoopCount(m.loopCount),
AlarmDisplayEnabled: boolPtr(m.alarmDisplayEnabled),
}) })
if err != nil { if err != nil {
return err return err
@ -86,32 +120,43 @@ func (m *ScanConfigManager) saveToFile() error {
func getScanConfig(rpcConn towgo.JsonRpcConnection) { func getScanConfig(rpcConn towgo.JsonRpcConnection) {
rpcConn.WriteResult(map[string]interface{}{ rpcConn.WriteResult(map[string]interface{}{
"loop_count": scanConfigManager.GetLoopCount(), "loop_count": scanConfigManager.GetLoopCount(),
"max_loop_count": maxLoopCount, "alarm_display_enabled": scanConfigManager.GetAlarmDisplayEnabled(),
"min_loop_count": 1, "max_loop_count": maxLoopCount,
"min_loop_count": 1,
}) })
} }
type SetScanConfigReq struct { type SetScanConfigReq struct {
LoopCount int `json:"loop_count"` LoopCount int `json:"loop_count"`
AlarmDisplayEnabled *bool `json:"alarm_display_enabled"`
} }
func setScanConfig(rpcConn towgo.JsonRpcConnection) { func setScanConfig(rpcConn towgo.JsonRpcConnection) {
var req SetScanConfigReq var req SetScanConfigReq
rpcConn.ReadParams(&req) rpcConn.ReadParams(&req)
if req.LoopCount < 1 || req.LoopCount > maxLoopCount { if req.LoopCount != 0 && (req.LoopCount < 1 || req.LoopCount > maxLoopCount) {
rpcConn.WriteError(400, "loop_count must be between 1 and 10") rpcConn.WriteError(400, "loop_count must be between 1 and 10")
return return
} }
if err := scanConfigManager.SetLoopCount(req.LoopCount); err != nil { if req.LoopCount == 0 && req.AlarmDisplayEnabled == nil {
rpcConn.WriteError(400, "loop_count or alarm_display_enabled is required")
return
}
if err := scanConfigManager.SetConfig(req.LoopCount, req.AlarmDisplayEnabled); err != nil {
rpcConn.WriteError(500, "save scan config failed: "+err.Error()) rpcConn.WriteError(500, "save scan config failed: "+err.Error())
return return
} }
rpcConn.WriteResult(map[string]interface{}{ rpcConn.WriteResult(map[string]interface{}{
"success": true, "success": true,
"loop_count": scanConfigManager.GetLoopCount(), "loop_count": scanConfigManager.GetLoopCount(),
"max_loop_count": maxLoopCount, "alarm_display_enabled": scanConfigManager.GetAlarmDisplayEnabled(),
"min_loop_count": 1, "max_loop_count": maxLoopCount,
"min_loop_count": 1,
}) })
} }
func boolPtr(value bool) *bool {
return &value
}

@ -32,11 +32,14 @@ func TestMonitorDisplayLoopCountAlwaysUsesMaxLoopCount(t *testing.T) {
func TestBuildDemoDeviceStatus2KeepsDisplayLoopsIndependentFromScanCount(t *testing.T) { func TestBuildDemoDeviceStatus2KeepsDisplayLoopsIndependentFromScanCount(t *testing.T) {
scanConfigManager.mu.Lock() scanConfigManager.mu.Lock()
oldLoopCount := scanConfigManager.loopCount oldLoopCount := scanConfigManager.loopCount
oldAlarmDisplayEnabled := scanConfigManager.alarmDisplayEnabled
scanConfigManager.loopCount = 6 scanConfigManager.loopCount = 6
scanConfigManager.alarmDisplayEnabled = true
scanConfigManager.mu.Unlock() scanConfigManager.mu.Unlock()
t.Cleanup(func() { t.Cleanup(func() {
scanConfigManager.mu.Lock() scanConfigManager.mu.Lock()
scanConfigManager.loopCount = oldLoopCount scanConfigManager.loopCount = oldLoopCount
scanConfigManager.alarmDisplayEnabled = oldAlarmDisplayEnabled
scanConfigManager.mu.Unlock() scanConfigManager.mu.Unlock()
}) })
@ -53,4 +56,24 @@ func TestBuildDemoDeviceStatus2KeepsDisplayLoopsIndependentFromScanCount(t *test
if status.Loops[6].HasFault { if status.Loops[6].HasFault {
t.Fatal("status.Loops[6].HasFault = true, want false outside the scan loop count") t.Fatal("status.Loops[6].HasFault = true, want false outside the scan loop count")
} }
if !status.AlarmDisplayEnabled {
t.Fatal("status.AlarmDisplayEnabled = false, want true")
}
}
func TestBuildDemoDeviceStatus2IncludesAlarmDisplayConfig(t *testing.T) {
scanConfigManager.mu.Lock()
oldAlarmDisplayEnabled := scanConfigManager.alarmDisplayEnabled
scanConfigManager.alarmDisplayEnabled = false
scanConfigManager.mu.Unlock()
t.Cleanup(func() {
scanConfigManager.mu.Lock()
scanConfigManager.alarmDisplayEnabled = oldAlarmDisplayEnabled
scanConfigManager.mu.Unlock()
})
status := buildDemoDeviceStatus2()
if status.AlarmDisplayEnabled {
t.Fatal("status.AlarmDisplayEnabled = true, want false")
}
} }

Loading…
Cancel
Save