diff --git a/server/services/sensor_values_service.go b/server/services/sensor_values_service.go index 8a79b07..b284a6d 100644 --- a/server/services/sensor_values_service.go +++ b/server/services/sensor_values_service.go @@ -14,13 +14,6 @@ type sensorValue struct { Value float64 `json:"value"` } -func min(a, b int64) int64 { - if a < b { - return a - } - return b -} - func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error) { res, err := s.ctx.DB.Exec("INSERT INTO sensor_values (timestamp, sensor_id, value) VALUES (?, ?, ?)", time.Now().Unix(), sensorId, value) @@ -32,36 +25,7 @@ func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error) } func (s *SensorValuesService) GetList(sensorId int64, from int64, to int64) ([]sensorValue, error) { - intervalSize := to - from - batchSize := intervalSize - - if intervalSize > 100*24*60 { - batchSize = 24 * 60 - } - - values := make([]sensorValue, 0) - current := from - - for current < to { - nextValue := min(to, current+batchSize) - - batchValues, err := s.getValueItems(sensorId, current, nextValue) - - if err != nil { - return nil, err - } - - sum := 0.0 - - for _, item := range batchValues { - sum += item.Value - } - - values = append(values, sensorValue{Timestamp: int64((nextValue + current) / 2.0), Value: sum / float64(len(batchValues))}) - current += batchSize - } - - return values, nil + return s.getValueItems(sensorId, from, to, getAutoSensorValuesInterval(from, to)) } func (s *SensorValuesService) GetLatest(sensorId int64, to int64) (*sensorValue, error) { @@ -77,10 +41,47 @@ func (s *SensorValuesService) GetLatest(sensorId int64, to int64) (*sensorValue, return &value, nil } -func (s *SensorValuesService) getValueItems(sensorId int64, from int64, to int64) ([]sensorValue, error) { +func (s *SensorValuesService) getValueListQuery(sensorId int64, from int64, to int64, divide int64) (*sql.Rows, error) { + if divide == 1 { + return s.ctx.DB.Query("SELECT timestamp, value FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? ORDER BY timestamp ASC", sensorId, from, to) + } + + return s.ctx.DB.Query( + "SELECT (timestamp/?)*?, AVG(value) FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? GROUP BY (timestamp/?) ORDER BY timestamp ASC", + divide, + divide, + sensorId, + from, + to, + divide, + ) +} + +func getAutoSensorValuesInterval(from int64, to int64) int64 { + diff := to - from + + // 360 days -> 1 day interval + if diff > 360*24*60*60 { + return 24 * 60 * 60 + } + + // 160 days -> 1 hour interval + if diff > 160*24*60*60 { + return 60 * 60 + } + + // 80 days -> 10 minutes + if diff > 80*24*60*60 { + return 10 * 60 + } + + return 1 +} + +func (s *SensorValuesService) getValueItems(sensorId int64, from int64, to int64, divide int64) ([]sensorValue, error) { values := make([]sensorValue, 0) - rows, err := s.ctx.DB.Query("SELECT timestamp, value FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? ORDER BY timestamp ASC", sensorId, from, to) + rows, err := s.getValueListQuery(sensorId, from, to, divide) if err != nil { if err == sql.ErrNoRows {