query data over rest api
This commit is contained in:
parent
4f501344d5
commit
877a46b9bf
3 changed files with 153 additions and 9 deletions
|
@ -43,19 +43,38 @@ func (api *weatherRestApi) handleRequests() *mux.Router {
|
|||
router.HandleFunc("/random", api.randomWeatherHandler)
|
||||
router.HandleFunc("/randomlist", api.randomWeatherListHandler)
|
||||
router.HandleFunc("/addData", api.addDataHandler)
|
||||
router.HandleFunc("/getData", api.getData)
|
||||
router.HandleFunc("/getData/{id}", api.getData)
|
||||
router.HandleFunc("/registerWeatherSensor/{name}", api.registerWeatherSensor)
|
||||
return router
|
||||
}
|
||||
|
||||
func (api *weatherRestApi) getData(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("content-type", "application/json")
|
||||
data, err := api.weaterStorage.GetData()
|
||||
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
|
||||
query, err := storage.ParseFromUrlQuery(r.URL.Query())
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("could not parse query: %v", err.Error()), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
query.SensorId, err = uuid.Parse(id)
|
||||
if err != nil {
|
||||
http.Error(w, "could not parse uuid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(query)
|
||||
|
||||
data, err := api.weaterStorage.GetData(query)
|
||||
if err != nil {
|
||||
http.Error(w, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(data)
|
||||
res := storage.GetOnlyQueriedFields(data, query)
|
||||
json.NewEncoder(w).Encode(res)
|
||||
}
|
||||
|
||||
func (api *weatherRestApi) randomWeatherHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -53,11 +53,37 @@ func (storage *influxStorage) Save(data WeatherData) error {
|
|||
}
|
||||
|
||||
//GetData datapoints from InfluxDB
|
||||
func (storage *influxStorage) GetData() ([]*WeatherData, error) {
|
||||
func (storage *influxStorage) GetData(query *WeatherQuery) ([]*WeatherData, error) {
|
||||
|
||||
query := fmt.Sprintf("from(bucket:\"%v\")|> range(start: -40m, stop: -20m) |> filter(fn: (r) => r._measurement == \"data\" and r.location == \"Hamburg\")", storage.bucket)
|
||||
fields := ""
|
||||
concat := ""
|
||||
|
||||
res, err := storage.executeFluxQuery(query)
|
||||
if query.Temperature {
|
||||
fields = fmt.Sprintf("%v %v r._field == \"temperature\"", fields, concat)
|
||||
concat = "or"
|
||||
}
|
||||
|
||||
if query.Humidity {
|
||||
fields = fmt.Sprintf("%v %v r._field == \"humidity\"", fields, concat)
|
||||
concat = "or"
|
||||
}
|
||||
|
||||
if query.Pressure {
|
||||
fields = fmt.Sprintf("%v %v r._field == \"pressure\"", fields, concat)
|
||||
concat = "or"
|
||||
}
|
||||
|
||||
if query.Co2Level {
|
||||
fields = fmt.Sprintf("%v %v r._field == \"co2level\"", fields, concat)
|
||||
concat = "or"
|
||||
}
|
||||
|
||||
fields = fmt.Sprintf(" and ( %v )", fields)
|
||||
|
||||
fluxQuery := fmt.Sprintf("from(bucket:\"%v\")|> range(start: %v, stop: %v) |> filter(fn: (r) => r._measurement == \"%v\" %v)", storage.bucket, query.Start.Format(time.RFC3339), query.End.Format(time.RFC3339), storage.measurement, fields)
|
||||
fmt.Println(fluxQuery)
|
||||
|
||||
res, err := storage.executeFluxQuery(fluxQuery)
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -10,7 +13,7 @@ import (
|
|||
//WeatherStorage interface for different storage-implementations of weather data
|
||||
type WeatherStorage interface {
|
||||
Save(WeatherData) error
|
||||
GetData() ([]*WeatherData, error)
|
||||
GetData(*WeatherQuery) ([]*WeatherData, error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
|
@ -25,13 +28,41 @@ type SensorRegistry interface {
|
|||
//WeatherData type
|
||||
type WeatherData struct {
|
||||
Humidity float64 `json:"humidity"`
|
||||
Pressure float64 `json:"airPressure"`
|
||||
Pressure float64 `json:"pressure"`
|
||||
Temperature float64 `json:"temperature"`
|
||||
CO2Level float64 `json:"co2level"`
|
||||
SensorId uuid.UUID `json:"SensorId"`
|
||||
SensorId uuid.UUID `json:"sensorId"`
|
||||
TimeStamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
func (data *WeatherData) GetQueriedValues(query *WeatherQuery) map[string]string {
|
||||
result := map[string]string{
|
||||
"sensorId": data.SensorId.String(),
|
||||
"timestamp": data.TimeStamp.String(),
|
||||
}
|
||||
if query.Temperature {
|
||||
result["temperature"] = strconv.FormatFloat(data.Temperature, 'f', -1, 32)
|
||||
}
|
||||
if query.Pressure {
|
||||
result["pressure"] = strconv.FormatFloat(data.Pressure, 'f', -1, 32)
|
||||
}
|
||||
if query.Co2Level {
|
||||
result["co2level"] = strconv.FormatFloat(data.CO2Level, 'f', -1, 32)
|
||||
}
|
||||
if query.Humidity {
|
||||
result["humidity"] = strconv.FormatFloat(data.Humidity, 'f', -1, 32)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func GetOnlyQueriedFields(dataPoints []*WeatherData, query *WeatherQuery) []map[string]string {
|
||||
var result []map[string]string
|
||||
for _, data := range dataPoints {
|
||||
result = append(result, data.GetQueriedValues(query))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
//WeatherSensor is the data for a new Sensorregistration
|
||||
type WeatherSensor struct {
|
||||
Name string
|
||||
|
@ -41,6 +72,74 @@ type WeatherSensor struct {
|
|||
Lattitude float64
|
||||
}
|
||||
|
||||
type WeatherQuery struct {
|
||||
Start time.Time
|
||||
End time.Time
|
||||
SensorId uuid.UUID
|
||||
Temperature bool
|
||||
Humidity bool
|
||||
Pressure bool
|
||||
Co2Level bool
|
||||
}
|
||||
|
||||
func (data *WeatherQuery) Init() {
|
||||
data.Start = time.Now().Add(-1 * time.Hour * 24 * 14)
|
||||
data.End = time.Now()
|
||||
data.SensorId = uuid.Nil
|
||||
data.Temperature = true
|
||||
data.Humidity = true
|
||||
data.Pressure = true
|
||||
data.Co2Level = true
|
||||
}
|
||||
|
||||
func ParseFromUrlQuery(query url.Values) (*WeatherQuery, error) {
|
||||
result := new(WeatherQuery)
|
||||
result.Init()
|
||||
|
||||
start := query.Get("start")
|
||||
end := query.Get("end")
|
||||
temperature := query.Get("temperature")
|
||||
humidity := query.Get("humidity")
|
||||
pressure := query.Get("pressure")
|
||||
co2level := query.Get("co2level")
|
||||
|
||||
if len(start) != 0 {
|
||||
if tval, err := time.Parse(time.RFC3339, start); err == nil {
|
||||
result.Start = tval
|
||||
} else if err != nil {
|
||||
fmt.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(end) != 0 {
|
||||
if tval, err := time.Parse(time.RFC3339, end); err == nil {
|
||||
result.End = tval
|
||||
} else if err != nil {
|
||||
fmt.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if bval, err := strconv.ParseBool(temperature); err == nil {
|
||||
result.Temperature = bval
|
||||
}
|
||||
|
||||
if bval, err := strconv.ParseBool(humidity); err == nil {
|
||||
result.Humidity = bval
|
||||
}
|
||||
|
||||
if bval, err := strconv.ParseBool(pressure); err == nil {
|
||||
result.Pressure = bval
|
||||
}
|
||||
|
||||
if bval, err := strconv.ParseBool(co2level); err == nil {
|
||||
result.Co2Level = bval
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
//NewRandomWeatherData creates random WeatherData with given Location
|
||||
func NewRandomWeatherData(sensorId uuid.UUID) WeatherData {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
|
Loading…
Add table
Reference in a new issue