From 3401330732284c72ed83cb7c9e8cb67bfe5d9a98 Mon Sep 17 00:00:00 2001 From: Nicolas Leclercq Date: Thu, 26 Oct 2017 16:39:20 +0200 Subject: [PATCH] * Remove usage of reflect as variable type are not propagated as expected with influxdb go client (cf netatmo-collector-go) * Add Info function to display RF, wifi and battery levels * Fix GustStrength --- README.md | 80 ++++++++++++++++++++++++++++++---------------- weather.go | 93 +++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 130 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index effff8c..c2f5ded 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ package main import ( "fmt" "os" + "time" netatmo "github.com/exzz/netatmo-api-go" ) @@ -41,16 +42,28 @@ func main() { os.Exit(1) } + ct := time.Now().UTC().Unix() + for _, station := range dc.Stations() { fmt.Printf("Station : %s\n", station.StationName) for _, module := range station.Modules() { fmt.Printf("\tModule : %s\n", module.ModuleName) - ts, data := module.Data() - for dataType, value := range data { - fmt.Printf("\t\t%s : %s (%d)\n", dataType, value, ts) + { + ts, data := module.Info() + for dataName, value := range data { + fmt.Printf("\t\t%s : %v (updated %ds ago)\n", dataName, value, ct-ts) + } } + + { + ts, data := module.Data() + for dataName, value := range data { + fmt.Printf("\t\t%s : %v (updated %ds ago)\n", dataName, value, ct-ts) + } + } + } } } @@ -58,31 +71,42 @@ func main() { Output should look like this : ``` -Station : Home - Module : Chambre Enfant - Temperature : %!s(float32=18.4) (1479127223) - CO2 : %!s(int32=567) (1479127223) - Humidity : %!s(int32=65) (1479127223) - Module : Chambre - Temperature : %!s(float32=18.1) (1479127230) - CO2 : %!s(int32=494) (1479127230) - Humidity : %!s(int32=65) (1479127230) - Module : Salon - Temperature : %!s(float32=18.3) (1479127217) - CO2 : %!s(int32=434) (1479127217) - Humidity : %!s(int32=63) (1479127217) - Module : Exterieur - Temperature : %!s(float32=11.9) (1479127243) - Humidity : %!s(int32=81) (1479127243) - Module : Pluie - Rain : %!s(float32=0) (1479127249) - Module : Salle à manger - Temperature : %!s(float32=17.8) (1479127255) - CO2 : %!s(int32=473) (1479127255) - Humidity : %!s(int32=68) (1479127255) - Noise : %!s(int32=36) (1479127255) - Pressure : %!s(float32=1033.3) (1479127255) - +Station : Home + Module : Chambre Elsa + BatteryPercent : 47 (updated 323s ago) + RFStatus : 68 (updated 323s ago) + Temperature : 22.8 (updated 323s ago) + Humidity : 53 (updated 323s ago) + CO2 : 446 (updated 323s ago) + Module : Chambre parents + BatteryPercent : 50 (updated 323s ago) + RFStatus : 71 (updated 323s ago) + Temperature : 19.9 (updated 323s ago) + Humidity : 61 (updated 323s ago) + CO2 : 428 (updated 323s ago) + Module : Chambre Jules + BatteryPercent : 46 (updated 323s ago) + RFStatus : 60 (updated 323s ago) + CO2 : 396 (updated 323s ago) + Temperature : 22 (updated 323s ago) + Humidity : 54 (updated 323s ago) + Module : Exterieur + BatteryPercent : 37 (updated 323s ago) + RFStatus : 66 (updated 323s ago) + Temperature : 23.4 (updated 323s ago) + Humidity : 52 (updated 323s ago) + Module : Pluie + BatteryPercent : 72 (updated 9684499s ago) + RFStatus : 54 (updated 9684499s ago) + Rain : 0.101 (updated 9684499s ago) + Module : Living + WifiStatus : 37 (updated 278s ago) + Temperature : 24 (updated 278s ago) + Humidity : 49 (updated 278s ago) + CO2 : 733 (updated 278s ago) + Noise : 50 (updated 278s ago) + Pressure : 1028.1 (updated 278s ago) + AbsolutePressure : 1008.4 (updated 278s ago) ``` ## Tips - Only Read() method actually do an API call and refresh all data at once diff --git a/weather.go b/weather.go index 23f17ca..dd27679 100644 --- a/weather.go +++ b/weather.go @@ -5,7 +5,6 @@ import ( "fmt" "net/http" "net/url" - "reflect" "strings" "golang.org/x/oauth2" @@ -51,6 +50,13 @@ type DeviceCollection struct { // ID : Mac address // StationName : Station name (only for station) // ModuleName : Module name +// BatteryPercent : Percentage of battery remaining +// WifiStatus : Wifi status per Base station +// RFStatus : Current radio status per module +// Firmware : Version of the software +// DateSetup : Date when the Weather station was set up +// LastMessage +// LastSeen // Type : Module type : // "NAMain" : for the base station // "NAModule1" : for the outdoor module @@ -61,11 +67,14 @@ type DeviceCollection struct { // DataType : List of available datas // LinkedModules : Associated modules (only for station) type Device struct { - ID string `json:"_id"` - StationName string `json:"station_name"` - ModuleName string `json:"module_name"` - Type string - DashboardData DashboardData `json:"dashboard_data"` + ID string `json:"_id"` + StationName string `json:"station_name"` + ModuleName string `json:"module_name"` + BatteryPercent *int32 `json:"battery_percent,omitempty"` + WifiStatus *int32 `json:"wifi_status,omitempty"` + RFStatus *int32 `json:"rf_status,omitempty"` + Type string + DashboardData DashboardData `json:"dashboard_data"` //DataType []string `json:"data_type"` LinkedModules []*Device `json:"modules"` } @@ -222,19 +231,73 @@ func (d *Device) Modules() []*Device { } // Data returns timestamp and the list of sensor value for this module -func (d *Device) Data() (int, map[string]interface{}) { +func (d *Device) Data() (int64, map[string]interface{}) { // return only populate field of DashboardData m := make(map[string]interface{}) - r := reflect.ValueOf(d.DashboardData) - for i := 0; i < r.NumField(); i++ { - //fmt.Println(r.Type().Field(i).Name) - if reflect.Indirect(r.Field(i)).IsValid() { - m[r.Type().Field(i).Name] = reflect.Indirect(r.Field(i)) - //fmt.Println(reflect.Indirect(r.Field(i))) - } + if d.DashboardData.Temperature != nil { + m["Temperature"] = *d.DashboardData.Temperature + } + if d.DashboardData.Humidity != nil { + m["Humidity"] = *d.DashboardData.Humidity + } + if d.DashboardData.CO2 != nil { + m["CO2"] = *d.DashboardData.CO2 + } + if d.DashboardData.Noise != nil { + m["Noise"] = *d.DashboardData.Noise + } + if d.DashboardData.Pressure != nil { + m["Pressure"] = *d.DashboardData.Pressure + } + if d.DashboardData.AbsolutePressure != nil { + m["AbsolutePressure"] = *d.DashboardData.AbsolutePressure + } + if d.DashboardData.Rain != nil { + m["Rain"] = *d.DashboardData.Rain + } + if d.DashboardData.Rain1Hour != nil { + m["Rain1Hour"] = *d.DashboardData.Rain1Hour + } + if d.DashboardData.Rain1Day != nil { + m["Rain1Day"] = *d.DashboardData.Rain1Day + } + if d.DashboardData.WindAngle != nil { + m["WindAngle"] = *d.DashboardData.WindAngle + } + if d.DashboardData.WindStrength != nil { + m["WindStrength"] = *d.DashboardData.WindStrength + } + if d.DashboardData.GustAngle != nil { + m["GustAngle"] = *d.DashboardData.GustAngle + } + if d.DashboardData.GustAngle != nil { + m["GustAngle"] = *d.DashboardData.GustAngle + } + if d.DashboardData.GustStrength != nil { + m["GustStrength"] = *d.DashboardData.GustStrength } - return int(*d.DashboardData.LastMesure), m + return *d.DashboardData.LastMesure, m +} + +// Info returns timestamp and the list of info value for this module +func (d *Device) Info() (int64, map[string]interface{}) { + + // return only populate field of DashboardData + m := make(map[string]interface{}) + + // Return data from module level + if d.BatteryPercent != nil { + m["BatteryPercent"] = *d.BatteryPercent + } + if d.WifiStatus != nil { + m["WifiStatus"] = *d.WifiStatus + } + if d.RFStatus != nil { + m["RFStatus"] = *d.RFStatus + } + + return *d.DashboardData.LastMesure, m }