diff --git a/cmd/meshobserv/meshobserv.go b/cmd/meshobserv/meshobserv.go index 1bc73f5..10eb932 100644 --- a/cmd/meshobserv/meshobserv.go +++ b/cmd/meshobserv/meshobserv.go @@ -101,6 +101,20 @@ func handleMessage(from uint32, topic string, portNum generated.PortNum, payload } Nodes[from].UpdateDeviceMetrics(batteryLevel, voltage, chUtil, airUtilTx, uptime) NodesMutex.Unlock() + } else if envMetrics := telemetry.GetEnvironmentMetrics(); envMetrics != nil { + temperature := envMetrics.GetTemperature() + relativeHumidity := envMetrics.GetRelativeHumidity() + barometricPressure := envMetrics.GetBarometricPressure() + log.Printf( + "[msg] %v (%v) %s: EnvironmentMetrics{temperature: %vC; humidity: %v%%; pressure: %vhPA}", + from, topic, portNum, temperature, relativeHumidity, barometricPressure, + ) + NodesMutex.Lock() + if Nodes[from] == nil { + Nodes[from] = meshtastic.NewNode(topic) + } + Nodes[from].UpdateEnvironmentMetrics(temperature, relativeHumidity, barometricPressure) + NodesMutex.Unlock() } case generated.PortNum_NEIGHBORINFO_APP: var neighborInfo generated.NeighborInfo diff --git a/internal/meshtastic/node.go b/internal/meshtastic/node.go index 5ff4a8d..e004765 100644 --- a/internal/meshtastic/node.go +++ b/internal/meshtastic/node.go @@ -42,6 +42,11 @@ type Node struct { AirUtilTx float32 `json:"airUtilTx,omitempty"` Uptime uint32 `json:"uptime,omitempty"` LastDeviceMetrics int64 `json:"lastDeviceMetrics,omitempty"` + // EnvironmentMetrics + Temperature float32 `json:"temperature,omitempty"` + RelativeHumidity float32 `json:"relativeHumidity,omitempty"` + BarometricPressure float32 `json:"barometricPressure,omitempty"` + LastEnvironmentMetrics int64 `json:"lastEnvironmentMetrics,omitempty"` // NeighborInfo Neighbors map[uint32]*NeighborInfo `json:"neighbors,omitempty"` // key=mqtt topic, value=first seen/last position update @@ -63,6 +68,13 @@ func (node *Node) ClearDeviceMetrics() { node.LastDeviceMetrics = 0 } +func (node *Node) ClearEnvironmentMetrics() { + node.Temperature = 0 + node.RelativeHumidity = 0 + node.BarometricPressure = 0 + node.LastEnvironmentMetrics = 0 +} + func (node *Node) ClearMapReportData() { node.FwVersion = "" node.Region = "" @@ -85,7 +97,7 @@ func (node *Node) IsValid() bool { return true } -func (node *Node) Prune(seenByTtl, neighborTtl, deviceMetricsTtl, mapReportTtl int64) { +func (node *Node) Prune(seenByTtl, neighborTtl, metricsTtl, mapReportTtl int64) { now := time.Now().Unix() // SeenBy for topic, lastSeen := range node.SeenBy { @@ -121,9 +133,13 @@ func (node *Node) Prune(seenByTtl, neighborTtl, deviceMetricsTtl, mapReportTtl i delete(node.Neighbors, toDelete) } // DeviceMetrics - if node.LastDeviceMetrics > 0 && node.LastDeviceMetrics+deviceMetricsTtl < now { + if node.LastDeviceMetrics > 0 && node.LastDeviceMetrics+metricsTtl < now { node.ClearDeviceMetrics() } + // EnvironmentMetrics + if node.LastEnvironmentMetrics > 0 && node.LastEnvironmentMetrics+metricsTtl < now { + node.ClearEnvironmentMetrics() + } // MapReport if node.LastMapReport > 0 && node.LastMapReport+mapReportTtl < now { node.ClearMapReportData() @@ -139,6 +155,13 @@ func (node *Node) UpdateDeviceMetrics(batteryLevel uint32, voltage, chUtil, airU node.LastDeviceMetrics = time.Now().Unix() } +func (node *Node) UpdateEnvironmentMetrics(temperature, relativeHumidity, barometricPressure float32) { + node.Temperature = temperature + node.RelativeHumidity = relativeHumidity + node.BarometricPressure = barometricPressure + node.LastEnvironmentMetrics = time.Now().Unix() +} + func (node *Node) UpdateMapReport(fwVersion, region, modemPreset string, hasDefaultCh bool, onlineLocalNodes uint32) { node.FwVersion = fwVersion node.Region = region @@ -178,9 +201,9 @@ func (node *Node) UpdateUser(longName, shortName, hwModel, role string) { type NodeDB map[uint32]*Node -func (db NodeDB) Prune(seenByTtl, neighborTtl, deviceMetricsTtl, mapReportTtl int64) { +func (db NodeDB) Prune(seenByTtl, neighborTtl, metricsTtl, mapReportTtl int64) { for nodeNum, node := range db { - node.Prune(seenByTtl, neighborTtl, deviceMetricsTtl, mapReportTtl) + node.Prune(seenByTtl, neighborTtl, metricsTtl, mapReportTtl) if len(node.SeenBy) == 0 { delete(db, nodeNum) }