106 lines
2.0 KiB
Go
106 lines
2.0 KiB
Go
package mqttingest
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type BarometerPayload struct {
|
|
PressureHPA float64
|
|
}
|
|
|
|
func ParseBarometer(b []byte) (*BarometerPayload, map[string]any, error) {
|
|
var raw map[string]any
|
|
if err := json.Unmarshal(b, &raw); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
pressure, ok := pressureHPAFromPayload(raw)
|
|
if !ok {
|
|
return nil, raw, fmt.Errorf("barometer payload missing pressure field")
|
|
}
|
|
|
|
return &BarometerPayload{
|
|
PressureHPA: pressure,
|
|
}, raw, nil
|
|
}
|
|
|
|
func pressureHPAFromPayload(raw map[string]any) (float64, bool) {
|
|
if v, ok := findFloat(raw,
|
|
"pressure_hpa",
|
|
"pressure_mb",
|
|
"pressure_mbar",
|
|
"barometer_hpa",
|
|
"baro_hpa",
|
|
"pressure",
|
|
); ok {
|
|
return v, true
|
|
}
|
|
if v, ok := findFloat(raw, "pressure_pa", "pa"); ok {
|
|
return v / 100.0, true
|
|
}
|
|
if v, ok := findFloat(raw, "pressure_kpa"); ok {
|
|
return v * 10.0, true
|
|
}
|
|
if v, ok := findFloat(raw, "pressure_inhg", "barometer_inhg", "altim"); ok {
|
|
return v * 33.8638866667, true
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
func findFloat(raw map[string]any, keys ...string) (float64, bool) {
|
|
for _, key := range keys {
|
|
v, ok := raw[key]
|
|
if !ok {
|
|
continue
|
|
}
|
|
if f, ok := asFloat(v); ok {
|
|
return f, true
|
|
}
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
func asFloat(v any) (float64, bool) {
|
|
switch t := v.(type) {
|
|
case float64:
|
|
return t, true
|
|
case float32:
|
|
return float64(t), true
|
|
case int:
|
|
return float64(t), true
|
|
case int8:
|
|
return float64(t), true
|
|
case int16:
|
|
return float64(t), true
|
|
case int32:
|
|
return float64(t), true
|
|
case int64:
|
|
return float64(t), true
|
|
case uint:
|
|
return float64(t), true
|
|
case uint8:
|
|
return float64(t), true
|
|
case uint16:
|
|
return float64(t), true
|
|
case uint32:
|
|
return float64(t), true
|
|
case uint64:
|
|
return float64(t), true
|
|
case json.Number:
|
|
f, err := t.Float64()
|
|
return f, err == nil
|
|
case string:
|
|
s := strings.TrimSpace(t)
|
|
if s == "" {
|
|
return 0, false
|
|
}
|
|
f, err := strconv.ParseFloat(s, 64)
|
|
return f, err == nil
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|