2022-08-13 23:33:50 +02:00
package services
2022-09-03 22:54:53 +02:00
import (
"database/sql"
"time"
)
2022-08-13 23:33:50 +02:00
type SensorValuesService struct {
ctx * Context
}
type sensorValue struct {
Timestamp int64 ` json:"timestamp" `
Value float64 ` json:"value" `
}
2022-09-04 09:22:38 +02:00
func min ( a , b int64 ) int64 {
if a < b {
return a
}
return b
}
2022-08-28 11:56:03 +02:00
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 )
2022-08-13 23:33:50 +02:00
if err != nil {
return 0 , err
}
return res . LastInsertId ( )
}
2022-08-28 11:56:03 +02:00
func ( s * SensorValuesService ) GetList ( sensorId int64 , from int64 , to int64 ) ( [ ] sensorValue , error ) {
2022-09-04 09:22:38 +02:00
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
}
func ( s * SensorValuesService ) GetLatest ( sensorId int64 , to int64 ) ( * sensorValue , error ) {
var value = sensorValue { }
row := s . ctx . DB . QueryRow ( "SELECT timestamp, value FROM sensor_values WHERE sensor_id = ? AND timestamp < ? ORDER BY timestamp DESC LIMIT 1" , sensorId , to )
err := row . Scan ( & value . Timestamp , & value . Value )
if err != nil {
return nil , err
}
return & value , nil
}
func ( s * SensorValuesService ) getValueItems ( sensorId int64 , from int64 , to int64 ) ( [ ] sensorValue , error ) {
2022-08-23 23:35:36 +02:00
values := make ( [ ] sensorValue , 0 )
2022-08-13 23:33:50 +02:00
2022-08-28 11:56:03 +02:00
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 )
2022-08-13 23:33:50 +02:00
if err != nil {
2022-09-03 22:54:53 +02:00
if err == sql . ErrNoRows {
return values , nil
}
2022-08-13 23:33:50 +02:00
return nil , err
}
defer rows . Close ( )
for rows . Next ( ) {
2022-09-04 09:22:38 +02:00
item := sensorValue { }
err := rows . Scan ( & item . Timestamp , & item . Value )
2022-08-13 23:33:50 +02:00
if err != nil {
return nil , err
}
2022-09-04 09:22:38 +02:00
values = append ( values , item )
2022-08-13 23:33:50 +02:00
}
err = rows . Err ( )
if err != nil {
return nil , err
}
return values , nil
}