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-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:42:12 +02:00
return s . getValueItems ( sensorId , from , to , getAutoSensorValuesInterval ( from , to ) )
2022-09-04 09:22:38 +02:00
}
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
}
2022-09-04 09:42:12 +02:00
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 ) {
2022-08-23 23:35:36 +02:00
values := make ( [ ] sensorValue , 0 )
2022-08-13 23:33:50 +02:00
2022-09-04 09:42:12 +02:00
rows , err := s . getValueListQuery ( sensorId , from , to , divide )
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
}