fix(pkg/daemon): use measuredValue interface instead of different structs
This commit is contained in:
		| @@ -225,7 +225,7 @@ func (c *Configuration) EnableSensor(name string) error { | ||||
| } | ||||
|  | ||||
| // GetHumiditySensors returns a list of humidity sensors | ||||
| func (c *Configuration) GetHumiditySensors(option Option) []sensor.HumiditySensor { | ||||
| func (c *Configuration) GetHumiditySensors(option Option) []sensor.Sensor { | ||||
| 	humiditySensors := c.getHumiditySensors() | ||||
|  | ||||
| 	switch option { | ||||
| @@ -235,22 +235,22 @@ func (c *Configuration) GetHumiditySensors(option Option) []sensor.HumiditySenso | ||||
| 				humiditySensors = append(humiditySensors[:i], humiditySensors[i+1:]...) | ||||
| 			} | ||||
| 		} | ||||
| 		return c.convertHumiditySensors(humiditySensors) | ||||
| 		return c.convertSensors(humiditySensors) | ||||
| 	case DISABLED: | ||||
| 		for i, humiditySensor := range humiditySensors { | ||||
| 			if humiditySensor.SensorEnabled { | ||||
| 				humiditySensors = append(humiditySensors[:i], humiditySensors[i+1:]...) | ||||
| 			} | ||||
| 		} | ||||
| 		return c.convertHumiditySensors(humiditySensors) | ||||
| 		return c.convertSensors(humiditySensors) | ||||
| 	default: | ||||
| 		return c.convertHumiditySensors(humiditySensors) | ||||
| 		return c.convertSensors(humiditySensors) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GetHumiditySensorsByName returns a list of temperature sensors by name, | ||||
| // uuid or wire-id | ||||
| func (c *Configuration) GetHumiditySensorsByName(names []string) []sensor.HumiditySensor { | ||||
| func (c *Configuration) GetHumiditySensorsByName(names []string) []sensor.Sensor { | ||||
| 	configHumiditySensors := make(map[string]*types.Sensor, 0) | ||||
|  | ||||
| 	for _, name := range names { | ||||
| @@ -271,7 +271,7 @@ func (c *Configuration) GetHumiditySensorsByName(names []string) []sensor.Humidi | ||||
| 		humiditySensors = append(humiditySensors, cs) | ||||
| 	} | ||||
|  | ||||
| 	return c.convertHumiditySensors(humiditySensors) | ||||
| 	return c.convertSensors(humiditySensors) | ||||
| } | ||||
|  | ||||
| func (c *Configuration) GetRGBLEDs(option Option) []rgbled.RGBLED { | ||||
| @@ -320,7 +320,7 @@ func (c *Configuration) GetRGBLEDsByName(names []string) []rgbled.RGBLED { | ||||
| } | ||||
|  | ||||
| // GetTemperatureSensors returns a list of temperature sensors | ||||
| func (c *Configuration) GetTemperatureSensors(option Option) []sensor.TemperatureSensor { | ||||
| func (c *Configuration) GetTemperatureSensors(option Option) []sensor.Sensor { | ||||
| 	temperatureSensors := c.getTemperatureSensors() | ||||
|  | ||||
| 	switch option { | ||||
| @@ -330,22 +330,22 @@ func (c *Configuration) GetTemperatureSensors(option Option) []sensor.Temperatur | ||||
| 				temperatureSensors = append(temperatureSensors[:i], temperatureSensors[i+1:]...) | ||||
| 			} | ||||
| 		} | ||||
| 		return c.convertTemperatureSensors(temperatureSensors) | ||||
| 		return c.convertSensors(temperatureSensors) | ||||
| 	case DISABLED: | ||||
| 		for i, temperatureSensor := range temperatureSensors { | ||||
| 			if temperatureSensor.SensorEnabled { | ||||
| 				temperatureSensors = append(temperatureSensors[:i], temperatureSensors[i+1:]...) | ||||
| 			} | ||||
| 		} | ||||
| 		return c.convertTemperatureSensors(temperatureSensors) | ||||
| 		return c.convertSensors(temperatureSensors) | ||||
| 	default: | ||||
| 		return c.convertTemperatureSensors(temperatureSensors) | ||||
| 		return c.convertSensors(temperatureSensors) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GetTemperatureSensorsByName returns a list of temperature sensors by name, | ||||
| // uuid or wire-id | ||||
| func (c *Configuration) GetTemperatureSensorsByName(names []string) []sensor.TemperatureSensor { | ||||
| func (c *Configuration) GetTemperatureSensorsByName(names []string) []sensor.Sensor { | ||||
| 	configTemperatureSensors := make(map[string]*types.Sensor, 0) | ||||
|  | ||||
| 	for _, name := range names { | ||||
| @@ -366,7 +366,7 @@ func (c *Configuration) GetTemperatureSensorsByName(names []string) []sensor.Tem | ||||
| 		temperatureSensors = append(temperatureSensors, cs) | ||||
| 	} | ||||
|  | ||||
| 	return c.convertTemperatureSensors(temperatureSensors) | ||||
| 	return c.convertSensors(temperatureSensors) | ||||
| } | ||||
|  | ||||
| // RemoveRGBLED deletes a LED by its name or its unique UUID | ||||
| @@ -431,22 +431,26 @@ func (c *Configuration) RenameSensor(oldName, newName string) error { | ||||
| 	return fmt.Errorf("Could not find remote %v to replace into with %v", oldName, newName) | ||||
| } | ||||
|  | ||||
| func (c *Configuration) convertHumiditySensors(sensors []*types.Sensor) []sensor.HumiditySensor { | ||||
| 	humiditySensors := make([]sensor.HumiditySensor, 0) | ||||
| func (c *Configuration) convertSensors(sensors []*types.Sensor) []sensor.Sensor { | ||||
| 	cachedSensors := make([]sensor.Sensor, 0) | ||||
|  | ||||
| 	for _, s := range sensors { | ||||
| 		switch s.SensorModel { | ||||
| 		case types.DHT11: | ||||
| 			humiditySensors = append(humiditySensors, &sensor.DHT11{ | ||||
| 			cachedSensors = append(cachedSensors, &sensor.DHT11{ | ||||
| 				Sensor: s, | ||||
| 			}) | ||||
| 		case types.DHT22: | ||||
| 			humiditySensors = append(humiditySensors, &sensor.DHT22{ | ||||
| 			cachedSensors = append(cachedSensors, &sensor.DHT22{ | ||||
| 				Sensor: s, | ||||
| 			}) | ||||
| 		case types.DS18B20: | ||||
| 			cachedSensors = append(cachedSensors, &sensor.DS18B20{ | ||||
| 				Sensor: s, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
| 	return humiditySensors | ||||
| 	return cachedSensors | ||||
| } | ||||
|  | ||||
| func (c *Configuration) convertRGBLEDs(rgbLEDs []*types.RGBLED) []rgbled.RGBLED { | ||||
| @@ -461,28 +465,6 @@ func (c *Configuration) convertRGBLEDs(rgbLEDs []*types.RGBLED) []rgbled.RGBLED | ||||
| 	return leds | ||||
| } | ||||
|  | ||||
| func (c *Configuration) convertTemperatureSensors(sensors []*types.Sensor) []sensor.TemperatureSensor { | ||||
| 	temperatureSensors := make([]sensor.TemperatureSensor, 0) | ||||
|  | ||||
| 	for _, s := range sensors { | ||||
| 		switch s.SensorModel { | ||||
| 		case types.DHT11: | ||||
| 			temperatureSensors = append(temperatureSensors, &sensor.DHT11{ | ||||
| 				Sensor: s, | ||||
| 			}) | ||||
| 		case types.DHT22: | ||||
| 			temperatureSensors = append(temperatureSensors, &sensor.DHT22{ | ||||
| 				Sensor: s, | ||||
| 			}) | ||||
| 		case types.DS18B20: | ||||
| 			temperatureSensors = append(temperatureSensors, &sensor.DS18B20{ | ||||
| 				Sensor: s, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
| 	return temperatureSensors | ||||
| } | ||||
|  | ||||
| func (c *Configuration) getHumiditySensors() []*types.Sensor { | ||||
| 	humiditySensors := make([]*types.Sensor, 0) | ||||
| 	for _, s := range c.Sensors { | ||||
|   | ||||
| @@ -16,15 +16,11 @@ import ( | ||||
| ) | ||||
|  | ||||
| // Start the daemon | ||||
| func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compression bool, degree types.TemperatureUnit, round float64, logger logger.Logger) { | ||||
| func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compression bool, logger logger.Logger) { | ||||
|  | ||||
| 	// Info | ||||
| 	logger.Info("Use clean-cache-interval: %v", cleanCacheInterval.String()) | ||||
| 	logger.Info("Use compression: %v", compression) | ||||
| 	logger.Info("Round values: %v", round) | ||||
| 	logger.Info("Temperature unit: %v", degree) | ||||
|  | ||||
| 	temperatureLogfile := logfile.New(cnf.Device.TemperatureLogfile) | ||||
|  | ||||
| 	ticker := time.Tick(cleanCacheInterval) | ||||
|  | ||||
| @@ -32,16 +28,16 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress | ||||
| 	signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM) | ||||
|  | ||||
| 	errorChannel := make(chan error, 0) | ||||
| 	//humidityChannel := make(chan *types.Humidity, 0) | ||||
| 	temperatureChannel := make(chan *types.Temperature, 0) | ||||
| 	measuredValueChannel := make(chan types.MeasuredValue, 0) | ||||
|  | ||||
| 	ctx := context.Background() | ||||
| 	childContext, cancel := context.WithCancel(ctx) | ||||
|  | ||||
| 	// go sensor.ReadHumiditiesContinuously(cnf.GetHumiditySensors(config.ENABLED), humidityChannel, errorChannel) | ||||
| 	go sensor.ReadTemperaturesContinuously(childContext, cnf.GetTemperatureSensors(config.ENABLED), degree, round, temperatureChannel, errorChannel) | ||||
| 	logfile := logfile.New(cnf) | ||||
|  | ||||
| 	temperatureCache := make([]*types.Temperature, 0) | ||||
| 	measuredValuesCache := make([]types.MeasuredValue, 0) | ||||
|  | ||||
| 	go sensor.ReadContinuously(childContext, cnf.GetTemperatureSensors(config.ENABLED), measuredValueChannel, errorChannel) | ||||
|  | ||||
| 	rgbLEDs := cnf.GetRGBLEDs(config.ENABLED) | ||||
|  | ||||
| @@ -70,7 +66,7 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress | ||||
| 				logger.Error("Can not turn on blue info light: %v", err) | ||||
| 			} | ||||
|  | ||||
| 			err = logfile.AppendTemperatures(temperatureLogfile, compression, temperatureCache) | ||||
| 			err = logfile.Append(compression, measuredValuesCache) | ||||
| 			if err != nil { | ||||
|  | ||||
| 				err = rgbled.Error(rgbLEDs) | ||||
| @@ -81,10 +77,10 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress | ||||
| 				cancel() | ||||
| 				logger.Fatal("Can not save temperatures: %v", err) | ||||
| 			} | ||||
| 			temperatureCache = make([]*types.Temperature, 0) | ||||
| 			measuredValuesCache = make([]types.MeasuredValue, 0) | ||||
|  | ||||
| 		case temperature, _ := <-temperatureChannel: | ||||
| 			temperatureCache = append(temperatureCache, temperature) | ||||
| 		case measuredValue, _ := <-measuredValueChannel: | ||||
| 			measuredValuesCache = append(measuredValuesCache, measuredValue) | ||||
|  | ||||
| 		case killSignal := <-interrupt: | ||||
| 			logger.Warn("Daemon was interruped by system signal %v\n", killSignal) | ||||
| @@ -96,8 +92,8 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress | ||||
| 				logger.Error("Can not turn on red info light: %v", err) | ||||
| 			} | ||||
|  | ||||
| 			logger.Warn("Save remaining temperature data from the cache") | ||||
| 			err = logfile.AppendTemperatures(temperatureLogfile, compression, temperatureCache) | ||||
| 			logger.Warn("Save remaining data from the cache: %v", len(measuredValuesCache)) | ||||
| 			err = logfile.Append(compression, measuredValuesCache) | ||||
| 			if err != nil { | ||||
| 				logger.Fatal("%v", err) | ||||
| 			} | ||||
|   | ||||
							
								
								
									
										20
									
								
								pkg/internal/collect/measuredValues.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								pkg/internal/collect/measuredValues.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| package collect | ||||
|  | ||||
| import ( | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| ) | ||||
|  | ||||
| func MeasuredValues(measuredValueChannel <-chan types.MeasuredValue) []types.MeasuredValue { | ||||
| 	cachedMeasuredValues := make([]types.MeasuredValue, 0) | ||||
| 	for { | ||||
| 		select { | ||||
| 		case measuredValue, more := <-measuredValueChannel: | ||||
| 			if more { | ||||
| 				cachedMeasuredValues = append(cachedMeasuredValues, measuredValue) | ||||
| 				continue | ||||
| 			} | ||||
| 		default: | ||||
| 			return cachedMeasuredValues | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -1,20 +0,0 @@ | ||||
| package collect | ||||
|  | ||||
| import ( | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| ) | ||||
|  | ||||
| func Temperatures(temperatureChannel <-chan *types.Temperature) []*types.Temperature { | ||||
| 	temperatureList := make([]*types.Temperature, 0) | ||||
| 	for { | ||||
| 		select { | ||||
| 		case temperature, more := <-temperatureChannel: | ||||
| 			if more { | ||||
| 				temperatureList = append(temperatureList, temperature) | ||||
| 				continue | ||||
| 			} | ||||
| 		default: | ||||
| 			return temperatureList | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -1,187 +1,175 @@ | ||||
| package logfile | ||||
|  | ||||
| import ( | ||||
| 	"encoding/csv" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| // type csvLogfile struct { | ||||
| // 	logfile string | ||||
| // } | ||||
|  | ||||
| 	"github.com/go-flucky/flucky/pkg/sensor" | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| ) | ||||
| // func (cl *csvLogfile) GetLogfile() string { | ||||
| // 	return cl.logfile | ||||
| // } | ||||
|  | ||||
| type csvLogfile struct { | ||||
| 	logfile string | ||||
| } | ||||
| // func (cl *csvLogfile) ReadHumidities() ([]*types.Humidity, error) { | ||||
| // 	if _, err := os.Stat(cl.logfile); os.IsNotExist(err) { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, cl.logfile) | ||||
| // 	} | ||||
|  | ||||
| func (cl *csvLogfile) GetLogfile() string { | ||||
| 	return cl.logfile | ||||
| } | ||||
| // 	humidities := make([]*types.Humidity, 0) | ||||
|  | ||||
| func (cl *csvLogfile) ReadHumidities() ([]*types.Humidity, error) { | ||||
| 	if _, err := os.Stat(cl.logfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, cl.logfile) | ||||
| 	} | ||||
| // 	f, err := os.Open(cl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, cl.logfile) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| 	humidities := make([]*types.Humidity, 0) | ||||
| // 	jsonDecoder := json.NewDecoder(f) | ||||
| // 	err = jsonDecoder.Decode(&humidities) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileDecode, err) | ||||
| // 	} | ||||
|  | ||||
| 	f, err := os.Open(cl.logfile) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, cl.logfile) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // 	return humidities, nil | ||||
| // } | ||||
|  | ||||
| 	jsonDecoder := json.NewDecoder(f) | ||||
| 	err = jsonDecoder.Decode(&humidities) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileDecode, err) | ||||
| 	} | ||||
| // func (cl *csvLogfile) ReadTemperatures() ([]*types.Temperature, error) { | ||||
|  | ||||
| 	return humidities, nil | ||||
| } | ||||
| // 	if _, err := os.Stat(cl.logfile); os.IsNotExist(err) { | ||||
| // 		return nil, fmt.Errorf("%v %v: %v", errorLogfileNotFound, cl.logfile, err) | ||||
| // 	} | ||||
|  | ||||
| func (cl *csvLogfile) ReadTemperatures() ([]*types.Temperature, error) { | ||||
| // 	temperatures := make([]*types.Temperature, 0) | ||||
|  | ||||
| 	if _, err := os.Stat(cl.logfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v %v: %v", errorLogfileNotFound, cl.logfile, err) | ||||
| 	} | ||||
| // 	f, err := os.Open(cl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v %v: %v", errorLogfileOpen, cl.logfile, err) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| 	temperatures := make([]*types.Temperature, 0) | ||||
| // 	r := csv.NewReader(f) | ||||
| // 	records, err := r.ReadAll() | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v %v: %v", errorLogfileDecode, cl.logfile, err) | ||||
| // 	} | ||||
|  | ||||
| 	f, err := os.Open(cl.logfile) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v %v: %v", errorLogfileOpen, cl.logfile, err) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // 	for _, record := range records { | ||||
| // 		times := make([]time.Time, 0) | ||||
| // 		for _, j := range []int{3, 4} { | ||||
| // 			time, err := time.Parse(timeFormat, record[j]) | ||||
| // 			if err != nil { | ||||
| // 				return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[j], err) | ||||
| // 			} | ||||
| // 			times = append(times, time) | ||||
| // 		} | ||||
|  | ||||
| 	r := csv.NewReader(f) | ||||
| 	records, err := r.ReadAll() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v %v: %v", errorLogfileDecode, cl.logfile, err) | ||||
| 	} | ||||
| // 		temperatureValue, err := strconv.ParseFloat(record[1], 64) | ||||
| // 		if err != nil { | ||||
| // 			return nil, fmt.Errorf("%v %v: %v", errorParseFloat, record[1], err) | ||||
| // 		} | ||||
|  | ||||
| 	for _, record := range records { | ||||
| 		times := make([]time.Time, 0) | ||||
| 		for _, j := range []int{3, 4} { | ||||
| 			time, err := time.Parse(timeFormat, record[j]) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[j], err) | ||||
| 			} | ||||
| 			times = append(times, time) | ||||
| 		} | ||||
| // 		measurementUnit, err := sensor.SelectTemperatureMeasurementUnit(record[2]) | ||||
| // 		if err != nil { | ||||
| // 			return nil, fmt.Errorf("%v %v: %v", errorParseMeasurementUnit, record[2], err) | ||||
| // 		} | ||||
|  | ||||
| 		temperatureValue, err := strconv.ParseFloat(record[1], 64) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("%v %v: %v", errorParseFloat, record[1], err) | ||||
| 		} | ||||
| // 		temperature := &types.Temperature{ | ||||
| // 			TemperatureID:       record[0],        // 0 | ||||
| // 			TemperatureValue:    temperatureValue, // 1 | ||||
| // 			TemperatureUnit:     measurementUnit,  // 2 | ||||
| // 			TemperatureFromDate: times[0],         // 3 | ||||
| // 			TemperatureTillDate: times[1],         // 4 | ||||
| // 			SensorID:            record[5],        // 5 | ||||
| // 		} | ||||
|  | ||||
| 		measurementUnit, err := sensor.SelectTemperatureMeasurementUnit(record[2]) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("%v %v: %v", errorParseMeasurementUnit, record[2], err) | ||||
| 		} | ||||
| // 		// Creation date | ||||
| // 		temperatureCreationDate, err := time.Parse(timeFormat, record[6]) | ||||
| // 		if err != nil { | ||||
| // 			return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[5], err) | ||||
| // 		} | ||||
| // 		temperature.CreationDate = &temperatureCreationDate | ||||
|  | ||||
| 		temperature := &types.Temperature{ | ||||
| 			TemperatureID:       record[0],        // 0 | ||||
| 			TemperatureValue:    temperatureValue, // 1 | ||||
| 			TemperatureUnit:     measurementUnit,  // 2 | ||||
| 			TemperatureFromDate: times[0],         // 3 | ||||
| 			TemperatureTillDate: times[1],         // 4 | ||||
| 			SensorID:            record[5],        // 5 | ||||
| 		} | ||||
| // 		if record[7] != "" { | ||||
| // 			temperatureUpdateDate, err := time.Parse(timeFormat, record[7]) | ||||
| // 			if err != nil { | ||||
| // 				return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[7], err) | ||||
| // 			} | ||||
|  | ||||
| 		// Creation date | ||||
| 		temperatureCreationDate, err := time.Parse(timeFormat, record[6]) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[5], err) | ||||
| 		} | ||||
| 		temperature.CreationDate = &temperatureCreationDate | ||||
| // 			temperature.UpdateDate = &temperatureUpdateDate | ||||
| // 		} | ||||
|  | ||||
| 		if record[7] != "" { | ||||
| 			temperatureUpdateDate, err := time.Parse(timeFormat, record[7]) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[7], err) | ||||
| 			} | ||||
| // 		temperatures = append(temperatures, temperature) | ||||
| // 	} | ||||
|  | ||||
| 			temperature.UpdateDate = &temperatureUpdateDate | ||||
| 		} | ||||
| // 	return temperatures, nil | ||||
| // } | ||||
|  | ||||
| 		temperatures = append(temperatures, temperature) | ||||
| 	} | ||||
| // func (cl *csvLogfile) WriteHumidities(humidities []*types.Humidity) error { | ||||
|  | ||||
| 	return temperatures, nil | ||||
| } | ||||
| // 	f, err := os.Create(cl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return fmt.Errorf("%v: %v", errorLogfileCreate, cl.logfile) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| func (cl *csvLogfile) WriteHumidities(humidities []*types.Humidity) error { | ||||
| // 	w := csv.NewWriter(f) | ||||
|  | ||||
| 	f, err := os.Create(cl.logfile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileCreate, cl.logfile) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // 	for _, humidity := range humidities { | ||||
| // 		w.Write([]string{ | ||||
| // 			fmt.Sprintf("%v", humidity.HumidityID), | ||||
| // 			fmt.Sprintf("%v", humidity.HumidityValue), | ||||
| // 			fmt.Sprintf("%v", humidity.HumidityFromDate.Format(timeFormat)), | ||||
| // 			fmt.Sprintf("%v", humidity.HumidityTillDate.Format(timeFormat)), | ||||
| // 			fmt.Sprintf("%v", humidity.SensorID), | ||||
| // 			fmt.Sprintf("%v", humidity.CreationDate.Format(timeFormat)), | ||||
| // 			fmt.Sprintf("%v", humidity.UpdateDate.Format(timeFormat)), | ||||
| // 		}) | ||||
| // 	} | ||||
|  | ||||
| 	w := csv.NewWriter(f) | ||||
| // 	w.Flush() | ||||
|  | ||||
| 	for _, humidity := range humidities { | ||||
| 		w.Write([]string{ | ||||
| 			fmt.Sprintf("%v", humidity.HumidityID), | ||||
| 			fmt.Sprintf("%v", humidity.HumidityValue), | ||||
| 			fmt.Sprintf("%v", humidity.HumidityFromDate.Format(timeFormat)), | ||||
| 			fmt.Sprintf("%v", humidity.HumidityTillDate.Format(timeFormat)), | ||||
| 			fmt.Sprintf("%v", humidity.SensorID), | ||||
| 			fmt.Sprintf("%v", humidity.CreationDate.Format(timeFormat)), | ||||
| 			fmt.Sprintf("%v", humidity.UpdateDate.Format(timeFormat)), | ||||
| 		}) | ||||
| 	} | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| 	w.Flush() | ||||
| // func (cl *csvLogfile) WriteTemperatures(temperatures []*types.Temperature) error { | ||||
| // 	f, err := os.Create(cl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return fmt.Errorf("%v: %v", errorLogfileCreate, cl.logfile) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| // 	writeCreationDate(temperatures) | ||||
|  | ||||
| func (cl *csvLogfile) WriteTemperatures(temperatures []*types.Temperature) error { | ||||
| 	f, err := os.Create(cl.logfile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileCreate, cl.logfile) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // 	w := csv.NewWriter(f) | ||||
|  | ||||
| 	writeCreationDate(temperatures) | ||||
| // 	for _, temperature := range temperatures { | ||||
| // 		record := make([]string, 0) | ||||
|  | ||||
| 	w := csv.NewWriter(f) | ||||
| // 		if temperature.UpdateDate != nil { | ||||
| // 			record = []string{ | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureID), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureValue), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureUnit), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureFromDate.Format(timeFormat)), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureTillDate.Format(timeFormat)), | ||||
| // 				fmt.Sprintf("%v", temperature.SensorID), | ||||
| // 				fmt.Sprintf("%v", temperature.CreationDate.Format(timeFormat)), | ||||
| // 				fmt.Sprintf("%v", temperature.UpdateDate.Format(timeFormat)), | ||||
| // 			} | ||||
| // 		} else { | ||||
| // 			record = []string{ | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureID), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureValue), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureUnit), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureFromDate.Format(timeFormat)), | ||||
| // 				fmt.Sprintf("%v", temperature.TemperatureTillDate.Format(timeFormat)), | ||||
| // 				fmt.Sprintf("%v", temperature.SensorID), | ||||
| // 				fmt.Sprintf("%v", temperature.CreationDate.Format(timeFormat)), | ||||
| // 				fmt.Sprintf(""), | ||||
| // 			} | ||||
| // 		} | ||||
|  | ||||
| 	for _, temperature := range temperatures { | ||||
| 		record := make([]string, 0) | ||||
| // 		w.Write(record) | ||||
| // 	} | ||||
|  | ||||
| 		if temperature.UpdateDate != nil { | ||||
| 			record = []string{ | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureID), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureValue), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureUnit), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureFromDate.Format(timeFormat)), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureTillDate.Format(timeFormat)), | ||||
| 				fmt.Sprintf("%v", temperature.SensorID), | ||||
| 				fmt.Sprintf("%v", temperature.CreationDate.Format(timeFormat)), | ||||
| 				fmt.Sprintf("%v", temperature.UpdateDate.Format(timeFormat)), | ||||
| 			} | ||||
| 		} else { | ||||
| 			record = []string{ | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureID), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureValue), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureUnit), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureFromDate.Format(timeFormat)), | ||||
| 				fmt.Sprintf("%v", temperature.TemperatureTillDate.Format(timeFormat)), | ||||
| 				fmt.Sprintf("%v", temperature.SensorID), | ||||
| 				fmt.Sprintf("%v", temperature.CreationDate.Format(timeFormat)), | ||||
| 				fmt.Sprintf(""), | ||||
| 			} | ||||
| 		} | ||||
| // 	w.Flush() | ||||
|  | ||||
| 		w.Write(record) | ||||
| 	} | ||||
|  | ||||
| 	w.Flush() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| // 	return nil | ||||
| // } | ||||
|   | ||||
| @@ -22,3 +22,5 @@ var errorNoValidSensorID = errors.New("No sensor id detected or available") | ||||
| var errorNoValidTemperatureID = errors.New("No valid temperature id detected or available") | ||||
| var errorNoValidTime = errors.New("No time detected or available") | ||||
| var errorNoValidTimePeriods = errors.New("No valid time periods") | ||||
|  | ||||
| var errorTypeSwitch = errors.New("Can not detect type via type switch") | ||||
|   | ||||
| @@ -5,9 +5,9 @@ import ( | ||||
| ) | ||||
|  | ||||
| type Logfile interface { | ||||
| 	GetLogfile() string | ||||
| 	ReadHumidities() ([]*types.Humidity, error) | ||||
| 	ReadTemperatures() ([]*types.Temperature, error) | ||||
| 	WriteHumidities(humidities []*types.Humidity) error | ||||
| 	WriteTemperatures(temperatures []*types.Temperature) error | ||||
| 	Append(compression bool, measuredValues []types.MeasuredValue) error | ||||
| 	Read() ([]types.MeasuredValue, error) | ||||
| 	// ReadCustom(r io.Reader) ([]types.MeasuredValue, error) | ||||
| 	Write(measuredValues []types.MeasuredValue) error | ||||
| 	// WriteCustom(w io.Writer, measuredValues []types.MeasuredValue) error | ||||
| } | ||||
|   | ||||
| @@ -3,68 +3,162 @@ package logfile | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/go-flucky/flucky/pkg/internal/collect" | ||||
| 	"github.com/go-flucky/flucky/pkg/internal/prittyprint" | ||||
|  | ||||
| 	"github.com/go-flucky/flucky/pkg/config" | ||||
|  | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| ) | ||||
|  | ||||
| type jsonLogfile struct { | ||||
| 	logfile string | ||||
| 	cnf *config.Configuration | ||||
| } | ||||
|  | ||||
| func (jl *jsonLogfile) GetLogfile() string { | ||||
| 	return jl.logfile | ||||
| func (jl *jsonLogfile) Append(compression bool, measuredValues []types.MeasuredValue) error { | ||||
|  | ||||
| 	allMeasuredValues, err := jl.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	log.Println(len(allMeasuredValues)) | ||||
|  | ||||
| 	allMeasuredValues = append(allMeasuredValues, measuredValues...) | ||||
|  | ||||
| 	log.Println(len(allMeasuredValues)) | ||||
|  | ||||
| 	err = jl.Write(allMeasuredValues) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (jl *jsonLogfile) ReadHumidities() ([]*types.Humidity, error) { | ||||
| 	if _, err := os.Stat(jl.logfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, jl.logfile) | ||||
| func (jl *jsonLogfile) Read() ([]types.MeasuredValue, error) { | ||||
|  | ||||
| 	measuredValues := make([]types.MeasuredValue, 0) | ||||
|  | ||||
| 	humidityValues, err := jl.readHumidities() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	measuredValues = append(measuredValues, humidityValues...) | ||||
|  | ||||
| 	temperatureValues, err := jl.readTemperatures() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	measuredValues = append(measuredValues, temperatureValues...) | ||||
|  | ||||
| 	return measuredValues, nil | ||||
| } | ||||
|  | ||||
| func (jl *jsonLogfile) readHumidities() ([]types.MeasuredValue, error) { | ||||
|  | ||||
| 	if _, err := os.Stat(jl.cnf.Device.HumidityLogfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, jl.cnf.Device.HumidityLogfile) | ||||
| 	} | ||||
|  | ||||
| 	humidities := make([]*types.Humidity, 0) | ||||
|  | ||||
| 	f, err := os.Open(jl.logfile) | ||||
| 	f, err := os.Open(jl.cnf.Device.HumidityLogfile) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, jl.logfile) | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, jl.cnf.Device.HumidityLogfile) | ||||
|  | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| 	jsonDecoder := json.NewDecoder(f) | ||||
| 	err = jsonDecoder.Decode(&humidities) | ||||
| 	if err != nil { | ||||
| 	if err = json.NewDecoder(f).Decode(&humidities); err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileDecode, err) | ||||
| 	} | ||||
|  | ||||
| 	return humidities, nil | ||||
| 	measuredValues := make([]types.MeasuredValue, 0) | ||||
|  | ||||
| 	for _, humidity := range humidities { | ||||
| 		measuredValues = append(measuredValues, humidity) | ||||
| 	} | ||||
|  | ||||
| 	return measuredValues, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func (jl *jsonLogfile) ReadTemperatures() ([]*types.Temperature, error) { | ||||
| 	if _, err := os.Stat(jl.logfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, jl.logfile) | ||||
| func (jl *jsonLogfile) readTemperatures() ([]types.MeasuredValue, error) { | ||||
| 	if _, err := os.Stat(jl.cnf.Device.TemperatureLogfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, jl.cnf.Device.TemperatureLogfile) | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	temperatures := make([]*types.Temperature, 0) | ||||
|  | ||||
| 	f, err := os.Open(jl.logfile) | ||||
| 	f, err := os.Open(jl.cnf.Device.TemperatureLogfile) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, jl.logfile) | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, jl.cnf.Device.TemperatureLogfile) | ||||
|  | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| 	jsonDecoder := json.NewDecoder(f) | ||||
| 	err = jsonDecoder.Decode(&temperatures) | ||||
| 	if err != nil { | ||||
| 	if err := json.NewDecoder(f).Decode(&temperatures); err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileDecode, err) | ||||
| 	} | ||||
|  | ||||
| 	return temperatures, nil | ||||
| 	measuredValues := make([]types.MeasuredValue, 0) | ||||
|  | ||||
| 	for _, temperature := range temperatures { | ||||
| 		measuredValues = append(measuredValues, temperature) | ||||
| 	} | ||||
|  | ||||
| 	return measuredValues, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func (jl *jsonLogfile) WriteHumidities(humidities []*types.Humidity) error { | ||||
| func (jl *jsonLogfile) Write(measuredValues []types.MeasuredValue) error { | ||||
| 	humidities := make([]*types.Humidity, 0) | ||||
| 	temperatures := make([]*types.Temperature, 0) | ||||
|  | ||||
| 	f, err := os.Create(jl.logfile) | ||||
| 	for _, measuredValue := range measuredValues { | ||||
| 		switch v := measuredValue.(type) { | ||||
| 		case *types.Humidity: | ||||
| 			humidities = append(humidities, v) | ||||
| 		case *types.Temperature: | ||||
| 			temperatures = append(temperatures, v) | ||||
| 		default: | ||||
| 			return fmt.Errorf("%v", errorTypeSwitch) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	errorChannel := make(chan error, 0) | ||||
|  | ||||
| 	wg := new(sync.WaitGroup) | ||||
| 	wg.Add(2) | ||||
|  | ||||
| 	go jl.writeHumidities(humidities, errorChannel, wg) | ||||
| 	go jl.writeTemperatures(temperatures, errorChannel, wg) | ||||
|  | ||||
| 	wg.Wait() | ||||
|  | ||||
| 	errors := collect.Errors(errorChannel) | ||||
| 	if len(errors) > 0 { | ||||
| 		return prittyprint.FormatErrors(errors) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func (jl *jsonLogfile) writeHumidities(humidities []*types.Humidity, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	defer wg.Done() | ||||
|  | ||||
| 	f, err := os.Create(jl.cnf.Device.HumidityLogfile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileCreate, jl.logfile) | ||||
| 		errorChannel <- fmt.Errorf("%v: %v", errorLogfileCreate, jl.cnf.Device.HumidityLogfile) | ||||
| 		return | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| @@ -72,25 +166,28 @@ func (jl *jsonLogfile) WriteHumidities(humidities []*types.Humidity) error { | ||||
| 	jsonEncoder.SetIndent("", "  ") | ||||
| 	err = jsonEncoder.Encode(humidities) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileEncode, err) | ||||
| 		errorChannel <- fmt.Errorf("%v: %v", errorLogfileEncode, err) | ||||
| 		return | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (jl *jsonLogfile) WriteTemperatures(temperatures []*types.Temperature) error { | ||||
| 	f, err := os.Create(jl.logfile) | ||||
| func (jl *jsonLogfile) writeTemperatures(temperatures []*types.Temperature, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	defer wg.Done() | ||||
|  | ||||
| 	f, err := os.Create(jl.cnf.Device.TemperatureLogfile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileCreate, jl.logfile) | ||||
| 		errorChannel <- fmt.Errorf("%v: %v", errorLogfileCreate, jl.cnf.Device.TemperatureLogfile) | ||||
| 		return | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| 	writeCreationDate(temperatures) | ||||
| 	//writeCreationDate(temperatures) | ||||
|  | ||||
| 	jsonEncoder := json.NewEncoder(f) | ||||
| 	jsonEncoder.SetIndent("", "  ") | ||||
| 	err = jsonEncoder.Encode(temperatures) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileEncode, err) | ||||
| 		errorChannel <- fmt.Errorf("%v: %v", errorLogfileEncode, err) | ||||
| 		return | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -1,45 +1,39 @@ | ||||
| package logfile | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"regexp" | ||||
| 	"sort" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| 	"github.com/go-flucky/flucky/pkg/config" | ||||
| ) | ||||
|  | ||||
| var validUUID = regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$") | ||||
| var timeFormat = "2006-01-02 15:04:05.999999999 -0700" | ||||
| // var validUUID = regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$") | ||||
| // var timeFormat = "2006-01-02 15:04:05.999999999 -0700" | ||||
|  | ||||
| // AppendTemperatures with temperature values from a logfile. As additional | ||||
| // option it's possible to compress the temperature data. | ||||
| func AppendTemperatures(logfile Logfile, compression bool, temperatures []*types.Temperature) error { | ||||
| // // AppendTemperatures with temperature values from a logfile. As additional | ||||
| // // option it's possible to compress the temperature data. | ||||
| // func AppendTemperatures(logfile Logfile, compression bool, temperatures []*types.Temperature) error { | ||||
|  | ||||
| 	allTemperatures := make([]*types.Temperature, 0) | ||||
| // 	allTemperatures := make([]*types.Temperature, 0) | ||||
|  | ||||
| 	if _, err := os.Stat(logfile.GetLogfile()); err == nil { | ||||
| 		temperaturesFromLogfile, err := logfile.ReadTemperatures() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| // 	if _, err := os.Stat(logfile.GetLogfile()); err == nil { | ||||
| // 		temperaturesFromLogfile, err := logfile.ReadTemperatures() | ||||
| // 		if err != nil { | ||||
| // 			return err | ||||
| // 		} | ||||
|  | ||||
| 		allTemperatures = append(allTemperatures, temperaturesFromLogfile...) | ||||
| 	} | ||||
| // 		allTemperatures = append(allTemperatures, temperaturesFromLogfile...) | ||||
| // 	} | ||||
|  | ||||
| 	allTemperatures = append(allTemperatures, temperatures...) | ||||
| // 	allTemperatures = append(allTemperatures, temperatures...) | ||||
|  | ||||
| 	if compression { | ||||
| 		allTemperatures = CompressTemperature(allTemperatures) | ||||
| 	} | ||||
| // 	if compression { | ||||
| // 		allTemperatures = CompressTemperature(allTemperatures) | ||||
| // 	} | ||||
|  | ||||
| 	err := logfile.WriteTemperatures(allTemperatures) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| // 	err := logfile.WriteTemperatures(allTemperatures) | ||||
| // 	if err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| // CompressTemperature compresses the temperatures from an array. It is checked | ||||
| // whether the measured temperature of a value corresponds to that of the | ||||
| @@ -47,116 +41,118 @@ func AppendTemperatures(logfile Logfile, compression bool, temperatures []*types | ||||
| // validity date of the predecessor value is set to that of the current value. | ||||
| // No information is lost as a result. The validity period of the measured value | ||||
| // is thereby exclusively increased. | ||||
| func CompressTemperature(temperatures []*types.Temperature) []*types.Temperature { | ||||
| 	compressedTemperatures := make([]*types.Temperature, 0) | ||||
| 	lastTemperatureBySensors := make(map[string]*types.Temperature, 0) | ||||
| // func Compression(measuredValues []types) []*types.Temperature { | ||||
| // 	compressedTemperatures := make([]*types.Temperature, 0) | ||||
| // 	lastTemperatureBySensors := make(map[string]*types.Temperature, 0) | ||||
|  | ||||
| 	// Sort all measured temperatures beforehand by the starting validity date to | ||||
| 	// avoid errors when compressing the temperatures. | ||||
| 	SortTemperatures(temperatures) | ||||
| // 	// Sort all measured temperatures beforehand by the starting validity date to | ||||
| // 	// avoid errors when compressing the temperatures. | ||||
| // 	SortTemperatures(temperatures) | ||||
|  | ||||
| 	for _, temperature := range temperatures { | ||||
| 		if lastTemperatureBySensor, ok := lastTemperatureBySensors[temperature.SensorID]; ok { | ||||
| 			if lastTemperatureBySensor.TemperatureValue == temperature.TemperatureValue { | ||||
| // 	for _, temperature := range temperatures { | ||||
| // 		if lastTemperatureBySensor, ok := lastTemperatureBySensors[temperature.SensorID]; ok { | ||||
| // 			if lastTemperatureBySensor.TemperatureValue == temperature.TemperatureValue { | ||||
|  | ||||
| 				lastTemperatureBySensors[temperature.SensorID].TemperatureTillDate = temperature.TemperatureTillDate | ||||
| // 				lastTemperatureBySensors[temperature.SensorID].TemperatureTillDate = temperature.TemperatureTillDate | ||||
|  | ||||
| 				now := time.Now() | ||||
| 				lastTemperatureBySensors[temperature.SensorID].UpdateDate = &now | ||||
| 			} else { | ||||
| 				compressedTemperatures = append(compressedTemperatures, lastTemperatureBySensors[temperature.SensorID]) | ||||
| 				lastTemperatureBySensors[temperature.SensorID] = temperature | ||||
| 			} | ||||
| 		} else { | ||||
| 			lastTemperatureBySensors[temperature.SensorID] = temperature | ||||
| 		} | ||||
| 	} | ||||
| // 				now := time.Now() | ||||
| // 				lastTemperatureBySensors[temperature.SensorID].UpdateDate = &now | ||||
| // 			} else { | ||||
| // 				compressedTemperatures = append(compressedTemperatures, lastTemperatureBySensors[temperature.SensorID]) | ||||
| // 				lastTemperatureBySensors[temperature.SensorID] = temperature | ||||
| // 			} | ||||
| // 		} else { | ||||
| // 			lastTemperatureBySensors[temperature.SensorID] = temperature | ||||
| // 		} | ||||
| // 	} | ||||
|  | ||||
| 	// Copy all remaining entries from the map into the array | ||||
| 	for _, lastTemperatureBySensor := range lastTemperatureBySensors { | ||||
| 		compressedTemperatures = append(compressedTemperatures, lastTemperatureBySensor) | ||||
| 	} | ||||
| // 	// Copy all remaining entries from the map into the array | ||||
| // 	for _, lastTemperatureBySensor := range lastTemperatureBySensors { | ||||
| // 		compressedTemperatures = append(compressedTemperatures, lastTemperatureBySensor) | ||||
| // 	} | ||||
|  | ||||
| 	return compressedTemperatures | ||||
| } | ||||
| // 	return compressedTemperatures | ||||
| // } | ||||
|  | ||||
| // New returns a log file with basic functions for reading and writing data. The | ||||
| // file extension of the logfile is taken into account to format the logfile | ||||
| // into the correct format. | ||||
| func New(logfile string) Logfile { | ||||
| func New(cnf *config.Configuration) Logfile { | ||||
|  | ||||
| 	ext := filepath.Ext(logfile) | ||||
| 	// switch ext { | ||||
| 	// case ".csv": | ||||
| 	// 	return &csvLogfile{ | ||||
| 	// 		logfile: logfile, | ||||
| 	// 	} | ||||
| 	// case ".json": | ||||
| 	// 	return &jsonLogfile{ | ||||
| 	// 		cnf: cnf, | ||||
| 	// 	} | ||||
| 	// case ".xml": | ||||
| 	// 	return &xmlLogfile{ | ||||
| 	// 		logfile: logfile, | ||||
| 	// 	} | ||||
| 	// default: | ||||
| 	// 	return &jsonLogfile{ | ||||
| 	// 		logfile: logfile, | ||||
| 	// 	} | ||||
| 	// } | ||||
|  | ||||
| 	switch ext { | ||||
| 	case ".csv": | ||||
| 		return &csvLogfile{ | ||||
| 			logfile: logfile, | ||||
| 		} | ||||
| 	case ".json": | ||||
| 		return &jsonLogfile{ | ||||
| 			logfile: logfile, | ||||
| 		} | ||||
| 	case ".xml": | ||||
| 		return &xmlLogfile{ | ||||
| 			logfile: logfile, | ||||
| 		} | ||||
| 	default: | ||||
| 		return &jsonLogfile{ | ||||
| 			logfile: logfile, | ||||
| 		} | ||||
| 	return &jsonLogfile{ | ||||
| 		cnf: cnf, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SplittTemperatures into multiple arrays. The Size can be defined by | ||||
| // temperatureSplitBy parameter. | ||||
| func SplittTemperatures(temperatures []*types.Temperature, templeratureSplitBy int) [][]*types.Temperature { | ||||
| 	splittedTemperatures := make([][]*types.Temperature, 0) | ||||
| 	newTemperatures := make([]*types.Temperature, 0) | ||||
| 	for _, temperature := range temperatures { | ||||
| 		if len(newTemperatures) == templeratureSplitBy { | ||||
| 			splittedTemperatures = append(splittedTemperatures, newTemperatures) | ||||
| 			newTemperatures = make([]*types.Temperature, 0) | ||||
| 		} | ||||
| 		newTemperatures = append(newTemperatures, temperature) | ||||
| 	} | ||||
| 	splittedTemperatures = append(splittedTemperatures, newTemperatures) | ||||
| 	return splittedTemperatures | ||||
| } | ||||
| // // SplittTemperatures into multiple arrays. The Size can be defined by | ||||
| // // temperatureSplitBy parameter. | ||||
| // func SplittTemperatures(temperatures []*types.Temperature, templeratureSplitBy int) [][]*types.Temperature { | ||||
| // 	splittedTemperatures := make([][]*types.Temperature, 0) | ||||
| // 	newTemperatures := make([]*types.Temperature, 0) | ||||
| // 	for _, temperature := range temperatures { | ||||
| // 		if len(newTemperatures) == templeratureSplitBy { | ||||
| // 			splittedTemperatures = append(splittedTemperatures, newTemperatures) | ||||
| // 			newTemperatures = make([]*types.Temperature, 0) | ||||
| // 		} | ||||
| // 		newTemperatures = append(newTemperatures, temperature) | ||||
| // 	} | ||||
| // 	splittedTemperatures = append(splittedTemperatures, newTemperatures) | ||||
| // 	return splittedTemperatures | ||||
| // } | ||||
|  | ||||
| // SortTemperatures by TemperatureFromDate | ||||
| func SortTemperatures(temperatures []*types.Temperature) { | ||||
| 	sort.SliceStable(temperatures, func(i int, j int) bool { | ||||
| 		return temperatures[i].TemperatureFromDate.Before(temperatures[j].TemperatureFromDate) | ||||
| 	}) | ||||
| } | ||||
| // // SortTemperatures by TemperatureFromDate | ||||
| // func SortTemperatures(temperatures []*types.Temperature) { | ||||
| // 	sort.SliceStable(temperatures, func(i int, j int) bool { | ||||
| // 		return temperatures[i].TemperatureFromDate.Before(temperatures[j].TemperatureFromDate) | ||||
| // 	}) | ||||
| // } | ||||
|  | ||||
| // ValidateTemperatures Checks if the temperature data is valid. | ||||
| // - Check the temperature id (uuid) | ||||
| // - Checks whether the time specifications are historically in a sequence. | ||||
| // - Check the sensor id (uuid) | ||||
| func ValidateTemperatures(temperatures []*types.Temperature) error { | ||||
| 	for _, temperature := range temperatures { | ||||
| 		if !validUUID.MatchString(temperature.TemperatureID) { | ||||
| 			return errorNoValidTemperatureID | ||||
| 		} else if temperature.TemperatureValue == 0 { | ||||
| 			return errorNoValidMesuredValue | ||||
| 		} else if temperature.TemperatureFromDate.After(temperature.TemperatureTillDate) { | ||||
| 			return errorNoValidTimePeriods | ||||
| 		} else if !validUUID.MatchString(temperature.SensorID) { | ||||
| 			return errorNoValidSensorID | ||||
| 		} else if temperature.CreationDate.After(*temperature.UpdateDate) && temperature.UpdateDate != nil { | ||||
| 			return errorNoValidTimePeriods | ||||
| 		} | ||||
| 	} | ||||
| // // ValidateTemperatures Checks if the temperature data is valid. | ||||
| // // - Check the temperature id (uuid) | ||||
| // // - Checks whether the time specifications are historically in a sequence. | ||||
| // // - Check the sensor id (uuid) | ||||
| // func ValidateTemperatures(temperatures []*types.Temperature) error { | ||||
| // 	for _, temperature := range temperatures { | ||||
| // 		if !validUUID.MatchString(temperature.TemperatureID) { | ||||
| // 			return errorNoValidTemperatureID | ||||
| // 		} else if temperature.TemperatureValue == 0 { | ||||
| // 			return errorNoValidMesuredValue | ||||
| // 		} else if temperature.TemperatureFromDate.After(temperature.TemperatureTillDate) { | ||||
| // 			return errorNoValidTimePeriods | ||||
| // 		} else if !validUUID.MatchString(temperature.SensorID) { | ||||
| // 			return errorNoValidSensorID | ||||
| // 		} else if temperature.CreationDate.After(*temperature.UpdateDate) && temperature.UpdateDate != nil { | ||||
| // 			return errorNoValidTimePeriods | ||||
| // 		} | ||||
| // 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| func writeCreationDate(temperatures []*types.Temperature) { | ||||
| 	now := time.Now() | ||||
| 	for _, temperature := range temperatures { | ||||
| 		if temperature.CreationDate == nil { | ||||
| 			temperature.CreationDate = &now | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| // func writeCreationDate(temperatures []*types.Temperature) { | ||||
| // 	now := time.Now() | ||||
| // 	for _, temperature := range temperatures { | ||||
| // 		if temperature.CreationDate == nil { | ||||
| // 			temperature.CreationDate = &now | ||||
| // 		} | ||||
| // 	} | ||||
| // } | ||||
|   | ||||
| @@ -1,121 +1,112 @@ | ||||
| package logfile | ||||
|  | ||||
| import ( | ||||
| 	"encoding/xml" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| // type xmlLogfile struct { | ||||
| // 	logfile string | ||||
| // } | ||||
|  | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| ) | ||||
| // func (xl *xmlLogfile) GetLogfile() string { | ||||
| // 	return xl.logfile | ||||
| // } | ||||
|  | ||||
| type xmlLogfile struct { | ||||
| 	logfile string | ||||
| } | ||||
| // func (xl *xmlLogfile) ReadHumidities() ([]*types.Humidity, error) { | ||||
| // 	if _, err := os.Stat(xl.logfile); os.IsNotExist(err) { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, xl.logfile) | ||||
| // 	} | ||||
|  | ||||
| func (xl *xmlLogfile) GetLogfile() string { | ||||
| 	return xl.logfile | ||||
| } | ||||
| // 	humidities := make([]*types.Humidity, 0) | ||||
|  | ||||
| func (xl *xmlLogfile) ReadHumidities() ([]*types.Humidity, error) { | ||||
| 	if _, err := os.Stat(xl.logfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, xl.logfile) | ||||
| 	} | ||||
| // 	f, err := os.Open(xl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, xl.logfile) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| 	humidities := make([]*types.Humidity, 0) | ||||
| // 	xmlDecoder := xml.NewDecoder(f) | ||||
| // 	err = xmlDecoder.Decode(&humidities) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileDecode, err) | ||||
| // 	} | ||||
|  | ||||
| 	f, err := os.Open(xl.logfile) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, xl.logfile) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // 	return humidities, nil | ||||
| // } | ||||
|  | ||||
| 	xmlDecoder := xml.NewDecoder(f) | ||||
| 	err = xmlDecoder.Decode(&humidities) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileDecode, err) | ||||
| 	} | ||||
| // func (xl *xmlLogfile) ReadTemperatures() ([]*types.Temperature, error) { | ||||
| // 	if _, err := os.Stat(xl.logfile); os.IsNotExist(err) { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, xl.logfile) | ||||
| // 	} | ||||
|  | ||||
| 	return humidities, nil | ||||
| } | ||||
| // 	f, err := os.Open(xl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, xl.logfile) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| func (xl *xmlLogfile) ReadTemperatures() ([]*types.Temperature, error) { | ||||
| 	if _, err := os.Stat(xl.logfile); os.IsNotExist(err) { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileNotFound, xl.logfile) | ||||
| 	} | ||||
| // 	bytes, err := ioutil.ReadAll(f) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileRead, err) | ||||
| // 	} | ||||
|  | ||||
| 	f, err := os.Open(xl.logfile) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileOpen, xl.logfile) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // 	tmpTemperatures := new(Temperatures) | ||||
|  | ||||
| 	bytes, err := ioutil.ReadAll(f) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileRead, err) | ||||
| 	} | ||||
| // 	err = xml.Unmarshal(bytes, tmpTemperatures) | ||||
| // 	if err != nil { | ||||
| // 		return nil, fmt.Errorf("%v: %v", errorLogfileUnmarshal, err) | ||||
| // 	} | ||||
|  | ||||
| 	tmpTemperatures := new(Temperatures) | ||||
| // 	temperatures := make([]*types.Temperature, 0) | ||||
|  | ||||
| 	err = xml.Unmarshal(bytes, tmpTemperatures) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("%v: %v", errorLogfileUnmarshal, err) | ||||
| 	} | ||||
| // 	for _, tmpTemperature := range tmpTemperatures.Temperatures { | ||||
| // 		temperatures = append(temperatures, tmpTemperature.Temperature) | ||||
| // 	} | ||||
|  | ||||
| 	temperatures := make([]*types.Temperature, 0) | ||||
| // 	return temperatures, nil | ||||
| // } | ||||
|  | ||||
| 	for _, tmpTemperature := range tmpTemperatures.Temperatures { | ||||
| 		temperatures = append(temperatures, tmpTemperature.Temperature) | ||||
| 	} | ||||
| // func (xl *xmlLogfile) WriteHumidities(humidities []*types.Humidity) error { | ||||
|  | ||||
| 	return temperatures, nil | ||||
| } | ||||
| // 	f, err := os.Create(xl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return fmt.Errorf("%v: %v", errorLogfileCreate, xl.logfile) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| func (xl *xmlLogfile) WriteHumidities(humidities []*types.Humidity) error { | ||||
| // 	xmlEncoder := xml.NewEncoder(f) | ||||
| // 	xmlEncoder.Indent("", "  ") | ||||
| // 	err = xmlEncoder.Encode(humidities) | ||||
| // 	if err != nil { | ||||
| // 		return fmt.Errorf("%v: %v", errorLogfileEncode, err) | ||||
| // 	} | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| 	f, err := os.Create(xl.logfile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileCreate, xl.logfile) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // func (xl *xmlLogfile) WriteTemperatures(temperatures []*types.Temperature) error { | ||||
| // 	f, err := os.Create(xl.logfile) | ||||
| // 	if err != nil { | ||||
| // 		return fmt.Errorf("%v: %v", errorLogfileCreate, xl.logfile) | ||||
| // 	} | ||||
| // 	defer f.Close() | ||||
|  | ||||
| 	xmlEncoder := xml.NewEncoder(f) | ||||
| 	xmlEncoder.Indent("", "  ") | ||||
| 	err = xmlEncoder.Encode(humidities) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileEncode, err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| // 	writeCreationDate(temperatures) | ||||
|  | ||||
| func (xl *xmlLogfile) WriteTemperatures(temperatures []*types.Temperature) error { | ||||
| 	f, err := os.Create(xl.logfile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileCreate, xl.logfile) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| // 	tmpTemperatures := new(Temperatures) | ||||
|  | ||||
| 	writeCreationDate(temperatures) | ||||
| // 	for _, temperature := range temperatures { | ||||
| // 		tmpTemperature := &Temperature{ | ||||
| // 			Temperature: temperature, | ||||
| // 		} | ||||
|  | ||||
| 	tmpTemperatures := new(Temperatures) | ||||
| // 		tmpTemperatures.Temperatures = append(tmpTemperatures.Temperatures, tmpTemperature) | ||||
| // 	} | ||||
|  | ||||
| 	for _, temperature := range temperatures { | ||||
| 		tmpTemperature := &Temperature{ | ||||
| 			Temperature: temperature, | ||||
| 		} | ||||
| // 	bytes, err := xml.MarshalIndent(tmpTemperatures, "", "  ") | ||||
| // 	if err != nil { | ||||
| // 		return fmt.Errorf("%v: %v", errorLogfileMarshal, err) | ||||
| // 	} | ||||
|  | ||||
| 		tmpTemperatures.Temperatures = append(tmpTemperatures.Temperatures, tmpTemperature) | ||||
| 	} | ||||
| // 	_, err = f.Write(bytes) | ||||
| // 	if err != nil { | ||||
| // 		return fmt.Errorf("%v: %v", errorLogfileWrite, err) | ||||
| // 	} | ||||
|  | ||||
| 	bytes, err := xml.MarshalIndent(tmpTemperatures, "", "  ") | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileMarshal, err) | ||||
| 	} | ||||
|  | ||||
| 	_, err = f.Write(bytes) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("%v: %v", errorLogfileWrite, err) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| // 	return nil | ||||
| // } | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package sensor | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| @@ -22,8 +21,9 @@ func (s *DHT11) GetSensorModel() types.SensorModel { | ||||
| 	return s.Sensor.SensorModel | ||||
| } | ||||
|  | ||||
| // ReadHumidity measure the humidity | ||||
| func (s *DHT11) ReadHumidity(round float64) (*types.Humidity, error) { | ||||
| // Read measured values | ||||
| func (s *DHT11) Read() ([]types.MeasuredValue, error) { | ||||
|  | ||||
| 	err := dht.HostInit() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("HostInit error: %v", err) | ||||
| @@ -39,117 +39,59 @@ func (s *DHT11) ReadHumidity(round float64) (*types.Humidity, error) { | ||||
| 		return nil, fmt.Errorf("NewDHT error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	humidityValue, _, err := dht.Read() | ||||
| 	humidityValue, temperatureValue, err := dht.Read() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Read error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if round != 0 { | ||||
| 		humidityValue = math.Round(humidityValue/round) * round | ||||
| 	measuredValues := []types.MeasuredValue{ | ||||
| 		&types.Humidity{ | ||||
| 			HumidityID:       uuid.NewV4().String(), | ||||
| 			HumidityValue:    humidityValue, | ||||
| 			HumidityFromDate: time.Now(), | ||||
| 			HumidityTillDate: time.Now(), | ||||
| 			SensorID:         s.SensorID, | ||||
| 		}, | ||||
| 		&types.Temperature{ | ||||
| 			TemperatureID:       uuid.NewV4().String(), | ||||
| 			TemperatureValue:    temperatureValue, | ||||
| 			TemperatureFromDate: time.Now(), | ||||
| 			TemperatureTillDate: time.Now(), | ||||
| 			SensorID:            s.SensorID, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	humidity := &types.Humidity{ | ||||
| 		HumidityID:       uuid.NewV4().String(), | ||||
| 		HumidityValue:    humidityValue, | ||||
| 		HumidityFromDate: time.Now(), | ||||
| 		HumidityTillDate: time.Now(), | ||||
| 		SensorID:         s.SensorID, | ||||
| 	} | ||||
|  | ||||
| 	return humidity, nil | ||||
| 	return measuredValues, nil | ||||
| } | ||||
|  | ||||
| // ReadHumidityWriteIntoChannel and write values into a channel | ||||
| func (s *DHT11) ReadHumidityWriteIntoChannel(round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| // ReadChannel reads the measured values from the sensor and writes them to a | ||||
| // channel. | ||||
| func (s *DHT11) ReadChannel(measuredValueChannel chan<- types.MeasuredValue, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	if wg != nil { | ||||
| 		defer wg.Done() | ||||
| 	} | ||||
|  | ||||
| 	humidity, err := s.ReadHumidity(round) | ||||
| 	measuredValues, err := s.Read() | ||||
| 	if err != nil { | ||||
| 		errorChannel <- err | ||||
| 		return | ||||
| 	} | ||||
| 	humidityChannel <- humidity | ||||
|  | ||||
| 	for _, measuredValue := range measuredValues { | ||||
| 		measuredValueChannel <- measuredValue | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadHumidityContinously into a channel until context closed | ||||
| func (s *DHT11) ReadHumidityContinously(ctx context.Context, round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error) { | ||||
| // ReadContinously reads the measured values continously from the sensor and | ||||
| // writes them to a channel. | ||||
| func (s *DHT11) ReadContinously(ctx context.Context, measuredValueChannel 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.ReadHumidityWriteIntoChannel(round, humidityChannel, errorChannel, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadTemperature measure the temperature | ||||
| func (s *DHT11) ReadTemperature(degree types.TemperatureUnit, round float64) (*types.Temperature, error) { | ||||
| 	err := dht.HostInit() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("HostInit error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	gpio, err := types.GPIOToString(*s.GPIONumber) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	dht, err := dht.NewDHT(gpio, dht.Celsius, "") | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("NewDHT error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	_, temperatureValue, err := dht.Read() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Read error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Convert temperature degree | ||||
| 	temperatureValue = convertTemperatureMeasurementUnit(temperatureValue, types.TemperatureUnitCelsius, degree) | ||||
|  | ||||
| 	if round != 0 { | ||||
| 		temperatureValue = math.Round(temperatureValue/round) * round | ||||
| 	} | ||||
|  | ||||
| 	temperature := &types.Temperature{ | ||||
| 		TemperatureID:       uuid.NewV4().String(), | ||||
| 		TemperatureValue:    temperatureValue, | ||||
| 		TemperatureUnit:     degree, | ||||
| 		TemperatureFromDate: time.Now(), | ||||
| 		TemperatureTillDate: time.Now(), | ||||
| 		SensorID:            s.SensorID, | ||||
| 	} | ||||
|  | ||||
| 	return temperature, nil | ||||
| } | ||||
|  | ||||
| // ReadTemperatureWriteIntoChannel and write values into a channel | ||||
| func (s *DHT11) ReadTemperatureWriteIntoChannel(degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	if wg != nil { | ||||
| 		defer wg.Done() | ||||
| 	} | ||||
|  | ||||
| 	temperature, err := s.ReadTemperature(degree, round) | ||||
| 	if err != nil { | ||||
| 		errorChannel <- err | ||||
| 		return | ||||
| 	} | ||||
| 	temperatureChannel <- temperature | ||||
| } | ||||
|  | ||||
| // ReadTemperatureContinously into a channel until context closed | ||||
| func (s *DHT11) ReadTemperatureContinously(ctx context.Context, degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error) { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-ctx.Done(): | ||||
| 			errorChannel <- fmt.Errorf("%v: Context closed: %v", s.SensorName, ctx.Err()) | ||||
| 			return | ||||
| 		default: | ||||
| 			s.ReadTemperatureWriteIntoChannel(degree, round, temperatureChannel, errorChannel, nil) | ||||
| 			s.ReadChannel(measuredValueChannel, errorChannel, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package sensor | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| @@ -22,8 +21,9 @@ func (s *DHT22) GetSensorModel() types.SensorModel { | ||||
| 	return s.Sensor.SensorModel | ||||
| } | ||||
|  | ||||
| // ReadHumidity measure the humidity | ||||
| func (s *DHT22) ReadHumidity(round float64) (*types.Humidity, error) { | ||||
| // Read measured values | ||||
| func (s *DHT22) Read() ([]types.MeasuredValue, error) { | ||||
|  | ||||
| 	err := dht.HostInit() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("HostInit error: %v", err) | ||||
| @@ -39,118 +39,59 @@ func (s *DHT22) ReadHumidity(round float64) (*types.Humidity, error) { | ||||
| 		return nil, fmt.Errorf("NewDHT error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	humidityValue, _, err := dht.Read() | ||||
| 	humidityValue, temperatureValue, err := dht.Read() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Read error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if round != 0 { | ||||
| 		humidityValue = math.Round(humidityValue/round) * round | ||||
| 	measuredValues := []types.MeasuredValue{ | ||||
| 		&types.Humidity{ | ||||
| 			HumidityID:       uuid.NewV4().String(), | ||||
| 			HumidityValue:    humidityValue, | ||||
| 			HumidityFromDate: time.Now(), | ||||
| 			HumidityTillDate: time.Now(), | ||||
| 			SensorID:         s.SensorID, | ||||
| 		}, | ||||
| 		&types.Temperature{ | ||||
| 			TemperatureID:       uuid.NewV4().String(), | ||||
| 			TemperatureValue:    temperatureValue, | ||||
| 			TemperatureFromDate: time.Now(), | ||||
| 			TemperatureTillDate: time.Now(), | ||||
| 			SensorID:            s.SensorID, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	humidity := &types.Humidity{ | ||||
| 		HumidityID:       uuid.NewV4().String(), | ||||
| 		HumidityValue:    humidityValue, | ||||
| 		HumidityFromDate: time.Now(), | ||||
| 		HumidityTillDate: time.Now(), | ||||
| 		SensorID:         s.SensorID, | ||||
| 	} | ||||
|  | ||||
| 	return humidity, nil | ||||
| 	return measuredValues, nil | ||||
| } | ||||
|  | ||||
| // ReadHumidityWriteIntoChannel and write values into a channel | ||||
| func (s *DHT22) ReadHumidityWriteIntoChannel(round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| // ReadChannel reads the measured values from the sensor and writes them to a | ||||
| // channel. | ||||
| func (s *DHT22) ReadChannel(measuredValueChannel chan<- types.MeasuredValue, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	if wg != nil { | ||||
| 		defer wg.Done() | ||||
| 	} | ||||
|  | ||||
| 	humidity, err := s.ReadHumidity(round) | ||||
| 	measuredValues, err := s.Read() | ||||
| 	if err != nil { | ||||
| 		errorChannel <- err | ||||
| 		return | ||||
| 	} | ||||
| 	humidityChannel <- humidity | ||||
|  | ||||
| 	for _, measuredValue := range measuredValues { | ||||
| 		measuredValueChannel <- measuredValue | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadHumidityContinously into a channel until context closed | ||||
| func (s *DHT22) ReadHumidityContinously(ctx context.Context, round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error) { | ||||
| // ReadContinously reads the measured values continously from the sensor and | ||||
| // writes them to a channel. | ||||
| func (s *DHT22) ReadContinously(ctx context.Context, measuredValueChannel 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.ReadHumidityWriteIntoChannel(round, humidityChannel, errorChannel, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadTemperature measure the temperature | ||||
| func (s *DHT22) ReadTemperature(degree types.TemperatureUnit, round float64) (*types.Temperature, error) { | ||||
| 	err := dht.HostInit() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("HostInit error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	gpio, err := types.GPIOToString(*s.GPIONumber) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	dht, err := dht.NewDHT(gpio, dht.Celsius, "") | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("NewDHT error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	_, temperatureValue, err := dht.Read() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Read error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Convert temperature degree | ||||
| 	temperatureValue = convertTemperatureMeasurementUnit(temperatureValue, types.TemperatureUnitCelsius, degree) | ||||
|  | ||||
| 	// round | ||||
| 	if round != 0 { | ||||
| 		temperatureValue = math.Round(temperatureValue/round) * round | ||||
| 	} | ||||
|  | ||||
| 	temperature := &types.Temperature{ | ||||
| 		TemperatureID:       uuid.NewV4().String(), | ||||
| 		TemperatureValue:    temperatureValue, | ||||
| 		TemperatureUnit:     degree, | ||||
| 		TemperatureFromDate: time.Now(), | ||||
| 		TemperatureTillDate: time.Now(), | ||||
| 		SensorID:            s.SensorID, | ||||
| 	} | ||||
|  | ||||
| 	return temperature, nil | ||||
| } | ||||
|  | ||||
| // ReadTemperatureWriteIntoChannel and write values into a channel | ||||
| func (s *DHT22) ReadTemperatureWriteIntoChannel(degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	if wg != nil { | ||||
| 		defer wg.Done() | ||||
| 	} | ||||
|  | ||||
| 	temperature, err := s.ReadTemperature(degree, round) | ||||
| 	if err != nil { | ||||
| 		errorChannel <- err | ||||
| 		return | ||||
| 	} | ||||
| 	temperatureChannel <- temperature | ||||
| } | ||||
|  | ||||
| // ReadTemperatureContinously into a channel until context closed | ||||
| func (s *DHT22) ReadTemperatureContinously(ctx context.Context, degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error) { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-ctx.Done(): | ||||
| 			errorChannel <- fmt.Errorf("%v: Context closed: %v", s.SensorName, ctx.Err()) | ||||
| 			return | ||||
| 		default: | ||||
| 			s.ReadTemperatureWriteIntoChannel(degree, round, temperatureChannel, errorChannel, nil) | ||||
| 			s.ReadChannel(measuredValueChannel, errorChannel, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"math" | ||||
| 	"path/filepath" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| @@ -25,13 +24,8 @@ func (s *DS18B20) GetSensorModel() types.SensorModel { | ||||
| 	return s.Sensor.SensorModel | ||||
| } | ||||
|  | ||||
| // GetSensor return the sensor struct | ||||
| func (s *DS18B20) GetSensor() *types.Sensor { | ||||
| 	return s.Sensor | ||||
| } | ||||
|  | ||||
| // ReadTemperature measure the temperature | ||||
| func (s *DS18B20) ReadTemperature(degree types.TemperatureUnit, round float64) (*types.Temperature, error) { | ||||
| // Read measured values | ||||
| func (s *DS18B20) Read() ([]types.MeasuredValue, error) { | ||||
|  | ||||
| 	data, err := ioutil.ReadFile(filepath.Join("/sys/bus/w1/devices", *s.WireID, "/w1_slave")) | ||||
| 	if err != nil { | ||||
| @@ -52,50 +46,49 @@ func (s *DS18B20) ReadTemperature(degree types.TemperatureUnit, round float64) ( | ||||
|  | ||||
| 	temperatureValue := c / 1000 | ||||
|  | ||||
| 	// Convert temperature degree | ||||
| 	temperatureValue = convertTemperatureMeasurementUnit(temperatureValue, types.TemperatureUnitCelsius, degree) | ||||
|  | ||||
| 	// round | ||||
| 	if round != 0 { | ||||
| 		temperatureValue = math.Round(temperatureValue/round) * round | ||||
| 	measuredValues := []types.MeasuredValue{ | ||||
| 		&types.Temperature{ | ||||
| 			TemperatureID:       uuid.NewV4().String(), | ||||
| 			TemperatureValue:    temperatureValue, | ||||
| 			TemperatureFromDate: time.Now(), | ||||
| 			TemperatureTillDate: time.Now(), | ||||
| 			SensorID:            s.SensorID, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	temperature := &types.Temperature{ | ||||
| 		TemperatureID:       uuid.NewV4().String(), | ||||
| 		TemperatureValue:    temperatureValue, | ||||
| 		TemperatureUnit:     degree, | ||||
| 		TemperatureFromDate: time.Now(), | ||||
| 		TemperatureTillDate: time.Now(), | ||||
| 		SensorID:            s.SensorID, | ||||
| 	} | ||||
|  | ||||
| 	return temperature, nil | ||||
| 	return measuredValues, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| // ReadTemperatureWriteIntoChannel and write values into a channel | ||||
| func (s *DS18B20) ReadTemperatureWriteIntoChannel(degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| // ReadChannel reads the measured values from the sensor and writes them to a | ||||
| // channel. | ||||
| func (s *DS18B20) ReadChannel(measuredValueChannel chan<- types.MeasuredValue, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	if wg != nil { | ||||
| 		defer wg.Done() | ||||
| 	} | ||||
|  | ||||
| 	temperature, err := s.ReadTemperature(degree, round) | ||||
| 	measuredValues, err := s.Read() | ||||
| 	if err != nil { | ||||
| 		errorChannel <- err | ||||
| 		return | ||||
| 	} | ||||
| 	temperatureChannel <- temperature | ||||
|  | ||||
| 	for _, measuredValue := range measuredValues { | ||||
| 		measuredValueChannel <- measuredValue | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| // ReadTemperatureContinously into a channel until context closed | ||||
| func (s *DS18B20) ReadTemperatureContinously(ctx context.Context, degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error) { | ||||
| // ReadContinously reads the measured values continously from the sensor and | ||||
| // writes them to a channel. | ||||
| func (s *DS18B20) ReadContinously(ctx context.Context, measuredValueChannel 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.ReadTemperatureWriteIntoChannel(degree, round, temperatureChannel, errorChannel, nil) | ||||
| 			s.ReadChannel(measuredValueChannel, errorChannel, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -7,18 +7,9 @@ import ( | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| ) | ||||
|  | ||||
| // HumiditySensor is a interface to describe required functions to measure humidities | ||||
| type HumiditySensor interface { | ||||
| type Sensor interface { | ||||
| 	GetSensorModel() types.SensorModel | ||||
| 	ReadHumidity(round float64) (*types.Humidity, error) | ||||
| 	ReadHumidityWriteIntoChannel(round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error, wg *sync.WaitGroup) | ||||
| 	ReadHumidityContinously(ctx context.Context, round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error) | ||||
| } | ||||
|  | ||||
| // TemperatureSensor is a interface to describe required functions to measure temperatures | ||||
| type TemperatureSensor interface { | ||||
| 	GetSensorModel() types.SensorModel | ||||
| 	ReadTemperature(degree types.TemperatureUnit, round float64) (*types.Temperature, error) | ||||
| 	ReadTemperatureWriteIntoChannel(degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error, wg *sync.WaitGroup) | ||||
| 	ReadTemperatureContinously(ctx context.Context, degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error) | ||||
| 	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) | ||||
| } | ||||
|   | ||||
| @@ -10,16 +10,16 @@ import ( | ||||
| 	"github.com/go-flucky/flucky/pkg/types" | ||||
| ) | ||||
|  | ||||
| // ReadHumidities returns a list of measured humidities by humidity sensors | ||||
| func ReadHumidities(humiditySensors []HumiditySensor, round float64) ([]*types.Humidity, error) { | ||||
| 	humidityChannel := make(chan *types.Humidity, len(humiditySensors)) | ||||
| 	errorChannel := make(chan error, len(humiditySensors)) | ||||
| // Read measured values from sensors | ||||
| func Read(ctx context.Context, sensors []Sensor) ([]types.MeasuredValue, error) { | ||||
| 	measuredValueChannel := make(chan types.MeasuredValue, len(sensors)) | ||||
| 	errorChannel := make(chan error, len(sensors)) | ||||
|  | ||||
| 	wg := new(sync.WaitGroup) | ||||
| 	wg.Add(len(humiditySensors)) | ||||
| 	wg.Add(len(sensors)) | ||||
|  | ||||
| 	for _, humiditySensor := range humiditySensors { | ||||
| 		go humiditySensor.ReadHumidityWriteIntoChannel(round, humidityChannel, errorChannel, wg) | ||||
| 	for _, sensor := range sensors { | ||||
| 		go sensor.ReadContinously(ctx, measuredValueChannel, errorChannel) | ||||
| 	} | ||||
|  | ||||
| 	wg.Wait() | ||||
| @@ -29,132 +29,29 @@ func ReadHumidities(humiditySensors []HumiditySensor, round float64) ([]*types.H | ||||
| 		return nil, prittyprint.FormatErrors(errors) | ||||
| 	} | ||||
|  | ||||
| 	humidities := collect.Humidities(humidityChannel) | ||||
| 	measuredValues := collect.MeasuredValues(measuredValueChannel) | ||||
|  | ||||
| 	return humidities, nil | ||||
| 	return measuredValues, nil | ||||
| } | ||||
|  | ||||
| // ReadHumiditiesWriteIntoChannel reads the humidity values of humidity sensors and writes them into a channel | ||||
| func ReadHumiditiesWriteIntoChannel(ctx context.Context, humiditySensors []HumiditySensor, round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	for _, humiditySensor := range humiditySensors { | ||||
| 		humiditySensor.ReadHumidityWriteIntoChannel(round, humidityChannel, errorChannel, wg) | ||||
| // 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 *sync.WaitGroup) { | ||||
| 	for _, sensor := range sensors { | ||||
| 		sensor.ReadChannel(measuredValueChannel, errorChannel, wg) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadHumiditiesContinuously reads the humidity values of humidity sensors continuously and writes them into a channel | ||||
| func ReadHumiditiesContinuously(ctx context.Context, humiditySensors []HumiditySensor, round float64, humidityChannel chan<- *types.Humidity, errorChannel chan<- error) { | ||||
| // 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) { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-ctx.Done(): | ||||
| 			errorChannel <- fmt.Errorf("Context closed: %v", ctx.Err()) | ||||
| 			return | ||||
| 		default: | ||||
| 			ReadHumiditiesWriteIntoChannel(ctx, humiditySensors, round, humidityChannel, errorChannel, nil) | ||||
| 			ReadChannel(ctx, sensors, measuredValueChannel, errorChannel, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadTemperatures returns a list of measured temperatures by temperature sensors | ||||
| func ReadTemperatures(temperatureSensors []TemperatureSensor, degree types.TemperatureUnit, round float64) ([]*types.Temperature, error) { | ||||
| 	temperatureChannel := make(chan *types.Temperature, len(temperatureSensors)) | ||||
| 	errorChannel := make(chan error, len(temperatureSensors)) | ||||
|  | ||||
| 	wg := new(sync.WaitGroup) | ||||
| 	wg.Add(len(temperatureSensors)) | ||||
|  | ||||
| 	for _, temperatureSensor := range temperatureSensors { | ||||
| 		go temperatureSensor.ReadTemperatureWriteIntoChannel(degree, round, temperatureChannel, errorChannel, wg) | ||||
| 	} | ||||
|  | ||||
| 	wg.Wait() | ||||
|  | ||||
| 	errors := collect.Errors(errorChannel) | ||||
| 	if len(errors) > 0 { | ||||
| 		return nil, prittyprint.FormatErrors(errors) | ||||
| 	} | ||||
|  | ||||
| 	temperatures := collect.Temperatures(temperatureChannel) | ||||
|  | ||||
| 	return temperatures, nil | ||||
| } | ||||
|  | ||||
| // ReadTemperaturesWriteIntoChannel reads the temperature values of temperature sensors and writes them into a channel | ||||
| func ReadTemperaturesWriteIntoChannel(ctx context.Context, temperatureSensors []TemperatureSensor, degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error, wg *sync.WaitGroup) { | ||||
| 	for _, temperatureSensor := range temperatureSensors { | ||||
| 		temperatureSensor.ReadTemperatureWriteIntoChannel(degree, round, temperatureChannel, errorChannel, wg) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadTemperaturesContinuously reads the temperature values of temperature sensors continuously and writes them into a chann | ||||
| func ReadTemperaturesContinuously(ctx context.Context, temperatureSensors []TemperatureSensor, degree types.TemperatureUnit, round float64, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error) { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-ctx.Done(): | ||||
| 			errorChannel <- fmt.Errorf("Context closed: %v", ctx.Err()) | ||||
| 			return | ||||
| 		default: | ||||
| 			ReadTemperaturesWriteIntoChannel(ctx, temperatureSensors, degree, round, temperatureChannel, errorChannel, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func convertTemperatureMeasurementUnit(value float64, fromDegree types.TemperatureUnit, toDegree types.TemperatureUnit) float64 { | ||||
|  | ||||
| 	switch fromDegree { | ||||
| 	// Celsius | ||||
| 	case types.TemperatureUnitCelsius: | ||||
| 		switch toDegree { | ||||
| 		// Celsius -> Celsius | ||||
| 		case types.TemperatureUnitCelsius: | ||||
| 			return value | ||||
| 		// Celsius -> Fahrenheit | ||||
| 		case types.TemperatureUnitFahrenheit: | ||||
| 			return (value * 9 / 5) + 32 | ||||
| 		// Celsius -> Kelvin | ||||
| 		case types.TemperatureUnitKelvin: | ||||
| 			return value + 273.15 | ||||
| 		} | ||||
|  | ||||
| 		// Fahrenheit | ||||
| 	case types.TemperatureUnitFahrenheit: | ||||
| 		switch toDegree { | ||||
| 		// Fahrenheit -> Celsius | ||||
| 		case types.TemperatureUnitCelsius: | ||||
| 			return (value - 32) * 5 / 9 | ||||
| 		// Fahrenheit -> Fahrenheit | ||||
| 		case types.TemperatureUnitFahrenheit: | ||||
| 			return value | ||||
| 		// Fahrenheit -> Kelvin | ||||
| 		case types.TemperatureUnitKelvin: | ||||
| 			return (value-32)*5/9 + 273.15 | ||||
| 		} | ||||
|  | ||||
| 	case types.TemperatureUnitKelvin: | ||||
| 		switch toDegree { | ||||
| 		// Kelvin -> Celsius | ||||
| 		case types.TemperatureUnitCelsius: | ||||
| 			return value - 273.15 | ||||
| 		// Kelvin -> Fahrenheit | ||||
| 		case types.TemperatureUnitFahrenheit: | ||||
| 			return (value-273.15)*9/5 + 32 | ||||
| 		// Kevin -> Kelvin | ||||
| 		case types.TemperatureUnitKelvin: | ||||
| 			return value | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return value | ||||
| } | ||||
|  | ||||
| func SelectTemperatureMeasurementUnit(unit string) (types.TemperatureUnit, error) { | ||||
| 	switch unit { | ||||
| 	case "celsius": | ||||
| 		return types.TemperatureUnitCelsius, nil | ||||
| 	case "fahrenheit": | ||||
| 		return types.TemperatureUnitFahrenheit, nil | ||||
| 	case "kelvin": | ||||
| 		return types.TemperatureUnitKelvin, nil | ||||
| 	default: | ||||
| 		return "", fmt.Errorf("Can not determine temperature measurement unit") | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -12,3 +12,15 @@ type Humidity struct { | ||||
| 	CreationDate     *time.Time `json:"creation_date" xml:"creation_date"` | ||||
| 	UpdateDate       *time.Time `json:"update_date" xml:"update_date"` | ||||
| } | ||||
|  | ||||
| func (h *Humidity) GetID() string { | ||||
| 	return h.HumidityID | ||||
| } | ||||
|  | ||||
| func (h *Humidity) GetSensorID() string { | ||||
| 	return h.SensorID | ||||
| } | ||||
|  | ||||
| func (h *Humidity) GetValue() float64 { | ||||
| 	return h.HumidityValue | ||||
| } | ||||
|   | ||||
							
								
								
									
										7
									
								
								pkg/types/measuredValue.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkg/types/measuredValue.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| package types | ||||
|  | ||||
| type MeasuredValue interface { | ||||
| 	GetID() string | ||||
| 	GetSensorID() string | ||||
| 	GetValue() float64 | ||||
| } | ||||
| @@ -1,31 +1,26 @@ | ||||
| package types | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
| ) | ||||
| import "time" | ||||
|  | ||||
| // Temperature ... | ||||
| type Temperature struct { | ||||
| 	TemperatureID       string          `json:"temperature_id" xml:"temperature_id"` | ||||
| 	TemperatureValue    float64         `json:"temperature_value,string" xml:"temperature_value,string"` | ||||
| 	TemperatureUnit     TemperatureUnit `json:"temperature_unit" xml:"temperature_unit"` | ||||
| 	TemperatureFromDate time.Time       `json:"temperature_from_date" xml:"temperature_from_date"` | ||||
| 	TemperatureTillDate time.Time       `json:"temperature_till_date" xml:"temperature_till_date"` | ||||
| 	SensorID            string          `json:"sensor_id" xml:"sensor_id"` | ||||
| 	CreationDate        *time.Time      `json:"creation_date" xml:"creation_date"` | ||||
| 	UpdateDate          *time.Time      `json:"update_date" xml:"update_date"` | ||||
| 	TemperatureID       string     `json:"temperature_id" xml:"temperature_id"` | ||||
| 	TemperatureValue    float64    `json:"temperature_value,string" xml:"temperature_value,string"` | ||||
| 	TemperatureFromDate time.Time  `json:"temperature_from_date" xml:"temperature_from_date"` | ||||
| 	TemperatureTillDate time.Time  `json:"temperature_till_date" xml:"temperature_till_date"` | ||||
| 	SensorID            string     `json:"sensor_id" xml:"sensor_id"` | ||||
| 	CreationDate        *time.Time `json:"creation_date" xml:"creation_date"` | ||||
| 	UpdateDate          *time.Time `json:"update_date" xml:"update_date"` | ||||
| } | ||||
|  | ||||
| // TemperatureUnit of measurement for temperature | ||||
| type TemperatureUnit string | ||||
| func (t *Temperature) GetID() string { | ||||
| 	return t.TemperatureID | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	// TemperatureUnitCelsius indicates the temperature in Celsius | ||||
| 	TemperatureUnitCelsius TemperatureUnit = "celsius" | ||||
| func (t *Temperature) GetSensorID() string { | ||||
| 	return t.SensorID | ||||
| } | ||||
|  | ||||
| 	// TemperatureUnitFahrenheit indicates the temperature in Fahrenheit | ||||
| 	TemperatureUnitFahrenheit = "fahrenheit" | ||||
|  | ||||
| 	// TemperatureUnitKelvin indicates the temperature in Kelvin | ||||
| 	TemperatureUnitKelvin = "kelvin" | ||||
| ) | ||||
| func (t *Temperature) GetValue() float64 { | ||||
| 	return t.TemperatureValue | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user