Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ab7ea3a
wip
andig Jan 11, 2026
94a9299
wip
andig Jan 11, 2026
ab4edba
wip
andig Jan 11, 2026
1bb02f0
Merge branch 'master' into feat/eebus-always-on
andig Jan 13, 2026
d46db9e
wip
andig Jan 13, 2026
158636d
wip
andig Jan 13, 2026
0ca4522
wip
andig Jan 13, 2026
560b737
wip
andig Jan 13, 2026
5e6ad8e
Simplify
andig Jan 13, 2026
a69ecdf
wip
andig Jan 13, 2026
00a5b49
Add test
andig Jan 14, 2026
0373b01
Update cmd/helper.go
andig Jan 15, 2026
65f26ad
EEBUS: configure by default (#26882)
Maschga Jan 22, 2026
9aed2f7
Update i18n/en.json
andig Jan 22, 2026
686f955
Update i18n/en.json
andig Jan 22, 2026
ff7ca30
Publish ski
andig Jan 22, 2026
952f028
merge
naltatis Jan 22, 2026
914a926
refactor
naltatis Jan 22, 2026
985bc96
fix lint
naltatis Jan 22, 2026
4cca3dd
Update i18n/en.json
andig Jan 22, 2026
502f43e
all advanced, add warning
Maschga Jan 23, 2026
767d39c
add shipid/ski; save/remove flow; explain texts
naltatis Jan 27, 2026
17430ae
redact private cert
Maschga Jan 28, 2026
45b325d
add tests
Maschga Jan 28, 2026
8daeb07
lint
Maschga Jan 28, 2026
18b8849
preserve changed values
Maschga Jan 28, 2026
8fc4575
Merge branch 'master' into eebus-always-on-ui
Maschga Jan 28, 2026
6166f3b
handle yaml configured
Maschga Jan 28, 2026
61d00dd
add services section
Maschga Jan 28, 2026
b07bb0d
fix tests
Maschga Jan 28, 2026
6bbf7e4
fix test
Maschga Jan 28, 2026
aa956c5
Merge branch 'master' into eebus-always-on-ui
andig Jan 28, 2026
6bf5e0b
Remove redactor
andig Jan 29, 2026
89df11a
rename: Info > ConfigStatus
naltatis Jan 30, 2026
f72a3e5
replace hideTags prop with slot check
naltatis Jan 30, 2026
dd0c45f
reuse no-buttons; migrate config.main.yaml to config.general.fromYaml…
naltatis Jan 30, 2026
f5442da
e2e: add from yaml test case
naltatis Jan 30, 2026
3b8bf69
Merge branch 'master' into eebus-always-on-ui
naltatis Jan 30, 2026
2167a44
improve warning message
Maschga Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions api/globalconfig/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ import (
"github.com/evcc-io/evcc/util/modbus"
)

// ConfigStatus for publishing config, status and source to UI and external systems
type ConfigStatus struct {
Config any `json:"config,omitempty"`
Status any `json:"status,omitempty"`
FromYaml bool `json:"fromYaml,omitempty"`
}

type All struct {
Network Network
Ocpp ocpp.Config
Expand Down Expand Up @@ -79,13 +86,6 @@ func (c Hems) Redacted() any {

var _ api.Redactor = (*Mqtt)(nil)

func masked(s any) string {
if s != "" {
return "***"
}
return ""
}

type Mqtt struct {
mqtt.Config `mapstructure:",squash"`
Topic string `json:"topic"`
Expand All @@ -97,12 +97,12 @@ func (m Mqtt) Redacted() any {
Config: mqtt.Config{
Broker: m.Broker,
User: m.User,
Password: masked(m.Password),
Password: util.Masked(m.Password),
ClientID: m.ClientID,
Insecure: m.Insecure,
CaCert: masked(m.CaCert),
ClientCert: masked(m.ClientCert),
ClientKey: masked(m.ClientKey),
CaCert: util.Masked(m.CaCert),
ClientCert: util.Masked(m.ClientCert),
ClientKey: util.Masked(m.ClientKey),
},
Topic: m.Topic,
}
Expand All @@ -124,10 +124,10 @@ func (c Influx) Redacted() any {
return Influx{
URL: c.URL,
Database: c.Database,
Token: masked(c.Token),
Token: util.Masked(c.Token),
Org: c.Org,
User: c.User,
Password: masked(c.Password),
Password: util.Masked(c.Password),
Insecure: c.Insecure,
}
}
Expand All @@ -147,7 +147,7 @@ type MessagingEventTemplate struct {
Title, Msg string
}

func (c Messaging) Configured() bool {
func (c Messaging) IsConfigured() bool {
return len(c.Services) > 0 || len(c.Events) > 0
}

Expand Down
13 changes: 9 additions & 4 deletions assets/js/components/Config/DeviceCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
'round-box--error': error,
'round-box--warning': warning,
'root--unconfigured': unconfigured,
'root--with-tags': $slots.tags,
}"
>
<div class="d-flex align-items-center mb-2">
<div class="d-flex align-items-center" :class="{ 'mb-2': $slots.tags }">
<div class="icon me-2">
<slot name="icon" />
</div>
Expand All @@ -33,8 +34,10 @@
<shopicon-regular-adjust size="s"></shopicon-regular-adjust>
</button>
</div>
<hr class="my-3 divide" />
<slot name="tags" />
<div v-if="$slots.tags">
<hr class="my-3 divide" />
<slot name="tags" />
</div>
</div>
</template>

Expand Down Expand Up @@ -67,7 +70,7 @@ export default {
}
let title = `${this.$t("config.main.name")}: <span class='font-monospace'>${this.name}</span>`;
if (!this.editable) {
title += `<div class="mt-1">${this.$t("config.main.yaml")}</div>`;
title += `<div class="mt-1">${this.$t("config.general.fromYamlHint")}</div>`;
}
return `<div class="text-start">${title}</div>`;
},
Expand Down Expand Up @@ -105,6 +108,8 @@ export default {
list-style-type: none;
border-radius: 1rem;
padding: 1rem 1.5rem;
}
.root--with-tags {
min-height: 8rem;
}
.root--unconfigured {
Expand Down
145 changes: 135 additions & 10 deletions assets/js/components/Config/EebusModal.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,151 @@
<template>
<YamlModal
<JsonModal
id="eebusModal"
:title="$t('config.eebus.title')"
:description="$t('config.eebus.description')"
docs="/docs/reference/configuration/eebus"
:defaultYaml="defaultYaml"
removeKey="eebus"
endpoint="/config/eebus"
state-key="eebus.config"
data-testid="eebus-modal"
:no-buttons="fromYaml"
:confirm-remove="$t('config.eebus.removeConfirm')"
@changed="$emit('changed')"
/>
>
<template #default="{ values }: { values: EebusConfig }">
<p v-if="fromYaml" class="text-muted">
{{ $t("config.general.fromYamlHint") }}
</p>
<FormRow
v-if="values.shipid"
:id="formId('shipid-display')"
:label="$t('config.eebus.shipid')"
:help="$t('config.eebus.shipidExplain')"
>
<input
:id="formId('shipid-display')"
:value="values.shipid"
readonly
class="form-control text-muted"
/>
</FormRow>
<FormRow
v-if="status.ski"
:id="formId('ski-display')"
:label="$t('config.eebus.ski')"
:help="$t('config.eebus.skiExplain')"
>
<input
:id="formId('ski-display')"
:value="status.ski"
readonly
class="form-control text-muted"
/>
</FormRow>
<PropertyCollapsible v-if="!fromYaml">
<template #advanced>
<div class="alert alert-danger">
{{ $t("config.eebus.descriptionAdvanced") }}
</div>
<FormRow
:id="formId('shipid')"
:label="$t('config.eebus.shipid')"
:help="$t('config.eebus.shipidHelp')"
optional
>
<PropertyField
:id="formId('shipid')"
v-model="values.shipid"
type="String"
/>
</FormRow>
<FormRow
:id="formId('port')"
:label="$t('config.eebus.port')"
:help="$t('config.eebus.portHelp')"
optional
>
<PropertyField
:id="formId('port')"
v-model="values.port"
property="port"
type="Int"
/>
</FormRow>
<FormRow
:id="formId('interfaces')"
:label="$t('config.eebus.interfaces')"
:help="$t('config.eebus.interfacesHelp')"
optional
example="eth0"
>
<PropertyField
:id="formId('interfaces')"
v-model="values.interfaces"
type="List"
/>
</FormRow>
<h6>{{ $t("config.eebus.certificate.title") }}</h6>
<FormRow
:id="formId('certificate-public')"
:label="$t('config.eebus.certificate.public')"
>
<PropertyCertField
:id="formId('certificate-public')"
:model-value="values.certificate?.public"
@update:model-value="
values.certificate ? (values.certificate.public = $event) : ''
"
/>
</FormRow>
<FormRow
:id="formId('certificate-private')"
:label="$t('config.eebus.certificate.private')"
>
<PropertyCertField
:id="formId('certificate-private')"
:model-value="values.certificate?.private"
@update:model-value="
values.certificate ? (values.certificate.private = $event) : ''
"
/>
</FormRow>
</template>
</PropertyCollapsible>
</template>
</JsonModal>
</template>

<script>
import YamlModal from "./YamlModal.vue";
import defaultYaml from "./defaultYaml/eebus.yaml?raw";
<script lang="ts">
import type { PropType } from "vue";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type { EebusConfig, EebusStatus } from "@/types/evcc";
import JsonModal from "./JsonModal.vue";
import FormRow from "./FormRow.vue";
import PropertyField from "./PropertyField.vue";
import PropertyCertField from "./PropertyCertField.vue";
import PropertyCollapsible from "./PropertyCollapsible.vue";

export default {
name: "EebusModal",
components: { YamlModal },
components: {
JsonModal,
FormRow,
PropertyField,
PropertyCertField,
PropertyCollapsible,
},
props: {
status: {
type: Object as PropType<EebusStatus>,
default: () => ({}),
},
fromYaml: Boolean,
},
emits: ["changed"],
data() {
return { defaultYaml: defaultYaml.trim() };
methods: {
formId(s: string) {
return `eebus-${s}`;
},
},
};
</script>
2 changes: 1 addition & 1 deletion assets/js/components/Config/HemsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</a>
</div>
<p v-if="fromYaml" class="text-muted">
{{ $t("config.hems.yamlConfigured") }}
{{ $t("config.general.fromYamlHint") }}
</p>
</template>
</YamlModal>
Expand Down
12 changes: 11 additions & 1 deletion assets/js/components/Config/JsonModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export default {
saveMethod: { type: String, default: "post" },
storeValuesInArray: Boolean,
size: { type: String },
confirmRemove: String,
},
emits: ["changed", "open"],
data() {
Expand Down Expand Up @@ -121,7 +122,13 @@ export default {
await this.load();
},
async load() {
this.serverValues = this.stateKey ? store.state[this.stateKey] : store.state;
if (this.stateKey) {
// Support nested keys like "eebus.config"
const keys = this.stateKey.split(".");
this.serverValues = keys.reduce((obj, key) => obj?.[key], store.state);
} else {
this.serverValues = store.state;
}
if (this.transformReadValues) {
this.serverValues = this.transformReadValues(this.serverValues);
}
Expand Down Expand Up @@ -155,6 +162,9 @@ export default {
this.saving = false;
},
async remove() {
if (this.confirmRemove && !window.confirm(this.confirmRemove)) {
return;
}
this.removing = true;
this.error = "";
try {
Expand Down
4 changes: 3 additions & 1 deletion assets/js/components/Config/PropertyField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ export default {
return this.property === "icon";
},
textarea() {
return ["accessToken", "refreshToken", "identifiers"].includes(this.property);
return (
this.array || ["accessToken", "refreshToken", "identifiers"].includes(this.property)
);
},
boolean() {
return this.type === "Bool";
Expand Down
12 changes: 0 additions & 12 deletions assets/js/components/Config/defaultYaml/eebus.yaml

This file was deleted.

25 changes: 24 additions & 1 deletion assets/js/types/evcc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export interface State {
hems?: Hems;
shm?: ShmConfig;
sponsor?: Sponsor;
eebus?: any;
eebus?: Eebus;
modbusproxy?: ModbusProxy[];
messaging?: any;
interval?: number;
Expand Down Expand Up @@ -440,6 +440,29 @@ export enum MODBUS_PROTOCOL {
RTU = "rtu",
}

export type Certificate = {
public: string;
private: string;
};

export type Eebus = {
config: EebusConfig;
status: EebusStatus;
fromYaml?: boolean;
};

export type EebusConfig = {
uri: string;
port: number;
shipid: string;
interfaces?: string[];
certificate?: Certificate;
};

export type EebusStatus = {
ski: string;
};

export type ModbusProxy = {
port: number;
readonly: MODBUS_PROXY_READONLY;
Expand Down
Loading
Loading