Added arm builds, improve database

- The program will now be cross-compiled and released for arm as well as x86
- What we previously called "cache" is not actually a cache, as it holds content that can't be always retrieved. Now we're stopping calling it a cache.
- Improved history merging
- Fixed the README to include the database as a volume, and to fix some errors
This commit is contained in:
MassiveBox 2023-01-29 21:16:04 +01:00
parent 52ba0ea4c1
commit 7a1214d492
6 changed files with 52 additions and 34 deletions

View file

@ -1,12 +1,6 @@
pipeline: pipeline:
build: docker:
image: golang
commands:
- go get ecodash
- go build
docker-publish:
image: plugins/docker image: plugins/docker
settings: settings:
registry: gitea.massivebox.net registry: gitea.massivebox.net
@ -16,11 +10,19 @@ pipeline:
password: password:
from_secret: auth_token from_secret: auth_token
build:
image: golang
commands:
- go get ecodash
- go build -o ecodash-x86
- env GOOS=linux GOARCH=arm go build -o ecodash-arm
prepare-gitea-release: prepare-gitea-release:
image: alpine image: alpine
commands: commands:
- apk update; apk add zip - apk update; apk add zip
- zip -r ecodash.zip templates ecodash - mv ecodash-x86 ecodash; zip -r ecodash-x86.zip templates ecodash
- mv ecodash-arm ecodash; zip -r ecodash-arm.zip templates ecodash
when: when:
event: tag event: tag
@ -28,7 +30,7 @@ pipeline:
image: plugins/gitea-release image: plugins/gitea-release
settings: settings:
base_url: https://gitea.massivebox.net base_url: https://gitea.massivebox.net
files: ecodash.zip files: ecodash-x86.zip ecodash-arm.zip
api_key: api_key:
from_secret: auth_token from_secret: auth_token
title: ${CI_COMMIT_TAG} title: ${CI_COMMIT_TAG}

View file

@ -1,4 +1,5 @@
# 🌿 EcoDash # 🌿 EcoDash
[![status-badge](https://woodpecker.massivebox.net/api/badges/massivebox/ecodash/status.svg)](https://woodpecker.massivebox.net/massivebox/ecodash) [![status-badge](https://woodpecker.massivebox.net/api/badges/massivebox/ecodash/status.svg)](https://woodpecker.massivebox.net/massivebox/ecodash)
EcoDash is a simple way to show your users how much your server consumes. EcoDash is a simple way to show your users how much your server consumes.
@ -15,14 +16,17 @@ You can see it in action here: https://ecodash.massivebox.net
## Installation ## Installation
#### Using Docker run: #### Using Docker run:
``` ```
touch config.json docker run -v /absolute_path_to/config.json:/app/config.json -v /absolute_path_to/database.db:/app/database.db --name ecodash -p 8080:80 gitea.massivebox.net/massivebox/ecodash
docker run -v ./config.json:/app/config.json --name ecodash -p 8080:80 gitea.massivebox.net/massivebox/ecodash
``` ```
This will open the container on port 8080. Replace "8080" in the command with whatever number you want to open that specific port. This will open the container on port 8080. Replace "8080" in the command with whatever number you want to open that specific port.
#### Using Docker Compose: #### Using Docker Compose:
Create a file `docker-compose.yml` with the following content: Create a file `docker-compose.yml` with the following content:
``` ```
version: '3' version: '3'
services: services:
@ -33,17 +37,20 @@ services:
- '8080:80' - '8080:80'
volumes: volumes:
- ./config.json:/app/config.json - ./config.json:/app/config.json
- ./database.db:/app/database.db
restart: always restart: always
```
Run the container with
``` ```
Run the container with
```
touch config.json
docker compose up -d docker compose up -d
``` ```
This will open the container on port 8080. Replace "8080" in the file with whatever number you want to open that specific port. This will open the container on port 8080. Replace "8080" in the file with whatever number you want to open that specific port.
#### Using the binary #### Using the binary
Grab a binary from the Releases page and run it. You can use the `PORT` environment variable to override the default port (80). Grab a binary from the Releases page and run it. You can use the `PORT` environment variable to override the default port (80).
## Set up ## Set up
@ -62,6 +69,7 @@ If you've just added your energy meter into HomeAssistant, note that it will tak
## Support ## Support
If something isn't working, you can find some help here: If something isn't working, you can find some help here:
- [Matrix support room](https://matrix.to/#/#support:massivebox.net) - [Matrix support room](https://matrix.to/#/#support:massivebox.net)
- [Issues page](./issues) - [Issues page](./issues)
- [Contact me](https://massivebox.net/contact.html) - [Contact me](https://massivebox.net/contact.html)

4
api.go
View file

@ -126,7 +126,7 @@ func (config Config) historyBulkAverageAndConvertToGreen(entityID string, startT
} }
value := float32(val) value := float32(val)
var found bool var found bool
dayNo := historyChange.LastUpdated.Local().Day() dayNo := dayStart(historyChange.LastUpdated.Local()).Day()
for key, day := range days { for key, day := range days {
if dayNo == day.DayNumber { if dayNo == day.DayNumber {
found = true found = true
@ -205,7 +205,7 @@ func (config Config) historyBulkDelta(entityID string, startTime, endTime time.T
} }
value := float32(val) value := float32(val)
var found bool var found bool
dayNo := historyChange.LastUpdated.Local().Day() dayNo := dayStart(historyChange.LastUpdated.Local()).Day()
for key, day := range days { for key, day := range days {
if dayNo == day.DayNumber { if dayNo == day.DayNumber {
found = true found = true

View file

@ -6,14 +6,14 @@ import (
"time" "time"
) )
type CacheEntry struct { type HistoryEntry struct {
Date int64 Date int64
GreenEnergyPercentage float32 GreenEnergyPercentage float32
PolledSmartEnergySummation float32 PolledSmartEnergySummation float32
} }
type CacheData []CacheEntry type History []HistoryEntry
func (config Config) updateCache() { func (config Config) updateHistory() {
greenEnergyPercentage, err := config.historyAverageAndConvertToGreen(config.Sensors.FossilPercentage, time.Now()) greenEnergyPercentage, err := config.historyAverageAndConvertToGreen(config.Sensors.FossilPercentage, time.Now())
if err != nil { if err != nil {
@ -24,9 +24,9 @@ func (config Config) updateCache() {
return return
} }
config.db.Exec("INSERT INTO cache(time,green_energy_percentage,energy_consumption) VALUES (?,?,?);", dayStart(time.Now()).Unix(), greenEnergyPercentage.Value, historyPolledSmartEnergySummation.Value) config.db.Exec("INSERT OR REPLACE INTO cache(time,green_energy_percentage,energy_consumption) VALUES (?,?,?);", dayStart(time.Now()).Unix(), greenEnergyPercentage.Value, historyPolledSmartEnergySummation.Value)
cached, err := config.readCache() cached, err := config.readHistory()
if err != nil { if err != nil {
return return
} }
@ -60,32 +60,40 @@ func (config Config) refreshCacheFromPast(pastTime time.Time) error {
return err return err
} }
_, err = config.db.Exec("DELETE FROM cache")
if err != nil {
return err
}
for key, day := range greenEnergyPercentage { for key, day := range greenEnergyPercentage {
_, err := config.db.Exec("INSERT INTO cache(time,green_energy_percentage,energy_consumption) VALUES (?,?,?);", day.DayTime.Unix(), greenEnergyPercentage[key].Value, historyPolledSmartEnergySummation[key].Value)
var action2 string
if greenEnergyPercentage[key].Value != 0 && historyPolledSmartEnergySummation[key].Value != 0 {
action2 = "REPLACE"
} else {
action2 = "IGNORE"
}
stmt, err := config.db.Prepare("INSERT OR " + action2 + " INTO cache(time, green_energy_percentage, energy_consumption) values(?,?,?)")
if err != nil { if err != nil {
return err return err
} }
_, err = stmt.Exec(day.DayTime.Unix(), greenEnergyPercentage[key].Value, historyPolledSmartEnergySummation[key].Value)
if err != nil {
return err
}
} }
return nil return nil
} }
func (config Config) readCache() (CacheData, error) { func (config Config) readHistory() (History, error) {
start := dayStart(time.Now()).AddDate(0, 0, -8) 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()) rows, err := config.db.Query("SELECT time, green_energy_percentage, energy_consumption FROM cache WHERE time > ?", start.Unix())
if err != nil { if err != nil {
return CacheData{}, err return History{}, err
} }
defer rows.Close() defer rows.Close()
var ret CacheData var ret History
for rows.Next() { for rows.Next() {
var ( var (
@ -94,7 +102,7 @@ func (config Config) readCache() (CacheData, error) {
polledSmartEnergyConsumption float32 polledSmartEnergyConsumption float32
) )
err = rows.Scan(&date, &greenEnergyPercentage, &polledSmartEnergyConsumption) err = rows.Scan(&date, &greenEnergyPercentage, &polledSmartEnergyConsumption)
ret = append(ret, CacheEntry{date, greenEnergyPercentage, polledSmartEnergyConsumption}) ret = append(ret, HistoryEntry{date, greenEnergyPercentage, polledSmartEnergyConsumption})
} }
return ret, nil return ret, nil

View file

@ -177,7 +177,7 @@ func (config Config) renderIndex(c *fiber.Ctx) error {
}, "base") }, "base")
} }
data, err := config.readCache() data, err := config.readHistory()
if err != nil { if err != nil {
return err return err
} }

View file

@ -18,12 +18,12 @@ func main() {
if !isFirstRun { if !isFirstRun {
cr := cron.New() cr := cron.New()
_, err = cr.AddFunc("@hourly", config.updateCache) _, err = cr.AddFunc("@hourly", config.updateHistory)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
cr.Start() cr.Start()
config.updateCache() config.updateHistory()
} }
engine := html.New("./templates/"+config.Dashboard.Theme, ".html") engine := html.New("./templates/"+config.Dashboard.Theme, ".html")