package logfile import ( "path/filepath" "time" ) // 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 = time.RFC3339 // // 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) // if _, err := os.Stat(logfile.GetLogfile()); err == nil { // temperaturesFromLogfile, err := logfile.ReadTemperatures() // if err != nil { // return err // } // allTemperatures = append(allTemperatures, temperaturesFromLogfile...) // } // allTemperatures = append(allTemperatures, temperatures...) // if compression { // allTemperatures = CompressTemperature(allTemperatures) // } // 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 // predecessor. If this is the case, the current value is discarded and the // 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 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) // for _, temperature := range temperatures { // if lastTemperatureBySensor, ok := lastTemperatureBySensors[temperature.SensorID]; ok { // if lastTemperatureBySensor.TemperatureValue == temperature.TemperatureValue { // 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 // } // } // // Copy all remaining entries from the map into the array // for _, lastTemperatureBySensor := range lastTemperatureBySensors { // compressedTemperatures = append(compressedTemperatures, lastTemperatureBySensor) // } // 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 { ext := filepath.Join(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, } } } // // 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) // }) // } // // 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 // } // func writeCreationDate(temperatures []*types.Temperature) { // now := time.Now() // for _, temperature := range temperatures { // if temperature.CreationDate == nil { // temperature.CreationDate = &now // } // } // }