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 } }
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) }
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) }