Added Radio.ID and refactored the Stats interface
This commit is contained in:
@@ -32,8 +32,8 @@ func NewCompanion(conn io.ReadWriteCloser) (*Node, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewRepeater(conn io.ReadWriteCloser, hasSNR bool) (*Node, error) {
|
||||
driver := newRepeaterDriver(conn, hasSNR)
|
||||
func NewRepeater(conn io.ReadWriteCloser) (*Node, error) {
|
||||
driver := newRepeaterDriver(conn)
|
||||
|
||||
if err := driver.Setup(); err != nil {
|
||||
return nil, err
|
||||
@@ -60,7 +60,7 @@ func (dev *Node) Info() *radio.Info {
|
||||
return dev.driver.Info()
|
||||
}
|
||||
|
||||
func (dev *Node) Stats() map[string]any {
|
||||
func (dev *Node) Stats() <-chan map[string]any {
|
||||
return dev.driver.Stats()
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ type nodeDriver interface {
|
||||
Setup() error
|
||||
|
||||
Packets() <-chan *Packet
|
||||
Stats() map[string]any
|
||||
Stats() <-chan map[string]any
|
||||
}
|
||||
|
||||
type nodeTracer interface {
|
||||
|
||||
@@ -47,7 +47,7 @@ type companionDriver struct {
|
||||
info companionInfo
|
||||
traceTag uint32
|
||||
traceAuthCode uint32
|
||||
stats map[string]any
|
||||
stats chan map[string]any
|
||||
}
|
||||
|
||||
type companionDriverWaiting struct {
|
||||
@@ -131,6 +131,7 @@ func newCompanionDriver(conn io.ReadWriteCloser) *companionDriver {
|
||||
conn: conn,
|
||||
waiting: make(chan *companionDriverWaiting, 16),
|
||||
traceTag: rand.Uint32(),
|
||||
stats: make(chan map[string]any, 2),
|
||||
//traceAuthCode: rand.Uint32(),
|
||||
}
|
||||
}
|
||||
@@ -144,7 +145,7 @@ func (drv *companionDriver) Setup() (err error) {
|
||||
if err = drv.sendAppStart(); err != nil {
|
||||
return
|
||||
}
|
||||
if err = drv.sendDeviceInfo(); err != nil {
|
||||
if err = drv.getDeviceInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
@@ -209,7 +210,7 @@ func (drv *companionDriver) Info() *radio.Info {
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *companionDriver) Stats() map[string]any {
|
||||
func (drv *companionDriver) Stats() <-chan map[string]any {
|
||||
return drv.stats
|
||||
}
|
||||
|
||||
@@ -397,7 +398,7 @@ func (drv *companionDriver) sendAppStart() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (drv *companionDriver) sendDeviceInfo() (err error) {
|
||||
func (drv *companionDriver) getDeviceInfo() (err error) {
|
||||
var (
|
||||
args = []byte{0x03}
|
||||
data []byte
|
||||
@@ -425,6 +426,11 @@ func (drv *companionDriver) sendDeviceInfo() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (drv *companionDriver) getPublicKey() (err error) {
|
||||
// TODO
|
||||
return err
|
||||
}
|
||||
|
||||
func (drv *companionDriver) poll() {
|
||||
for {
|
||||
frame, err := drv.readFrame()
|
||||
|
||||
@@ -3,6 +3,7 @@ package meshcore
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
@@ -23,7 +24,7 @@ type repeaterDriver struct {
|
||||
lastFrame []byte
|
||||
lastFrameAt time.Time
|
||||
info repeaterInfo
|
||||
stats map[string]any
|
||||
stats chan map[string]any
|
||||
err error
|
||||
}
|
||||
|
||||
@@ -78,7 +79,7 @@ type repeaterInfo struct {
|
||||
Type NodeType
|
||||
Power byte // in dBm
|
||||
MaxPower byte // in dBm
|
||||
PublicKey [32]byte
|
||||
PublicKey string
|
||||
Latitude float64
|
||||
Longitude float64
|
||||
HasMultiACKs bool
|
||||
@@ -98,15 +99,20 @@ type repeaterInfo struct {
|
||||
Manufacturer string
|
||||
}
|
||||
|
||||
func newRepeaterDriver(conn io.ReadWriteCloser, hasSNR bool) *repeaterDriver {
|
||||
func newRepeaterDriver(conn io.ReadWriteCloser) *repeaterDriver {
|
||||
return &repeaterDriver{
|
||||
conn: conn,
|
||||
waiting: make(chan *repeaterDriverWaiting, 16),
|
||||
hasSNR: hasSNR,
|
||||
stats: make(map[string]any),
|
||||
stats: make(chan map[string]any, 2),
|
||||
}
|
||||
}
|
||||
|
||||
func newRepeaterDriverWithSNRPatch(conn io.ReadWriteCloser) *repeaterDriver {
|
||||
driver := newRepeaterDriver(conn)
|
||||
driver.hasSNR = true
|
||||
return driver
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) Close() error {
|
||||
return drv.conn.Close()
|
||||
}
|
||||
@@ -150,6 +156,7 @@ func (drv *repeaterDriver) Info() *radio.Info {
|
||||
}
|
||||
|
||||
return &radio.Info{
|
||||
ID: drv.info.PublicKey,
|
||||
Name: drv.info.Name,
|
||||
Manufacturer: manufacturer,
|
||||
Device: device,
|
||||
@@ -179,7 +186,7 @@ func (drv *repeaterDriver) RawPackets() <-chan *protocol.Packet {
|
||||
return drv.rawPackets
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) Stats() map[string]any {
|
||||
func (drv *repeaterDriver) Stats() <-chan map[string]any {
|
||||
return drv.stats
|
||||
}
|
||||
|
||||
@@ -193,6 +200,11 @@ func (drv *repeaterDriver) queryDeviceInfo() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch public key
|
||||
if drv.info.PublicKey, err = drv.writeCommand("get", "public.key"); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var line string
|
||||
|
||||
// Fetch frequency, bandwidth and LoRa settings
|
||||
@@ -412,24 +424,26 @@ func (drv *repeaterDriver) poll() {
|
||||
}
|
||||
|
||||
func (drv *repeaterDriver) pollStats() {
|
||||
ticker := time.NewTicker(time.Minute)
|
||||
ticker := time.NewTicker(time.Second * 10)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
stats := make(map[string]any)
|
||||
|
||||
neighbors, err := drv.getNeighbors()
|
||||
if err != nil {
|
||||
Logger.Warnf("meshcore: failed to get neighbors: %v", err)
|
||||
} else {
|
||||
drv.stats["neighbors"] = neighbors
|
||||
stats["neighbors"] = neighbors
|
||||
}
|
||||
|
||||
response, err := drv.writeCommand("stats")
|
||||
response, err := drv.writeCommand("stats-core")
|
||||
if err != nil {
|
||||
Logger.Warnf("meshcore: failed to get stats: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
stats := make(map[string]any)
|
||||
neighborStats := make(map[string]any)
|
||||
for _, line := range strings.Split(response, "\n") {
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
@@ -439,15 +453,53 @@ func (drv *repeaterDriver) pollStats() {
|
||||
value := parts[1]
|
||||
|
||||
if i, err := strconv.Atoi(value); err == nil {
|
||||
stats[key] = i
|
||||
neighborStats[key] = i
|
||||
} else if f, err := strconv.ParseFloat(value, 64); err == nil {
|
||||
stats[key] = f
|
||||
neighborStats[key] = f
|
||||
} else {
|
||||
stats[key] = value
|
||||
neighborStats[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
drv.stats = stats
|
||||
var (
|
||||
coreStats = make(map[string]any)
|
||||
radioStats = make(map[string]any)
|
||||
packetStats = make(map[string]any)
|
||||
)
|
||||
if response, err := drv.writeCommand("stats-core"); err == nil {
|
||||
if err = json.Unmarshal([]byte(response), &coreStats); err != nil {
|
||||
Logger.Warnf("meshcore: failed to decode core stats: %v", err)
|
||||
}
|
||||
} else {
|
||||
Logger.Warnf("meshcore: failed to get core stats: %v", err)
|
||||
}
|
||||
|
||||
if response, err := drv.writeCommand("stats-radio"); err == nil {
|
||||
if err = json.Unmarshal([]byte(response), &radioStats); err != nil {
|
||||
Logger.Warnf("meshcore: failed to decode radio stats: %v", err)
|
||||
}
|
||||
} else {
|
||||
Logger.Warnf("meshcore: failed to get radio stats: %v", err)
|
||||
}
|
||||
|
||||
if response, err := drv.writeCommand("stats-packets"); err == nil {
|
||||
if err = json.Unmarshal([]byte(response), &packetStats); err != nil {
|
||||
Logger.Warnf("meshcore: failed to decode packet stats: %v", err)
|
||||
}
|
||||
} else {
|
||||
Logger.Warnf("meshcore: failed to get packet stats: %v", err)
|
||||
}
|
||||
|
||||
stats["neighbors"] = neighborStats
|
||||
stats["core"] = coreStats
|
||||
stats["radio"] = radioStats
|
||||
stats["packets"] = packetStats
|
||||
|
||||
select {
|
||||
case drv.stats <- stats:
|
||||
default:
|
||||
Logger.Warn("meshcore: stats channel full, dropping stats")
|
||||
}
|
||||
|
||||
<-ticker.C
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user