You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
1.7 KiB
Go

2 years ago
package device
import (
"errors"
"fmt"
"sync"
"time"
)
type SensorManager struct {
SampleRate int `mapstructure:"sample_rate"` // in (ms)
// sampling
sampleMu sync.RWMutex
LatestSample float32
SampleTimestamp int64
2 years ago
*DeviceManager `mapstructure:",squash"`
// gRPC server
pb.UnimplementedSensorServer
2 years ago
}
func NewSensorManager() *SensorManager {
s := &SensorManager{}
return s
}
func (s *SensorManager) SetDeviceManager(d *DeviceManager) {
s.DeviceManager = d
}
type takeReading func(int, int) (float64, error)
func (s *SensorManager) Start(f takeReading) error {
// loading config
if err := s.LoadConfig(); err != nil {
return err
}
// starting
if err := s.DeviceManager.Start(); err != nil {
return err
}
// starting monitoring
go s.Monitor(f)
return nil
}
func (s *SensorManager) LoadConfig() error {
// setting keys
mainKey := fmt.Sprintf("devices.%d", s.Address)
sampleKey := fmt.Sprintf("%s.sample_rate", mainKey)
if !s.Config.IsSet(sampleKey) {
// no sample rate, default to 10s
s.Config.Set(sampleKey, 10000)
}
// loading lower
s.DeviceManager.LoadConfig()
s.Config.UnmarshalKey(mainKey, s)
return nil
}
func (s *SensorManager) Monitor(f takeReading) {
ch := make(chan struct{}) // hb chan
go s.HeartBeat(ch, s.SampleRate, 2000, time.Millisecond)
var reading float64
var err error
for range ch {
if reading, err = f(s.Bus, s.Address); err != nil {
if !errors.Is(err, ErrReadFail) {
// unknown error, panic
panic(err)
}
fmt.Printf("Reading failed, skipping!\n")
}
// update sample
if !errors.Is(err, ErrReadFail) {
fmt.Printf("Got %f\n", reading)
s.sampleMu.Lock()
s.LatestSample = float32(reading)
s.SampleTimestamp = time.Now.Unix()
2 years ago
s.sampleMu.Unlock()
}
}
}