package main import ( "database/sql" "errors" "log" "time" ) type HistoryEntry struct { Date int64 GreenEnergyPercentage float32 PolledSmartEnergySummation float32 } type History []HistoryEntry func (config *Config) updateHistory() { greenEnergyPercentage, err := config.historyAverageAndConvertToGreen(config.Sensors.FossilPercentage, time.Now()) if err != nil { return } historyPolledSmartEnergySummation, err := config.historyDelta(config.Sensors.PolledSmartEnergySummation, time.Now()) if err != nil { return } _, err = config.db.Exec("INSERT OR REPLACE INTO cache(time,green_energy_percentage,energy_consumption) VALUES (?,?,?);", dayStart(time.Now()).Unix(), greenEnergyPercentage.Value, historyPolledSmartEnergySummation.Value) if err != nil { log.Println("Error inserting into cache", err.Error()) } cached, err := config.readHistory() if err != nil { return } if len(cached) != 8 && time.Since(config.HomeAssistant.InstallationDate) > 8*time.Hour*24 { err := config.refreshCacheFromPast(time.Now().Add(-8 * time.Hour * 24)) if err != nil { log.Println("Error refreshing cache", err.Error()) return } } } func (config *Config) refreshCacheFromInstall() error { return config.refreshCacheFromPast(config.HomeAssistant.InstallationDate) } var errNoInstallDate = errors.New("installation date not set") func (config *Config) refreshCacheFromPast(pastTime time.Time) error { // in order to avoid querying and storing each day's data from 0001-01-01 in future versions if config.HomeAssistant.InstallationDate.IsZero() { return errNoInstallDate } greenEnergyPercentage, err := config.historyBulkAverageAndConvertToGreen(config.Sensors.FossilPercentage, pastTime, time.Now()) if err != nil { return err } historyPolledSmartEnergySummation, err := config.historyBulkDelta(config.Sensors.PolledSmartEnergySummation, pastTime, time.Now()) if err != nil { return err } stmtReplace, err := config.db.Prepare("INSERT OR REPLACE INTO cache(time, green_energy_percentage, energy_consumption) values(?,?,?)") if err != nil { return err } defer stmtReplace.Close() stmtIgnore, err := config.db.Prepare("INSERT OR IGNORE INTO cache(time, green_energy_percentage, energy_consumption) values(?,?,?)") if err != nil { return err } defer stmtIgnore.Close() for key, day := range greenEnergyPercentage { var stmt *sql.Stmt if greenEnergyPercentage[key].Value != 0 && historyPolledSmartEnergySummation[key].Value != 0 { stmt = stmtReplace } else { stmt = stmtIgnore } _, err = stmt.Exec(day.DayTime.Unix(), greenEnergyPercentage[key].Value, historyPolledSmartEnergySummation[key].Value) if err != nil { return err } } return nil } func (config *Config) readHistory() (History, error) { start := dayStart(time.Now()).AddDate(0, 0, -8) rows, err := config.db.Query("SELECT time, green_energy_percentage, energy_consumption FROM cache WHERE time > ?", start.Unix()) if err != nil { return History{}, err } defer rows.Close() var ret History for rows.Next() { var ( date int64 greenEnergyPercentage float32 polledSmartEnergyConsumption float32 ) err = rows.Scan(&date, &greenEnergyPercentage, &polledSmartEnergyConsumption) if err != nil { return History{}, err } ret = append(ret, HistoryEntry{date, greenEnergyPercentage, polledSmartEnergyConsumption}) } if rows.Err() != nil { return History{}, rows.Err() } return ret, nil }