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:
- 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:
- `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
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
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:
s.decodeTS(payload)
case 0x1a:
s.decodeDataMode(payload)
s.decodeDataModeAndOVF(payload)
case 0x14:
s.decodePower(payload)
case 0x1c:
@ -218,23 +218,35 @@ func (s *civControlStruct) decodeTS(d []byte) {
statusLog.reportTS(s.state.ts)
}
func (s *civControlStruct) decodeDataMode(d []byte) {
if len(d) < 3 || d[0] != 0x06 {
func (s *civControlStruct) decodeDataModeAndOVF(d []byte) {
if len(d) < 2 {
return
}
var dataMode string
var filter string
if d[1] == 1 {
dataMode = "-D"
s.state.dataMode = true
s.state.filterIdx = s.decodeFilterValueToFilterIdx(d[2])
filter = civFilters[s.state.filterIdx].name
} else {
s.state.dataMode = false
}
switch d[0] {
case 0x06:
if len(d) < 3 {
return
}
var dataMode string
var filter string
if d[1] == 1 {
dataMode = "-D"
s.state.dataMode = true
s.state.filterIdx = s.decodeFilterValueToFilterIdx(d[2])
filter = civFilters[s.state.filterIdx].name
} else {
s.state.dataMode = false
}
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) {
@ -539,6 +551,10 @@ func (s *civControlStruct) getS() error {
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 {
return s.st.send([]byte{254, 254, civAddress, 224, 0x10, 253})
}
@ -551,6 +567,7 @@ func (s *civControlStruct) loop() {
return
case <-time.After(sReadInterval):
_ = s.getS()
_ = s.getOVF()
case <-s.resetSReadTimer:
}
}
@ -585,6 +602,9 @@ func (s *civControlStruct) init(st *serialStream) error {
if err := s.getS(); err != nil {
return err
}
if err := s.getOVF(); err != nil {
return err
}
if err := s.getTS(); err != nil {
return err
}

View file

@ -24,6 +24,7 @@ type statusLogData struct {
vd string
txPower string
s string
ovf bool
ts string
startTime time.Time
@ -55,6 +56,8 @@ type statusLogStruct struct {
monOn string
rec string
}
ovf string
}
data *statusLogData
@ -168,6 +171,16 @@ func (s *statusLogStruct) reportS(sValue string) {
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) {
s.mutex.Lock()
defer s.mutex.Unlock()
@ -249,7 +262,11 @@ func (s *statusLogStruct) update() {
s.mutex.Lock()
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
if s.data.ts != "" {
@ -396,6 +413,10 @@ func (s *statusLogStruct) initIfNeeded() {
s.preGenerated.stateStr.tune = c.Sprint(" TUNE ")
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.Add(color.BgYellow)
s.preGenerated.lostColor = color.New(color.FgHiWhite)