コード例 #1
0
ファイル: server.go プロジェクト: geoffholden/gowx
func convertUnit(unitmap map[string]string, datatype string, input float64) float64 {
	switch datatype {
	case "temperature":
		u := units.NewTemperatureCelsius(input)
		if v2, err := u.Get(unitmap["Temperature"]); err == nil {
			return v2
		} else {
			return input
		}
	case "pressure":
		u := units.NewPressureHpa(input)
		if v2, err := u.Get(unitmap["Pressure"]); err == nil {
			return v2
		} else {
			return input
		}
	case "wind":
		u := units.NewSpeedMetersPerSecond(input)
		if v2, err := u.Get(unitmap["WindSpeed"]); err == nil {
			return v2
		} else {
			return input
		}
	case "rain":
		u := units.NewDistanceMillimeters(input)
		if v2, err := u.Get(unitmap["Rain"]); err == nil {
			return v2
		} else {
			return input
		}
	default:
		return input
	}
}
コード例 #2
0
ファイル: server.go プロジェクト: geoffholden/gowx
func windHandler(w http.ResponseWriter, r *http.Request, db *data.Database) {
	t, _ := computeTime(r.FormValue("time"))

	var queries []map[string]string
	err := json.Unmarshal([]byte(r.FormValue("query")), &queries)
	if err != nil {
		jww.ERROR.Println(err)
		return
	}

	var result struct {
		Data  [][]float64
		Label []string
	}

	result.Data = make([][]float64, len(queries))
	result.Label = make([]string, len(queries))

	rxp := regexp.MustCompile(`\[([^]]*)\]`)
	for index, querymap := range queries {
		result.Label[index] = querymap["label"]
		result.Data[index] = make([]float64, 32)

		id := "%"
		if _, ok := querymap["id"]; ok {
			id = querymap["id"]
		}
		datatype := "%"
		if _, ok := querymap["type"]; ok {
			datatype = querymap["type"]
		}
		if _, ok := querymap["label"]; ok {
			result.Label[index] = querymap["label"]
		} else {
			result.Label[index] = "Unknown"
		}
		cols := rxp.FindStringSubmatch(datatype)
		var col string
		if len(cols) > 1 {
			col = cols[1]
		} else {
			col = "avg"
		}

		key := rxp.ReplaceAllString(datatype, "")

		for row := range db.QueryWind(t, key, col, id, 0) {
			speed := units.NewSpeedMetersPerSecond(row.Value)
			result.Data[index][int(row.Dir)], err = speed.Get(viper.GetStringMapString("units")["WindSpeed"])
			if err != nil {
				jww.ERROR.Println(err)
				return
			}
		}
	}

	json.NewEncoder(w).Encode(result)
}
コード例 #3
0
ファイル: server.go プロジェクト: geoffholden/gowx
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)
}