Skip to content

Commit 5fd70da

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents b798554 + 6f7489a commit 5fd70da

File tree

291 files changed

+10174
-2951
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

291 files changed

+10174
-2951
lines changed

.devcontainer/devcontainer.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2+
// README at: https://github.com/devcontainers/templates/tree/main/src/go
3+
{
4+
"name": "evcc",
5+
"image": "mcr.microsoft.com/devcontainers/go:1-1.23-bookworm",
6+
"features": {
7+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
8+
"moby": true,
9+
"installDockerBuildx": true,
10+
"version": "latest",
11+
"dockerDashComposeVersion": "v2"
12+
},
13+
"ghcr.io/devcontainers/features/node:1": {
14+
"nodeGypDependencies": true,
15+
"installYarnUsingApt": true,
16+
"version": "latest",
17+
"pnpmVersion": "latest",
18+
"nvmVersion": "latest"
19+
}
20+
},
21+
"postCreateCommand": "make install-ui && make install",
22+
"customizations": {
23+
"vscode": {
24+
"extensions": [
25+
"esbenp.prettier-vscode",
26+
"octref.vetur"
27+
]
28+
}
29+
}
30+
}

.eslintrc.cjs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module.exports = {
1818
"vue/attribute-hyphenation": "off",
1919
"vue/multi-word-component-names": "off",
2020
"vue/no-reserved-component-names": "off",
21+
/*"vue/no-undef-properties": "warn",*/
2122
"no-param-reassign": "error",
2223
},
2324
};

.github/workflows/nightly.yml

+7-3
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ jobs:
8989
go-version: ${{ env.GO_VERSION }}
9090
id: go
9191

92-
- name: Install Cloudsmith CLI
93-
run: pip install --upgrade cloudsmith-cli
94-
9592
- name: Patch ASN1
9693
run: make patch-asn1-sudo
9794

@@ -111,6 +108,13 @@ jobs:
111108
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
112109
TESLA_CLIENT_ID: ${{ secrets.TESLA_CLIENT_ID }}
113110

111+
- uses: actions/setup-python@v5
112+
with:
113+
python-version: 3.12
114+
115+
- name: Install Cloudsmith CLI
116+
run: pip install --upgrade cloudsmith-cli
117+
114118
- name: Publish .deb to Cloudsmith
115119
env:
116120
CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }}

.github/workflows/release.yml

+8-4
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ jobs:
6868
go-version: ${{ env.GO_VERSION }}
6969
id: go
7070

71-
- name: Install Cloudsmith CLI
72-
run: pip install --upgrade cloudsmith-cli
73-
7471
- name: Patch ASN1
7572
run: make patch-asn1-sudo
7673

@@ -105,6 +102,13 @@ jobs:
105102
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
106103
TESLA_CLIENT_ID: ${{ secrets.TESLA_CLIENT_ID }}
107104

105+
- uses: actions/setup-python@v5
106+
with:
107+
python-version: 3.12
108+
109+
- name: Install Cloudsmith CLI
110+
run: pip install --upgrade cloudsmith-cli
111+
108112
- name: Publish .deb to Cloudsmith
109113
env:
110114
CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }}
@@ -138,7 +142,7 @@ jobs:
138142

139143
- name: Update version
140144
run: |
141-
sed -i -e s#\"version.*#\"version\":\ \"$(echo ${{ github.ref }} | sed -e s#refs/tags/##)\",# ./hassio/evcc/config.json
145+
sed -i -e s#version.*#version\:\ $(echo ${{ github.ref }} | sed -e s#refs/tags/##)# ./hassio/evcc/config.yaml
142146
143147
- name: Push
144148
run: |

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ __debug_bin*
66
*.py
77
*.log
88
*.json
9+
!.devcontainer/devcontainer.json
910
*.yaml
1011
!templates/**/*.yaml
1112
!templates/**/*-schema.json

.goreleaser-nightly.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
version: 2
2+
13
dist: release
24
release:
35
disable: true
@@ -48,7 +50,7 @@ checksum:
4850
name_template: "checksums.txt"
4951

5052
snapshot:
51-
name_template: '{{ .Version }}{{ if eq (len (split .Version ".")) 2 }}.0{{ end }}+{{ .Timestamp }}'
53+
version_template: '{{ .Version }}{{ if eq (len (split .Version ".")) 2 }}.0{{ end }}+{{ .Timestamp }}'
5254

5355
changelog:
5456
sort: asc
@@ -73,6 +75,9 @@ nfpms:
7375
formats:
7476
- deb
7577

78+
dependencies:
79+
- adduser
80+
7681
contents:
7782
- src: ./packaging/init/evcc.service
7883
dst: /lib/systemd/system/evcc.service

.goreleaser.yml

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ nfpms:
8181
formats:
8282
- deb
8383

84+
dependencies:
85+
- adduser
86+
8487
contents:
8588
- src: ./packaging/init/evcc.service
8689
dst: /lib/systemd/system/evcc.service

CONTRIBUTING.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
Developing evcc requires [Go][1] 1.23 and [Node][2] 22. We recommend VSCode with the [Go](https://marketplace.visualstudio.com/items?itemName=golang.Go), [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) and [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) extensions.
88

9+
Alternatively, if you use VS Code and [devcontainers](https://code.visualstudio.com/docs/devcontainers/containers), you can use the "Dev containers: Clone repository in container volume" action. This will create a devcontainer with the required toolchain and install the prerequisites as explained below. Wait until the startup log says "Done. Press any key to close the terminal." and check for any errors.
10+
911
We use linters (golangci-lint, Prettier) to keep a coherent source code formatting. It's recommended to use the format-on-save feature of your editor. You can manually reformat your code by running:
1012

1113
```sh

Dockerfile

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# STEP 1 build ui
2-
FROM --platform=$BUILDPLATFORM node:22-alpine as node
2+
FROM --platform=$BUILDPLATFORM node:22-alpine AS node
33

44
RUN apk update && apk add --no-cache make
55

@@ -20,7 +20,7 @@ RUN make ui
2020

2121

2222
# STEP 2 build executable binary
23-
FROM --platform=$BUILDPLATFORM golang:1.23-alpine as builder
23+
FROM --platform=$BUILDPLATFORM golang:1.23-alpine AS builder
2424

2525
# Install git + SSL ca certificates.
2626
# Git is required for fetching the dependencies.
@@ -69,7 +69,7 @@ RUN RELEASE=${RELEASE} GOOS=${TARGETOS} GOARCH=${TARGETARCH} make build
6969

7070

7171
# STEP 3 build a small image including module support
72-
FROM alpine:3.19
72+
FROM alpine:3.20
7373

7474
WORKDIR /app
7575

api/api.go

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ type BatteryCapacity interface {
4444
Capacity() float64
4545
}
4646

47+
// MaxACPower provides max AC power in W
48+
type MaxACPower interface {
49+
MaxACPower() float64
50+
}
51+
4752
// ChargeState provides current charging status
4853
type ChargeState interface {
4954
Status() (ChargeStatus, error)

api/globalconfig/types.go

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ type Influx struct {
8888
Org string `json:"org"`
8989
User string `json:"user"`
9090
Password string `json:"password"`
91+
Insecure bool `json:"insecure"`
9192
}
9293

9394
// Redacted implements the redactor interface used by the tee publisher
@@ -98,11 +99,13 @@ func (c Influx) Redacted() any {
9899
Database string `json:"database"`
99100
Org string `json:"org"`
100101
User string `json:"user"`
102+
Insecure bool `json:"insecure"`
101103
}{
102104
URL: c.URL,
103105
Database: c.Database,
104106
Org: c.Org,
105107
User: c.User,
108+
Insecure: c.Insecure,
106109
}
107110
}
108111

assets/css/app.css

+13-5
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323

2424
:root {
2525
--evcc-green: #baffcb;
26-
--evcc-dark-green: #0fde41;
27-
--evcc-darker-green: #0ba631;
28-
--evcc-darkest-green: #076f20;
26+
--evcc-dark-green: #0fde41ff;
27+
--evcc-darker-green: #0ba631ff;
28+
--evcc-darkest-green: #076f20ff;
2929
--evcc-darkest-green-rgb: 11, 166, 49;
3030
--evcc-yellow: #faf000;
3131
--evcc-dark-yellow: #bbb400;
@@ -90,7 +90,7 @@
9090
--evcc-grid: var(--bs-gray-medium);
9191
--evcc-background: var(--bs-gray-deep);
9292
--evcc-box: var(--bs-gray-dark);
93-
--evcc-box-border: var(--vs-gray-darker);
93+
--evcc-box-border: var(--bs-gray-darker);
9494
--evcc-default-text: var(--bs-white);
9595
--evcc-gray: var(--bs-gray-light);
9696
--evcc-accent1: var(--evcc-yellow);
@@ -195,6 +195,10 @@ a:hover {
195195
color: inherit;
196196
}
197197

198+
.evcc-background {
199+
background-color: var(--evcc-background);
200+
}
201+
198202
.btn-primary,
199203
.btn-primary:focus {
200204
background-color: var(--bs-primary);
@@ -217,7 +221,11 @@ a:hover {
217221
color: inherit !important;
218222
background-color: inherit !important;
219223
border-color: inherit !important;
220-
opacity: 0.2;
224+
opacity: 0.3;
225+
}
226+
227+
.dark .btn-disabled {
228+
opacity: 0.4;
221229
}
222230

223231
.btn-outline-primary {

assets/js/colors.js

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { reactive } from "vue";
2+
3+
// alternatives
4+
// const COLORS = [ "#40916C", "#52B788", "#74C69D", "#95D5B2", "#B7E4C7", "#D8F3DC", "#081C15", "#1B4332", "#2D6A4F"];
5+
// const COLORS = ["#577590", "#43AA8B", "#90BE6D", "#F9C74F", "#F8961E", "#F3722C", "#F94144"];
6+
// const COLORS = ["#0077b6", "#00b4d8", "#90e0ef", "#caf0f8", "#03045e"];
7+
// const COLORS = [ "#0077B6FF", "#0096C7FF", "#00B4D8FF", "#48CAE4FF", "#90E0EFFF", "#ADE8F4FF", "#CAF0F8FF", "#03045EFF", "#023E8AFF",
8+
// const COLORS = [ "#0077B6FF", "#00B4D8FF", "#90E0EFFF", "#40A578FF", "#9DDE8BFF", "#F8961EFF", "#F9C74FFF", "#E6FF94FF"];
9+
10+
const colors = reactive({
11+
text: null,
12+
muted: null,
13+
border: null,
14+
self: null,
15+
grid: null,
16+
co2PerKWh: null,
17+
pricePerKWh: null,
18+
price: "#FF912FFF",
19+
co2: "#00916EFF",
20+
background: null,
21+
selfPalette: ["#0fde41ff", "#0ba631ff", "#076f20ff", "#054e18ff", "#043611ff", "#02230bff"],
22+
palette: [
23+
"#03C1EFFF",
24+
"#FD6158FF",
25+
"#31AB4AFF",
26+
"#41517AFF",
27+
"#FF922EFF",
28+
"#0F662DFF",
29+
"#0470D4FF",
30+
"#FFBD2FFF",
31+
"#77C93EFF",
32+
"#4E1D10FF",
33+
"#0AAFBFFF",
34+
"#813504FF",
35+
],
36+
});
37+
38+
function updateCssColors() {
39+
const style = window.getComputedStyle(document.documentElement);
40+
colors.text = style.getPropertyValue("--evcc-default-text");
41+
colors.muted = style.getPropertyValue("--bs-gray-medium");
42+
colors.border = style.getPropertyValue("--bs-border-color-translucent");
43+
colors.self = style.getPropertyValue("--evcc-self");
44+
colors.grid = style.getPropertyValue("--evcc-grid");
45+
colors.background = style.getPropertyValue("--evcc-background");
46+
colors.pricePerKWh = style.getPropertyValue("--bs-gray-medium");
47+
colors.co2PerKWh = style.getPropertyValue("--bs-gray-medium");
48+
}
49+
50+
// update colors on theme change
51+
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", updateCssColors);
52+
updateCssColors();
53+
54+
export const dimColor = (color) => {
55+
return color.toLowerCase().replace(/ff$/, "20");
56+
};
57+
58+
export const fullColor = (color) => {
59+
return color.toLowerCase().replace(/20$/, "ff");
60+
};
61+
62+
export default colors;

assets/js/components/BatterySettingsModal.vue

+12-6
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
@change="changeBufferStart"
161161
>
162162
<span class="text-decoration-underline">
163-
{{ bufferStartOption.name }}
163+
{{ selectedBufferStartName }}
164164
</span>
165165
</CustomSelect>
166166
</small>
@@ -332,20 +332,21 @@ export default {
332332
for (let i = 100; i >= this.bufferSoc; i -= 5) {
333333
options.push({
334334
value: i,
335-
name: this.$t(`batterySettings.bufferStart.${i === 100 ? "full" : "above"}`, {
336-
soc: this.fmtSoc(i),
337-
}),
335+
name: this.getBufferStartName(i),
338336
});
339337
}
340338
options.push({
341339
value: 0,
342-
name: this.$t("batterySettings.bufferStart.never"),
340+
name: this.getBufferStartName(0),
343341
});
344342
return options;
345343
},
346344
bufferStartOption() {
347345
return this.bufferStartOptions.find((option) => this.bufferStartSoc >= option.value);
348346
},
347+
selectedBufferStartName() {
348+
return this.getBufferStartName(this.selectedBufferStartSoc);
349+
},
349350
topHeight() {
350351
return 100 - (this.bufferSoc || 100);
351352
},
@@ -361,7 +362,7 @@ export default {
361362
}
362363
return this.battery
363364
.filter(({ capacity }) => capacity > 0)
364-
.map(({ soc, capacity }) => {
365+
.map(({ soc = 0, capacity }) => {
365366
const multipleBatteries = this.battery.length > 1;
366367
const energy = this.fmtWh(
367368
(capacity / 100) * soc * 1e3,
@@ -488,6 +489,11 @@ export default {
488489
console.error(err);
489490
}
490491
},
492+
getBufferStartName(value) {
493+
const key = value === 0 ? "never" : value === 100 ? "full" : "above";
494+
const soc = this.fmtSoc(value);
495+
return this.$t(`batterySettings.bufferStart.${key}`, { soc });
496+
},
491497
},
492498
};
493499
</script>

assets/js/components/Config/InfluxModal.vue

+13
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@
7373
autocomplete="off"
7474
/>
7575
</FormRow>
76+
<FormRow id="influxInsecure" :label="$t('config.influx.labelInsecure')">
77+
<div class="d-flex">
78+
<input
79+
class="form-check-input"
80+
id="influxInsecure"
81+
type="checkbox"
82+
v-model="values.insecure"
83+
/>
84+
<label class="form-check-label ms-2" for="influxInsecure">
85+
{{ $t("config.influx.labelCheckInsecure") }}
86+
</label>
87+
</div>
88+
</FormRow>
7689
<p>
7790
<button
7891
v-if="showV1(values)"

0 commit comments

Comments
 (0)