func aggregator(cmd *cobra.Command, args []string) { if verbose { jww.SetStdoutThreshold(jww.LevelTrace) } db, err := data.OpenDatabase() if err != nil { jww.FATAL.Println(err) panic(err) } dataChannel := make(chan data.SensorData) topic := "/gowx/sample" opts := MQTT.NewClientOptions().AddBroker(viper.GetString("broker")).SetClientID("aggregator").SetCleanSession(true) opts.OnConnect = func(c *MQTT.Client) { if token := c.Subscribe(topic, 0, func(client *MQTT.Client, msg MQTT.Message) { r := bytes.NewReader(msg.Payload()) decoder := json.NewDecoder(r) var data data.SensorData err := decoder.Decode(&data) if err != nil { jww.ERROR.Println(err) return } dataChannel <- data }); token.Wait() && token.Error() != nil { jww.FATAL.Println(token.Error()) panic(token.Error()) } } client := MQTT.NewClient(opts) if token := client.Connect(); token.Wait() && token.Error() != nil { jww.FATAL.Println(token.Error()) panic(token.Error()) } defer client.Disconnect(0) ticker := time.NewTicker(time.Duration(viper.GetInt("interval")) * time.Second) thedata := make(map[mapKey][]float64) for { select { case <-ticker.C: sumData(&thedata, db) case d := <-dataChannel: addData(&thedata, d) } } }
func server(cmd *cobra.Command, args []string) { if verbose { jww.SetStdoutThreshold(jww.LevelTrace) } var currentData struct { Temperature float64 Humidity float64 Pressure float64 Wind float64 WindDir float64 RainRate float64 } opts := MQTT.NewClientOptions().AddBroker(viper.GetString("broker")).SetClientID("web").SetCleanSession(true) opts.OnConnect = func(c *MQTT.Client) { if token := c.Subscribe("/gowx/sample", 0, func(client *MQTT.Client, msg MQTT.Message) { r := bytes.NewReader(msg.Payload()) decoder := json.NewDecoder(r) var data data.SensorData err := decoder.Decode(&data) if err != nil { jww.ERROR.Println(err) return } if value, ok := dataMatch("temperature", data); ok { temp := units.NewTemperatureCelsius(value) currentData.Temperature, err = temp.Get(viper.GetStringMapString("units")["Temperature"]) if err != nil { jww.ERROR.Println(err) return } } if value, ok := dataMatch("humidity", data); ok { currentData.Humidity = value } if value, ok := dataMatch("pressure", data); ok { pres := units.NewPressureHectopascal(value) currentData.Pressure, err = pres.Get(viper.GetStringMapString("units")["Pressure"]) if err != nil { jww.ERROR.Println(err) return } } if value, ok := dataMatch("wind", data); ok { speed := units.NewSpeedMetersPerSecond(value) currentData.Wind, err = speed.Get(viper.GetStringMapString("units")["WindSpeed"]) if err != nil { jww.ERROR.Println(err) return } } if value, ok := dataMatch("winddir", data); ok { currentData.WindDir = value } if value, ok := dataMatch("rain", data); ok { rate := units.NewDistanceMillimeters(value) currentData.RainRate, err = rate.Get(viper.GetStringMapString("units")["Rain"]) } }); token.Wait() && token.Error() != nil { jww.FATAL.Println(token.Error()) panic(token.Error()) } } client := MQTT.NewClient(opts) if token := client.Connect(); token.Wait() && token.Error() != nil { jww.FATAL.Println(token.Error()) panic(token.Error()) } defer client.Disconnect(0) var err error db, err := data.OpenDatabase() if err != nil { jww.FATAL.Println(err) panic(err) } var d templateData d.Units = viper.GetStringMapString("units") bytes, err := json.Marshal(convertToStringMap("temperature")) if err == nil { d.Temperature = string(bytes) } bytes, err = json.Marshal(convertToStringMap("pressure")) if err == nil { d.Pressure = string(bytes) } bytes, err = json.Marshal(convertToStringMap("humidity")) if err == nil { d.Humidity = string(bytes) } bytes, err = json.Marshal(convertToStringMap("wind")) if err == nil { d.Wind = string(bytes) } bytes, err = json.Marshal(convertToStringMap("rain")) if err == nil { d.Rain = string(bytes) } staticServer := http.FileServer(http.Dir(viper.GetString("webroot"))) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { serveTemplate(w, r, staticServer, d) }) http.HandleFunc("/data.json", func(w http.ResponseWriter, r *http.Request) { dataHandler(w, r, db) }) http.HandleFunc("/change.json", func(w http.ResponseWriter, r *http.Request) { changeHandler(w, r, db) }) http.HandleFunc("/wind.json", func(w http.ResponseWriter, r *http.Request) { windHandler(w, r, db) }) http.HandleFunc("/currentdata.json", func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(currentData) }) listener, err := net.Listen("tcp", viper.GetString("address")) if err != nil { jww.FATAL.Println(err) panic(err) } addr := listener.Addr() jww.INFO.Println("Listening on", addr.String()) http.Serve(listener, nil) }