Add support for querying S meter overflow

This commit is contained in:
Nonoo 2020-11-04 09:18:48 +01:00
parent b7c79a2bd4
commit 73d92d96a4
3 changed files with 59 additions and 17 deletions

View file

@ -85,7 +85,8 @@ kappanhang displays a "realtime" status bar (when the audio/serial connection
is up) with the following info: is up) with the following info:
- First status bar line: - First status bar line:
- `S meter`: periodically refreshed S meter value - `S meter`: periodically refreshed S meter value, OVF is displayed on
overflow
- Second status bar line: - Second status bar line:
- `state`: RX/TX/TUNE depending on the PTT status - `state`: RX/TX/TUNE depending on the PTT status
@ -108,7 +109,7 @@ is up) with the following info:
- `lost`: lost audio/serial packet count from the server - `lost`: lost audio/serial packet count from the server
Data for the first 2 status bar lines are acquired by monitoring CiV traffic Data for the first 2 status bar lines are acquired by monitoring CiV traffic
in the serial stream. S value is queried periodically. in the serial stream. S value and OVF are queried periodically.
`retx` and `lost` are displayed in a 1 minute window, which means they will be `retx` and `lost` are displayed in a 1 minute window, which means they will be
reset to 0 if they don't increase for 1 minute. A `retx` value other than 0 reset to 0 if they don't increase for 1 minute. A `retx` value other than 0

View file

@ -105,7 +105,7 @@ func (s *civControlStruct) decode(d []byte) {
case 0x10: case 0x10:
s.decodeTS(payload) s.decodeTS(payload)
case 0x1a: case 0x1a:
s.decodeDataMode(payload) s.decodeDataModeAndOVF(payload)
case 0x14: case 0x14:
s.decodePower(payload) s.decodePower(payload)
case 0x1c: case 0x1c:
@ -218,11 +218,16 @@ func (s *civControlStruct) decodeTS(d []byte) {
statusLog.reportTS(s.state.ts) statusLog.reportTS(s.state.ts)
} }
func (s *civControlStruct) decodeDataMode(d []byte) { func (s *civControlStruct) decodeDataModeAndOVF(d []byte) {
if len(d) < 3 || d[0] != 0x06 { if len(d) < 2 {
return return
} }
switch d[0] {
case 0x06:
if len(d) < 3 {
return
}
var dataMode string var dataMode string
var filter string var filter string
if d[1] == 1 { if d[1] == 1 {
@ -235,6 +240,13 @@ func (s *civControlStruct) decodeDataMode(d []byte) {
} }
statusLog.reportDataMode(dataMode, filter) statusLog.reportDataMode(dataMode, filter)
case 0x09:
if d[1] != 0 {
statusLog.reportOVF(true)
} else {
statusLog.reportOVF(false)
}
}
} }
func (s *civControlStruct) decodePower(d []byte) { func (s *civControlStruct) decodePower(d []byte) {
@ -539,6 +551,10 @@ func (s *civControlStruct) getS() error {
return s.st.send([]byte{254, 254, civAddress, 224, 0x15, 0x02, 253}) return s.st.send([]byte{254, 254, civAddress, 224, 0x15, 0x02, 253})
} }
func (s *civControlStruct) getOVF() error {
return s.st.send([]byte{254, 254, civAddress, 224, 0x1a, 0x09, 253})
}
func (s *civControlStruct) getTS() error { func (s *civControlStruct) getTS() error {
return s.st.send([]byte{254, 254, civAddress, 224, 0x10, 253}) return s.st.send([]byte{254, 254, civAddress, 224, 0x10, 253})
} }
@ -551,6 +567,7 @@ func (s *civControlStruct) loop() {
return return
case <-time.After(sReadInterval): case <-time.After(sReadInterval):
_ = s.getS() _ = s.getS()
_ = s.getOVF()
case <-s.resetSReadTimer: case <-s.resetSReadTimer:
} }
} }
@ -585,6 +602,9 @@ func (s *civControlStruct) init(st *serialStream) error {
if err := s.getS(); err != nil { if err := s.getS(); err != nil {
return err return err
} }
if err := s.getOVF(); err != nil {
return err
}
if err := s.getTS(); err != nil { if err := s.getTS(); err != nil {
return err return err
} }

View file

@ -24,6 +24,7 @@ type statusLogData struct {
vd string vd string
txPower string txPower string
s string s string
ovf bool
ts string ts string
startTime time.Time startTime time.Time
@ -55,6 +56,8 @@ type statusLogStruct struct {
monOn string monOn string
rec string rec string
} }
ovf string
} }
data *statusLogData data *statusLogData
@ -168,6 +171,16 @@ func (s *statusLogStruct) reportS(sValue string) {
s.data.s = sValue s.data.s = sValue
} }
func (s *statusLogStruct) reportOVF(ovf bool) {
s.mutex.Lock()
defer s.mutex.Unlock()
if s.data == nil {
return
}
s.data.ovf = ovf
}
func (s *statusLogStruct) reportTS(ts uint) { func (s *statusLogStruct) reportTS(ts uint) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
@ -249,7 +262,11 @@ func (s *statusLogStruct) update() {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
s.data.line1 = fmt.Sprint(s.data.s) var ovfStr string
if s.data.ovf {
ovfStr = " " + s.preGenerated.ovf
}
s.data.line1 = fmt.Sprint(s.data.s, ovfStr)
var tsStr string var tsStr string
if s.data.ts != "" { if s.data.ts != "" {
@ -396,6 +413,10 @@ func (s *statusLogStruct) initIfNeeded() {
s.preGenerated.stateStr.tune = c.Sprint(" TUNE ") s.preGenerated.stateStr.tune = c.Sprint(" TUNE ")
s.preGenerated.audioStateStr.rec = c.Sprint(" REC ") s.preGenerated.audioStateStr.rec = c.Sprint(" REC ")
c = color.New(color.FgHiWhite)
c.Add(color.BgRed)
s.preGenerated.ovf = c.Sprint(" OVF ")
s.preGenerated.retransmitsColor = color.New(color.FgHiWhite) s.preGenerated.retransmitsColor = color.New(color.FgHiWhite)
s.preGenerated.retransmitsColor.Add(color.BgYellow) s.preGenerated.retransmitsColor.Add(color.BgYellow)
s.preGenerated.lostColor = color.New(color.FgHiWhite) s.preGenerated.lostColor = color.New(color.FgHiWhite)