diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index fb13fb5aa..f61992e07 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -31,8 +31,8 @@ jobs:
&& ! contains(github.head_ref, 'refs/heads/chore/')
uses: evcc-io/evcc/.github/workflows/default.yml@master
- dockerlatest:
- name: Publish Docker :latest
+ docker:
+ name: Publish Docker :nightly
needs:
- call-build-workflow
runs-on: ubuntu-latest
@@ -45,7 +45,7 @@ jobs:
- name: Install
env:
- SEIHON_VERSION: v0.8.4
+ SEIHON_VERSION: v0.9.0
run: curl -sfL https://raw.githubusercontent.com/ldez/seihon/master/godownloader.sh | sudo bash -s -- -b $GOPATH/bin ${SEIHON_VERSION}
- name: Login
@@ -55,9 +55,10 @@ jobs:
password: ${{ secrets.DOCKER_PASS }}
- name: Publish
- run: make publish-latest-ci
+ run: make publish-nightly
- nightly:
+
+ apt:
name: Publish APT nightly
needs:
- call-build-workflow
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index d90cf9224..e98c36e89 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -10,7 +10,7 @@ jobs:
if: "startsWith(github.ref, 'refs/tags')"
uses: evcc-io/evcc/.github/workflows/default.yml@master
- dockerrelease:
+ docker:
name: Publish Docker :release
needs:
- call-build-workflow
@@ -24,7 +24,9 @@ jobs:
fetch-depth: 0
- name: Install
- run: curl -sfL https://raw.githubusercontent.com/ldez/seihon/master/godownloader.sh | sudo bash -s -- -b $GOPATH/bin v0.5.1
+ env:
+ SEIHON_VERSION: v0.9.0
+ run: curl -sfL https://raw.githubusercontent.com/ldez/seihon/master/godownloader.sh | sudo bash -s -- -b $GOPATH/bin ${SEIHON_VERSION}
- name: Login
uses: docker/login-action@v1
@@ -33,10 +35,10 @@ jobs:
password: ${{ secrets.DOCKER_PASS }}
- name: Publish
- run: make publish-images
+ run: make publish-release
- release:
+ apt:
name: Publish Github & APT release
needs:
- call-build-workflow
diff --git a/.goreleaser-nightly.yml b/.goreleaser-nightly.yml
index 9e18bb7a5..982451902 100644
--- a/.goreleaser-nightly.yml
+++ b/.goreleaser-nightly.yml
@@ -1,13 +1,14 @@
dist: release
release:
disable: true
+
builds:
- id: evcc
main: main.go
flags:
- -tags=release
ldflags:
- - -X github.com/evcc-io/evcc/server.Version={{.Version}}.{{.Timestamp}} -X github.com/evcc-io/evcc/server.Commit={{.ShortCommit}} -s -w
+ - -X github.com/evcc-io/evcc/server.Version={{.Version}} -X github.com/evcc-io/evcc/server.Commit={{.ShortCommit}} -s -w
env:
- CGO_ENABLED=0
goos:
@@ -18,6 +19,7 @@ builds:
- arm64
goarm:
- "6"
+
archives:
- builds:
- evcc
@@ -29,17 +31,30 @@ archives:
format: zip
files:
- evcc.dist.yaml
- name_template: "{{.ProjectName}}_{{ .Version }}.{{.Timestamp}}_{{.Os}}-{{.Arch}}{{ if .Arm }}hf{{ end }}"
+ name_template: "{{.ProjectName}}_{{ .Version }}_{{.Os}}-{{.Arch}}{{ if .Arm }}hf{{ end }}"
+
universal_binaries:
- replace: true
+
checksum:
name_template: 'checksums.txt'
+
snapshot:
name_template: "{{ .Version }}.{{.Timestamp}}"
+
+changelog:
+ sort: asc
+ filters:
+ exclude:
+ - '^chore'
+ - '^bump'
+ - '^docs:'
+ - '^test:'
+
nfpms:
- id: default
package_name: evcc
- file_name_template: "{{.ProjectName}}_{{ .Version }}.{{.Timestamp}}_{{.Os}}-{{.Arch}}{{ if .Arm }}hf{{ end }}"
+ file_name_template: "{{.ProjectName}}_{{ .Version }}_{{.Os}}-{{.Arch}}{{ if .Arm }}hf{{ end }}"
homepage: https://evcc.io
description: EV Charge Controller
@@ -57,4 +72,4 @@ nfpms:
scripts:
postinstall: ./packaging/scripts/postinstall.sh
preremove: ./packaging/scripts/preremove.sh
- postremove: ./packaging/scripts/postremove.sh
\ No newline at end of file
+ postremove: ./packaging/scripts/postremove.sh
diff --git a/.goreleaser.yml b/.goreleaser.yml
index ffc1e02fd..6b8ce43d3 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -3,16 +3,14 @@ release:
github:
owner: evcc-io
name: evcc
-# extra_files:
-# - glob: evcc_*.image.gz
-# - glob: evcc_*.rootfs.gz
+
builds:
- id: evcc
main: main.go
flags:
- -tags=release
ldflags:
- - -X github.com/evcc-io/evcc/server.Version={{.Version}} -X github.com/evcc-io/evcc/server.Commit={{.ShortCommit}} -s -w
+ - -X github.com/evcc-io/evcc/server.Version={{.Version}} -s -w
env:
- CGO_ENABLED=0
goos:
@@ -30,6 +28,7 @@ builds:
goarch: arm
- goos: windows
goarch: arm64
+
archives:
- builds:
- evcc
@@ -41,12 +40,16 @@ archives:
format: zip
files:
- evcc.dist.yaml
+
universal_binaries:
- replace: true
+
checksum:
name_template: 'checksums.txt'
+
snapshot:
name_template: "{{ .Tag }}-next"
+
changelog:
sort: asc
filters:
@@ -55,6 +58,7 @@ changelog:
- '^bump'
- '^docs:'
- '^test:'
+
nfpms:
- id: default
package_name: evcc
@@ -77,6 +81,7 @@ nfpms:
postinstall: ./packaging/scripts/postinstall.sh
preremove: ./packaging/scripts/preremove.sh
postremove: ./packaging/scripts/postremove.sh
+
brews:
- tap:
owner: evcc-io
diff --git a/Dockerfile b/Dockerfile
index 4704bea3d..fb53c07fa 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
# STEP 1 build ui
FROM node:16-alpine as node
-RUN apk update && apk add --no-cache make
+RUN apk update && apk add --no-cache make alpine-sdk python3
WORKDIR /build
@@ -27,6 +27,9 @@ RUN apk update && apk add --no-cache git ca-certificates tzdata alpine-sdk && up
WORKDIR /build
+# define --build-arg RELEASE=1 to hide commit hash
+ARG RELEASE
+
# install go tools and cache modules
COPY Makefile .
COPY go.mod .
@@ -43,7 +46,7 @@ RUN make assets
COPY --from=node /build/dist /build/dist
# build
-RUN make build
+RUN RELEASE=${RELEASE} make build
# STEP 3 build a small image including module support
diff --git a/Makefile b/Makefile
index 5383720e6..dc883fb7f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,15 +1,20 @@
.PHONY: default all clean install install-ui ui assets lint test-ui lint-ui test build test-release release
-.PHONY: docker publish-testing publish-latest publish-images
+.PHONY: docker publish-testing publish-latest publish-nightly publish-release
.PHONY: prepare-image image-rootfs image-update
.PHONY: soc stamps
# build vars
TAG_NAME := $(shell test -d .git && git describe --abbrev=0 --tags)
SHA := $(shell test -d .git && git rev-parse --short HEAD)
+COMMIT := $(SHA)
+# hide commit for releases
+ifeq ($(RELEASE),1)
+ COMMIT :=
+endif
VERSION := $(if $(TAG_NAME),$(TAG_NAME),$(SHA))
BUILD_DATE := $(shell date -u '+%Y-%m-%d_%H:%M:%S')
BUILD_TAGS := -tags=release
-LD_FLAGS := -X github.com/evcc-io/evcc/server.Version=$(VERSION) -X github.com/evcc-io/evcc/server.Commit=$(SHA) -s -w
+LD_FLAGS := -X github.com/evcc-io/evcc/server.Version=$(VERSION) -X github.com/evcc-io/evcc/server.Commit=$(COMMIT) -s -w
BUILD_ARGS := -ldflags='$(LD_FLAGS)'
# docker
@@ -55,7 +60,7 @@ test:
go test ./...
build:
- @echo Version: $(VERSION) $(BUILD_DATE)
+ @echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
go build -v $(BUILD_TAGS) $(BUILD_ARGS)
release-test:
@@ -65,28 +70,27 @@ release:
goreleaser --rm-dist
docker:
- @echo Version: $(VERSION) $(BUILD_DATE)
+ @echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
docker build --tag $(DOCKER_IMAGE):testing .
publish-testing:
- @echo Version: $(VERSION) $(BUILD_DATE)
- seihon publish --dry-run=false --template docker/ci.Dockerfile --base-runtime-image alpine:$(ALPINE_VERSION) \
+ @echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
+ seihon publish --dry-run=false --template docker/tmpl.Dockerfile --base-runtime-image alpine:$(ALPINE_VERSION) \
--image-name $(DOCKER_IMAGE) -v "testing" --targets=$(TARGETS)
publish-latest:
- @echo Version: $(VERSION) $(BUILD_DATE)
+ @echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
seihon publish --dry-run=false --template docker/tmpl.Dockerfile --base-runtime-image alpine:$(ALPINE_VERSION) \
--image-name $(DOCKER_IMAGE) -v "latest" --targets=$(TARGETS)
-publish-latest-ci:
- @echo Version: $(VERSION) $(BUILD_DATE)
+publish-nightly:
+ @echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
seihon publish --dry-run=false --template docker/ci.Dockerfile --base-runtime-image alpine:$(ALPINE_VERSION) \
--image-name $(DOCKER_IMAGE) -v "nightly" --targets=$(TARGETS)
-# TODO: -v "0" needs to be replaced by MAJOR, MINOR and PATCH as soon as we made it to semantic versioning
-publish-images:
- @echo Version: $(VERSION) $(BUILD_DATE)
- seihon publish --dry-run=false --template docker/tmpl.Dockerfile --base-runtime-image alpine:$(ALPINE_VERSION) \
+publish-release:
+ @echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
+ RELEASE=1 seihon publish --dry-run=false --template docker/ci.Dockerfile --base-runtime-image alpine:$(ALPINE_VERSION) \
--image-name $(DOCKER_IMAGE) -v "latest" -v "$(TAG_NAME)" --targets=$(TARGETS)
# gokrazy image
@@ -111,7 +115,7 @@ image-update:
gokr-packer -update yes $(IMAGE_OPTIONS)
soc:
- @echo Version: $(VERSION) $(BUILD_DATE)
+ @echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
go build $(BUILD_TAGS) $(BUILD_ARGS) github.com/evcc-io/evcc/cmd/soc
stamps:
diff --git a/assets/js/components/Version.vue b/assets/js/components/Version.vue
index c83690897..182e09537 100644
--- a/assets/js/components/Version.vue
+++ b/assets/js/components/Version.vue
@@ -26,7 +26,8 @@
}}
{{
$t("footer.version.versionLong", { installed })
- }}
+ }} ({{ commit }})
diff --git a/assets/js/views/App.vue b/assets/js/views/App.vue
index 61c802129..114bcf7e6 100644
--- a/assets/js/views/App.vue
+++ b/assets/js/views/App.vue
@@ -124,6 +124,7 @@ export default {
version: function () {
return {
installed: this.installedVersion,
+ commit: this.commit,
available: this.store.state.availableVersion,
releaseNotes: this.store.state.releaseNotes,
hasUpdater: this.store.state.hasUpdater,
diff --git a/cmd/charger.go b/cmd/charger.go
index 1b27b516c..8ad934158 100644
--- a/cmd/charger.go
+++ b/cmd/charger.go
@@ -22,7 +22,7 @@ func init() {
func runCharger(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
// load config
conf, err := loadConfigFile(cfgFile)
diff --git a/cmd/configure/main.go b/cmd/configure/main.go
index a6d91ef15..74b103c7d 100644
--- a/cmd/configure/main.go
+++ b/cmd/configure/main.go
@@ -45,7 +45,7 @@ func (c *CmdConfigure) Run(log *util.Logger, flagLang string, advancedMode, expa
c.advancedMode = advancedMode
c.expandedMode = expandedMode
- c.log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ c.log.INFO.Printf("evcc %s", server.FormattedVersion())
bundle := i18n.NewBundle(language.German)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
diff --git a/cmd/dump.go b/cmd/dump.go
index fb6dd4998..866d933e7 100644
--- a/cmd/dump.go
+++ b/cmd/dump.go
@@ -23,7 +23,7 @@ func init() {
func runDump(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
// load config
conf, err := loadConfigFile(cfgFile)
diff --git a/cmd/eebus.go b/cmd/eebus.go
index 6591045ae..bfed4b54a 100644
--- a/cmd/eebus.go
+++ b/cmd/eebus.go
@@ -65,7 +65,7 @@ func generateEEBUSCert() {
func runEEBUSCert(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
generateEEBUSCert()
}
diff --git a/cmd/health.go b/cmd/health.go
index 2981d11de..68dffdc90 100644
--- a/cmd/health.go
+++ b/cmd/health.go
@@ -31,7 +31,7 @@ func init() {
func runHealth(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
u := &httpunix.Transport{
DialTimeout: 100 * time.Millisecond,
diff --git a/cmd/meter.go b/cmd/meter.go
index ca0656e9b..fc1bd81ff 100644
--- a/cmd/meter.go
+++ b/cmd/meter.go
@@ -21,7 +21,7 @@ func init() {
func runMeter(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
// load config
conf, err := loadConfigFile(cfgFile)
diff --git a/cmd/root.go b/cmd/root.go
index caf63b881..0a68087f6 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -37,7 +37,7 @@ var (
var rootCmd = &cobra.Command{
Use: "evcc",
Short: "EV Charge Controller",
- Version: fmt.Sprintf("%s (%s)", server.Version, server.Commit),
+ Version: server.FormattedVersion(),
Run: run,
}
@@ -144,7 +144,7 @@ func Execute() {
func run(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
// load config and re-configure logging after reading config file
conf, err := loadConfigFile(cfgFile)
diff --git a/cmd/token.go b/cmd/token.go
index 4eafa8662..7e8c8fce7 100644
--- a/cmd/token.go
+++ b/cmd/token.go
@@ -25,7 +25,7 @@ func init() {
func runToken(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
// load config
conf, err := loadConfigFile(cfgFile)
diff --git a/cmd/vehicle.go b/cmd/vehicle.go
index e29fc8f6e..04922d0a5 100644
--- a/cmd/vehicle.go
+++ b/cmd/vehicle.go
@@ -21,7 +21,7 @@ func init() {
func runVehicle(cmd *cobra.Command, args []string) {
util.LogLevel(viper.GetString("log"), viper.GetStringMapString("levels"))
- log.INFO.Printf("evcc %s (%s)", server.Version, server.Commit)
+ log.INFO.Printf("evcc %s", server.FormattedVersion())
// load config
conf, err := loadConfigFile(cfgFile)
diff --git a/dist/css/index.6aeecebf.css b/dist/css/index.1cb8281c.css
similarity index 97%
rename from dist/css/index.6aeecebf.css
rename to dist/css/index.1cb8281c.css
index c463dc624..aa0cfa982 100644
--- a/dist/css/index.6aeecebf.css
+++ b/dist/css/index.1cb8281c.css
@@ -1 +1 @@
-:root{--evcc-green:#66d85a;--evcc-dark-green:#3aba2c;--evcc-yellow:#ffe000;--evcc-grid:var(--bs-gray-dark);--evcc-self:var(--evcc-dark-green);--evcc-export:var(--evcc-yellow);--bs-primary:var(--evcc-dark-green);--bs-primary-rgb:58,186,44}.bg-primary{background-color:var(--evcc-dark-green)!important}a{color:var(--evcc-dark-green)}.progress-bar-animated{animation-direction:reverse}.bg-muted{opacity:.25}.btn-primary,.btn-primary:focus{background-color:var(--bs-gray-dark);border-color:var(--bs-gray-dark)}.btn-primary:active,.btn-primary:hover{background-color:var(--evcc-dark-green);border-color:var(--evcc-dark-green)}.btn-outline-primary{color:var(--bs-gray-dark);border-color:var(--bs-gray-dark)}.btn-outline-primary:hover{background-color:var(--evcc-dark-green);border-color:var(--evcc-dark-green)}.text-evcc{color:var(--evcc-dark-green)}.text-grid{color:var(--evcc-grid)}@media screen and (min-width:400px) and (max-width:574px){.d-xs-none{display:none!important}.d-xs-inline{display:inline!important}}.cursor-pointer{cursor:pointer}.v-popper__inner{margin:0 12px!important}.icon[data-v-7872ae76]{color:var(--evcc-dark-green)}.confetti-button[data-v-6edb9fae]{touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@media (max-width:575px){.modal-dialog.modal-dialog-centered[data-v-bd18982c]{align-items:flex-end;margin-bottom:0}.modal.fade .modal-dialog[data-v-bd18982c]{transition:transform .4s ease;transform:translateY(150px)}.modal.show .modal-dialog[data-v-bd18982c]{transform:none}.modal-dialog-scrollable[data-v-bd18982c]{height:calc(100% - .5rem)}.modal-content[data-v-bd18982c]{border-radius:1rem 1rem 0 0}}.chart[data-v-bd18982c]{height:1.6rem}.chart-item--self[data-v-bd18982c]{background-color:var(--evcc-self)}.chart-item--grid[data-v-bd18982c]{background-color:var(--evcc-grid)}.chart-item--no-data[data-v-bd18982c]{background-color:var(--bs-gray)}.chart-item[data-v-bd18982c]{transition-property:width;transition-duration:.5s;transition-timing-function:linear}.logo[data-v-63bd1ae6]{width:85px}.app[data-v-63bd1ae6]{min-height:100vh}.title[data-v-63bd1ae6]{position:relative;top:.1rem}.battery[data-v-2dcca16c]{transform:translateX(.35rem) rotate(-90deg);transition-property:transform;transition-duration:.25s;transition-timing-function:ease}.power--in .battery[data-v-2dcca16c]{transform:translateX(.7rem) rotate(-90deg)}.power--out .battery[data-v-2dcca16c]{transform:translateX(0) rotate(-90deg)}.arrow[data-v-2dcca16c]{margin-left:-.2rem;opacity:0;transform:translateX(-.5rem);transition-property:opacity,transform;transition-duration:.25s;transition-timing-function:ease}.power--in .arrow[data-v-2dcca16c]{opacity:1;transform:translateX(-1rem) scaleX(1)}.power--out .arrow[data-v-2dcca16c]{opacity:1;transform:translateX(0) scaleX(1)}.grid[data-v-c8e84f48]{transform:translateX(.35rem);transition-property:transform;transition-duration:.25s;transition-timing-function:ease}.power-export .grid[data-v-c8e84f48]{transform:translateX(.9rem)}.power-import .grid[data-v-c8e84f48]{transform:translateX(-.1rem)}.arrow[data-v-c8e84f48]{margin-left:-.2rem;opacity:0;transform:translateX(-.5rem);transition-property:opacity,transform;transition-duration:.25s;transition-timing-function:ease}.power-export .arrow[data-v-c8e84f48]{opacity:1;transform:translateX(-.9rem) scaleX(1)}.power-import .arrow[data-v-c8e84f48]{opacity:1;transform:translateX(.1em) scaleX(1)}.label-bar[data-v-17da7e54]{width:0;margin:0;height:1.7rem;padding:.6rem 0;opacity:1;overflow:hidden}.label-bar-scale--hidden[data-v-17da7e54]{opacity:0}.label-bar-scale[data-v-17da7e54]{border:1px solid var(--bs-gray);height:.5rem;background:none;display:flex;justify-content:center;align-items:center;white-space:nowrap;border-radius:0;transition:border-radius .5s linear}.label-bar--top .label-bar-scale[data-v-17da7e54]{border-bottom:none}.label-bar--bottom .label-bar-scale[data-v-17da7e54]{border-top:none}.label-bar--top.label-bar--first .label-bar-scale[data-v-17da7e54]{border-top-left-radius:4px}.label-bar--top.label-bar--last .label-bar-scale[data-v-17da7e54]{border-top-right-radius:4px}.label-bar--bottom.label-bar--first .label-bar-scale[data-v-17da7e54]{border-bottom-left-radius:4px}.label-bar--bottom.label-bar--last .label-bar-scale[data-v-17da7e54]{border-bottom-right-radius:4px}.label-bar:not(.label-bar--first) .label-bar-scale[data-v-17da7e54]{border-left:none}.label-bar-icon[data-v-17da7e54]{background-color:#fff;color:var(--bs-gray);padding:0 .3rem;opacity:1}.label-bar--top .label-bar-icon[data-v-17da7e54]{margin-top:-6px}.label-bar--bottom .label-bar-icon[data-v-17da7e54]{margin-top:6px}.label-bar--hidden[data-v-17da7e54],.label-bar--hide-icon .label-bar-icon[data-v-17da7e54]{opacity:0}.site-progress[data-v-0c035ffc]{--height:38px;height:var(--height);margin:.25rem 0;border-radius:5px;display:flex;overflow:hidden}.site-progress-bar[data-v-0c035ffc]{display:flex;justify-content:center;align-items:center;overflow:hidden;position:relative;width:0}.visualization--ready .site-progress-bar[data-v-0c035ffc]{transition-property:width;transition-duration:.5s;transition-timing-function:linear}.grid-import[data-v-0c035ffc]{background-color:var(--evcc-grid);color:var(--bs-white)}.self-consumption[data-v-0c035ffc]{background-color:var(--evcc-self);color:var(--bs-white)}.pv-export[data-v-0c035ffc]{background-color:var(--evcc-export);color:var(--bs-dark)}.power[data-v-0c035ffc]{display:block;margin:0 .2rem;white-space:nowrap;overflow:hidden}.visualization--ready[data-v-0c035ffc] .label-bar{transition-property:width,opacity;transition-duration:.5s,.25s;transition-timing-function:linear,ease}.visualization--ready[data-v-0c035ffc] .label-bar-icon{transition:opacity .25s ease-in}.energyflow[data-v-c2b4f05e]{cursor:pointer}.color-grid[data-v-c2b4f05e]{color:var(--evcc-grid)}.color-self[data-v-c2b4f05e]{color:var(--evcc-self)}.color-export[data-v-c2b4f05e]{color:var(--evcc-export)}.details-icon[data-v-c2b4f05e]{text-align:center;width:30px;margin-right:.25rem;white-space:nowrap;flex-shrink:0}.btn[data-v-1ff39d22]{flex-basis:0;white-space:nowrap}.vehicle-soc[data-v-66f68a62]{--height:38px;--thumb-overlap:3px;--thumb-width:3px;--thumb-horizontal-padding:15px;--label-height:26px;position:relative;height:var(--height)}.progress[data-v-66f68a62]{height:100%;font-size:1rem}.progress-bar.bg-muted[data-v-66f68a62]{color:var(--white)}.bg-light[data-v-66f68a62]{color:var(--bs-gray-dark)}.target-label[data-v-66f68a62]{width:3em;margin-left:-1.5em;height:var(--label-height);position:absolute;top:calc(var(--label-height)*-1 + var(--thumb-overlap)*-1);text-align:center;color:var(--bs-gray-dark);font-size:1rem;opacity:1;transition:opacity .2s ease 1s}.target-slider[data-v-66f68a62]{-webkit-appearance:none;position:absolute;top:calc(var(--thumb-overlap)*-1);left:calc(var(--thumb-horizontal-padding)*-1);height:calc(100% + var(--thumb-overlap)*2);width:calc(100% + var(--thumb-horizontal-padding)*2);background:transparent}.target-slider[data-v-66f68a62]:focus{outline:none}.target-slider[data-v-66f68a62]::-webkit-slider-runnable-track{position:relative;background:transparent;border:none;height:100%;cursor:pointer}.target-slider[data-v-66f68a62]::-moz-range-track{background:transparent;border:none;height:100%;cursor:pointer}.target-slider[data-v-66f68a62]::-webkit-slider-thumb{-webkit-appearance:none;position:relative;top:calc(var(--label-height)*-1);height:100%;width:var(--thumb-width);padding:var(--label-height) var(--thumb-horizontal-padding) 0;box-sizing:content-box;background-clip:content-box;background-color:var(--bs-gray-dark);cursor:-webkit-grab;cursor:grab;border:none;opacity:1;-webkit-transition:opacity .2s ease 1s;transition:opacity .2s ease 1s;box-shadow:none}.target-slider[data-v-66f68a62]::-moz-range-thumb{position:relative;top:calc(var(--label-height)*-1);height:100%;width:var(--thumb-width);padding:0 var(--thumb-horizontal-padding) 0;box-sizing:content-box;background-clip:content-box;background-color:var(--bs-gray-dark);cursor:grab;border:none;opacity:1;-moz-transition:opacity .5s ease 1s;transition:opacity .5s ease 1s}.target--slider-hidden .target-label[data-v-66f68a62],.target--slider-hidden .target-slider[data-v-66f68a62]::-webkit-slider-thumb{opacity:0}.target--slider-hidden .target-label[data-v-66f68a62],.target--slider-hidden .target-slider[data-v-66f68a62]::-moz-range-thumb{opacity:0}.target:hover .target-label[data-v-66f68a62],.target:hover .target-slider[data-v-66f68a62]::-webkit-slider-thumb{opacity:1;transition-delay:0s}.target:hover .target-label[data-v-66f68a62],.target:hover .target-slider[data-v-66f68a62]::-moz-range-thumb{opacity:1;transition-delay:0s}.dots[data-v-60c12baf]{height:1em;width:1em}.dots-back[data-v-60c12baf],.dots-front[data-v-60c12baf]{display:block}.dots-back[data-v-60c12baf]{opacity:.25}.dots-front[data-v-60c12baf]{opacity:1}.direction-up .dots-front[data-v-60c12baf]{-webkit-animation:dots-vertical-data-v-60c12baf 2s steps(4,jump-none) infinite normal;animation:dots-vertical-data-v-60c12baf 2s steps(4,jump-none) infinite normal}.direction-down .dots-front[data-v-60c12baf]{animation:dots-vertical-data-v-60c12baf 2s steps(4,jump-none) infinite reverse}@-webkit-keyframes dots-vertical-data-v-60c12baf{25%{-webkit-clip-path:inset(100% 0 0 0);clip-path:inset(100% 0 0 0)}75%{-webkit-clip-path:inset(0 0 0 0);clip-path:inset(0 0 0 0)}}@keyframes dots-vertical-data-v-60c12baf{25%{-webkit-clip-path:inset(100% 0 0 0);clip-path:inset(100% 0 0 0)}75%{-webkit-clip-path:inset(0 0 0 0);clip-path:inset(0 0 0 0)}}.root[data-v-60c12baf] svg{display:block}
\ No newline at end of file
+:root{--evcc-green:#66d85a;--evcc-dark-green:#3aba2c;--evcc-yellow:#ffe000;--evcc-grid:var(--bs-gray-dark);--evcc-self:var(--evcc-dark-green);--evcc-export:var(--evcc-yellow);--bs-primary:var(--evcc-dark-green);--bs-primary-rgb:58,186,44}.bg-primary{background-color:var(--evcc-dark-green)!important}a{color:var(--evcc-dark-green)}.progress-bar-animated{animation-direction:reverse}.bg-muted{opacity:.25}.btn-primary,.btn-primary:focus{background-color:var(--bs-gray-dark);border-color:var(--bs-gray-dark)}.btn-primary:active,.btn-primary:hover{background-color:var(--evcc-dark-green);border-color:var(--evcc-dark-green)}.btn-outline-primary{color:var(--bs-gray-dark);border-color:var(--bs-gray-dark)}.btn-outline-primary:hover{background-color:var(--evcc-dark-green);border-color:var(--evcc-dark-green)}.text-evcc{color:var(--evcc-dark-green)}.text-grid{color:var(--evcc-grid)}@media screen and (min-width:400px) and (max-width:574px){.d-xs-none{display:none!important}.d-xs-inline{display:inline!important}}.cursor-pointer{cursor:pointer}.v-popper__inner{margin:0 12px!important}.icon[data-v-59ac7046]{color:var(--evcc-dark-green)}.confetti-button[data-v-6edb9fae]{touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@media (max-width:575px){.modal-dialog.modal-dialog-centered[data-v-bd18982c]{align-items:flex-end;margin-bottom:0}.modal.fade .modal-dialog[data-v-bd18982c]{transition:transform .4s ease;transform:translateY(150px)}.modal.show .modal-dialog[data-v-bd18982c]{transform:none}.modal-dialog-scrollable[data-v-bd18982c]{height:calc(100% - .5rem)}.modal-content[data-v-bd18982c]{border-radius:1rem 1rem 0 0}}.chart[data-v-bd18982c]{height:1.6rem}.chart-item--self[data-v-bd18982c]{background-color:var(--evcc-self)}.chart-item--grid[data-v-bd18982c]{background-color:var(--evcc-grid)}.chart-item--no-data[data-v-bd18982c]{background-color:var(--bs-gray)}.chart-item[data-v-bd18982c]{transition-property:width;transition-duration:.5s;transition-timing-function:linear}.logo[data-v-57ba3c9e]{width:85px}.app[data-v-57ba3c9e]{min-height:100vh}.title[data-v-57ba3c9e]{position:relative;top:.1rem}.battery[data-v-2dcca16c]{transform:translateX(.35rem) rotate(-90deg);transition-property:transform;transition-duration:.25s;transition-timing-function:ease}.power--in .battery[data-v-2dcca16c]{transform:translateX(.7rem) rotate(-90deg)}.power--out .battery[data-v-2dcca16c]{transform:translateX(0) rotate(-90deg)}.arrow[data-v-2dcca16c]{margin-left:-.2rem;opacity:0;transform:translateX(-.5rem);transition-property:opacity,transform;transition-duration:.25s;transition-timing-function:ease}.power--in .arrow[data-v-2dcca16c]{opacity:1;transform:translateX(-1rem) scaleX(1)}.power--out .arrow[data-v-2dcca16c]{opacity:1;transform:translateX(0) scaleX(1)}.grid[data-v-c8e84f48]{transform:translateX(.35rem);transition-property:transform;transition-duration:.25s;transition-timing-function:ease}.power-export .grid[data-v-c8e84f48]{transform:translateX(.9rem)}.power-import .grid[data-v-c8e84f48]{transform:translateX(-.1rem)}.arrow[data-v-c8e84f48]{margin-left:-.2rem;opacity:0;transform:translateX(-.5rem);transition-property:opacity,transform;transition-duration:.25s;transition-timing-function:ease}.power-export .arrow[data-v-c8e84f48]{opacity:1;transform:translateX(-.9rem) scaleX(1)}.power-import .arrow[data-v-c8e84f48]{opacity:1;transform:translateX(.1em) scaleX(1)}.label-bar[data-v-17da7e54]{width:0;margin:0;height:1.7rem;padding:.6rem 0;opacity:1;overflow:hidden}.label-bar-scale--hidden[data-v-17da7e54]{opacity:0}.label-bar-scale[data-v-17da7e54]{border:1px solid var(--bs-gray);height:.5rem;background:none;display:flex;justify-content:center;align-items:center;white-space:nowrap;border-radius:0;transition:border-radius .5s linear}.label-bar--top .label-bar-scale[data-v-17da7e54]{border-bottom:none}.label-bar--bottom .label-bar-scale[data-v-17da7e54]{border-top:none}.label-bar--top.label-bar--first .label-bar-scale[data-v-17da7e54]{border-top-left-radius:4px}.label-bar--top.label-bar--last .label-bar-scale[data-v-17da7e54]{border-top-right-radius:4px}.label-bar--bottom.label-bar--first .label-bar-scale[data-v-17da7e54]{border-bottom-left-radius:4px}.label-bar--bottom.label-bar--last .label-bar-scale[data-v-17da7e54]{border-bottom-right-radius:4px}.label-bar:not(.label-bar--first) .label-bar-scale[data-v-17da7e54]{border-left:none}.label-bar-icon[data-v-17da7e54]{background-color:#fff;color:var(--bs-gray);padding:0 .3rem;opacity:1}.label-bar--top .label-bar-icon[data-v-17da7e54]{margin-top:-6px}.label-bar--bottom .label-bar-icon[data-v-17da7e54]{margin-top:6px}.label-bar--hidden[data-v-17da7e54],.label-bar--hide-icon .label-bar-icon[data-v-17da7e54]{opacity:0}.site-progress[data-v-0c035ffc]{--height:38px;height:var(--height);margin:.25rem 0;border-radius:5px;display:flex;overflow:hidden}.site-progress-bar[data-v-0c035ffc]{display:flex;justify-content:center;align-items:center;overflow:hidden;position:relative;width:0}.visualization--ready .site-progress-bar[data-v-0c035ffc]{transition-property:width;transition-duration:.5s;transition-timing-function:linear}.grid-import[data-v-0c035ffc]{background-color:var(--evcc-grid);color:var(--bs-white)}.self-consumption[data-v-0c035ffc]{background-color:var(--evcc-self);color:var(--bs-white)}.pv-export[data-v-0c035ffc]{background-color:var(--evcc-export);color:var(--bs-dark)}.power[data-v-0c035ffc]{display:block;margin:0 .2rem;white-space:nowrap;overflow:hidden}.visualization--ready[data-v-0c035ffc] .label-bar{transition-property:width,opacity;transition-duration:.5s,.25s;transition-timing-function:linear,ease}.visualization--ready[data-v-0c035ffc] .label-bar-icon{transition:opacity .25s ease-in}.energyflow[data-v-c2b4f05e]{cursor:pointer}.color-grid[data-v-c2b4f05e]{color:var(--evcc-grid)}.color-self[data-v-c2b4f05e]{color:var(--evcc-self)}.color-export[data-v-c2b4f05e]{color:var(--evcc-export)}.details-icon[data-v-c2b4f05e]{text-align:center;width:30px;margin-right:.25rem;white-space:nowrap;flex-shrink:0}.btn[data-v-1ff39d22]{flex-basis:0;white-space:nowrap}.vehicle-soc[data-v-66f68a62]{--height:38px;--thumb-overlap:3px;--thumb-width:3px;--thumb-horizontal-padding:15px;--label-height:26px;position:relative;height:var(--height)}.progress[data-v-66f68a62]{height:100%;font-size:1rem}.progress-bar.bg-muted[data-v-66f68a62]{color:var(--white)}.bg-light[data-v-66f68a62]{color:var(--bs-gray-dark)}.target-label[data-v-66f68a62]{width:3em;margin-left:-1.5em;height:var(--label-height);position:absolute;top:calc(var(--label-height)*-1 + var(--thumb-overlap)*-1);text-align:center;color:var(--bs-gray-dark);font-size:1rem;opacity:1;transition:opacity .2s ease 1s}.target-slider[data-v-66f68a62]{-webkit-appearance:none;position:absolute;top:calc(var(--thumb-overlap)*-1);left:calc(var(--thumb-horizontal-padding)*-1);height:calc(100% + var(--thumb-overlap)*2);width:calc(100% + var(--thumb-horizontal-padding)*2);background:transparent}.target-slider[data-v-66f68a62]:focus{outline:none}.target-slider[data-v-66f68a62]::-webkit-slider-runnable-track{position:relative;background:transparent;border:none;height:100%;cursor:pointer}.target-slider[data-v-66f68a62]::-moz-range-track{background:transparent;border:none;height:100%;cursor:pointer}.target-slider[data-v-66f68a62]::-webkit-slider-thumb{-webkit-appearance:none;position:relative;top:calc(var(--label-height)*-1);height:100%;width:var(--thumb-width);padding:var(--label-height) var(--thumb-horizontal-padding) 0;box-sizing:content-box;background-clip:content-box;background-color:var(--bs-gray-dark);cursor:-webkit-grab;cursor:grab;border:none;opacity:1;-webkit-transition:opacity .2s ease 1s;transition:opacity .2s ease 1s;box-shadow:none}.target-slider[data-v-66f68a62]::-moz-range-thumb{position:relative;top:calc(var(--label-height)*-1);height:100%;width:var(--thumb-width);padding:0 var(--thumb-horizontal-padding) 0;box-sizing:content-box;background-clip:content-box;background-color:var(--bs-gray-dark);cursor:grab;border:none;opacity:1;-moz-transition:opacity .5s ease 1s;transition:opacity .5s ease 1s}.target--slider-hidden .target-label[data-v-66f68a62],.target--slider-hidden .target-slider[data-v-66f68a62]::-webkit-slider-thumb{opacity:0}.target--slider-hidden .target-label[data-v-66f68a62],.target--slider-hidden .target-slider[data-v-66f68a62]::-moz-range-thumb{opacity:0}.target:hover .target-label[data-v-66f68a62],.target:hover .target-slider[data-v-66f68a62]::-webkit-slider-thumb{opacity:1;transition-delay:0s}.target:hover .target-label[data-v-66f68a62],.target:hover .target-slider[data-v-66f68a62]::-moz-range-thumb{opacity:1;transition-delay:0s}.dots[data-v-60c12baf]{height:1em;width:1em}.dots-back[data-v-60c12baf],.dots-front[data-v-60c12baf]{display:block}.dots-back[data-v-60c12baf]{opacity:.25}.dots-front[data-v-60c12baf]{opacity:1}.direction-up .dots-front[data-v-60c12baf]{-webkit-animation:dots-vertical-data-v-60c12baf 2s steps(4,jump-none) infinite normal;animation:dots-vertical-data-v-60c12baf 2s steps(4,jump-none) infinite normal}.direction-down .dots-front[data-v-60c12baf]{animation:dots-vertical-data-v-60c12baf 2s steps(4,jump-none) infinite reverse}@-webkit-keyframes dots-vertical-data-v-60c12baf{25%{-webkit-clip-path:inset(100% 0 0 0);clip-path:inset(100% 0 0 0)}75%{-webkit-clip-path:inset(0 0 0 0);clip-path:inset(0 0 0 0)}}@keyframes dots-vertical-data-v-60c12baf{25%{-webkit-clip-path:inset(100% 0 0 0);clip-path:inset(100% 0 0 0)}75%{-webkit-clip-path:inset(0 0 0 0);clip-path:inset(0 0 0 0)}}.root[data-v-60c12baf] svg{display:block}
\ No newline at end of file
diff --git a/dist/index.html b/dist/index.html
index 07a115856..dc6d10af2 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -1,5 +1,5 @@
-
evcc
\ No newline at end of file
+ };