meshtastic: support
This commit is contained in:
@@ -60,6 +60,10 @@ func (dev *Node) Info() *radio.Info {
|
||||
return dev.driver.Info()
|
||||
}
|
||||
|
||||
func (dev *Node) Stats() map[string]any {
|
||||
return dev.driver.Stats()
|
||||
}
|
||||
|
||||
func (dev *Node) Trace(path []byte) (snr []float64, err error) {
|
||||
if tracer, ok := dev.driver.(nodeTracer); ok {
|
||||
return tracer.Trace(path)
|
||||
@@ -74,6 +78,7 @@ type nodeDriver interface {
|
||||
Setup() error
|
||||
|
||||
Packets() <-chan *Packet
|
||||
Stats() map[string]any
|
||||
}
|
||||
|
||||
type nodeTracer interface {
|
||||
|
||||
@@ -47,6 +47,7 @@ type companionDriver struct {
|
||||
info companionInfo
|
||||
traceTag uint32
|
||||
traceAuthCode uint32
|
||||
stats map[string]any
|
||||
}
|
||||
|
||||
type companionDriverWaiting struct {
|
||||
@@ -208,6 +209,10 @@ func (drv *companionDriver) Info() *radio.Info {
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *companionDriver) Stats() map[string]any {
|
||||
return drv.stats
|
||||
}
|
||||
|
||||
func (drv *companionDriver) Trace(path []byte) (snr []float64, err error) {
|
||||
var (
|
||||
args = make([]byte, 4+4+1+len(path))
|
||||
|
||||
@@ -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