forked from massivebox/ecodash
SQLite Initial Implementation
This is the first, most basic implementation of a SQLite database for caching. Future commits will make it much more optimized and able to efficiently store data for periods longer than 8 days.
This commit is contained in:
parent
6dc8fa3750
commit
e9125b783c
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
config.json
|
config.json
|
||||||
cache.json
|
cache.json
|
||||||
go.sum
|
go.sum
|
||||||
.idea
|
.idea
|
||||||
|
database.db
|
60
cache.go
60
cache.go
|
@ -1,18 +1,16 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CacheEntry struct {
|
type CacheEntry struct {
|
||||||
Date string `json:"date""`
|
Date int64
|
||||||
GreenEnergyPercentage float32 `json:"green_energy_percentage"`
|
GreenEnergyPercentage float32
|
||||||
PolledSmartEnergySummation float32 `json:"polled_smart_energy_summation"`
|
PolledSmartEnergySummation float32
|
||||||
}
|
}
|
||||||
type CacheFile []CacheEntry
|
type CacheData []CacheEntry
|
||||||
|
|
||||||
func (config Config) updateCache() {
|
func (config Config) updateCache() {
|
||||||
|
|
||||||
|
@ -36,37 +34,41 @@ func (config Config) updateCache() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var cacheEntries []CacheEntry
|
_, err = config.db.Exec("DELETE FROM cache")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error deleting previous records to cache: -", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for key, day := range greenEnergyPercentage {
|
for key, day := range greenEnergyPercentage {
|
||||||
cacheEntries = append(cacheEntries, CacheEntry{
|
_, err := config.db.Exec("INSERT INTO cache(time,green_energy_percentage,energy_consumption) VALUES (?,?,?);", day.DayTime.Unix(), greenEnergyPercentage[key].Value, historyPolledSmartEnergySummation[key].Value)
|
||||||
Date: day.DayTime.Format("02/01"),
|
if err != nil {
|
||||||
GreenEnergyPercentage: greenEnergyPercentage[key].Value,
|
fmt.Println("Error adding record to cache: -", err.Error())
|
||||||
PolledSmartEnergySummation: historyPolledSmartEnergySummation[key].Value,
|
return
|
||||||
})
|
}
|
||||||
}
|
|
||||||
|
|
||||||
out, _ := json.Marshal(cacheEntries)
|
|
||||||
|
|
||||||
err = os.WriteFile("cache.json", out, 0666)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error saving cached data to file -" + err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func readCache() (CacheFile, error) {
|
func (config Config) readCache() (CacheData, error) {
|
||||||
|
|
||||||
data, err := os.ReadFile("cache.json")
|
rows, err := config.db.Query("SELECT time, green_energy_percentage, energy_consumption FROM cache")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return CacheFile{}, err
|
return CacheData{}, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var ret CacheData
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var (
|
||||||
|
date int64
|
||||||
|
greenEnergyPercentage float32
|
||||||
|
polledSmartEnergyConsumption float32
|
||||||
|
)
|
||||||
|
err = rows.Scan(&date, &greenEnergyPercentage, &polledSmartEnergyConsumption)
|
||||||
|
ret = append(ret, CacheEntry{date, greenEnergyPercentage, polledSmartEnergyConsumption})
|
||||||
}
|
}
|
||||||
|
|
||||||
var cache CacheFile
|
return ret, nil
|
||||||
err = json.Unmarshal(data, &cache)
|
|
||||||
if err != nil {
|
|
||||||
return CacheFile{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return cache, nil
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
19
config.go
19
config.go
|
@ -2,10 +2,12 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -13,6 +15,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
db *sql.DB
|
||||||
HomeAssistant HomeAssistant `json:"home_assistant"`
|
HomeAssistant HomeAssistant `json:"home_assistant"`
|
||||||
Sensors Sensors `json:"sensors"`
|
Sensors Sensors `json:"sensors"`
|
||||||
Administrator Administrator `json:"administrator"`
|
Administrator Administrator `json:"administrator"`
|
||||||
|
@ -94,6 +97,22 @@ func loadConfig() (config Config, err error, isFirstRun bool) {
|
||||||
return Config{}, err, false
|
return Config{}, err, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db, err := sql.Open("sqlite3", "./database.db")
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err, false
|
||||||
|
}
|
||||||
|
conf.db = db
|
||||||
|
|
||||||
|
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS "cache" (
|
||||||
|
"time" NUMERIC NOT NULL,
|
||||||
|
"green_energy_percentage" REAL NOT NULL,
|
||||||
|
"energy_consumption" REAL NOT NULL,
|
||||||
|
PRIMARY KEY("time")
|
||||||
|
);`)
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err, false
|
||||||
|
}
|
||||||
|
|
||||||
return conf, nil, false
|
return conf, nil, false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.17
|
||||||
require (
|
require (
|
||||||
github.com/gofiber/fiber/v2 v2.37.1
|
github.com/gofiber/fiber/v2 v2.37.1
|
||||||
github.com/gofiber/template v1.7.1
|
github.com/gofiber/template v1.7.1
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.16
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
4
http.go
4
http.go
|
@ -181,7 +181,7 @@ func (config Config) renderIndex(c *fiber.Ctx) error {
|
||||||
}, "base")
|
}, "base")
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := readCache()
|
data, err := config.readCache()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ func (config Config) renderIndex(c *fiber.Ctx) error {
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, datum := range data {
|
for _, datum := range data {
|
||||||
labels = append(labels, datum.Date)
|
labels = append(labels, time.Unix(datum.Date, 0).Format("02/01"))
|
||||||
greenEnergyPercents = append(greenEnergyPercents, datum.GreenEnergyPercentage)
|
greenEnergyPercents = append(greenEnergyPercents, datum.GreenEnergyPercentage)
|
||||||
greenEnergyConsumptionAbsolute = append(greenEnergyConsumptionAbsolute, datum.GreenEnergyPercentage/100*datum.PolledSmartEnergySummation)
|
greenEnergyConsumptionAbsolute = append(greenEnergyConsumptionAbsolute, datum.GreenEnergyPercentage/100*datum.PolledSmartEnergySummation)
|
||||||
energyConsumptions = append(energyConsumptions, datum.PolledSmartEnergySummation)
|
energyConsumptions = append(energyConsumptions, datum.PolledSmartEnergySummation)
|
||||||
|
|
2
main.go
2
main.go
|
@ -20,7 +20,7 @@ func main() {
|
||||||
cr := cron.New()
|
cr := cron.New()
|
||||||
_, err = cr.AddFunc("@hourly", config.updateCache)
|
_, err = cr.AddFunc("@hourly", config.updateCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
cr.Start()
|
cr.Start()
|
||||||
config.updateCache()
|
config.updateCache()
|
||||||
|
|
Loading…
Reference in a new issue