meshtastic: support
This commit is contained in:
@@ -23,6 +23,7 @@ type repeaterDriver struct {
|
||||
lastFrame []byte
|
||||
lastFrameAt time.Time
|
||||
info repeaterInfo
|
||||
stats map[string]any
|
||||
err error
|
||||
}
|
||||
|
||||
@@ -102,6 +103,7 @@ func newRepeaterDriver(conn io.ReadWriteCloser, hasSNR bool) *repeaterDriver {
|
||||
conn: conn,
|
||||
waiting: make(chan *repeaterDriverWaiting, 16),
|
||||
hasSNR: hasSNR,
|
||||
stats: make(map[string]any),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +116,7 @@ func (drv *repeaterDriver) Setup() (err error) {
|
||||
if err = drv.queryDeviceInfo(); err != nil {
|
||||
return err
|
||||
}
|
||||
go drv.pollStats()
|
||||
return drv.err
|
||||
}
|
||||
|
||||
@@ -176,6 +179,10 @@ func (drv *repeaterDriver) RawPackets() <-chan *protocol.Packet {
|
||||
return drv.rawPackets
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) Stats() map[string]any {
|
||||
return drv.stats
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) queryDeviceInfo() (err error) {
|
||||
if drv.info.FirmwareVersion, err = drv.writeCommand("ver"); err != nil {
|
||||
return
|
||||
@@ -404,6 +411,73 @@ func (drv *repeaterDriver) poll() {
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) pollStats() {
|
||||
ticker := time.NewTicker(time.Minute)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
neighbors, err := drv.getNeighbors()
|
||||
if err != nil {
|
||||
Logger.Warnf("meshcore: failed to get neighbors: %v", err)
|
||||
} else {
|
||||
drv.stats["neighbors"] = neighbors
|
||||
}
|
||||
|
||||
response, err := drv.writeCommand("stats")
|
||||
if err != nil {
|
||||
Logger.Warnf("meshcore: failed to get stats: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
stats := make(map[string]any)
|
||||
for _, line := range strings.Split(response, "\n") {
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
key := parts[0]
|
||||
value := parts[1]
|
||||
|
||||
if i, err := strconv.Atoi(value); err == nil {
|
||||
stats[key] = i
|
||||
} else if f, err := strconv.ParseFloat(value, 64); err == nil {
|
||||
stats[key] = f
|
||||
} else {
|
||||
stats[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
drv.stats = stats
|
||||
|
||||
<-ticker.C
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) getNeighbors() (neighbors map[string]float64, err error) {
|
||||
// "neighbors" command returns a list of neighbors, one per line, in the format: "78CCC5A3:470:47\n"
|
||||
var response string
|
||||
if response, err = drv.writeCommand("neighbors"); err != nil {
|
||||
return
|
||||
}
|
||||
Logger.Tracef("meshcore: neighbors response: %q", response)
|
||||
neighbors = make(map[string]float64)
|
||||
for _, line := range strings.Split(response, "\n") {
|
||||
parts := strings.SplitN(line, ":", 3)
|
||||
if len(parts) != 3 {
|
||||
continue
|
||||
}
|
||||
var (
|
||||
prefix = parts[0]
|
||||
snr float64
|
||||
)
|
||||
if snr, err = strconv.ParseFloat(parts[2], 64); err != nil {
|
||||
return
|
||||
}
|
||||
neighbors[prefix] = snr
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) parsePacket(line string) (time.Time, string, error) {
|
||||
// "11:08:38 - 15/5/2024 U: TX, len=124 (type=4, route=D, payload_len=122)"
|
||||
if len(line) < 22 {
|
||||
|
||||
Reference in New Issue
Block a user