fix(pkg/sensor): reduce interface functions for better error handling
This commit is contained in:
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/d2r2/go-bsbmp"
|
||||
"github.com/d2r2/go-i2c"
|
||||
@ -19,9 +20,8 @@ type BME280 struct {
|
||||
*types.Sensor
|
||||
}
|
||||
|
||||
// GetSensorModel returns the sensor model
|
||||
func (s *BME280) GetSensorModel() types.SensorModel {
|
||||
return s.Sensor.SensorModel
|
||||
func (s *BME280) ID() string {
|
||||
return s.SensorID
|
||||
}
|
||||
|
||||
// Read measured values
|
||||
@ -124,3 +124,12 @@ func (s *BME280) ReadContinously(ctx context.Context, measuredValueChannel chan<
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ticker returns a new ticker, which tick every when the sensor should be read
|
||||
func (s *BME280) Ticker() *time.Ticker {
|
||||
duration, err := time.ParseDuration(s.TickDuration)
|
||||
if err != nil {
|
||||
duration = time.Minute
|
||||
}
|
||||
return time.NewTicker(duration)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/internal/format"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
@ -16,9 +17,8 @@ type DHT11 struct {
|
||||
*types.Sensor
|
||||
}
|
||||
|
||||
// GetSensorModel returns the sensor model
|
||||
func (s *DHT11) GetSensorModel() types.SensorModel {
|
||||
return s.Sensor.SensorModel
|
||||
func (s *DHT11) ID() string {
|
||||
return s.SensorID
|
||||
}
|
||||
|
||||
// Read measured values
|
||||
@ -98,3 +98,12 @@ func (s *DHT11) ReadContinously(ctx context.Context, measuredValueChannel chan<-
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ticker returns a new ticker, which tick every when the sensor should be read
|
||||
func (s *DHT11) Ticker() *time.Ticker {
|
||||
duration, err := time.ParseDuration(s.TickDuration)
|
||||
if err != nil {
|
||||
duration = time.Minute
|
||||
}
|
||||
return time.NewTicker(duration)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/internal/format"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
@ -16,9 +17,8 @@ type DHT22 struct {
|
||||
*types.Sensor
|
||||
}
|
||||
|
||||
// GetSensorModel returns the sensor model
|
||||
func (s *DHT22) GetSensorModel() types.SensorModel {
|
||||
return s.Sensor.SensorModel
|
||||
func (s *DHT22) ID() string {
|
||||
return s.SensorID
|
||||
}
|
||||
|
||||
// Read measured values
|
||||
@ -98,3 +98,12 @@ func (s *DHT22) ReadContinously(ctx context.Context, measuredValueChannel chan<-
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ticker returns a new ticker, which tick every when the sensor should be read
|
||||
func (s *DHT22) Ticker() *time.Ticker {
|
||||
duration, err := time.ParseDuration(s.TickDuration)
|
||||
if err != nil {
|
||||
duration = time.Minute
|
||||
}
|
||||
return time.NewTicker(duration)
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/internal/format"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
@ -19,9 +20,8 @@ type DS18B20 struct {
|
||||
*types.Sensor
|
||||
}
|
||||
|
||||
// GetSensorModel returns the sensor model
|
||||
func (s *DS18B20) GetSensorModel() types.SensorModel {
|
||||
return s.Sensor.SensorModel
|
||||
func (s *DS18B20) ID() string {
|
||||
return s.SensorID
|
||||
}
|
||||
|
||||
// Read measured values
|
||||
@ -40,12 +40,12 @@ func (s *DS18B20) Read() ([]*types.MeasuredValue, error) {
|
||||
|
||||
i := strings.LastIndex(raw, "t=")
|
||||
if i == -1 {
|
||||
return nil, ErrReadSensor
|
||||
return nil, errorReadData
|
||||
}
|
||||
|
||||
c, err := strconv.ParseFloat(raw[i+2:len(raw)-1], 64)
|
||||
if err != nil {
|
||||
return nil, ErrParseData
|
||||
return nil, errorParseData
|
||||
}
|
||||
|
||||
temperatureValue := c / 1000
|
||||
@ -97,3 +97,12 @@ func (s *DS18B20) ReadContinously(ctx context.Context, measuredValueChannel chan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ticker returns a new ticker, which tick every when the sensor should be read
|
||||
func (s *DS18B20) Ticker() *time.Ticker {
|
||||
duration, err := time.ParseDuration(s.TickDuration)
|
||||
if err != nil {
|
||||
duration = time.Minute
|
||||
}
|
||||
return time.NewTicker(duration)
|
||||
}
|
||||
|
@ -4,5 +4,7 @@ import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrParseData = errors.New("Can not parse data")
|
||||
var ErrReadSensor = errors.New("Can not read data from Sensor")
|
||||
var (
|
||||
errorParseData = errors.New("Failed to parse data")
|
||||
errorReadData = errors.New("Failed to read data from sensor")
|
||||
)
|
||||
|
@ -1,15 +1,12 @@
|
||||
package sensor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Sensor interface {
|
||||
GetSensorModel() types.SensorModel
|
||||
ID() string
|
||||
Read() ([]*types.MeasuredValue, error)
|
||||
ReadChannel(measuredValueChannel chan<- *types.MeasuredValue, errorChannel chan<- error, wg *sync.WaitGroup)
|
||||
ReadContinously(ctx context.Context, measuredValueChannel chan<- *types.MeasuredValue, errorChannel chan<- error)
|
||||
Ticker() *time.Ticker
|
||||
}
|
||||
|
@ -1,58 +1,46 @@
|
||||
package sensor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/internal/collect"
|
||||
"github.com/go-flucky/flucky/pkg/internal/prittyprint"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
)
|
||||
|
||||
// Read measured values from sensors
|
||||
func Read(ctx context.Context, sensors []Sensor) ([]*types.MeasuredValue, error) {
|
||||
func Read(sensors []Sensor, measuredValueType types.MeasuredValueType) ([]*types.MeasuredValue, error) {
|
||||
|
||||
measuredValueChannel := make(chan *types.MeasuredValue, len(sensors))
|
||||
errorChannel := make(chan error, len(sensors))
|
||||
|
||||
ReadChannel(ctx, sensors, measuredValueChannel, errorChannel)
|
||||
|
||||
errors := collect.Errors(errorChannel)
|
||||
if len(errors) > 0 {
|
||||
return nil, prittyprint.FormatErrors(errors)
|
||||
type result struct {
|
||||
measuredValues []*types.MeasuredValue
|
||||
err error
|
||||
}
|
||||
|
||||
measuredValues := collect.MeasuredValues(measuredValueChannel)
|
||||
resultChannel := make(chan *result, len(sensors))
|
||||
|
||||
return measuredValues, nil
|
||||
}
|
||||
|
||||
// ReadChannel reads the measured values from sensors and writes them to a
|
||||
// channel.
|
||||
func ReadChannel(ctx context.Context, sensors []Sensor, measuredValueChannel chan<- *types.MeasuredValue, errorChannel chan<- error) {
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(len(sensors))
|
||||
|
||||
for _, sensor := range sensors {
|
||||
go sensor.ReadChannel(measuredValueChannel, errorChannel, wg)
|
||||
// producers
|
||||
// read measured values
|
||||
for _, s := range sensors {
|
||||
go func(s Sensor) {
|
||||
measuredValues, err := s.Read()
|
||||
resultChannel <- &result{
|
||||
measuredValues: measuredValues,
|
||||
err: err,
|
||||
}
|
||||
}(s)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// ReadContinuously reads the measured values continously from sensors and writes
|
||||
// them to a channel.
|
||||
func ReadContinuously(ctx context.Context, sensors []Sensor, measuredValueChannel chan<- *types.MeasuredValue, errorChannel chan<- error) {
|
||||
// consumer
|
||||
measuredValues := make([]*types.MeasuredValue, 0)
|
||||
counter := len(sensors)
|
||||
for {
|
||||
if counter == 0 {
|
||||
break
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
errorChannel <- fmt.Errorf("Context closed: %v", ctx.Err())
|
||||
return
|
||||
default:
|
||||
ReadChannel(ctx, sensors, measuredValueChannel, errorChannel)
|
||||
case result := <-resultChannel:
|
||||
counter--
|
||||
if result.err != nil {
|
||||
return nil, result.err
|
||||
}
|
||||
measuredValues = append(measuredValues, result.measuredValues...)
|
||||
}
|
||||
}
|
||||
|
||||
return types.SelectMeasuredValues(measuredValueType, measuredValues), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user