package sensor import ( "context" "fmt" "log" "sync" "time" "github.com/d2r2/go-bsbmp" "github.com/d2r2/go-i2c" "github.com/d2r2/go-logger" "github.com/go-flucky/flucky/pkg/types" uuid "github.com/satori/go.uuid" ) // BME280 is a sensor to measure humidity and temperature. type BME280 struct { *types.Sensor } // GetSensorModel returns the sensor model func (s *BME280) GetSensorModel() types.SensorModel { return s.Sensor.SensorModel } // Read measured values func (s *BME280) Read() ([]types.MeasuredValue, error) { // Create new connection to i2c-bus on 1 line with address 0x76. // Use i2cdetect utility to find device address over the i2c-bus i2c, err := i2c.NewI2C(*s.I2CAddress, *s.I2CBus) if err != nil { log.Fatal(err) } defer i2c.Close() logger.ChangePackageLogLevel("i2c", logger.InfoLevel) sensor, err := bsbmp.NewBMP(bsbmp.BME280, i2c) if err != nil { log.Fatal(err) } logger.ChangePackageLogLevel("bsbmp", logger.InfoLevel) temperatureValue, err := sensor.ReadTemperatureC(bsbmp.ACCURACY_STANDARD) if err != nil { log.Fatal(err) } // p, err := sensor.ReadPressurePa(bsbmp.ACCURACY_STANDARD) // if err != nil { // log.Fatal(err) // } _, humidityValue, err := sensor.ReadHumidityRH(bsbmp.ACCURACY_STANDARD) if err != nil { log.Fatal(err) } measuredValues := []types.MeasuredValue{ &types.Humidity{ HumidityID: uuid.NewV4().String(), HumidityValue: float64(humidityValue), HumidityFromDate: time.Now(), HumidityTillDate: time.Now(), SensorID: s.SensorID, }, &types.Temperature{ TemperatureID: uuid.NewV4().String(), TemperatureValue: float64(temperatureValue), TemperatureFromDate: time.Now(), TemperatureTillDate: time.Now(), SensorID: s.SensorID, }, } return measuredValues, nil } // ReadChannel reads the measured values from the sensor and writes them to a // channel. func (s *BME280) ReadChannel(measuredValuesChannel chan<- []types.MeasuredValue, errorChannel chan<- error, wg *sync.WaitGroup) { if wg != nil { defer wg.Done() } measuredValues, err := s.Read() if err != nil { errorChannel <- err return } measuredValuesChannel <- measuredValues } // ReadContinously reads the measured values continously from the sensor and // writes them to a channel. func (s *BME280) ReadContinously(ctx context.Context, measuredValuesChannel chan<- []types.MeasuredValue, errorChannel chan<- error) { for { select { case <-ctx.Done(): errorChannel <- fmt.Errorf("%v: Context closed: %v", s.SensorName, ctx.Err()) return default: s.ReadChannel(measuredValuesChannel, errorChannel, nil) } } }