Ejemplo n.º 1
0
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)
		}
	}
}
Ejemplo n.º 2
0
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)
}