79 lines
2.3 KiB
Go
79 lines
2.3 KiB
Go
package statusupdate
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
|
|
"src.dualinventive.com/go/lib/dilog"
|
|
)
|
|
|
|
// UpdateDecoder decodes cp3000 update messages
|
|
type UpdateDecoder struct {
|
|
mu sync.RWMutex
|
|
prevUpdateState *StatusUpdate
|
|
logger dilog.Logger
|
|
}
|
|
|
|
// NewUpdateDecoder creates a new update decoder. The logger is already attatched
|
|
func NewUpdateDecoder(logger dilog.Logger) *UpdateDecoder {
|
|
return &UpdateDecoder{
|
|
prevUpdateState: &StatusUpdate{},
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// Decode decodes the cp3000 update message
|
|
func (d *UpdateDecoder) Decode(args []string) error {
|
|
r := csv.NewReader(strings.NewReader(args[1]))
|
|
r.Comma = ','
|
|
r.LazyQuotes = true
|
|
records, err := r.Read()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
f, err := strconv.ParseUint(strings.Trim(args[0], "\""), 10, 32)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fields := StatUpdateField(f)
|
|
|
|
newStat := *d.prevUpdateState
|
|
newStat.Fields = fields
|
|
// IMPORTANT the order here is important
|
|
records = decodeState(d.logger, &newStat, fields, records)
|
|
records = decodePMGT(d.logger, &newStat, fields, records)
|
|
records = decodeSwitch(d.logger, &newStat, fields, records)
|
|
records = decodeWCPUState(d.logger, &newStat, fields, records)
|
|
records = decodeRMS(d.logger, &newStat, fields, records)
|
|
records = decodeBA(d.logger, &newStat, fields, records)
|
|
records = decodeNATWS(d.logger, &newStat, fields, records)
|
|
records = decodeAutocal(d.logger, &newStat, fields, records)
|
|
records = decodeBatSelected(d.logger, &newStat, fields, records)
|
|
records = decodeBatt1Level(d.logger, &newStat, fields, records)
|
|
records = decodeBatt2Level(d.logger, &newStat, fields, records)
|
|
records = decodeTempOnBoard(d.logger, &newStat, fields, records)
|
|
records = decodeTempNTC(d.logger, &newStat, fields, records)
|
|
records = decodeGSM(d.logger, &newStat, fields, records)
|
|
records = decodeGPS(d.logger, &newStat, fields, records)
|
|
records = decodeTilt(d.logger, &newStat, fields, records)
|
|
|
|
if len(records) > 0 {
|
|
d.logger.WithField("recs", records).WithField("fields", fields).Info("more data left")
|
|
}
|
|
|
|
d.mu.Lock()
|
|
d.prevUpdateState = &newStat
|
|
d.mu.Unlock()
|
|
return nil
|
|
}
|
|
|
|
// StatusUpdate returns the last known status update
|
|
func (d *UpdateDecoder) StatusUpdate() *StatusUpdate {
|
|
d.mu.RLock()
|
|
defer d.mu.RUnlock()
|
|
return d.prevUpdateState
|
|
}
|