weather-api/storage/weather-data.go
2021-04-24 23:38:58 +02:00

142 lines
3.4 KiB
Go

package storage
import (
"errors"
"math/rand"
"time"
"github.com/google/uuid"
)
type SensorValueType string
const (
Temperature SensorValueType = "temperature"
Pressure SensorValueType = "pressure"
Humidity SensorValueType = "humidity"
Co2Level SensorValueType = "co2level"
)
const (
SensorId string = "sensorId"
TimeStamp string = "timeStamp"
)
func GetSensorValueTypes() []SensorValueType {
return []SensorValueType{Temperature, Pressure, Humidity, Co2Level}
}
//WeatherData type
type WeatherData struct {
Values map[SensorValueType]float64
SensorId uuid.UUID
TimeStamp time.Time
}
//NewRandomWeatherData creates random WeatherData
func NewRandomWeatherData() *WeatherData {
rand.Seed(time.Now().UnixNano())
var data = new(WeatherData)
data.Values = make(map[SensorValueType]float64)
data.Values[Humidity] = rand.Float64() * 100
data.Values[Pressure] = rand.Float64()*80 + 960
data.Values[Temperature] = rand.Float64()*40 - 5
data.Values[Co2Level] = rand.Float64()*50 + 375
data.SensorId = uuid.New()
data.TimeStamp = time.Now()
return data
}
//NewRandomWeatherData creates random WeatherData
func NewWeatherData() *WeatherData {
var data = new(WeatherData)
data.Values = make(map[SensorValueType]float64)
return data
}
//OnlyQueriedValues remove all values not contained by the WeatherQuery
func (data *WeatherData) OnlyQueriedValues(query *WeatherQuery) *WeatherData {
for sensorValueType, value := range query.Values {
if !value {
delete(data.Values, sensorValueType)
}
}
return data
}
//ToMap converts WeatherData to a map[string]interface{}
func (data *WeatherData) ToMap() map[string]interface{} {
mappedData := map[string]interface{}{
SensorId: data.SensorId.String(),
TimeStamp: data.TimeStamp.String(),
}
for sensorValueType, value := range data.Values {
mappedData[string(sensorValueType)] = value
}
return mappedData
}
//FromMap converts a map[string]interface{} to WeatherData
func FromMap(value map[string]interface{}) (*WeatherData, error) {
var data = new(WeatherData)
data.Values = make(map[SensorValueType]float64)
var err error
copy := make(map[string]interface{})
for key, value := range value {
copy[key] = value
}
_, exists := copy[SensorId]
idString, ok := copy[SensorId].(string)
if exists && !ok {
return nil, errors.New("sensorId must be of type string")
}
if exists {
data.SensorId, err = uuid.Parse(idString)
if err != nil {
return nil, err
}
delete(copy, SensorId)
}
timeStampString, ok := copy[TimeStamp].(string)
if !ok {
return nil, errors.New("timeStamp must be of type string")
}
data.TimeStamp, err = time.Parse(time.RFC3339, timeStampString)
if err != nil {
return nil, err
}
delete(copy, TimeStamp)
for key, val := range copy {
switch v := val.(type) {
case float64:
data.Values[SensorValueType(key)] = float64(v)
default:
}
}
return data, nil
}
//GetOnlyQueriedFields execute onlyQueriedValues on WeatherData slice an return this
func GetOnlyQueriedFields(dataPoints []*WeatherData, query *WeatherQuery) []*WeatherData {
for _, data := range dataPoints {
data.OnlyQueriedValues(query)
}
return dataPoints
}
//ToMap mapps all WeatherData of a slice ToMap
func ToMap(dataPoints []*WeatherData) []map[string]interface{} {
var result = make([]map[string]interface{}, 0)
for _, data := range dataPoints {
result = append(result, data.ToMap())
}
return result
}