Config UI: add heating support (#22177)
This commit is contained in:
parent
b6ff1cad92
commit
f3b60644e8
60 changed files with 1399 additions and 486 deletions
|
|
@ -21,7 +21,7 @@
|
|||
/>
|
||||
|
||||
<YamlEntry
|
||||
v-if="values.type === 'custom'"
|
||||
v-if="showYamlInput"
|
||||
v-model="values.yaml"
|
||||
type="charger"
|
||||
:error-line="test.errorLine"
|
||||
|
|
@ -112,8 +112,16 @@ import {
|
|||
type ModbusCapability,
|
||||
applyDefaultsFromTemplate,
|
||||
createDeviceUtils,
|
||||
customChargerName,
|
||||
} from "./DeviceModal";
|
||||
import defaultYaml from "./defaultYaml/charger.yaml?raw";
|
||||
import customChargerYaml from "./defaultYaml/customCharger.yaml?raw";
|
||||
import customHeaterYaml from "./defaultYaml/customHeater.yaml?raw";
|
||||
import heatpumpYaml from "./defaultYaml/heatpump.yaml?raw";
|
||||
import switchsocketHeaterYaml from "./defaultYaml/switchsocketHeater.yaml?raw";
|
||||
import switchsocketChargerYaml from "./defaultYaml/switchsocketCharger.yaml?raw";
|
||||
import sgreadyYaml from "./defaultYaml/sgready.yaml?raw";
|
||||
import sgreadyBoostYaml from "./defaultYaml/sgreadyBoost.yaml?raw";
|
||||
import { LOADPOINT_TYPE } from "@/types/evcc";
|
||||
|
||||
const initialValues = { type: ConfigType.Template };
|
||||
const device = createDeviceUtils("charger");
|
||||
|
|
@ -157,6 +165,7 @@ export default defineComponent({
|
|||
props: {
|
||||
id: Number,
|
||||
name: String,
|
||||
loadpointType: { type: String as () => LOADPOINT_TYPE | null, default: null },
|
||||
fade: String,
|
||||
isSponsor: Boolean,
|
||||
},
|
||||
|
|
@ -177,35 +186,58 @@ export default defineComponent({
|
|||
computed: {
|
||||
modalTitle() {
|
||||
if (this.isNew) {
|
||||
return this.$t(`config.charger.titleAdd`);
|
||||
return this.$t(`config.charger.titleAdd.${this.loadpointType}`);
|
||||
}
|
||||
return this.$t(`config.charger.titleEdit`);
|
||||
return this.$t(`config.charger.titleEdit.${this.loadpointType}`);
|
||||
},
|
||||
modalSize() {
|
||||
return this.values.type === ConfigType.Custom ? "xl" : undefined;
|
||||
return this.showYamlInput ? "xl" : undefined;
|
||||
},
|
||||
templateOptions() {
|
||||
return [
|
||||
{
|
||||
const result = [];
|
||||
|
||||
if (this.isHeating) {
|
||||
result.push({
|
||||
label: "generic",
|
||||
options: [
|
||||
...this.products.filter((p) => p.group === "heatinggeneric"),
|
||||
...[
|
||||
ConfigType.Custom,
|
||||
ConfigType.SgReadyBoost,
|
||||
ConfigType.SgReady,
|
||||
ConfigType.Heatpump,
|
||||
ConfigType.SwitchSocket,
|
||||
].map((type) =>
|
||||
customTemplateOption(this.$t(customChargerName(type, true)), type)
|
||||
),
|
||||
],
|
||||
});
|
||||
result.push({
|
||||
label: "heatingdevices",
|
||||
options: this.products.filter((p) => p.group === "heating"),
|
||||
});
|
||||
} else {
|
||||
result.push({
|
||||
label: "generic",
|
||||
options: [
|
||||
...this.products.filter((p) => p.group === "generic"),
|
||||
customTemplateOption(this.$t("config.general.customOption")),
|
||||
...[ConfigType.Custom, ConfigType.SwitchSocket].map((type) =>
|
||||
customTemplateOption(this.$t(customChargerName(type, false)), type)
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
});
|
||||
result.push({
|
||||
label: "chargers",
|
||||
options: this.products.filter((p) => !p.group),
|
||||
},
|
||||
{
|
||||
label: "switchsockets",
|
||||
options: this.products.filter((p) => p.group === "switchsockets"),
|
||||
},
|
||||
{
|
||||
label: "heatingdevices",
|
||||
options: this.products.filter((p) => p.group === "heating"),
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
result.push({
|
||||
label: "switchsockets",
|
||||
options: this.products.filter((p) => p.group === "switchsockets"),
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
templateParams() {
|
||||
const params = this.template?.Params || [];
|
||||
|
|
@ -233,7 +265,7 @@ export default defineComponent({
|
|||
this.templateParams.some((p) => p.Name === "connector") &&
|
||||
this.templateParams.some((p) => p.Name === "stationid");
|
||||
if (isOcpp) {
|
||||
return `ws://${window.location.hostname}:8887`;
|
||||
return `ws://${window.location.hostname}:8887/${this.values["stationid"] || ""}`;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
|
@ -250,7 +282,11 @@ export default defineComponent({
|
|||
return this.template?.Requirements?.Description;
|
||||
},
|
||||
productName() {
|
||||
return this.values.deviceProduct || this.templateName || "";
|
||||
return (
|
||||
this.values.deviceProduct ||
|
||||
this.templateName ||
|
||||
this.$t(customChargerName(this.values.type, this.isHeating))
|
||||
);
|
||||
},
|
||||
sponsorTokenRequired() {
|
||||
const requirements = this.template?.Requirements as Requirements | undefined;
|
||||
|
|
@ -269,11 +305,17 @@ export default defineComponent({
|
|||
isNew() {
|
||||
return this.id === undefined;
|
||||
},
|
||||
isHeating() {
|
||||
return this.loadpointType === LOADPOINT_TYPE.HEATING;
|
||||
},
|
||||
isDeletable() {
|
||||
return !this.isNew;
|
||||
},
|
||||
showActions() {
|
||||
return this.templateName || this.values.type === ConfigType.Custom;
|
||||
return this.templateName || this.showYamlInput;
|
||||
},
|
||||
showYamlInput() {
|
||||
return this.isYamlInput(this.values.type);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -311,12 +353,29 @@ export default defineComponent({
|
|||
// TODO: adjust GET response to match POST/PUT formats
|
||||
this.values.type = charger.type;
|
||||
this.values.deviceProduct = charger.deviceProduct;
|
||||
applyDefaultsFromTemplate(this.template, this.values);
|
||||
this.applyDefaults();
|
||||
this.templateName = this.values.template;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
applyDefaults() {
|
||||
applyDefaultsFromTemplate(this.template, this.values);
|
||||
if (this.isHeating) {
|
||||
// enable heating and integrated device params if exist
|
||||
const hasParam = (name: string) =>
|
||||
this.template?.Params.some((p) => p.Name === name);
|
||||
["heating", "integrateddevice"].forEach((param) => {
|
||||
if (hasParam(param) && this.values[param] === undefined) {
|
||||
this.values[param] = true;
|
||||
}
|
||||
});
|
||||
// default heater icon
|
||||
if (hasParam("icon") && this.values["icon"] === undefined) {
|
||||
this.values["icon"] = "heater";
|
||||
}
|
||||
}
|
||||
},
|
||||
async loadProducts() {
|
||||
if (!this.isModalVisible) {
|
||||
return;
|
||||
|
|
@ -329,11 +388,11 @@ export default defineComponent({
|
|||
},
|
||||
async loadTemplate() {
|
||||
this.template = null;
|
||||
if (!this.templateName || this.templateName === ConfigType.Custom) return;
|
||||
if (!this.templateName || this.isYamlInput(this.templateName as ConfigType)) return;
|
||||
this.loadingTemplate = true;
|
||||
try {
|
||||
this.template = await device.loadTemplate(this.templateName, this.$i18n?.locale);
|
||||
applyDefaultsFromTemplate(this.template, this.values);
|
||||
this.applyDefaults();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
|
@ -407,13 +466,38 @@ export default defineComponent({
|
|||
this.isModalVisible = false;
|
||||
},
|
||||
templateChanged(e: Event) {
|
||||
const value = (e.target as HTMLSelectElement).value;
|
||||
const value = (e.target as HTMLSelectElement).value as ConfigType;
|
||||
this.reset();
|
||||
if (value === ConfigType.Custom) {
|
||||
this.values.type = ConfigType.Custom;
|
||||
this.values.yaml = defaultYaml;
|
||||
if (this.isYamlInput(value)) {
|
||||
this.values.type = value;
|
||||
this.values.yaml = this.defaultYaml(value);
|
||||
}
|
||||
},
|
||||
defaultYaml(type: ConfigType) {
|
||||
switch (type) {
|
||||
case ConfigType.Custom:
|
||||
return this.isHeating ? customHeaterYaml : customChargerYaml;
|
||||
case ConfigType.Heatpump:
|
||||
return heatpumpYaml;
|
||||
case ConfigType.SwitchSocket:
|
||||
return this.isHeating ? switchsocketHeaterYaml : switchsocketChargerYaml;
|
||||
case ConfigType.SgReady:
|
||||
return sgreadyYaml;
|
||||
case ConfigType.SgReadyBoost:
|
||||
return sgreadyBoostYaml;
|
||||
default: // template
|
||||
return "";
|
||||
}
|
||||
},
|
||||
isYamlInput(type: ConfigType) {
|
||||
return [
|
||||
ConfigType.Custom,
|
||||
ConfigType.Heatpump,
|
||||
ConfigType.SwitchSocket,
|
||||
ConfigType.SgReady,
|
||||
ConfigType.SgReadyBoost,
|
||||
].includes(type);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<li class="root round-box" :class="{ 'round-box--error': error }">
|
||||
<div class="root round-box" :class="{ 'round-box--error': error }">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="icon me-2">
|
||||
<slot name="icon" />
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
<hr class="my-3 divide" />
|
||||
<slot name="tags" />
|
||||
</li>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export default defineComponent({
|
|||
},
|
||||
});
|
||||
|
||||
export function customTemplateOption(name: string) {
|
||||
return { template: "custom", name };
|
||||
export function customTemplateOption(name: string, template = "custom") {
|
||||
return { name, template };
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ export const timeout = 15000;
|
|||
export enum ConfigType {
|
||||
Template = "template",
|
||||
Custom = "custom",
|
||||
Heatpump = "heatpump",
|
||||
SwitchSocket = "switchsocket",
|
||||
SgReady = "sgready",
|
||||
SgReadyBoost = "sgready-boost",
|
||||
}
|
||||
|
||||
export function applyDefaultsFromTemplate(template: Template | null, values: DeviceValues) {
|
||||
|
|
@ -68,6 +72,18 @@ export function applyDefaultsFromTemplate(template: Template | null, values: Dev
|
|||
});
|
||||
}
|
||||
|
||||
export function customChargerName(type: ConfigType, isHeating: boolean) {
|
||||
if (!type) {
|
||||
return "config.general.customOption";
|
||||
}
|
||||
const prefix = "config.charger.type.";
|
||||
const suffix = isHeating ? ".heating" : ".charging";
|
||||
if (type === ConfigType.Custom) {
|
||||
return `${prefix}custom${suffix}`;
|
||||
}
|
||||
return `${prefix}${type}`;
|
||||
}
|
||||
|
||||
export function createDeviceUtils(deviceType: DeviceType) {
|
||||
function test(id: number | undefined, data: any) {
|
||||
let url = `config/test/${deviceType}`;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import formatter, { POWER_UNIT } from "@/mixins/formatter";
|
|||
|
||||
const NO_TRUNCATE = ["phasePowers", "phaseVoltages", "phaseCurrents"];
|
||||
|
||||
const HIDDEN_TAGS = ["icon", "heating", "integratedDevice"];
|
||||
|
||||
export default {
|
||||
name: "DeviceTags",
|
||||
mixins: [formatter],
|
||||
|
|
@ -37,11 +39,11 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
entries() {
|
||||
return Object.entries(this.tags).map(
|
||||
([name, { value, error, warning, muted, options }]) => {
|
||||
return Object.entries(this.tags)
|
||||
.filter(([name]) => !HIDDEN_TAGS.includes(name))
|
||||
.map(([name, { value, error, warning, muted, options }]) => {
|
||||
return { name, value, error, warning, muted, options };
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -9,11 +9,27 @@
|
|||
@opened="onOpened"
|
||||
@close="onClose"
|
||||
>
|
||||
<form ref="form" class="container mx-0 px-0" @submit.prevent="isNew ? create() : update()">
|
||||
<div v-if="!loadpointType" class="d-flex flex-column gap-4">
|
||||
<NewDeviceButton
|
||||
v-for="t in typeChoices"
|
||||
:key="t"
|
||||
:title="$t(`config.loadpoint.option.${t}`)"
|
||||
class="addButton"
|
||||
@click="selectType(t)"
|
||||
/>
|
||||
</div>
|
||||
<form
|
||||
v-else
|
||||
ref="form"
|
||||
class="container mx-0 px-0"
|
||||
@submit.prevent="isNew ? create() : update()"
|
||||
>
|
||||
<FormRow
|
||||
id="loadpointParamTitle"
|
||||
:label="$t('config.loadpoint.titleLabel')"
|
||||
:example="$t('config.loadpoint.titleExample')"
|
||||
:example="
|
||||
loadpointType ? $t(`config.loadpoint.titleExample.${loadpointType}`) : undefined
|
||||
"
|
||||
>
|
||||
<PropertyField
|
||||
id="loadpointParamTitle"
|
||||
|
|
@ -26,8 +42,8 @@
|
|||
<FormRow
|
||||
v-if="charger || !isNew"
|
||||
id="loadpointParamCharger"
|
||||
:label="$t('config.loadpoint.chargerLabel')"
|
||||
:error="!charger ? $t('config.loadpoint.chargerError') : null"
|
||||
:label="$t(`config.loadpoint.chargerLabel.${loadpointType}`)"
|
||||
:error="!charger ? $t(`config.loadpoint.chargerError.${loadpointType}`) : undefined"
|
||||
>
|
||||
<div class="d-flex">
|
||||
<PropertyField
|
||||
|
|
@ -56,7 +72,7 @@
|
|||
:disabled="values.title?.length === 0"
|
||||
@click.prevent="editCharger"
|
||||
>
|
||||
{{ $t("config.loadpoint.addCharger") }}
|
||||
{{ addChargerLabel }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="charger || !isNew">
|
||||
|
|
@ -95,7 +111,7 @@
|
|||
tabindex="0"
|
||||
@click="editMeter"
|
||||
>
|
||||
{{ $t("config.loadpoint.addMeter") }}
|
||||
{{ $t(`config.loadpoint.addMeter`) }}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -108,8 +124,8 @@
|
|||
:label="$t('config.loadpoint.defaultModeLabel')"
|
||||
:help="
|
||||
values.defaultMode === ''
|
||||
? $t('config.loadpoint.defaultModeHelpKeep')
|
||||
: $t('config.loadpoint.defaultModeHelp')
|
||||
? $t(`config.loadpoint.defaultModeHelpKeep`)
|
||||
: $t(`config.loadpoint.defaultModeHelp.${loadpointType}`)
|
||||
"
|
||||
>
|
||||
<PropertyField
|
||||
|
|
@ -129,7 +145,6 @@
|
|||
</FormRow>
|
||||
|
||||
<FormRow
|
||||
v-show="showAll"
|
||||
id="loadpointSolarMode"
|
||||
:label="$t('config.loadpoint.solarBehaviorLabel')"
|
||||
:help="
|
||||
|
|
@ -281,7 +296,6 @@
|
|||
</div>
|
||||
|
||||
<FormRow
|
||||
v-show="showAll"
|
||||
v-if="showPriority"
|
||||
id="loadpointParamPriority"
|
||||
:label="$t('config.loadpoint.priorityLabel')"
|
||||
|
|
@ -298,7 +312,7 @@
|
|||
/>
|
||||
</FormRow>
|
||||
|
||||
<h6 v-show="showAll">
|
||||
<h6>
|
||||
{{ $t("config.loadpoint.electricalTitle") }}
|
||||
<small class="text-muted">{{
|
||||
$t("config.loadpoint.electricalSubtitle")
|
||||
|
|
@ -334,7 +348,11 @@
|
|||
id="loadpointMinCurrent"
|
||||
:label="$t('config.loadpoint.minCurrentLabel')"
|
||||
class="col-sm-6 mb-sm-0"
|
||||
:help="values.minCurrent < 6 ? $t('config.loadpoint.minCurrentHelp') : null"
|
||||
:help="
|
||||
values.minCurrent < 6
|
||||
? $t('config.loadpoint.minCurrentHelp')
|
||||
: undefined
|
||||
"
|
||||
>
|
||||
<PropertyField
|
||||
id="loadpointMinCurrent"
|
||||
|
|
@ -354,7 +372,7 @@
|
|||
:help="
|
||||
values.maxCurrent < values.minCurrent
|
||||
? $t('config.loadpoint.maxCurrentHelp')
|
||||
: null
|
||||
: undefined
|
||||
"
|
||||
>
|
||||
<PropertyField
|
||||
|
|
@ -371,7 +389,6 @@
|
|||
|
||||
<template v-if="!chargerIsSinglePhase">
|
||||
<FormRow
|
||||
v-show="showAll"
|
||||
v-if="chargerSupports1p3p"
|
||||
id="loadpointParamPhases"
|
||||
:label="$t('config.loadpoint.phasesAutomatic')"
|
||||
|
|
@ -380,7 +397,6 @@
|
|||
</FormRow>
|
||||
<FormRow
|
||||
v-else
|
||||
v-show="showAll"
|
||||
id="loadpointParamPhases"
|
||||
:label="$t('config.loadpoint.phasesLabel')"
|
||||
:help="$t('config.loadpoint.phasesHelp')"
|
||||
|
|
@ -389,10 +405,7 @@
|
|||
id="loadpointParamPhases"
|
||||
v-model="values.phasesConfigured"
|
||||
class="w-100"
|
||||
:options="[
|
||||
{ value: 1, name: $t('config.loadpoint.phases1p') },
|
||||
{ value: 3, name: $t('config.loadpoint.phases3p') },
|
||||
]"
|
||||
:options="phasesOptions"
|
||||
transparent
|
||||
equal-width
|
||||
/>
|
||||
|
|
@ -400,7 +413,6 @@
|
|||
</template>
|
||||
|
||||
<FormRow
|
||||
v-show="showAll"
|
||||
v-if="showCircuit"
|
||||
id="loadpointParamCircuit"
|
||||
:label="$t('config.loadpoint.circuitLabel')"
|
||||
|
|
@ -416,107 +428,102 @@
|
|||
/>
|
||||
</FormRow>
|
||||
|
||||
<h6 v-show="showAll">{{ $t("config.loadpoint.vehiclesTitle") }}</h6>
|
||||
<div v-if="!chargerIsIntegratedDevice">
|
||||
<h6>{{ $t("config.loadpoint.vehiclesTitle") }}</h6>
|
||||
|
||||
<div v-if="vehicleOptions.length">
|
||||
<FormRow
|
||||
id="loadpointParamVehicle"
|
||||
:label="$t('config.loadpoint.vehicleLabel')"
|
||||
:help="
|
||||
values.vehicle
|
||||
? $t('config.loadpoint.vehicleHelpDefault')
|
||||
: $t('config.loadpoint.vehicleHelpAutoDetection')
|
||||
"
|
||||
>
|
||||
<PropertyField
|
||||
<div v-if="vehicleOptions.length">
|
||||
<FormRow
|
||||
id="loadpointParamVehicle"
|
||||
v-model="values.vehicle"
|
||||
type="Choice"
|
||||
class="me-2"
|
||||
:choice="allVehicleOptions"
|
||||
required
|
||||
/>
|
||||
</FormRow>
|
||||
:label="$t('config.loadpoint.vehicleLabel')"
|
||||
:help="
|
||||
values.vehicle
|
||||
? $t('config.loadpoint.vehicleHelpDefault')
|
||||
: $t('config.loadpoint.vehicleHelpAutoDetection')
|
||||
"
|
||||
>
|
||||
<PropertyField
|
||||
id="loadpointParamVehicle"
|
||||
v-model="values.vehicle"
|
||||
type="Choice"
|
||||
class="me-2"
|
||||
:choice="allVehicleOptions"
|
||||
required
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<FormRow
|
||||
v-show="showAll"
|
||||
id="loadpointPollMode"
|
||||
:label="$t('config.loadpoint.pollModeLabel')"
|
||||
:help="
|
||||
values.soc.poll.mode === 'charging'
|
||||
? $t('config.loadpoint.pollModeChargingHelp')
|
||||
: values.soc.poll.mode === 'connected'
|
||||
? $t('config.loadpoint.pollModeConnectedHelp')
|
||||
: values.soc.poll.mode === 'always'
|
||||
? $t('config.loadpoint.pollModeAlwaysHelp')
|
||||
: null
|
||||
"
|
||||
>
|
||||
<SelectGroup
|
||||
<FormRow
|
||||
id="loadpointPollMode"
|
||||
v-model="values.soc.poll.mode"
|
||||
class="w-100"
|
||||
:options="[
|
||||
{
|
||||
value: 'charging',
|
||||
name: $t('config.loadpoint.pollModeCharging'),
|
||||
},
|
||||
{
|
||||
value: 'connected',
|
||||
name: $t('config.loadpoint.pollModeConnected'),
|
||||
},
|
||||
{ value: 'always', name: $t('config.loadpoint.pollModeAlways') },
|
||||
]"
|
||||
transparent
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow
|
||||
v-show="showAll"
|
||||
v-if="values.soc.poll.mode !== 'charging'"
|
||||
id="loadpointPollInterval"
|
||||
class="ms-3 mb-5"
|
||||
:label="$t('config.loadpoint.pollIntervalLabel')"
|
||||
:help="$t('config.loadpoint.pollIntervalHelp')"
|
||||
:danger="$t('config.loadpoint.pollIntervalDanger')"
|
||||
>
|
||||
<PropertyField
|
||||
:label="$t('config.loadpoint.pollModeLabel')"
|
||||
:help="
|
||||
values.soc.poll.mode === 'charging'
|
||||
? $t('config.loadpoint.pollModeChargingHelp')
|
||||
: values.soc.poll.mode === 'connected'
|
||||
? $t('config.loadpoint.pollModeConnectedHelp')
|
||||
: values.soc.poll.mode === 'always'
|
||||
? $t('config.loadpoint.pollModeAlwaysHelp')
|
||||
: undefined
|
||||
"
|
||||
>
|
||||
<SelectGroup
|
||||
id="loadpointPollMode"
|
||||
v-model="values.soc.poll.mode"
|
||||
class="w-100"
|
||||
:options="[
|
||||
{
|
||||
value: 'charging',
|
||||
name: $t('config.loadpoint.pollModeCharging'),
|
||||
},
|
||||
{
|
||||
value: 'connected',
|
||||
name: $t('config.loadpoint.pollModeConnected'),
|
||||
},
|
||||
{
|
||||
value: 'always',
|
||||
name: $t('config.loadpoint.pollModeAlways'),
|
||||
},
|
||||
]"
|
||||
transparent
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow
|
||||
v-if="values.soc.poll.mode !== 'charging'"
|
||||
id="loadpointPollInterval"
|
||||
v-model="values.soc.poll.interval"
|
||||
type="Duration"
|
||||
unit="minute"
|
||||
size="w-25 w-min-200"
|
||||
class="me-2"
|
||||
required
|
||||
/>
|
||||
</FormRow>
|
||||
class="ms-3 mb-5"
|
||||
:label="$t('config.loadpoint.pollIntervalLabel')"
|
||||
:help="$t('config.loadpoint.pollIntervalHelp')"
|
||||
:danger="$t('config.loadpoint.pollIntervalDanger')"
|
||||
>
|
||||
<PropertyField
|
||||
id="loadpointPollInterval"
|
||||
v-model="values.soc.poll.interval"
|
||||
type="Duration"
|
||||
unit="minute"
|
||||
size="w-25 w-min-200"
|
||||
class="me-2"
|
||||
required
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<div v-show="showAll" class="d-flex mb-4">
|
||||
<input
|
||||
id="loadpointEstimate"
|
||||
v-model="values.soc.estimate"
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label class="form-check-label ms-2" for="loadpointEstimate">
|
||||
{{ $t("config.loadpoint.estimateLabel") }}
|
||||
</label>
|
||||
<div>
|
||||
<div class="d-flex mb-4">
|
||||
<input
|
||||
id="loadpointEstimate"
|
||||
v-model="values.soc.estimate"
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label class="form-check-label ms-2" for="loadpointEstimate">
|
||||
{{ $t("config.loadpoint.estimateLabel") }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p class="text-muted">{{ $t("config.loadpoint.noVehicles") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else v-show="showAll">
|
||||
<p class="text-muted">{{ $t("config.loadpoint.noVehicles") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-if="!showAll && values.charger"
|
||||
class="btn btn-link btn-sm text-gray px-0 border-0 d-flex align-items-center mb-2"
|
||||
type="button"
|
||||
tabindex="0"
|
||||
@click="showAllSelected = true"
|
||||
>
|
||||
{{ $t("config.loadpoint.showAllSettings") }}
|
||||
</button>
|
||||
|
||||
<div v-if="values.charger" class="mt-5 mb-4 d-flex justify-content-between">
|
||||
<button
|
||||
v-if="isDeletable"
|
||||
|
|
@ -548,7 +555,7 @@
|
|||
</GenericModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import FormRow from "./FormRow.vue";
|
||||
import PropertyField from "./PropertyField.vue";
|
||||
import SelectGroup from "../Helper/SelectGroup.vue";
|
||||
|
|
@ -558,10 +565,14 @@ import deepClone from "@/utils/deepClone";
|
|||
import deepEqual from "@/utils/deepEqual";
|
||||
import formatter, { POWER_UNIT } from "@/mixins/formatter";
|
||||
import EditIcon from "../MaterialIcon/Edit.vue";
|
||||
import NewDeviceButton from "./NewDeviceButton.vue";
|
||||
import { type ConfigType, handleError, customChargerName } from "./DeviceModal";
|
||||
import { LOADPOINT_TYPE } from "@/types/evcc";
|
||||
|
||||
const nsPerMin = 60 * 1e9;
|
||||
|
||||
const defaultValues = {
|
||||
id: undefined,
|
||||
title: "",
|
||||
phasesConfigured: 3,
|
||||
minCurrent: 6,
|
||||
|
|
@ -587,57 +598,79 @@ const defaultThresholds = {
|
|||
disable: { delay: 3 * nsPerMin, threshold: 0 },
|
||||
};
|
||||
|
||||
type LoadpointValues = typeof defaultValues;
|
||||
|
||||
type Charger = {
|
||||
name: string;
|
||||
deviceProduct: string;
|
||||
type: ConfigType;
|
||||
config: { template: string };
|
||||
};
|
||||
|
||||
type Meter = {
|
||||
name: string;
|
||||
deviceProduct: string;
|
||||
config: { template: string };
|
||||
};
|
||||
|
||||
type Circuit = {
|
||||
name: string;
|
||||
config: { title: string };
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "LoadpointModal",
|
||||
components: { FormRow, PropertyField, GenericModal, SelectGroup, EditIcon },
|
||||
components: { FormRow, PropertyField, GenericModal, SelectGroup, EditIcon, NewDeviceButton },
|
||||
mixins: [formatter],
|
||||
props: {
|
||||
id: Number,
|
||||
name: String,
|
||||
vehicleOptions: { type: Array, default: () => [] },
|
||||
loadpointCount: Number,
|
||||
loadpointCount: { type: Number, default: 0 },
|
||||
fade: String,
|
||||
chargers: { type: Array, default: () => [] },
|
||||
chargers: { type: Array as () => Charger[], default: () => [] },
|
||||
chargerValues: { type: Object, default: () => {} },
|
||||
meters: { type: Array, default: () => [] },
|
||||
circuits: { type: Array, default: () => [] },
|
||||
meters: { type: Array as () => Meter[], default: () => [] },
|
||||
circuits: { type: Array as () => Circuit[], default: () => [] },
|
||||
},
|
||||
emits: ["updated", "openMeterModal", "openChargerModal", "opened"],
|
||||
data() {
|
||||
return {
|
||||
isModalVisible: false,
|
||||
saving: false,
|
||||
selectedType: null,
|
||||
values: deepClone(defaultValues),
|
||||
selectedType: null as LOADPOINT_TYPE | null,
|
||||
values: deepClone(defaultValues) as LoadpointValues,
|
||||
chargerPower: "11kw",
|
||||
solarMode: "default",
|
||||
tab: "solar",
|
||||
showAllSelected: false,
|
||||
powerUnit: POWER_UNIT,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
modalTitle() {
|
||||
if (this.isNew) {
|
||||
return this.$t(`config.loadpoint.titleAdd`);
|
||||
return this.$t(`config.loadpoint.titleAdd.${this.loadpointType || "unknown"}`);
|
||||
}
|
||||
return this.$t(`config.loadpoint.titleEdit`);
|
||||
return this.$t(`config.loadpoint.titleEdit.${this.loadpointType || "unknown"}`);
|
||||
},
|
||||
isNew() {
|
||||
return this.id === undefined;
|
||||
},
|
||||
showAll() {
|
||||
return !this.isNew || this.showAllSelected;
|
||||
},
|
||||
charger() {
|
||||
return this.chargers.find((c) => c.name === this.values.charger);
|
||||
},
|
||||
chargerType() {
|
||||
if (!this.charger) {
|
||||
return null;
|
||||
}
|
||||
return this.chargerIsHeating ? LOADPOINT_TYPE.HEATING : LOADPOINT_TYPE.CHARGING;
|
||||
},
|
||||
chargerTitle() {
|
||||
if (!this.charger) return "";
|
||||
const title =
|
||||
this.charger.deviceProduct ||
|
||||
this.charger.config?.template ||
|
||||
this.$t("config.general.customOption");
|
||||
this.$t(customChargerName(this.charger.type, this.chargerIsHeating));
|
||||
return `${title} [${this.values.charger}]`;
|
||||
},
|
||||
chargerStatus() {
|
||||
|
|
@ -652,6 +685,12 @@ export default {
|
|||
chargerIsSinglePhase() {
|
||||
return this.chargerStatus.singlePhase?.value || false;
|
||||
},
|
||||
chargerIsIntegratedDevice() {
|
||||
return this.chargerStatus.integratedDevice?.value || false;
|
||||
},
|
||||
chargerIsHeating() {
|
||||
return this.chargerStatus.heating?.value === true;
|
||||
},
|
||||
meterTitle() {
|
||||
const name = this.values.meter;
|
||||
if (!name) return "";
|
||||
|
|
@ -669,12 +708,21 @@ export default {
|
|||
return this.isNew ? this.loadpointCount > 0 : this.loadpointCount > 1;
|
||||
},
|
||||
priorityOptions() {
|
||||
const result = Array.from({ length: 11 }, (_, i) => ({ key: i, name: `${i}` }));
|
||||
const result = Array.from({ length: 11 }, (_, i) => ({ key: i, name: `${i}` })) as {
|
||||
key?: number;
|
||||
name: string;
|
||||
}[];
|
||||
result[0].name = "0 (default)";
|
||||
result[0].key = undefined;
|
||||
result[10].name = "10 (highest)";
|
||||
return result;
|
||||
},
|
||||
phasesOptions() {
|
||||
return [
|
||||
{ value: "1", name: this.$t("config.loadpoint.phases1p") },
|
||||
{ value: "3", name: this.$t("config.loadpoint.phases3p") },
|
||||
];
|
||||
},
|
||||
showCircuit() {
|
||||
return this.circuits.length > 0;
|
||||
},
|
||||
|
|
@ -692,6 +740,18 @@ export default {
|
|||
...this.vehicleOptions,
|
||||
];
|
||||
},
|
||||
typeChoices(): LOADPOINT_TYPE[] {
|
||||
return Object.values(LOADPOINT_TYPE);
|
||||
},
|
||||
loadpointType(): LOADPOINT_TYPE | null {
|
||||
return this.selectedType ?? this.chargerType;
|
||||
},
|
||||
addChargerLabel() {
|
||||
if (this.loadpointType) {
|
||||
return this.$t(`config.loadpoint.addCharger.${this.loadpointType}`);
|
||||
}
|
||||
return "";
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isModalVisible(visible) {
|
||||
|
|
@ -728,6 +788,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
reset() {
|
||||
this.selectedType = null;
|
||||
this.values = deepClone(defaultValues);
|
||||
this.updatePhases();
|
||||
},
|
||||
|
|
@ -748,10 +809,9 @@ export default {
|
|||
const values = deepClone(this.values);
|
||||
await api.put(`config/loadpoints/${this.id}`, values);
|
||||
this.$emit("updated");
|
||||
this.$refs.modal.close();
|
||||
(this.$refs["modal"] as any).close();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert("update failed");
|
||||
handleError(e, "update failed");
|
||||
}
|
||||
this.saving = false;
|
||||
},
|
||||
|
|
@ -759,7 +819,7 @@ export default {
|
|||
try {
|
||||
await api.delete(`config/loadpoints/${this.id}`);
|
||||
this.$emit("updated");
|
||||
this.$refs.modal.close();
|
||||
(this.$refs["modal"] as any).close();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert("delete failed");
|
||||
|
|
@ -770,11 +830,9 @@ export default {
|
|||
try {
|
||||
await api.post("config/loadpoints", this.values);
|
||||
this.$emit("updated");
|
||||
this.$refs.modal.close();
|
||||
(this.$refs["modal"] as any).close();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const error = e.response?.data?.error;
|
||||
alert(`failed to create loadpoint: ${error}`);
|
||||
handleError(e, "create failed");
|
||||
}
|
||||
this.saving = false;
|
||||
},
|
||||
|
|
@ -785,21 +843,20 @@ export default {
|
|||
this.$emit("opened");
|
||||
},
|
||||
onClose() {
|
||||
this.showAllSelected = false;
|
||||
this.isModalVisible = false;
|
||||
},
|
||||
editCharger() {
|
||||
this.$emit("openChargerModal", this.values.charger);
|
||||
this.$emit("openChargerModal", this.values.charger, this.loadpointType);
|
||||
},
|
||||
editMeter() {
|
||||
this.$emit("openMeterModal", this.values.meter);
|
||||
},
|
||||
// called externally
|
||||
setMeter(meter) {
|
||||
setMeter(meter: string) {
|
||||
this.values.meter = meter;
|
||||
},
|
||||
// called externally
|
||||
setCharger(charger) {
|
||||
setCharger(charger: string) {
|
||||
this.values.charger = charger;
|
||||
},
|
||||
updateChargerPower() {
|
||||
|
|
@ -835,6 +892,9 @@ export default {
|
|||
return;
|
||||
}
|
||||
},
|
||||
selectType(type: LOADPOINT_TYPE) {
|
||||
this.selectedType = type;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
@open="open"
|
||||
@close="close"
|
||||
>
|
||||
<div v-if="!meterType">
|
||||
<div v-if="!meterType" class="d-flex flex-column gap-4">
|
||||
<NewDeviceButton
|
||||
v-for="t in typeChoices"
|
||||
:key="t"
|
||||
:title="$t(`config.meter.option.${t}`)"
|
||||
class="mb-4 addButton"
|
||||
class="addButton"
|
||||
@click="selectType(t)"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
<template>
|
||||
<li class="root" :class="{ attention }">
|
||||
<button
|
||||
class="d-flex align-items-center justify-content-center p-3"
|
||||
tabindex="0"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<shopicon-regular-plus class="me-1"></shopicon-regular-plus>
|
||||
{{ title }}
|
||||
</button>
|
||||
</li>
|
||||
<button
|
||||
class="root d-flex align-items-center justify-content-center"
|
||||
:class="{ attention }"
|
||||
tabindex="0"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<shopicon-regular-plus class="me-1"></shopicon-regular-plus>
|
||||
<span class="text-start">{{ title }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -26,31 +25,21 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.root {
|
||||
padding: 0;
|
||||
display: block;
|
||||
list-style-type: none;
|
||||
min-height: 9rem;
|
||||
border-radius: 1rem;
|
||||
border: 1px solid var(--evcc-gray-50);
|
||||
padding: 1rem 1rem 0.5rem;
|
||||
padding: 2rem;
|
||||
transition: border-color var(--evcc-transition-fast) linear;
|
||||
background: none;
|
||||
width: 100%;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
.root:hover,
|
||||
.root:focus-within {
|
||||
border-color: var(--evcc-default-text);
|
||||
color: var(--evcc-default-text);
|
||||
}
|
||||
button {
|
||||
border-radius: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: inherit;
|
||||
}
|
||||
button:focus {
|
||||
outline: none;
|
||||
}
|
||||
.attention {
|
||||
animation: wiggle 3s cubic-bezier(0.36, 0.07, 0.19, 0.97) infinite;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
class="btn btn-outline-secondary"
|
||||
:class="key === value ? 'active' : ''"
|
||||
:for="`icon_${key}`"
|
||||
:aria-label="key"
|
||||
>
|
||||
<VehicleIcon v-if="key" :name="key" />
|
||||
<shopicon-regular-minus v-else></shopicon-regular-minus>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
## required attributes
|
||||
## required attributes [type: custom]
|
||||
|
||||
status: # charger status [A..F]
|
||||
status: # charger status (A: not connected, B: connected, C: charging)
|
||||
source: const
|
||||
value: "A"
|
||||
enabled: # is charging enabled?
|
||||
|
|
@ -27,9 +27,6 @@ maxcurrent: # set maximum charge current in A
|
|||
#soc: # state of charge in %
|
||||
# source: const
|
||||
# value: 75
|
||||
#phases: # number of physical phases (1..3)
|
||||
# source: const
|
||||
# value: 3
|
||||
#powers: # phase powers in W
|
||||
# - source: const
|
||||
# value: 3600
|
||||
|
|
@ -51,27 +48,16 @@ maxcurrent: # set maximum charge current in A
|
|||
# value: 230.2
|
||||
# - source: const
|
||||
# value: 230.3
|
||||
#temp: # current temperature in °C (heating)
|
||||
# source: const
|
||||
# value: 45.5
|
||||
#templimit: # temperature limit in °C (heating)
|
||||
# source: const
|
||||
# value: 60
|
||||
#getmode: # SG-Ready mode (heat pump)
|
||||
# source: const
|
||||
# value: 1
|
||||
|
||||
## optional attributes (writeable)
|
||||
|
||||
#maxcurrentmilis: # set maximum charge current in A with decimal precision
|
||||
#maxcurrentmillis: # set maximum charge current in A with decimal precision
|
||||
# source: js
|
||||
# script: console.log(maxcurrentmilis);
|
||||
# script: console.log(maxcurrentmillis);
|
||||
#phases1p3p: # switch phases (requires 'tos: true')
|
||||
# source: js
|
||||
# script: console.log(phases1p3p);
|
||||
#tos: true
|
||||
#wakeup: # wake up vehicle
|
||||
# source: js
|
||||
# script: console.log(wakeup);
|
||||
#setmode: # change SG-Ready mode (1: normal, 2: boost, 3: stop)
|
||||
# source: js
|
||||
# script: console.log(setmode);
|
||||
54
assets/js/components/Config/defaultYaml/customHeater.yaml
Normal file
54
assets/js/components/Config/defaultYaml/customHeater.yaml
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
## required attributes [type: custom]
|
||||
|
||||
status: # heating status (B: standby, C: heating)
|
||||
source: const
|
||||
value: "B"
|
||||
enabled: # is heating enabled?
|
||||
source: const
|
||||
value: true
|
||||
enable: # enable/disable charging
|
||||
source: js
|
||||
script: console.log(enable)
|
||||
maxcurrent: # set maximum heating current in A
|
||||
source: js
|
||||
script: console.log(maxcurrent)
|
||||
|
||||
features:
|
||||
- heating # treat as a heating device
|
||||
- integrateddevice # no charging sessions, no connected vehicles
|
||||
|
||||
## optional attributes (read-only)
|
||||
|
||||
#power: # heating power in W
|
||||
# source: const
|
||||
# value: 11000
|
||||
#energy: # meter reading in kWh
|
||||
# source: const
|
||||
# value: 42.5
|
||||
#powers: # phase powers in W
|
||||
# - source: const
|
||||
# value: 3600
|
||||
# - source: const
|
||||
# value: 3700
|
||||
# - source: const
|
||||
# value: 3800
|
||||
#currents: # phase currents in A
|
||||
# - source: const
|
||||
# value: 16.0
|
||||
# - source: const
|
||||
# value: 16.1
|
||||
# - source: const
|
||||
# value: 16.2
|
||||
#voltages: # phase voltages in V
|
||||
# - source: const
|
||||
# value: 230.1
|
||||
# - source: const
|
||||
# value: 230.2
|
||||
# - source: const
|
||||
# value: 230.3
|
||||
|
||||
## optional attributes (writeable)
|
||||
|
||||
#maxcurrentmillis: # set maximum heating current in A with decimal precision
|
||||
# source: js
|
||||
# script: console.log(maxcurrentmillis);
|
||||
23
assets/js/components/Config/defaultYaml/heatpump.yaml
Normal file
23
assets/js/components/Config/defaultYaml/heatpump.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
## required attributes [type: heatpump]
|
||||
|
||||
setmaxpower: # update the maximum heating power
|
||||
source: js
|
||||
script: console.log(setmaxpower); #
|
||||
|
||||
## optional attributes (read-only)
|
||||
|
||||
#getmaxpower: # heating power in W
|
||||
# source: const
|
||||
# value: 5000
|
||||
#power: # heating power in W
|
||||
# source: const
|
||||
# value: 2000
|
||||
#energy: # meter reading in kWh
|
||||
# source: const
|
||||
# value: 42.5
|
||||
#temp: # current temperature (°C)
|
||||
# source: const
|
||||
# value: 45.5
|
||||
#limittemp: # temperature limit (°C) configured in device
|
||||
# source: const
|
||||
# value: 60
|
||||
29
assets/js/components/Config/defaultYaml/sgready.yaml
Normal file
29
assets/js/components/Config/defaultYaml/sgready.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
## required attributes [type: sgready]
|
||||
|
||||
setmode: # set operation mode (1: reduced, 2: normal, 3 boost)
|
||||
source: js
|
||||
script: console.log(setmode) #
|
||||
|
||||
## optional attributes (read-only)
|
||||
|
||||
#getmode: # operation mode (1: reduced, 2: normal, 3 boost)
|
||||
# source: const
|
||||
# value: 2
|
||||
#power: # charge power in W
|
||||
# source: const
|
||||
# value: 11000
|
||||
#energy: # meter reading in kWh
|
||||
# source: const
|
||||
# value: 42.5
|
||||
#temp: # current temperature (°C)
|
||||
# source: const
|
||||
# value: 42
|
||||
#limittemp: # temperature limit (°C) configured in device
|
||||
# source: const
|
||||
# value: 84
|
||||
|
||||
## optional attributes (writeable)
|
||||
|
||||
#setmaxpower: # update the maximum charging power
|
||||
# source: js
|
||||
# script: console.log(setmaxpower);
|
||||
15
assets/js/components/Config/defaultYaml/sgreadyBoost.yaml
Normal file
15
assets/js/components/Config/defaultYaml/sgreadyBoost.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
## required attributes [type: sgready-boost]
|
||||
|
||||
charger: # configuration of a switch controlling the sg-ready port
|
||||
type: template
|
||||
template: shelly # example shelly
|
||||
host: 192.168.0.101 #
|
||||
|
||||
## optional attributes (read-only)
|
||||
|
||||
#temp: # current temperature (°C)
|
||||
# source: const
|
||||
# value: 42
|
||||
#limittemp: # temperature limit (°C) configured in device
|
||||
# source: const
|
||||
# value: 84
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
## required attributes [type: switchsocket]
|
||||
|
||||
enabled: # is switch enabled?
|
||||
source: const
|
||||
value: true
|
||||
enable: # enable/disable switch
|
||||
source: js
|
||||
script: console.log(enable)
|
||||
power: # charge power reading in W
|
||||
source: const
|
||||
value: 11000
|
||||
standbypower: 20 # in W, below values will be treaded as inactive
|
||||
|
||||
features:
|
||||
- integrateddevice # no charging sessions, no connected vehicles
|
||||
|
||||
## optional attributes (read-only)
|
||||
|
||||
#energy: # meter reading in kWh
|
||||
# source: const
|
||||
# value: 42.5
|
||||
#soc: # charge level (%) of the connected device
|
||||
# source: const
|
||||
# value: 75
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
## required attributes [type: switchsocket]
|
||||
|
||||
enabled: # is switch enabled?
|
||||
source: const
|
||||
value: true
|
||||
enable: # enable/disable switch
|
||||
source: js
|
||||
script: console.log(enable)
|
||||
power: # charge power reading in W
|
||||
source: const
|
||||
value: 11000
|
||||
standbypower: 20 # in W, below values will be treaded as inactive
|
||||
|
||||
features:
|
||||
- heating # treat as a heating device
|
||||
- integrateddevice # no charging sessions, no connected vehicles
|
||||
|
||||
## optional attributes (read-only)
|
||||
|
||||
#energy: # meter reading in kWh
|
||||
# source: const
|
||||
# value: 42.5
|
||||
#soc: # temperature (°C) of the connected device
|
||||
# source: const
|
||||
# value: 75
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
<template>
|
||||
<component :is="singleIcon" v-if="single" :class="`icon icon--${size}`"></component>
|
||||
<component
|
||||
:is="singleIcon"
|
||||
v-if="single"
|
||||
:class="`icon icon--${size}`"
|
||||
role="img"
|
||||
:aria-label="name"
|
||||
></component>
|
||||
<MultiIcon v-else :count="count" :size="size"></MultiIcon>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,11 @@ export enum PHASES {
|
|||
THREE_PHASES = 3,
|
||||
}
|
||||
|
||||
export enum LOADPOINT_TYPE {
|
||||
CHARGING = "charging",
|
||||
HEATING = "heating",
|
||||
}
|
||||
|
||||
export type SessionInfoKey =
|
||||
| "remaining"
|
||||
| "finished"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
>
|
||||
{{ $t("config.main.loadpointRequired") }}
|
||||
</p>
|
||||
<ul class="p-0 config-list">
|
||||
<div class="p-0 config-list">
|
||||
<DeviceCard
|
||||
v-for="loadpoint in loadpoints"
|
||||
:key="loadpoint.name"
|
||||
|
|
@ -47,10 +47,10 @@
|
|||
:attention="loadpointsRequired"
|
||||
@click="newLoadpoint"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 class="my-4">{{ $t("config.section.vehicles") }} 🧪</h2>
|
||||
<ul class="p-0 config-list">
|
||||
<div class="p-0 config-list">
|
||||
<DeviceCard
|
||||
v-for="vehicle in vehicles"
|
||||
:key="vehicle.name"
|
||||
|
|
@ -73,10 +73,10 @@
|
|||
:title="$t('config.main.addVehicle')"
|
||||
@click="newVehicle"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 class="my-4 mt-5">{{ $t("config.section.grid") }} 🧪</h2>
|
||||
<ul class="p-0 config-list">
|
||||
<div class="p-0 config-list">
|
||||
<DeviceCard
|
||||
v-if="gridMeter"
|
||||
:title="$t('config.grid.title')"
|
||||
|
|
@ -120,9 +120,9 @@
|
|||
data-testid="add-tariffs"
|
||||
@click="openModal('tariffsModal')"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
<h2 class="my-4 mt-5">{{ $t("config.section.meter") }} 🧪</h2>
|
||||
<ul class="p-0 config-list">
|
||||
<div class="p-0 config-list">
|
||||
<DeviceCard
|
||||
v-for="meter in pvMeters"
|
||||
:key="meter.name"
|
||||
|
|
@ -169,10 +169,10 @@
|
|||
:title="$t('config.main.addPvBattery')"
|
||||
@click="addSolarBatteryMeter"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 class="my-4 mt-5">{{ $t("config.section.additionalMeter") }} 🧪</h2>
|
||||
<ul class="p-0 config-list">
|
||||
<div class="p-0 config-list">
|
||||
<DeviceCard
|
||||
v-for="meter in auxMeters"
|
||||
:key="meter.name"
|
||||
|
|
@ -198,11 +198,11 @@
|
|||
:title="$t('config.main.addAdditional')"
|
||||
@click="newAdditionalMeter"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 class="my-4 mt-5">{{ $t("config.section.integrations") }} 🧪</h2>
|
||||
|
||||
<ul class="p-0 config-list">
|
||||
<div class="p-0 config-list">
|
||||
<DeviceCard
|
||||
:title="$t('config.mqtt.title')"
|
||||
editable
|
||||
|
|
@ -303,7 +303,7 @@
|
|||
<DeviceTags :tags="hemsTags" />
|
||||
</template>
|
||||
</DeviceCard>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-5" />
|
||||
|
|
@ -348,6 +348,7 @@
|
|||
<ChargerModal
|
||||
:id="selectedChargerId"
|
||||
:name="selectedChargerName"
|
||||
:loadpointType="selectedLoadpointType"
|
||||
:fade="loadpointSubModalOpen ? 'right' : ''"
|
||||
:isSponsor="isSponsor"
|
||||
@added="chargerAdded"
|
||||
|
|
@ -467,6 +468,7 @@ export default {
|
|||
selectedMeterTypeChoices: [],
|
||||
selectedChargerId: undefined,
|
||||
selectedLoadpointId: undefined,
|
||||
selectedLoadpointType: undefined,
|
||||
loadpointSubModalOpen: false,
|
||||
site: { grid: "", pv: [], battery: [], title: "" },
|
||||
deviceValueTimeout: undefined,
|
||||
|
|
@ -689,7 +691,7 @@ export default {
|
|||
chargerModal() {
|
||||
return Modal.getOrCreateInstance(document.getElementById("chargerModal"));
|
||||
},
|
||||
editLoadpointCharger(name) {
|
||||
editLoadpointCharger(name, loadpointType) {
|
||||
this.loadpointSubModalOpen = true;
|
||||
const charger = this.chargers.find((c) => c.name === name);
|
||||
if (charger && charger.id === undefined) {
|
||||
|
|
@ -699,7 +701,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.loadpointModal().hide();
|
||||
this.$nextTick(() => this.editCharger(charger?.id));
|
||||
this.$nextTick(() => this.editCharger(charger?.id, loadpointType));
|
||||
},
|
||||
editLoadpointMeter(name) {
|
||||
this.loadpointSubModalOpen = true;
|
||||
|
|
@ -733,12 +735,9 @@ export default {
|
|||
this.selectedMeterTypeChoices = ["aux", "ext"];
|
||||
this.$nextTick(() => this.meterModal().show());
|
||||
},
|
||||
editCharger(id) {
|
||||
editCharger(id, loadpointType) {
|
||||
this.selectedChargerId = id;
|
||||
this.$nextTick(() => this.chargerModal().show());
|
||||
},
|
||||
newCharger() {
|
||||
this.selectedChargerId = undefined;
|
||||
this.selectedLoadpointType = loadpointType;
|
||||
this.$nextTick(() => this.chargerModal().show());
|
||||
},
|
||||
async meterChanged() {
|
||||
|
|
@ -806,7 +805,7 @@ export default {
|
|||
meterRemoved(type) {
|
||||
if (type === "charge") {
|
||||
// update loadpoint
|
||||
this.$refs.loadpointModal?.setMeter(undefined);
|
||||
this.$refs.loadpointModal?.setMeter("");
|
||||
} else {
|
||||
// update site grid, pv, battery, aux, ext
|
||||
this.loadSite();
|
||||
|
|
@ -819,7 +818,7 @@ export default {
|
|||
this.$refs.loadpointModal?.setCharger(name);
|
||||
},
|
||||
chargerRemoved() {
|
||||
this.$refs.loadpointModal?.setCharger(undefined);
|
||||
this.$refs.loadpointModal?.setCharger("");
|
||||
this.chargerChanged();
|
||||
},
|
||||
meterModalClosed() {
|
||||
|
|
@ -920,7 +919,8 @@ export default {
|
|||
},
|
||||
chargerIcon(chargerName) {
|
||||
const charger = this.chargers.find((c) => c.name === chargerName);
|
||||
return charger?.config?.icon;
|
||||
|
||||
return charger?.config?.icon || this.deviceValues?.charger?.[chargerName]?.icon?.value;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
24
i18n/bg.json
24
i18n/bg.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "Адрес на OCPP сървъра",
|
||||
"switchsockets": "Контакти с прекъсвач",
|
||||
"template": "Производител",
|
||||
"titleAdd": "Добави зарядно",
|
||||
"titleEdit": "Промени зарядно"
|
||||
"titleAdd": {
|
||||
"charging": "Добави зарядно"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Промени зарядно"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Гарантира, че сумата от всички точки на натоварване, свързани към една верига, не надвишава конфигурираните граници на мощност и ток. Веригите могат да бъдат вложени, за да се изгради йерархия.",
|
||||
|
|
@ -172,11 +176,17 @@
|
|||
"v2Support": "Назад към InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Добави зарядно",
|
||||
"addCharger": {
|
||||
"charging": "Добави зарядно"
|
||||
},
|
||||
"addMeter": "Добави електромер за зарядното",
|
||||
"cancel": "Откажи",
|
||||
"chargerError": "Необходимо е да конфигурирате зарядното.",
|
||||
"chargerLabel": "Зарядно",
|
||||
"chargerError": {
|
||||
"charging": "Необходимо е да конфигурирате зарядното."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Зарядно"
|
||||
},
|
||||
"chargerPower11kw": "11 кВт",
|
||||
"chargerPower11kwHelp": "Ще бъде използван ток в диапазона от 6 до 16 А.",
|
||||
"chargerPower22kw": "22 кВт",
|
||||
|
|
@ -187,7 +197,9 @@
|
|||
"chargingTitle": "Зарежда",
|
||||
"circuitLabel": "Верига",
|
||||
"circuitUnassigned": "неразпределен",
|
||||
"defaultModeHelp": "Режим на зареждане при свързване с автомобила.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Режим на зареждане при свързване с автомобила."
|
||||
},
|
||||
"defaultModeHelpKeep": "Запазва последно избрания режим на зареждане.",
|
||||
"defaultModeLabel": "Режим по подразбиране",
|
||||
"delete": "Изтрий",
|
||||
|
|
|
|||
24
i18n/cs.json
24
i18n/cs.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "Přepínatelné zásuvky",
|
||||
"template": "Výrobce",
|
||||
"titleAdd": "Přidat nabíječku",
|
||||
"titleEdit": "Upravit nabíječku"
|
||||
"titleAdd": {
|
||||
"charging": "Přidat nabíječku"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Upravit nabíječku"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Zajišťuje, že součet všech nabíjecích bodů připojených k danému okruhu nepřekročí nastavené limity výkonu a proudu. Okruhy lze vnořovat a vytvářet tak hierarchii.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Zpět na InfluxDB verze 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Přidat nabíječku",
|
||||
"addCharger": {
|
||||
"charging": "Přidat nabíječku"
|
||||
},
|
||||
"addMeter": "Přidat samostatný měřič nabíječky",
|
||||
"cancel": "Zrušit",
|
||||
"chargerError": "Konfigurace nabíječky je povinná.",
|
||||
"chargerLabel": "Nabíječka",
|
||||
"chargerError": {
|
||||
"charging": "Konfigurace nabíječky je povinná."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Nabíječka"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Použije se nastavení proudu od 6 do 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Řízení zátěže zajišťující nepřekročení limitů proudu a výkonu.",
|
||||
"circuitLabel": "Elektrický okruh",
|
||||
"circuitUnassigned": "nepřiřazeno",
|
||||
"defaultModeHelp": "Režim nabíjení po připojení vozidla.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Režim nabíjení po připojení vozidla."
|
||||
},
|
||||
"defaultModeHelpKeep": "Zachová naposledy zvolený režim nabíjení.",
|
||||
"defaultModeLabel": "Výchozí režim",
|
||||
"delete": "Smazat",
|
||||
|
|
|
|||
24
i18n/da.json
24
i18n/da.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "Omskiftelige stikkontakter",
|
||||
"template": "Fabrikant",
|
||||
"titleAdd": "Tilføj oplader",
|
||||
"titleEdit": "Ændre oplader"
|
||||
"titleAdd": {
|
||||
"charging": "Tilføj oplader"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Ændre oplader"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Sikrer, at summen af alle ladepunkter forbundet til et kredsløb ikke overstiger de konfigurerede effekt- og strømgrænser. Kredsløb kan indlejres for at opbygge et hierarki.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Tilbage til InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Tilføj oplader",
|
||||
"addCharger": {
|
||||
"charging": "Tilføj oplader"
|
||||
},
|
||||
"addMeter": "Tilføj dedikeret opladningsmåler",
|
||||
"cancel": "Afbryd",
|
||||
"chargerError": "Konfiguration af en oplader er påkrævet.",
|
||||
"chargerLabel": "Oplader",
|
||||
"chargerError": {
|
||||
"charging": "Konfiguration af en oplader er påkrævet."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Oplader"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Benytter en strømstyrke mellem 6 og 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Belastningsstyring som sikrer, at effekt- og strømgrænser ikke overskrides.",
|
||||
"circuitLabel": "Kredsløb",
|
||||
"circuitUnassigned": "ikke tildelt",
|
||||
"defaultModeHelp": "Opladningstilstand når køretøjet forbindes.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Opladningstilstand når køretøjet forbindes."
|
||||
},
|
||||
"defaultModeHelpKeep": "Gemmer den senest valgte opladningstilstand.",
|
||||
"defaultModeLabel": "Standardtilstand",
|
||||
"delete": "Slet",
|
||||
|
|
|
|||
77
i18n/de.json
77
i18n/de.json
|
|
@ -44,8 +44,24 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "Schaltbare Steckdosen",
|
||||
"template": "Hersteller",
|
||||
"titleAdd": "Wallbox hinzufügen",
|
||||
"titleEdit": "Wallbox bearbeiten"
|
||||
"titleAdd": {
|
||||
"charging": "Wallbox hinzufügen",
|
||||
"heating": "Heizung hinzufügen"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Wallbox bearbeiten",
|
||||
"heating": "Heizung bearbeiten"
|
||||
},
|
||||
"type": {
|
||||
"custom": {
|
||||
"charging": "Benutzerdefinierte Wallbox",
|
||||
"heating": "Benutzerdefinierte Heizung"
|
||||
},
|
||||
"heatpump": "Benutzerdefinierte Wärmepumpe",
|
||||
"sgready": "Benutzerdefinierte Wärmepumpe (sg-ready, komplett)",
|
||||
"sgready-boost": "Benutzerdefinierte Wärmepumpe (sg-ready, boost)",
|
||||
"switchsocket": "Benutzerdefinierte schaltbare Steckdose"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Stellt sicher, dass die Summe aller Ladepunkte, die an einen Stromkreis angeschlossen sind, die konfigurierten Leistungs- und Stromgrenzen nicht überschreitet. Stromkreise können verschachtelt werden, um eine Hierarchie aufzubauen.",
|
||||
|
|
@ -180,11 +196,20 @@
|
|||
"v2Support": "Zurück zu InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Wallbox hinzufügen",
|
||||
"addMeter": "Zusätzlichen Zähler hinzufügen",
|
||||
"addCharger": {
|
||||
"charging": "Wallbox hinzufügen",
|
||||
"heating": "Heizung hinzufügen"
|
||||
},
|
||||
"addMeter": "Zusätzlichen Energiezähler hinzufügen",
|
||||
"cancel": "Abbrechen",
|
||||
"chargerError": "Wallbox muss konfiguriert sein.",
|
||||
"chargerLabel": "Wallbox",
|
||||
"chargerError": {
|
||||
"charging": "Wallbox muss konfiguriert sein.",
|
||||
"heating": "Heizung muss konfiguriert sein."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Wallbox",
|
||||
"heating": "Heizung"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Verwendet einen Strombereich von 6 bis 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -192,11 +217,14 @@
|
|||
"chargerPowerCustom": "andere",
|
||||
"chargerPowerCustomHelp": "Definiere einen eigenen Strombereich.",
|
||||
"chargerTypeLabel": "Ladetyp",
|
||||
"chargingTitle": "Laden",
|
||||
"chargingTitle": "Verhalten",
|
||||
"circuitHelp": "Lastmanagement-Zuordnung, um die Leistungs- und Stromgrenzen nicht zu überschreiten.",
|
||||
"circuitLabel": "Stromkreis",
|
||||
"circuitUnassigned": "nicht zugewiesen",
|
||||
"defaultModeHelp": "Lademodus beim Anschließen des Fahrzeugs.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Lademodus beim Anschließen des Fahrzeugs.",
|
||||
"heating": "Wird beim Systemstart gesetzt."
|
||||
},
|
||||
"defaultModeHelpKeep": "Zuletzt ausgewählter Modus wird beibehalten.",
|
||||
"defaultModeLabel": "Standard-Modus",
|
||||
"delete": "Löschen",
|
||||
|
|
@ -210,6 +238,10 @@
|
|||
"minCurrentHelp": "Gehe nur unter 6 A, wenn du weißt, was du tust.",
|
||||
"minCurrentLabel": "Minimaler Strom",
|
||||
"noVehicles": "Keine Fahrzeuge konfiguriert.",
|
||||
"option": {
|
||||
"charging": "Ladepunkt hinzufügen",
|
||||
"heating": "Heizungsgerät hinzufügen"
|
||||
},
|
||||
"phases1p": "1-phasig",
|
||||
"phases3p": "3-phasig",
|
||||
"phasesAutomatic": "Automatische Phasen",
|
||||
|
|
@ -232,8 +264,8 @@
|
|||
"showAllSettings": "Alle Einstellungen anzeigen",
|
||||
"solarBehaviorCustomHelp": "Definiere eigene Ein- und Ausschaltschwellen und Verzögerungen.",
|
||||
"solarBehaviorDefaultHelp": "Nur mit PV-Überschuss laden. Start nach {enableDelay} Überschuss. Stop wenn für {disableDelay} nicht genug Überschuss vorhanden ist.",
|
||||
"solarBehaviorLabel": "PV-Verhalten",
|
||||
"solarModeCustom": "eigenes",
|
||||
"solarBehaviorLabel": "PV-Überschuss",
|
||||
"solarModeCustom": "manuell",
|
||||
"solarModeMaximum": "nur Sonne",
|
||||
"thresholdDisableDelayLabel": "Ausschaltverzögerung",
|
||||
"thresholdDisableHelpInvalid": "Bitte verwende einen positiven Wert.",
|
||||
|
|
@ -245,9 +277,20 @@
|
|||
"thresholdEnableHelpNegative": "Laden starten, wenn {surplus} Überschuss für {delay} verfügbar ist.",
|
||||
"thresholdEnableHelpZero": "Starten, wenn minimale Ladeleistung für {delay} als Überschuss verfügbar ist.",
|
||||
"thresholdEnableLabel": "Netzleistung einschalten",
|
||||
"titleAdd": "Ladepunkt hinzufügen",
|
||||
"titleEdit": "Ladepunkt bearbeiten",
|
||||
"titleExample": "Garage, Carport, etc.",
|
||||
"titleAdd": {
|
||||
"charging": "Ladepunkt hinzufügen",
|
||||
"heating": "Heizung hinzufügen",
|
||||
"unknown": "Wallbox oder Heizung hinzufügen"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Ladepunkt bearbeiten",
|
||||
"heating": "Heizung bearbeiten",
|
||||
"unknown": "Wallbox oder Heizung bearbeiten"
|
||||
},
|
||||
"titleExample": {
|
||||
"charging": "Garage, Carport, etc.",
|
||||
"heating": "Wärmepumpe, Heizung, etc."
|
||||
},
|
||||
"titleLabel": "Titel",
|
||||
"vehicleAutoDetection": "automatische Erkennung",
|
||||
"vehicleHelpAutoDetection": "Wählt automatisch das plausibelste Fahrzeug aus. Manuelle Übersteuerung möglich.",
|
||||
|
|
@ -258,7 +301,7 @@
|
|||
"main": {
|
||||
"addAdditional": "Zusätzlichen Zähler hinzufügen",
|
||||
"addGrid": "Netzzähler hinzufügen",
|
||||
"addLoadpoint": "Ladepunkt hinzufügen",
|
||||
"addLoadpoint": "Wallbox oder Heizung hinzufügen",
|
||||
"addPvBattery": "PV oder Speicher hinzufügen",
|
||||
"addTariffs": "Tarife hinzufügen",
|
||||
"addVehicle": "Fahrzeug hinzufügen",
|
||||
|
|
@ -351,6 +394,10 @@
|
|||
"big": "big-endian",
|
||||
"little": "little-endian"
|
||||
},
|
||||
"operationMode": {
|
||||
"heating": "Heizen",
|
||||
"standby": "Standby"
|
||||
},
|
||||
"schema": {
|
||||
"http": "HTTP (unverschlüsselt)",
|
||||
"https": "HTTPS (verschlüsselt)"
|
||||
|
|
@ -370,7 +417,7 @@
|
|||
"general": "Allgemein",
|
||||
"grid": "Netzanschluss",
|
||||
"integrations": "Integrationen",
|
||||
"loadpoints": "Ladepunkte",
|
||||
"loadpoints": "Laden & Heizen",
|
||||
"meter": "PV & Batterie",
|
||||
"system": "System",
|
||||
"vehicles": "Fahrzeuge"
|
||||
|
|
|
|||
24
i18n/el.json
24
i18n/el.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "Πρίζες με δυνατότητα εναλλαγής",
|
||||
"template": "Κατασκευαστής",
|
||||
"titleAdd": "Προσθήκη Φορτιστή",
|
||||
"titleEdit": "Επεξεργασία Φορτιστή"
|
||||
"titleAdd": {
|
||||
"charging": "Προσθήκη Φορτιστή"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Επεξεργασία Φορτιστή"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Διασφαλίζει ότι το άθροισμα όλων των σημείων φόρτισης που είναι συνδεδεμένα σε ένα κύκλωμα δεν υπερβαίνει τα οριζόμενα όρια ισχύος και έντασης ρεύματος. Τα κυκλώματα μπορούν να είναι σε ένθετες δομές για τη δημιουργία μιας ιεραρχίας.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Επιστροφή σε InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Προσθήκη φορτιστή",
|
||||
"addCharger": {
|
||||
"charging": "Προσθήκη φορτιστή"
|
||||
},
|
||||
"addMeter": "Προσθήκη αποκλειστικού μετρητή για το φορτιστή",
|
||||
"cancel": "Άκυρο",
|
||||
"chargerError": "Απαιτείται διαμόρφωση φορτιστή.",
|
||||
"chargerLabel": "Φορτιστής",
|
||||
"chargerError": {
|
||||
"charging": "Απαιτείται διαμόρφωση φορτιστή."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Φορτιστής"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Θα χρησιμοποιήσει εύρος έντασης ρεύματος από 6 έως 16 Α.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Εκχώρηση διαχείρισης φορτίου για τη διασφάλιση της μη υπέρβασης των ορίων ισχύος και ρεύματος.",
|
||||
"circuitLabel": "Κύκλωμα",
|
||||
"circuitUnassigned": "μη εκχωρημένο",
|
||||
"defaultModeHelp": "Λειτουργία φόρτισης όταν συνδεθεί το όχημα.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Λειτουργία φόρτισης όταν συνδεθεί το όχημα."
|
||||
},
|
||||
"defaultModeHelpKeep": "Διατηρεί τον τελευταίο επιλεγμένο τρόπο φόρτισης.",
|
||||
"defaultModeLabel": "Προεπιλεγμένη λειτουργία",
|
||||
"delete": "Διαγραφή",
|
||||
|
|
|
|||
95
i18n/en.json
95
i18n/en.json
|
|
@ -44,8 +44,24 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "Switchable sockets",
|
||||
"template": "Manufacturer",
|
||||
"titleAdd": "Add Charger",
|
||||
"titleEdit": "Edit Charger"
|
||||
"titleAdd": {
|
||||
"charging": "Add Charger",
|
||||
"heating": "Add Heater"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Edit Charger",
|
||||
"heating": "Edit Heater"
|
||||
},
|
||||
"type": {
|
||||
"custom": {
|
||||
"charging": "User-defined charger",
|
||||
"heating": "User-defined heater"
|
||||
},
|
||||
"heatpump": "User-defined heat pump",
|
||||
"sgready": "User-defined heat pump (sg-ready, all)",
|
||||
"sgready-boost": "User-defined heat pump (sg-ready, boost)",
|
||||
"switchsocket": "User-defined switch socket"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Ensures, that the sum of all loadpoints connected to a circuit does not exceed the configured power and current limits. Circuits can be nested to build a hierarchy.",
|
||||
|
|
@ -180,11 +196,20 @@
|
|||
"v2Support": "Back to InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Add charger",
|
||||
"addMeter": "Add dedicated charger meter",
|
||||
"addCharger": {
|
||||
"charging": "Add charger",
|
||||
"heating": "Add heater"
|
||||
},
|
||||
"addMeter": "Add dedicated energy meter",
|
||||
"cancel": "Cancel",
|
||||
"chargerError": "Configuring a charger is required.",
|
||||
"chargerLabel": "Charger",
|
||||
"chargerError": {
|
||||
"charging": "Configuring a charger is required.",
|
||||
"heating": "Configuring a heater is required."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Charger",
|
||||
"heating": "Heater"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Will use a current range of 6 to 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -192,12 +217,15 @@
|
|||
"chargerPowerCustom": "other",
|
||||
"chargerPowerCustomHelp": "Define a custom current range.",
|
||||
"chargerTypeLabel": "Charger type",
|
||||
"chargingTitle": "Charging",
|
||||
"chargingTitle": "Behaviour",
|
||||
"circuitHelp": "Load management assignment to ensure power and current limits are not exceeded.",
|
||||
"circuitLabel": "Circuit",
|
||||
"circuitUnassigned": "unassigned",
|
||||
"defaultModeHelp": "Charging mode when connecting the vehicle.",
|
||||
"defaultModeHelpKeep": "Keeps the last selected charging mode.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Charging mode when connecting the vehicle.",
|
||||
"heating": "Is set when on system start."
|
||||
},
|
||||
"defaultModeHelpKeep": "Keeps the last selected mode.",
|
||||
"defaultModeLabel": "Default mode",
|
||||
"delete": "Delete",
|
||||
"electricalSubtitle": "When in doubt, ask your electrician.",
|
||||
|
|
@ -210,11 +238,15 @@
|
|||
"minCurrentHelp": "Only go below 6 A if you know what you're doing.",
|
||||
"minCurrentLabel": "Minimum current",
|
||||
"noVehicles": "No vehicles are configured.",
|
||||
"option": {
|
||||
"charging": "Add charging point",
|
||||
"heating": "Add heating device"
|
||||
},
|
||||
"phases1p": "1-phase",
|
||||
"phases3p": "3-phase",
|
||||
"phasesAutomatic": "Automatic phases",
|
||||
"phasesAutomaticHelp": "Your charger supports automatic switching between 1- and 3-phase charging. In the main screen you can adjust phase behaviour while charging.",
|
||||
"phasesHelp": "Number of phases connected to the charger.",
|
||||
"phasesHelp": "Number of phases connected.",
|
||||
"phasesLabel": "Phases",
|
||||
"pollIntervalDanger": "Regularly querying the vehicle may drain the vehicle battery. Some vehicle manufacturers may actively prevent charging in this case. Not recommended! Only use this if you're aware of the risks.",
|
||||
"pollIntervalHelp": "Time between vehicle API updates. Short intervals may drain the vehicle battery.",
|
||||
|
|
@ -226,28 +258,39 @@
|
|||
"pollModeConnected": "connected",
|
||||
"pollModeConnectedHelp": "Update vehicle status in regular intervals when connected.",
|
||||
"pollModeLabel": "Update behaviour",
|
||||
"priorityHelp": "Higher priority charge points get preferred access to solar surplus.",
|
||||
"priorityHelp": "Higher priority get preferred access to solar surplus.",
|
||||
"priorityLabel": "Priority",
|
||||
"save": "Save",
|
||||
"showAllSettings": "Show all settings",
|
||||
"solarBehaviorCustomHelp": "Define your own enable and disable thresholds and delays.",
|
||||
"solarBehaviorDefaultHelp": "Only charge with solar surplus. Start after {enableDelay} of surplus. Stop when there is not enough surplus for {disableDelay}.",
|
||||
"solarBehaviorLabel": "Solar behaviour",
|
||||
"solarBehaviorDefaultHelp": "Start after {enableDelay} of sufficient surplus. Stop when there is not enough surplus for {disableDelay}.",
|
||||
"solarBehaviorLabel": "Solar",
|
||||
"solarModeCustom": "custom",
|
||||
"solarModeMaximum": "maximum solar",
|
||||
"thresholdDisableDelayLabel": "Disable delay",
|
||||
"thresholdDisableHelpInvalid": "Please use a positive value.",
|
||||
"thresholdDisableHelpPositive": "Stop charging, when more than {power} is used from the grid for {delay}.",
|
||||
"thresholdDisableHelpZero": "Stop when minimum charge power can't be satisfied for {delay}.",
|
||||
"thresholdDisableHelpPositive": "Stop, when more than {power} is used from the grid for {delay}.",
|
||||
"thresholdDisableHelpZero": "Stop when minimum required power can't be satisfied for {delay}.",
|
||||
"thresholdDisableLabel": "Disable grid power",
|
||||
"thresholdEnableDelayLabel": "Enable delay",
|
||||
"thresholdEnableHelpInvalid": "Please use a negative value.",
|
||||
"thresholdEnableHelpNegative": "Start charging, when {surplus} surplus is available for {delay}.",
|
||||
"thresholdEnableHelpZero": "Start when minimum charge power surplus is available for {delay}.",
|
||||
"thresholdEnableHelpNegative": "Start, when {surplus} surplus is available for {delay}.",
|
||||
"thresholdEnableHelpZero": "Start when minimum required power can be satisfied for {delay}.",
|
||||
"thresholdEnableLabel": "Enable grid power",
|
||||
"titleAdd": "Add Charge Point",
|
||||
"titleEdit": "Edit Charge Point",
|
||||
"titleExample": "Garage, Carport, etc.",
|
||||
"titleAdd": {
|
||||
"charging": "Add Charging Point",
|
||||
"heating": "Add Heating Device",
|
||||
"unknown": "Add Charger or Heater"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Edit Charging Point",
|
||||
"heating": "Edit Heating Device",
|
||||
"unknown": "Edit Charger or Heater"
|
||||
},
|
||||
"titleExample": {
|
||||
"charging": "Garage, Carport, etc.",
|
||||
"heating": "Heatpump, Heater, etc."
|
||||
},
|
||||
"titleLabel": "Title",
|
||||
"vehicleAutoDetection": "auto detection",
|
||||
"vehicleHelpAutoDetection": "Automatically selects the most plausible vehicle. Manual override is possible.",
|
||||
|
|
@ -258,13 +301,13 @@
|
|||
"main": {
|
||||
"addAdditional": "Add additional meter",
|
||||
"addGrid": "Add grid meter",
|
||||
"addLoadpoint": "Add charge point",
|
||||
"addLoadpoint": "Add charger or heater",
|
||||
"addPvBattery": "Add solar or battery",
|
||||
"addTariffs": "Add tariffs",
|
||||
"addVehicle": "Add vehicle",
|
||||
"configured": "configured",
|
||||
"edit": "edit",
|
||||
"loadpointRequired": "At least one charge point has to be configured.",
|
||||
"loadpointRequired": "At least one charging point has to be configured.",
|
||||
"name": "Name",
|
||||
"title": "Configuration",
|
||||
"unconfigured": "not configured",
|
||||
|
|
@ -351,6 +394,10 @@
|
|||
"big": "big-endian",
|
||||
"little": "little-endian"
|
||||
},
|
||||
"operationMode": {
|
||||
"heating": "Heating",
|
||||
"standby": "Standby"
|
||||
},
|
||||
"schema": {
|
||||
"http": "HTTP (unencrypted)",
|
||||
"https": "HTTPS (encrypted)"
|
||||
|
|
@ -370,7 +417,7 @@
|
|||
"general": "General",
|
||||
"grid": "Grid",
|
||||
"integrations": "Integrations",
|
||||
"loadpoints": "Charging points",
|
||||
"loadpoints": "Charging & Heating",
|
||||
"meter": "Solar & Battery",
|
||||
"system": "System",
|
||||
"vehicles": "Vehicles"
|
||||
|
|
@ -420,7 +467,7 @@
|
|||
"delete": "Delete",
|
||||
"generic": "Other integrations",
|
||||
"identifiers": "RFID identifiers",
|
||||
"identifiersHelp": "List of RFID strings to identify the vehicle. One entry per line. The current identifier can be found at the respective charge point on the overview page.",
|
||||
"identifiersHelp": "List of RFID strings to identify the vehicle. One entry per line. The current identifier can be found at the respective charging point on the overview page.",
|
||||
"maximumCurrent": "Maximum current",
|
||||
"maximumCurrentHelp": "Must be greater than minimum current.",
|
||||
"maximumPhases": "Maximum phases",
|
||||
|
|
|
|||
24
i18n/fi.json
24
i18n/fi.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-palvelimen URL",
|
||||
"switchsockets": "Kytkettävät pistorasiat",
|
||||
"template": "Valmistaja",
|
||||
"titleAdd": "Lisää laturi",
|
||||
"titleEdit": "Muokkaa laturia"
|
||||
"titleAdd": {
|
||||
"charging": "Lisää laturi"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Muokkaa laturia"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Varmistaa, että kaikkien piiriin kytkettyjen kuormituspisteiden summa ei ylitä määritettyjä teho- ja virtarajoja. Piirejä voi rakentaa sisäkkäin.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Takaisin InfluxDB 2.x:ään"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Lisää laturi",
|
||||
"addCharger": {
|
||||
"charging": "Lisää laturi"
|
||||
},
|
||||
"addMeter": "Lisää erillinen latausmittari",
|
||||
"cancel": "Peruuta",
|
||||
"chargerError": "Vaaditaan käyttöönottoasetusten määrittely laturille.",
|
||||
"chargerLabel": "Laturi",
|
||||
"chargerError": {
|
||||
"charging": "Vaaditaan käyttöönottoasetusten määrittely laturille."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Laturi"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Käyttää 6-16 A:n virta-aluetta.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Kuormanhallinnan määritys varmistaa, että teho ja virtarajoitteita ei ylitetä.",
|
||||
"circuitLabel": "Piiri",
|
||||
"circuitUnassigned": "määräämätön",
|
||||
"defaultModeHelp": "Lataustila ajoneuvoa kytkettäessä.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Lataustila ajoneuvoa kytkettäessä."
|
||||
},
|
||||
"defaultModeHelpKeep": "Säilyttää viimeksi valitun lataustilan.",
|
||||
"defaultModeLabel": "Oletustila",
|
||||
"delete": "Poista",
|
||||
|
|
|
|||
24
i18n/fr.json
24
i18n/fr.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "URL du serveur OCPP",
|
||||
"switchsockets": "Prises commutables",
|
||||
"template": "Fabricant",
|
||||
"titleAdd": "Ajouter un chargeur",
|
||||
"titleEdit": "Modifier chargeur"
|
||||
"titleAdd": {
|
||||
"charging": "Ajouter un chargeur"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Modifier chargeur"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Vérifiez que la somme de tous les points de charges connectés à un circuit ne dépassent pas les limites de puissance et de courant. Les circuits peuvent être combinés pour construire une hiérarchie.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Revenir à InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Ajouter un chargeur",
|
||||
"addCharger": {
|
||||
"charging": "Ajouter un chargeur"
|
||||
},
|
||||
"addMeter": "Ajouter un compteur dédié pour le chargeur",
|
||||
"cancel": "Annuler",
|
||||
"chargerError": "Il est nécessaire de configurer un chargeur.",
|
||||
"chargerLabel": "Chargeur",
|
||||
"chargerError": {
|
||||
"charging": "Il est nécessaire de configurer un chargeur."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Chargeur"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Va utiliser des courants de 6 à 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Assignation de la gestion de charge afin d’assurer que les limites de puissance et de courant ne sont pas dépassées.",
|
||||
"circuitLabel": "Circuit",
|
||||
"circuitUnassigned": "non assigné",
|
||||
"defaultModeHelp": "Mode de charge lors de la connexion du véhicule.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Mode de charge lors de la connexion du véhicule."
|
||||
},
|
||||
"defaultModeHelpKeep": "Conserver le dernier mode de charge sélectionné.",
|
||||
"defaultModeLabel": "Mode par défaut",
|
||||
"delete": "Supprimer",
|
||||
|
|
|
|||
24
i18n/hr.json
24
i18n/hr.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "URL OCPP poslužitelja",
|
||||
"switchsockets": "Promijenjive utičnice",
|
||||
"template": "Proizvođač",
|
||||
"titleAdd": "Dodati punjač",
|
||||
"titleEdit": "Urediti punjač"
|
||||
"titleAdd": {
|
||||
"charging": "Dodati punjač"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Urediti punjač"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Osigurava da suma svih točaka punjenja povezanih na mrežu ne prelazi postavljene granice snage i struje. Krugovi mogu biti složeni hijerarhijski.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Natrag na InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Dodati punjač",
|
||||
"addCharger": {
|
||||
"charging": "Dodati punjač"
|
||||
},
|
||||
"addMeter": "Dodati zasebni strujomjer",
|
||||
"cancel": "Odustati",
|
||||
"chargerError": "Nužno je postaviti punjač.",
|
||||
"chargerLabel": "Punjač",
|
||||
"chargerError": {
|
||||
"charging": "Nužno je postaviti punjač."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Punjač"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Koristiti će raspon struje od 6 i 16A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Postavljanje upravljanja energijom kako bi se osiguralo da se ne prijeđu trenutna ograničenja.",
|
||||
"circuitLabel": "Strujni krug",
|
||||
"circuitUnassigned": "nepostavljen",
|
||||
"defaultModeHelp": "Način punjenja kada se vozilo poveže.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Način punjenja kada se vozilo poveže."
|
||||
},
|
||||
"defaultModeHelpKeep": "Zadržava posljednje korišteni način punjenja.",
|
||||
"defaultModeLabel": "Uobičajeni način",
|
||||
"delete": "Obrisati",
|
||||
|
|
|
|||
24
i18n/hu.json
24
i18n/hu.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "Kapcsolható dugaljak",
|
||||
"template": "Gyártó",
|
||||
"titleAdd": "Töltő Hozzáadása",
|
||||
"titleEdit": "Töltő Szerkesztése"
|
||||
"titleAdd": {
|
||||
"charging": "Töltő Hozzáadása"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Töltő Szerkesztése"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Gondoskodik arról, hogy az áramkörhöz csatlakoztatott összes terhelési pont összege ne haladja meg a beállított teljesítmény- és áramkorlátokat. Az áramkörök egymásba ágyazhatók a hierarchia felépítéséhez.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Vissza az InfluxDB 2.x verzióhoz"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Töltő hozzáadása",
|
||||
"addCharger": {
|
||||
"charging": "Töltő hozzáadása"
|
||||
},
|
||||
"addMeter": "Dedikált töltő fogyasztásmérő hozzáadása",
|
||||
"cancel": "Mégse",
|
||||
"chargerError": "Töltő konfigurálása szükséges.",
|
||||
"chargerLabel": "Töltő",
|
||||
"chargerError": {
|
||||
"charging": "Töltő konfigurálása szükséges."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Töltő"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "6 és 16 A közötti áramtartomány lesz használatban.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Terheléskezelési hozzárendelés a teljesítmény- és áramkorlátok túllépésének biztosítására.",
|
||||
"circuitLabel": "Áramkör",
|
||||
"circuitUnassigned": "nincs hozzárendelve",
|
||||
"defaultModeHelp": "Töltési mód, amikor csatlakoztatja a járművet.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Töltési mód, amikor csatlakoztatja a járművet."
|
||||
},
|
||||
"defaultModeHelpKeep": "A legutoljára kiválasztott töltési mód lesz aktív.",
|
||||
"defaultModeLabel": "Alapértelmezett mód",
|
||||
"delete": "Törlés",
|
||||
|
|
|
|||
24
i18n/it.json
24
i18n/it.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "URL Server OCPP",
|
||||
"switchsockets": "Prese commutabili",
|
||||
"template": "Produttore",
|
||||
"titleAdd": "Aggiungi caricabatterie",
|
||||
"titleEdit": "Modifica caricabatterie"
|
||||
"titleAdd": {
|
||||
"charging": "Aggiungi caricabatterie"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Modifica caricabatterie"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Garantisce che la somma dei carichi connessi ad un circuito non superi i limiti di corrente configurati. I circuiti possono essere annidati in una struttura gerarchica.",
|
||||
|
|
@ -172,11 +176,17 @@
|
|||
"v2Support": "Torna a InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Aggiungi caricabatterie",
|
||||
"addCharger": {
|
||||
"charging": "Aggiungi caricabatterie"
|
||||
},
|
||||
"addMeter": "Aggiungi un contatore dedicato per il caricabatterie",
|
||||
"cancel": "Annulla",
|
||||
"chargerError": "È necessario configurare un caricatore.",
|
||||
"chargerLabel": "Caricabatterie",
|
||||
"chargerError": {
|
||||
"charging": "È necessario configurare un caricatore."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Caricabatterie"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Utilizzerà un intervallo di corrente tra 6 e 16A",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -187,7 +197,9 @@
|
|||
"chargingTitle": "In carica",
|
||||
"circuitLabel": "Circuito",
|
||||
"circuitUnassigned": "non assegnato",
|
||||
"defaultModeHelp": "Modalità di ricarica quando si collega il veicolo.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Modalità di ricarica quando si collega il veicolo."
|
||||
},
|
||||
"defaultModeHelpKeep": "Mantiene l'ultima modalità di ricarica selezionata.",
|
||||
"defaultModeLabel": "Modalità predefinita",
|
||||
"delete": "Cancella",
|
||||
|
|
|
|||
24
i18n/lb.json
24
i18n/lb.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "URL vum OCPP-Server",
|
||||
"switchsockets": "Schaltbar Steckdousen",
|
||||
"template": "Hiersteller",
|
||||
"titleAdd": "Wallbox derbäi fügen",
|
||||
"titleEdit": "Wallbox beaarbechten"
|
||||
"titleAdd": {
|
||||
"charging": "Wallbox derbäi fügen"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Wallbox beaarbechten"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Sécherstellen, datt d'Zomm vun all den Luedstatiounen déi mam Circuit verbonne sinn net déi konfiguréiert Leeschtung an aktuell Grenzen iwwerschreit. Circuiten kënnen agenist ginn fir eng Hierarchie opzebauen.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Zréck op InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Wallbox derbäi fügen",
|
||||
"addCharger": {
|
||||
"charging": "Wallbox derbäi fügen"
|
||||
},
|
||||
"addMeter": "Zousätzlechen Zieler derbäi fügen",
|
||||
"cancel": "Ofbriechen",
|
||||
"chargerError": "Wallbox muss konfiguréiert sinn.",
|
||||
"chargerLabel": "Wallbox",
|
||||
"chargerError": {
|
||||
"charging": "Wallbox muss konfiguréiert sinn."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Wallbox"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Verwennt Stroum vu 6 bis 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Laaschtmanagement-Zouweisung, fir sécher ze goen, dass d'Leeschtung a Stroumlimitten net iwwerschratt ginn.",
|
||||
"circuitLabel": "Stroumkrees",
|
||||
"circuitUnassigned": "net zougewisen",
|
||||
"defaultModeHelp": "Luedmodus beim Uschléisse vum Gefier.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Luedmodus beim Uschléisse vum Gefier."
|
||||
},
|
||||
"defaultModeHelpKeep": "De leschte Modus deen ausgewielt gouf gëtt bäibehal.",
|
||||
"defaultModeLabel": "Standard-Modus",
|
||||
"delete": "Läschen",
|
||||
|
|
|
|||
24
i18n/lt.json
24
i18n/lt.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-Serverio URL",
|
||||
"switchsockets": "Išmanios rozetės",
|
||||
"template": "Gamintojas",
|
||||
"titleAdd": "Pridėti įkroviklį",
|
||||
"titleEdit": "Redaguoti įkroviklį"
|
||||
"titleAdd": {
|
||||
"charging": "Pridėti įkroviklį"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Redaguoti įkroviklį"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Užtikrina, kad naudojant visus į grandinę sujungtus įkroviklius, neviršytumėte sukonfigūruotų galios ir srovės ribų. Grandines galima sudėlioti, kad būtų sukurta hierarchija.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Atgal į InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Pridėti įkroviklį",
|
||||
"addCharger": {
|
||||
"charging": "Pridėti įkroviklį"
|
||||
},
|
||||
"addMeter": "Pridėti įkroviklio skaitiklį",
|
||||
"cancel": "Atšaukti",
|
||||
"chargerError": "Reikia sukonfigūruoti įkroviklį.",
|
||||
"chargerLabel": "Įkroviklis",
|
||||
"chargerError": {
|
||||
"charging": "Reikia sukonfigūruoti įkroviklį."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Įkroviklis"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Naudos įkrovimo srovę nuo 6 iki 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Apkrovos valdymo priskyrimas, siekiant užtikrinti, kad nebūtų viršytos galios ir srovės ribos.",
|
||||
"circuitLabel": "Grandinė",
|
||||
"circuitUnassigned": "nepriskirtas",
|
||||
"defaultModeHelp": "Įkrovimo režimas prijungus automobilį.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Įkrovimo režimas prijungus automobilį."
|
||||
},
|
||||
"defaultModeHelpKeep": "Išsaugo paskutinį pasirinktą įkrovimo režimą.",
|
||||
"defaultModeLabel": "Numatytasis režimas",
|
||||
"delete": "Ištrinti",
|
||||
|
|
|
|||
24
i18n/nl.json
24
i18n/nl.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "schakelbare stopcontacten",
|
||||
"template": "Fabrikant",
|
||||
"titleAdd": "Voeg Lader toe",
|
||||
"titleEdit": "Editeer Lader"
|
||||
"titleAdd": {
|
||||
"charging": "Voeg Lader toe"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Editeer Lader"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Zorgt ervoor dat de som van alle laadpunten die zijn aangesloten op een circuit de ingestelde vermogens- en stroomlimieten niet overschrijdt. Circuits kunnen genest worden om een hiërarchie op te bouwen.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Terug naar InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Laadpunt toevoegen",
|
||||
"addCharger": {
|
||||
"charging": "Laadpunt toevoegen"
|
||||
},
|
||||
"addMeter": "Toevoegen van een toegewijde laadmeter",
|
||||
"cancel": "Annuleren",
|
||||
"chargerError": "Het configureren van een oplader is vereist.",
|
||||
"chargerLabel": "Oplader",
|
||||
"chargerError": {
|
||||
"charging": "Het configureren van een oplader is vereist."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Oplader"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Zal een stroom van 6 tot 16 A gebruiken.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Toewijzing van Load management om te voorkomen dat de vermogens- en stroomlimieten niet worden overschreden.",
|
||||
"circuitLabel": "Circuit",
|
||||
"circuitUnassigned": "niet toegewezen",
|
||||
"defaultModeHelp": "Laadmodus bij het aansluiten van een voertuig.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Laadmodus bij het aansluiten van een voertuig."
|
||||
},
|
||||
"defaultModeHelpKeep": "Behoud de laatst-geselecteerde laadmodus.",
|
||||
"defaultModeLabel": "Standaard mode",
|
||||
"delete": "Wissen",
|
||||
|
|
|
|||
12
i18n/pl.json
12
i18n/pl.json
|
|
@ -37,8 +37,12 @@
|
|||
"ocppHelp": "Skopiuj ten adres do konfiguracji Twojej ładowarki",
|
||||
"switchsockets": "Przełączalne gniazdka",
|
||||
"template": "Producent",
|
||||
"titleAdd": "Dodaj ładowarkę",
|
||||
"titleEdit": "Edytuj ładowarkę"
|
||||
"titleAdd": {
|
||||
"charging": "Dodaj ładowarkę"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Edytuj ładowarkę"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Zapewnia, że suma wszystkich punktów obciążenia podłączonych do obwodu nie przekracza skonfigurowanych limitów mocy i prądu. Obwody można zagnieżdżać, aby zbudować hierarchię.",
|
||||
|
|
@ -126,7 +130,9 @@
|
|||
"title": "InfluxDB"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Dodaj ładowarkę"
|
||||
"addCharger": {
|
||||
"charging": "Dodaj ładowarkę"
|
||||
}
|
||||
},
|
||||
"main": {
|
||||
"addLoadpoint": "Dodaj ładowarkę",
|
||||
|
|
|
|||
24
i18n/pt.json
24
i18n/pt.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "URL do servidor OCPP",
|
||||
"switchsockets": "Tomadas comandadas",
|
||||
"template": "Fabricante",
|
||||
"titleAdd": "Adicionar Carregador",
|
||||
"titleEdit": "Editar Carregador"
|
||||
"titleAdd": {
|
||||
"charging": "Adicionar Carregador"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Editar Carregador"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Assegura que a soma de todos os Postos de Carregamento conectados a um circuito não excede os limites de potência e corrente configurados. Os circuitos podem ser combinados para construir uma hierarquia.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Voltar ao InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Adicionar Carregador",
|
||||
"addCharger": {
|
||||
"charging": "Adicionar Carregador"
|
||||
},
|
||||
"addMeter": "Adicionar um Contador de Carregador dedicado",
|
||||
"cancel": "Cancelar",
|
||||
"chargerError": "É necessário configurar um Carregador EV.",
|
||||
"chargerLabel": "Carregador",
|
||||
"chargerError": {
|
||||
"charging": "É necessário configurar um Carregador EV."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Carregador"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Utilização de uma gama de correntes de 6 a 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Atribuição de gestão de carga para garantir que os limites de potência e corrente não são excedidos.",
|
||||
"circuitLabel": "Circuito",
|
||||
"circuitUnassigned": "não atribuído",
|
||||
"defaultModeHelp": "Modo de carregamento ao ligar o veículo.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Modo de carregamento ao ligar o veículo."
|
||||
},
|
||||
"defaultModeHelpKeep": "Mantém o último modo de carregamento selecionado.",
|
||||
"defaultModeLabel": "Modo predefinido",
|
||||
"delete": "Apagar",
|
||||
|
|
|
|||
20
i18n/sl.json
20
i18n/sl.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "URL strežnika OCPP",
|
||||
"switchsockets": "Preklopne vtičnice",
|
||||
"template": "Proizvajalec",
|
||||
"titleAdd": "Dodaj polnilnik",
|
||||
"titleEdit": "Uredi polnilec"
|
||||
"titleAdd": {
|
||||
"charging": "Dodaj polnilnik"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Uredi polnilec"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Zagotavlja, da vsota vseh obremenitvenih točk, povezanih z vezjem, ne preseže konfiguriranih omejitev moči in toka. Vezja je mogoče ugnezditi za izgradnjo hierarhije.",
|
||||
|
|
@ -174,10 +178,14 @@
|
|||
"v2Support": "Nazaj na InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Dodaj polnilnik",
|
||||
"addCharger": {
|
||||
"charging": "Dodaj polnilnik"
|
||||
},
|
||||
"addMeter": "Dodaj namenski merilnik za polnilnico",
|
||||
"cancel": "Prekliči",
|
||||
"chargerLabel": "Polnilnica",
|
||||
"chargerLabel": {
|
||||
"charging": "Polnilnica"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Uporabilo se bo tokovno območje od 6 do 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -188,7 +196,9 @@
|
|||
"chargingTitle": "Polnjenje",
|
||||
"circuitLabel": "Krog",
|
||||
"circuitUnassigned": "nedodeljeno",
|
||||
"defaultModeHelp": "Način polnjenja pri priklopu vozila.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Način polnjenja pri priklopu vozila."
|
||||
},
|
||||
"defaultModeHelpKeep": "Ohrani zadnji izbrani način polnjenja.",
|
||||
"defaultModeLabel": "Privzeti način",
|
||||
"delete": "Izbriši",
|
||||
|
|
|
|||
32
i18n/sv.json
32
i18n/sv.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP-Server URL",
|
||||
"switchsockets": "Byt kontakt",
|
||||
"template": "Tillverkare",
|
||||
"titleAdd": "Lägg till laddare",
|
||||
"titleEdit": "Ändra laddare"
|
||||
"titleAdd": {
|
||||
"charging": "Lägg till laddare"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Ändra laddare"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Säkrar, att summan av laddpunkter kopplad till en krets inte överskrider den konfigurerade effektgränsen. Kretsar kan nästlas för att bygga en hierarki.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Tillbaka till InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Lägg till laddare",
|
||||
"addCharger": {
|
||||
"charging": "Lägg till laddare"
|
||||
},
|
||||
"addMeter": "Lägg till dedikerad laddmätare",
|
||||
"cancel": "Avbryt",
|
||||
"chargerError": "Konfigurering av laddare krävs.",
|
||||
"chargerLabel": "Laddare",
|
||||
"chargerError": {
|
||||
"charging": "Konfigurering av laddare krävs."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Laddare"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Använder mellan 6 och 16 A.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Belastningsstyrning som säkrar att effekt och strömgränser ej överskrids.",
|
||||
"circuitLabel": "Krets",
|
||||
"circuitUnassigned": "ej vald",
|
||||
"defaultModeHelp": "Laddningsläge vid anslutning till fordon.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Laddningsläge vid anslutning till fordon."
|
||||
},
|
||||
"defaultModeHelpKeep": "Använder senast valda laddningsläge.",
|
||||
"defaultModeLabel": "Standardinställning",
|
||||
"delete": "Radera",
|
||||
|
|
@ -245,8 +257,12 @@
|
|||
"thresholdEnableHelpNegative": "Börjar ladda när {surplus} överskott finns i {delay}.",
|
||||
"thresholdEnableHelpZero": "Starta när minimum överskott av laddningseffekt finns i {delay}.",
|
||||
"thresholdEnableLabel": "Anslut elnätet",
|
||||
"titleAdd": "Lägg till laddare",
|
||||
"titleEdit": "Redigera laddare",
|
||||
"titleAdd": {
|
||||
"charging": "Lägg till laddare"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Redigera laddare"
|
||||
},
|
||||
"titleExample": "Garage, Carport, et cetera.",
|
||||
"titleLabel": "Titel",
|
||||
"vehicleAutoDetection": "automatisk detektering",
|
||||
|
|
|
|||
24
i18n/tr.json
24
i18n/tr.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP sunucusu URL'si",
|
||||
"switchsockets": "“Açılıp kapanabilen prizler”",
|
||||
"template": "Üretici",
|
||||
"titleAdd": "Doldurma Cihazı Ekle",
|
||||
"titleEdit": "Doldurma Cihazını Düzenle"
|
||||
"titleAdd": {
|
||||
"charging": "Doldurma Cihazı Ekle"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Doldurma Cihazını Düzenle"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Bir devreye bağlı tüm yük noktalarının toplamının, yapılandırılan güç ve akım limitlerini aşmamasını sağlar. Devreler, bir hiyerarşi oluşturacak şekilde iç içe yerleştirilebilir.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "InfluxDB 2.x'e geri dön"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "“Doldurma cihazı ekle”",
|
||||
"addCharger": {
|
||||
"charging": "“Doldurma cihazı ekle”"
|
||||
},
|
||||
"addMeter": "“Ek doldurma sayacı ekle”",
|
||||
"cancel": "“İptal”",
|
||||
"chargerError": "Bir şarj cihazının yapılandırılması gereklidir.",
|
||||
"chargerLabel": "“Doldurma cihazı”",
|
||||
"chargerError": {
|
||||
"charging": "Bir şarj cihazının yapılandırılması gereklidir."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "“Doldurma cihazı”"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "6 ila 16 A akım aralığını kullanır.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Güç ve akım limitlerinin aşılmaması için yük yönetim ataması.",
|
||||
"circuitLabel": "“Devre”",
|
||||
"circuitUnassigned": "“atanmamış”",
|
||||
"defaultModeHelp": "Araç bağlandığında doldurma şekli.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Araç bağlandığında doldurma şekli."
|
||||
},
|
||||
"defaultModeHelpKeep": "Son seçilen doldurma şeklini korur.",
|
||||
"defaultModeLabel": "“Varsayılan şekil”",
|
||||
"delete": "“Sil”",
|
||||
|
|
|
|||
24
i18n/uk.json
24
i18n/uk.json
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "URL-адреса OCPP-сервера",
|
||||
"switchsockets": "Перемикаються розетки",
|
||||
"template": "Виробник",
|
||||
"titleAdd": "Додати зарядний пристрій",
|
||||
"titleEdit": "Редагувати зарядний пристрій"
|
||||
"titleAdd": {
|
||||
"charging": "Додати зарядний пристрій"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "Редагувати зарядний пристрій"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "Гарантує, що сума всіх точок навантаження, підключених до ланцюга, не перевищує налаштованих обмежень потужності та струму. Схеми можуть бути вкладеними для побудови ієрархії.",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "Назад до InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "Додати зарядний пристрій",
|
||||
"addCharger": {
|
||||
"charging": "Додати зарядний пристрій"
|
||||
},
|
||||
"addMeter": "Додати спеціальний лічильник зарядного пристрою",
|
||||
"cancel": "Скасувати",
|
||||
"chargerError": "Необхідно налаштувати зарядний пристрій.",
|
||||
"chargerLabel": "Зарядний пристрій",
|
||||
"chargerError": {
|
||||
"charging": "Необхідно налаштувати зарядний пристрій."
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "Зарядний пристрій"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "Використовуватиметься діапазон струму від 6 до 16 А.",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "Призначення керування навантаженням для забезпечення неперевищення обмежень потужності та струму.",
|
||||
"circuitLabel": "Схема",
|
||||
"circuitUnassigned": "непризначений",
|
||||
"defaultModeHelp": "Режим зарядки при підключенні автомобіля.",
|
||||
"defaultModeHelp": {
|
||||
"charging": "Режим зарядки при підключенні автомобіля."
|
||||
},
|
||||
"defaultModeHelpKeep": "Зберігає останній вибраний режим заряджання.",
|
||||
"defaultModeLabel": "Режим за замовчуванням",
|
||||
"delete": "Видалити",
|
||||
|
|
|
|||
|
|
@ -44,8 +44,12 @@
|
|||
"ocppLabel": "OCPP 服务器 URL",
|
||||
"switchsockets": "可切换插座",
|
||||
"template": "制造商",
|
||||
"titleAdd": "添加充电桩",
|
||||
"titleEdit": "编辑充电桩"
|
||||
"titleAdd": {
|
||||
"charging": "添加充电桩"
|
||||
},
|
||||
"titleEdit": {
|
||||
"charging": "编辑充电桩"
|
||||
}
|
||||
},
|
||||
"circuits": {
|
||||
"description": "确保连接到同一电路的所有充电点的总和不超过配置的功率和电流限制。电路可以嵌套以构建层级结构。",
|
||||
|
|
@ -180,11 +184,17 @@
|
|||
"v2Support": "返回 InfluxDB 2.x"
|
||||
},
|
||||
"loadpoint": {
|
||||
"addCharger": "添加充电桩",
|
||||
"addCharger": {
|
||||
"charging": "添加充电桩"
|
||||
},
|
||||
"addMeter": "添加专用充电桩计量表",
|
||||
"cancel": "取消",
|
||||
"chargerError": "必须配置充电桩。",
|
||||
"chargerLabel": "充电桩",
|
||||
"chargerError": {
|
||||
"charging": "必须配置充电桩。"
|
||||
},
|
||||
"chargerLabel": {
|
||||
"charging": "充电桩"
|
||||
},
|
||||
"chargerPower11kw": "11 kW",
|
||||
"chargerPower11kwHelp": "将使用 6 至 16 A 的电流范围。",
|
||||
"chargerPower22kw": "22 kW",
|
||||
|
|
@ -196,7 +206,9 @@
|
|||
"circuitHelp": "负载管理分配,以确保不超过功率和电流限制。",
|
||||
"circuitLabel": "电路",
|
||||
"circuitUnassigned": "未分配",
|
||||
"defaultModeHelp": "连接车辆时的充电模式。",
|
||||
"defaultModeHelp": {
|
||||
"charging": "连接车辆时的充电模式。"
|
||||
},
|
||||
"defaultModeHelpKeep": "保留上次选择的充电模式。",
|
||||
"defaultModeLabel": "默认模式",
|
||||
"delete": "删除",
|
||||
|
|
|
|||
|
|
@ -22,8 +22,11 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
typeCustom = "custom" // typeCustom is the custom configuration type
|
||||
typeTemplate = "template" // typeTemplate is the updatable configuration type
|
||||
typeCustom = "custom" // typeCustom is the custom configuration type
|
||||
typeTemplate = "template" // typeTemplate is the updatable configuration type
|
||||
typeHeatpump = "heatpump" // typeHeatpump is the heatpump configuration type
|
||||
typeSwitchSocket = "switchsocket" // typeSwitchSocket is the switch socket configuration type
|
||||
typeSgReady = "sgready" // typeSgReady is the SG-Ready configuration type
|
||||
|
||||
// masked indicates a masked config parameter value
|
||||
masked = "***"
|
||||
|
|
@ -280,6 +283,18 @@ func testInstance(instance any) map[string]testResult {
|
|||
makeResult("phases1p3p", true, nil)
|
||||
}
|
||||
|
||||
if hasFeature(instance, api.Heating) {
|
||||
makeResult("heating", true, nil)
|
||||
}
|
||||
|
||||
if hasFeature(instance, api.IntegratedDevice) {
|
||||
makeResult("integratedDevice", true, nil)
|
||||
}
|
||||
|
||||
if dev, ok := instance.(api.IconDescriber); ok && dev.Icon() != "" {
|
||||
makeResult("icon", dev.Icon(), nil)
|
||||
}
|
||||
|
||||
if cc, ok := instance.(api.PhaseDescriber); ok && cc.Phases() == 1 {
|
||||
makeResult("singlePhase", true, nil)
|
||||
}
|
||||
|
|
@ -338,8 +353,11 @@ func decodeDeviceConfig(r io.Reader) (configReq, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
if !strings.EqualFold(res.Type, typeCustom) {
|
||||
return configReq{}, errors.New("invalid config: yaml only allowed for custom type")
|
||||
if !(strings.EqualFold(res.Type, typeCustom) ||
|
||||
strings.EqualFold(res.Type, typeHeatpump) ||
|
||||
strings.EqualFold(res.Type, typeSwitchSocket) ||
|
||||
strings.EqualFold(res.Type, typeSgReady)) {
|
||||
return configReq{}, errors.New("invalid config: yaml only allowed for custom, heatpump, switchsocket, and sgready types")
|
||||
}
|
||||
|
||||
if len(res.Other) != 0 {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ params:
|
|||
description:
|
||||
de: Leistung
|
||||
en: Power
|
||||
unit: W
|
||||
type: int
|
||||
default: 0
|
||||
- name: enabled
|
||||
|
|
|
|||
86
templates/definition/charger/demo-heatpump.yaml
Normal file
86
templates/definition/charger/demo-heatpump.yaml
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
template: demo-heatpump
|
||||
group: heatinggeneric
|
||||
products:
|
||||
- description:
|
||||
de: Demowärmepumpe
|
||||
en: Demo heat pump
|
||||
requirements:
|
||||
description:
|
||||
en: For demonstration purposes. Heat pump with a fixed set of values.
|
||||
de: Zu Demonstrationszwecken. Wärmepumpe mit festen Werten.
|
||||
params:
|
||||
- name: operationMode
|
||||
description:
|
||||
de: Betriebszustand
|
||||
en: Operation status
|
||||
type: choice
|
||||
choice: ["standby", "heating"]
|
||||
default: "heating"
|
||||
required: true
|
||||
- name: power
|
||||
description:
|
||||
de: Leistung
|
||||
en: Power
|
||||
type: int
|
||||
unit: W
|
||||
default: 0
|
||||
- name: enabled
|
||||
description:
|
||||
de: Bereit zum Heizen
|
||||
en: Ready to heat
|
||||
type: bool
|
||||
default: true
|
||||
- name: soc
|
||||
description:
|
||||
de: Temperatur
|
||||
en: Temperature
|
||||
type: int
|
||||
unit: °C
|
||||
default: 50
|
||||
advanced: true
|
||||
- name: limitSoc
|
||||
description:
|
||||
de: Temperaturgrenze
|
||||
en: Temperature limit
|
||||
type: int
|
||||
unit: °C
|
||||
default: 80
|
||||
advanced: true
|
||||
- name: maxcurrent
|
||||
description:
|
||||
de: Maximale Stromstärke
|
||||
en: Maximum amperage
|
||||
unit: A
|
||||
help:
|
||||
example: 16
|
||||
type: int
|
||||
advanced: true
|
||||
|
||||
render: |
|
||||
type: custom
|
||||
enable:
|
||||
source: js
|
||||
script:
|
||||
enabled:
|
||||
source: const
|
||||
value: {{ .enabled }}
|
||||
status:
|
||||
source: const
|
||||
value: {{ if eq .operationMode "heating" }}C{{ else }}B{{ end }}
|
||||
maxcurrent:
|
||||
source: js
|
||||
script: |
|
||||
{{ .maxcurrent }}
|
||||
power:
|
||||
source: const
|
||||
value: {{ .power }}
|
||||
soc:
|
||||
source: const
|
||||
value: {{ .soc }}
|
||||
limitSoc:
|
||||
source: const
|
||||
value: {{ .limitSoc }}
|
||||
features:
|
||||
- heating
|
||||
- integrateddevice
|
||||
icon: heatpump
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
template: ocpp
|
||||
products:
|
||||
- description:
|
||||
de: OCPP 1.6J kompatibel (Smart Charging)
|
||||
en: OCPP 1.6J compatible (Smart Charging)
|
||||
de: OCPP 1.6J kompatibel
|
||||
en: OCPP 1.6J compatible
|
||||
group: generic
|
||||
capabilities: ["mA", "rfid", "1p3p"]
|
||||
requirements:
|
||||
|
|
|
|||
|
|
@ -1,28 +1,27 @@
|
|||
template: plugchoice
|
||||
products:
|
||||
- brand: Plugchoice
|
||||
group: generic
|
||||
requirements:
|
||||
evcc: ["sponsorship", "skiptest"]
|
||||
description:
|
||||
en: |
|
||||
Chargers connected through Plugchoice can leverage its OCPP proxy functionality to establish a connection to other backoffices while maintaining full control through EVCC. This allows seamless management of Plugchoice-registered chargers directly from EVCC.
|
||||
Chargers connected through Plugchoice can leverage its OCPP proxy functionality to establish a connection to other backoffices while maintaining full control through evcc. This allows seamless management of Plugchoice-registered chargers directly from evcc.
|
||||
|
||||
For improved meter readings, it is recommended to configure the following settings in the Plugchoice portal under the configuration tab:
|
||||
|
||||
- Set `MeterValueSampleInterval` to 10 seconds (or another interval according to your preference).
|
||||
- Set `MeterValuesSampledData` to `Energy.Active.Import.Register,Current.Offered,Current.Import,Voltage`.
|
||||
|
||||
These adjustments enable more frequent and detailed reporting of charging data to EVCC.
|
||||
These adjustments enable more frequent and detailed reporting of charging data to evcc.
|
||||
de: |
|
||||
Über Plugchoice angeschlossene Ladegeräte können die OCPP-Proxy-Funktionalität nutzen, um eine Verbindung zu anderen Backoffices herzustellen und gleichzeitig die volle Kontrolle über EVCC zu behalten. Dies ermöglicht eine nahtlose Verwaltung der bei Plugchoice registrierten Ladegeräte direkt vom EVCC aus.
|
||||
Über Plugchoice angeschlossene Ladegeräte können die OCPP-Proxy-Funktionalität nutzen, um eine Verbindung zu anderen Backoffices herzustellen und gleichzeitig die volle Kontrolle über evcc zu behalten. Dies ermöglicht eine nahtlose Verwaltung der bei Plugchoice registrierten Ladegeräte direkt vom evcc aus.
|
||||
|
||||
Für eine optimierte Zählerablesung empfehlen wir, die folgenden Einstellungen im Plugchoice-Portal unter `Konfiguration` zu konfigurieren:
|
||||
|
||||
– Stellen Sie `MeterValueSampleInterval` auf 10 Sekunden (oder ein anderes Intervall Ihrer Wahl) ein.
|
||||
– Stellen Sie `MeterValuesSampledData` auf `Energy.Active.Import.Register,Current.Offered,Current.Import,Voltage` ein.
|
||||
|
||||
Diese Anpassungen ermöglichen eine häufigere und detailliertere Meldung der Ladedaten an EVCC.
|
||||
Diese Anpassungen ermöglichen eine häufigere und detailliertere Meldung der Ladedaten an evcc.
|
||||
params:
|
||||
- name: token
|
||||
required: true
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ test.describe("boost", async () => {
|
|||
});
|
||||
|
||||
test("activate boost in solar mode", async ({ page }) => {
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
await expect(page.getByTestId("vehicle-status-batteryboost")).not.toBeVisible();
|
||||
await page
|
||||
.getByTestId("mode")
|
||||
|
|
@ -42,7 +42,7 @@ test.describe("boost", async () => {
|
|||
});
|
||||
|
||||
test("disabled in fast mode", async ({ page }) => {
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
await page.getByTestId("mode").first().getByRole("button", { name: "Fast" }).click();
|
||||
await page.getByTestId("loadpoint-settings-button").nth(1).click();
|
||||
const modal = page.getByTestId("loadpoint-settings-modal");
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ test.afterEach(async () => {
|
|||
test.describe("aux meter", async () => {
|
||||
test("create and remove aux meter", async ({ page }) => {
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("aux")).toHaveCount(0);
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ test.describe("aux meter", async () => {
|
|||
|
||||
test("user-defined meter", async ({ page }) => {
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await page.getByRole("button", { name: "Add additional meter" }).click();
|
||||
const modal = page.getByTestId("meter-modal");
|
||||
|
|
@ -160,7 +160,7 @@ energy:
|
|||
|
||||
test("user-defined meter with errors", async ({ page }) => {
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await page.getByRole("button", { name: "Add additional meter" }).click();
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ test.afterAll(async () => {
|
|||
test.describe("battery meter", async () => {
|
||||
test("create, edit and remove battery meter", async ({ page }) => {
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("battery")).toHaveCount(0);
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ test.describe("battery meter", async () => {
|
|||
|
||||
test("advanced fields", async ({ page }) => {
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await page.getByRole("button", { name: "Add solar or battery" }).click();
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ test.describe("circuit", async () => {
|
|||
await start(CONFIG_YAML);
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("loadpoint")).toHaveCount(1);
|
||||
await expect(page.getByTestId("loadpoint")).toContainText(["Power", "1.0 kW"].join(""));
|
||||
|
|
@ -60,8 +60,9 @@ test.describe("circuit", async () => {
|
|||
|
||||
// add loadpoint and charger
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await page.getByRole("button", { name: "Add charge point" }).click();
|
||||
await page.getByRole("button", { name: "Add charger or heater" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await lpModal.getByRole("button", { name: "Add charging point" }).click();
|
||||
await lpModal.getByLabel("Title").fill("Carport");
|
||||
|
||||
// add charger
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ test.describe("grid meter", async () => {
|
|||
await page.getByRole("button", { name: "Apply changes" }).click();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("grid")).toHaveCount(0);
|
||||
await expect(page.getByTestId("add-grid")).toBeVisible();
|
||||
|
|
|
|||
|
|
@ -5,27 +5,41 @@ import { expectModalVisible, expectModalHidden, editorClear, editorPaste } from
|
|||
const CONFIG_ONE_LP = "config-one-lp.evcc.yaml";
|
||||
|
||||
test.use({ baseURL: baseUrl() });
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.afterEach(async () => {
|
||||
await stop();
|
||||
});
|
||||
|
||||
async function enableExperimental(page: Page) {
|
||||
await page
|
||||
.getByTestId("generalconfig-experimental")
|
||||
.getByRole("button", { name: "edit" })
|
||||
.click();
|
||||
await page.getByLabel("Experimental 🧪").click();
|
||||
await page.getByRole("button", { name: "Close" }).click();
|
||||
enum LoadpointType {
|
||||
Charging = "charging",
|
||||
Heating = "heating",
|
||||
}
|
||||
|
||||
async function addDemoCharger(page: Page) {
|
||||
async function enableExperimental(page: Page, inline = true) {
|
||||
if (inline) {
|
||||
await page.getByRole("button", { name: "Enable Experimental Features" }).click();
|
||||
} else {
|
||||
await page
|
||||
.getByTestId("generalconfig-experimental")
|
||||
.getByRole("button", { name: "edit" })
|
||||
.click();
|
||||
await page.getByLabel("Experimental 🧪").click();
|
||||
await page.getByRole("button", { name: "Close" }).click();
|
||||
}
|
||||
}
|
||||
|
||||
async function addDemoCharger(page: Page, type: LoadpointType = LoadpointType.Charging) {
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await lpModal.getByRole("button", { name: "Add charger" }).click();
|
||||
await lpModal
|
||||
.getByRole("button", { name: type === LoadpointType.Heating ? "Add heater" : "Add charger" })
|
||||
.click();
|
||||
|
||||
const modal = page.getByTestId("charger-modal");
|
||||
await expectModalVisible(modal);
|
||||
await modal.getByLabel("Manufacturer").selectOption("Demo charger");
|
||||
await modal
|
||||
.getByLabel("Manufacturer")
|
||||
.selectOption(type === LoadpointType.Heating ? "Demo heat pump" : "Demo charger");
|
||||
await modal.getByRole("button", { name: "Save" }).click();
|
||||
await expectModalHidden(modal);
|
||||
await expectModalVisible(lpModal);
|
||||
|
|
@ -33,7 +47,7 @@ async function addDemoCharger(page: Page) {
|
|||
|
||||
async function addDemoMeter(page: Page, power = "0") {
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await lpModal.getByRole("button", { name: "Add dedicated charger meter" }).click();
|
||||
await lpModal.getByRole("button", { name: "Add dedicated energy meter" }).click();
|
||||
|
||||
const modal = page.getByTestId("meter-modal");
|
||||
await expectModalVisible(modal);
|
||||
|
|
@ -54,14 +68,23 @@ async function addVehicle(page: Page, title: string) {
|
|||
await expectModalHidden(modal);
|
||||
}
|
||||
|
||||
async function newLoadpoint(page: Page, title: string) {
|
||||
async function newLoadpoint(
|
||||
page: Page,
|
||||
title: string,
|
||||
type: LoadpointType = LoadpointType.Charging
|
||||
) {
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await page.getByRole("button", { name: "Add charge point" }).click();
|
||||
await page.getByRole("button", { name: "Add charger or heater" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await lpModal
|
||||
.getByRole("button", {
|
||||
name: type === LoadpointType.Heating ? "Add heating device" : "Add charging point",
|
||||
})
|
||||
.click();
|
||||
await lpModal.getByLabel("Title").fill(title);
|
||||
}
|
||||
|
||||
test.describe("loadpoint", async () => {
|
||||
test.describe("charging loadpoint", async () => {
|
||||
test("create, update and delete", async ({ page }) => {
|
||||
await start();
|
||||
|
||||
|
|
@ -106,6 +129,7 @@ test.describe("loadpoint", async () => {
|
|||
// update loadpoint title
|
||||
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await expect(lpModal.getByRole("heading", { name: "Edit Charging Point" })).toBeVisible();
|
||||
await lpModal.getByLabel("Title").fill("Solar Carport 2");
|
||||
await lpModal.getByRole("button", { name: "Save" }).click();
|
||||
await expect(page.getByTestId("loadpoint")).toContainText("Solar Carport 2");
|
||||
|
|
@ -160,7 +184,7 @@ test.describe("loadpoint", async () => {
|
|||
test("priority", async ({ page }) => {
|
||||
await start(CONFIG_ONE_LP);
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
|
||||
|
|
@ -368,6 +392,8 @@ test.describe("loadpoint", async () => {
|
|||
await expectModalVisible(chargerModal);
|
||||
await chargerModal.getByRole("button", { name: "Delete" }).click();
|
||||
await expectModalHidden(chargerModal);
|
||||
await expectModalVisible(lpModal);
|
||||
await expect(lpModal.getByRole("heading", { name: "Edit Charger or Heater" })).toBeVisible();
|
||||
|
||||
// restart without saving loadpoint
|
||||
await restart();
|
||||
|
|
@ -376,6 +402,7 @@ test.describe("loadpoint", async () => {
|
|||
// check loadpoint default vehicle
|
||||
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await lpModal.getByRole("button", { name: "Add charging point" }).click();
|
||||
await expect(lpModal.getByRole("textbox", { name: "Title" })).toHaveValue("Garage");
|
||||
await expect(lpModal).toContainText("Configuring a charger is required.");
|
||||
});
|
||||
|
|
@ -412,9 +439,7 @@ test.describe("loadpoint", async () => {
|
|||
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await expect(lpModal.getByRole("textbox", { name: "Title" })).toHaveValue("Garage");
|
||||
await expect(
|
||||
lpModal.getByRole("button", { name: "Add dedicated charger meter" })
|
||||
).toBeVisible();
|
||||
await expect(lpModal.getByRole("button", { name: "Add dedicated energy meter" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("user-defined charger", async ({ page }) => {
|
||||
|
|
@ -430,10 +455,12 @@ test.describe("loadpoint", async () => {
|
|||
// add user-defined charger
|
||||
const chargerModal = page.getByTestId("charger-modal");
|
||||
await expectModalVisible(chargerModal);
|
||||
await chargerModal.getByLabel("Manufacturer").selectOption("User-defined device");
|
||||
await chargerModal.getByLabel("Manufacturer").selectOption("User-defined charger");
|
||||
await page.waitForLoadState("networkidle");
|
||||
const chargerEditor = chargerModal.getByTestId("yaml-editor");
|
||||
await expect(chargerEditor).toContainText("status: # charger status [A..F]");
|
||||
await expect(chargerEditor).toContainText(
|
||||
"status: # charger status (A: not connected, B: connected, C: charging)"
|
||||
);
|
||||
|
||||
await editorClear(chargerEditor, 20);
|
||||
await editorPaste(
|
||||
|
|
@ -468,7 +495,7 @@ power:
|
|||
await expectModalVisible(lpModal);
|
||||
|
||||
// add user-defined meter
|
||||
await lpModal.getByRole("button", { name: "Add dedicated charger meter" }).click();
|
||||
await lpModal.getByRole("button", { name: "Add dedicated energy meter" }).click();
|
||||
const meterModal = page.getByTestId("meter-modal");
|
||||
await expectModalVisible(meterModal);
|
||||
await meterModal.getByLabel("Manufacturer").selectOption("User-defined device");
|
||||
|
|
@ -512,16 +539,158 @@ power:
|
|||
await lpEntry.getByRole("button", { name: "edit" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
|
||||
await expect(lpModal.getByLabel("Charger").first()).toHaveValue("User-defined device [db:1]");
|
||||
await expect(lpModal.getByLabel("Charger").first()).toHaveValue("User-defined charger [db:1]");
|
||||
await expect(lpModal.getByLabel("Energy meter").first()).toHaveValue(
|
||||
"User-defined device [db:2]"
|
||||
);
|
||||
await lpModal.getByLabel("Charger").first().click();
|
||||
await expectModalVisible(chargerModal);
|
||||
|
||||
await expect(chargerModal.getByLabel("Manufacturer")).toHaveValue("User-defined device");
|
||||
await expect(chargerModal.getByLabel("Manufacturer")).toHaveValue("User-defined charger");
|
||||
await page.waitForLoadState("networkidle");
|
||||
await expect(chargerEditor).toContainText("value: 'C'");
|
||||
await expect(chargerEditor).toContainText("value: 11000");
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("heating loadpoint", async () => {
|
||||
test("create, update and delete", async ({ page }) => {
|
||||
await start();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
|
||||
// add loadpoint
|
||||
await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating);
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await lpModal.getByRole("button", { name: "Add heater" }).click();
|
||||
await addDemoCharger(page, LoadpointType.Heating);
|
||||
|
||||
// check heading
|
||||
await expect(lpModal.getByRole("heading", { name: "Add Heating Device" })).toBeVisible();
|
||||
await lpModal.getByRole("button", { name: "Save" }).click();
|
||||
await expectModalHidden(lpModal);
|
||||
|
||||
// restart edit
|
||||
await restart();
|
||||
await page.reload();
|
||||
const lpEntry = page.getByTestId("loadpoint");
|
||||
await expect(lpEntry.getByRole("img", { name: "heatpump" })).toBeVisible();
|
||||
await expect(lpEntry).toContainText("Wärmepumpe");
|
||||
await lpEntry.getByRole("button", { name: "edit" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await expect(lpModal.getByRole("heading", { name: "Edit Heating Device" })).toBeVisible();
|
||||
await lpModal.getByRole("button", { name: "Save" }).click();
|
||||
await expectModalHidden(lpModal);
|
||||
|
||||
// delete
|
||||
await lpEntry.getByRole("button", { name: "edit" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await lpModal.getByRole("button", { name: "Delete" }).click();
|
||||
await expectModalHidden(lpModal);
|
||||
|
||||
// restart delete
|
||||
await restart();
|
||||
await page.reload();
|
||||
|
||||
// check loadpoint
|
||||
await expect(page.getByTestId("loadpoint")).not.toBeVisible();
|
||||
});
|
||||
|
||||
// add user-defined heat pump
|
||||
test("user-defined heat pump", async ({ page }) => {
|
||||
await start();
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
|
||||
// add loadpoint
|
||||
await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating);
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await lpModal.getByRole("button", { name: "Add heater" }).click();
|
||||
|
||||
// add user-defined heat pump
|
||||
const modal = page.getByTestId("charger-modal");
|
||||
await expectModalVisible(modal);
|
||||
await modal.getByLabel("Manufacturer").selectOption("User-defined heater");
|
||||
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump");
|
||||
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump (sg-ready, all)");
|
||||
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump (sg-ready, boost)");
|
||||
await modal.getByLabel("Manufacturer").selectOption("User-defined switch socket");
|
||||
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump");
|
||||
|
||||
const editor = modal.getByTestId("yaml-editor");
|
||||
await editorClear(editor, 20);
|
||||
await editorPaste(
|
||||
editor,
|
||||
page,
|
||||
`setmaxpower:
|
||||
source: js
|
||||
script: console.log(setmaxpower);
|
||||
getmaxpower:
|
||||
source: const
|
||||
value: 2000
|
||||
power:
|
||||
source: const
|
||||
value: 1000
|
||||
energy:
|
||||
source: const
|
||||
value: 0.7
|
||||
limittemp:
|
||||
source: const
|
||||
value: 50
|
||||
temp:
|
||||
source: const
|
||||
value: 25
|
||||
`
|
||||
);
|
||||
|
||||
const restResult = modal.getByTestId("test-result");
|
||||
await expect(restResult).toContainText("Status: unknown");
|
||||
await restResult.getByRole("link", { name: "validate" }).click();
|
||||
await expect(restResult).toContainText("Status: successful");
|
||||
await expect(restResult).toContainText(["Power", "1.0 kW"].join(""));
|
||||
await expect(restResult).toContainText(["Energy", "0.7 kWh"].join(""));
|
||||
await expect(restResult).toContainText(["Temperature", "25.0°C"].join(""));
|
||||
await expect(restResult).toContainText(["Heater limit", "50.0°C"].join(""));
|
||||
|
||||
await modal.getByRole("button", { name: "Save" }).click();
|
||||
await expectModalHidden(modal);
|
||||
await expectModalVisible(lpModal);
|
||||
|
||||
// create
|
||||
await lpModal.getByRole("button", { name: "Save" }).click();
|
||||
await expectModalHidden(lpModal);
|
||||
|
||||
await expect(page.getByTestId("loadpoint")).toHaveCount(1);
|
||||
const lpEntry = page.getByTestId("loadpoint").first();
|
||||
await expect(lpEntry.getByRole("img", { name: "heatpump" })).toBeVisible();
|
||||
await expect(lpEntry).toContainText("Wärmepumpe");
|
||||
await expect(lpEntry).toContainText(["Power", "1.0 kW"].join(""));
|
||||
});
|
||||
|
||||
test("delete charger/heater reverts to loadpoint type select screen", async ({ page }) => {
|
||||
await start();
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
|
||||
// add loadpoint
|
||||
await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating);
|
||||
await addDemoCharger(page, LoadpointType.Heating);
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await lpModal.getByRole("button", { name: "Save" }).click();
|
||||
await expectModalHidden(lpModal);
|
||||
|
||||
// delete heater
|
||||
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
|
||||
await expectModalVisible(lpModal);
|
||||
await lpModal.getByRole("textbox", { name: "Heater" }).click();
|
||||
const chargerModal = page.getByTestId("charger-modal");
|
||||
await expectModalVisible(chargerModal);
|
||||
await chargerModal.getByRole("button", { name: "Delete" }).click();
|
||||
await expectModalHidden(chargerModal);
|
||||
await expectModalVisible(lpModal);
|
||||
await expect(lpModal.getByRole("heading", { name: "Edit Charger or Heater" })).toBeVisible();
|
||||
await expect(lpModal.getByRole("button", { name: "Add charging point" })).toBeVisible();
|
||||
await expect(lpModal.getByRole("button", { name: "Add heating device" })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ import { test, expect, type Page } from "@playwright/test";
|
|||
import { start, stop, baseUrl } from "./evcc";
|
||||
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
|
||||
|
||||
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
|
||||
|
||||
test.use({ baseURL: baseUrl() });
|
||||
|
||||
test.afterEach(async () => {
|
||||
|
|
@ -19,7 +17,7 @@ async function goToConfig(page: Page) {
|
|||
|
||||
test.describe("messaging", async () => {
|
||||
test("save a comment", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
await goToConfig(page);
|
||||
|
||||
await page.getByTestId("messaging").getByRole("button", { name: "edit" }).click();
|
||||
|
|
|
|||
|
|
@ -3,15 +3,13 @@ import { start, stop, restart, baseUrl } from "./evcc";
|
|||
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
|
||||
import { isMqttReachable } from "./mqtt";
|
||||
|
||||
const CONFIG = "config-grid-only.evcc.yaml";
|
||||
|
||||
test.use({ baseURL: baseUrl() });
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await start(CONFIG);
|
||||
await start();
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
|
|
@ -57,7 +55,7 @@ test.describe("mqtt", async () => {
|
|||
.getByRole("button", { name: "Restart" });
|
||||
await expect(restartButton).toBeVisible();
|
||||
|
||||
await restart(CONFIG);
|
||||
await restart();
|
||||
|
||||
// config error
|
||||
await expect(page.getByTestId("mqtt")).toHaveClass(/round-box--error/);
|
||||
|
|
@ -80,7 +78,7 @@ test.describe("mqtt", async () => {
|
|||
await expect(page.getByTestId("mqtt")).toContainText(
|
||||
["Broker", VALID_BROKER, "Topic", VALID_TOPIC].join("")
|
||||
);
|
||||
await restart(CONFIG);
|
||||
await restart();
|
||||
|
||||
await expect(page.getByTestId("fatal-error")).not.toBeVisible();
|
||||
await expect(page.getByTestId("mqtt")).not.toHaveClass(/round-box--error/);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ test.describe("onboarding", async () => {
|
|||
await expect(page.getByTestId("loadpoint-required")).toBeVisible();
|
||||
await page.getByTestId("add-loadpoint").click();
|
||||
const lpModal = page.getByTestId("loadpoint-modal");
|
||||
await expectModalVisible(lpModal);
|
||||
await lpModal.getByRole("button", { name: "Add charging point" }).click();
|
||||
await lpModal.getByLabel("Title").fill("Solar Carport");
|
||||
await lpModal.getByRole("button", { name: "Add charger" }).click();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ test.afterAll(async () => {
|
|||
test.describe("pv meter", async () => {
|
||||
test("create, edit and remove pv meter", async ({ page }) => {
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("pv")).toHaveCount(0);
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ test.describe("pv meter", async () => {
|
|||
await startSimulator();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
// create meter
|
||||
await page.getByRole("button", { name: "Add solar or battery" }).click();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {
|
|||
editorPaste,
|
||||
} from "./utils";
|
||||
|
||||
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
|
||||
const CONFIG_WITH_TARIFFS = "config-with-tariffs.evcc.yaml";
|
||||
|
||||
test.use({ baseURL: baseUrl() });
|
||||
|
|
@ -25,7 +24,7 @@ async function goToConfig(page: Page) {
|
|||
|
||||
test.describe("tariffs", async () => {
|
||||
test("tariffs not configured", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
await goToConfig(page);
|
||||
|
||||
await expect(page.getByTestId("tariffs")).not.toBeVisible();
|
||||
|
|
@ -33,7 +32,7 @@ test.describe("tariffs", async () => {
|
|||
});
|
||||
|
||||
test("tariffs via ui", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
await goToConfig(page);
|
||||
|
||||
await page.getByTestId("add-tariffs").click();
|
||||
|
|
@ -74,7 +73,7 @@ grid:
|
|||
.getByRole("button", { name: "Restart" });
|
||||
await expect(restartButton).toBeVisible();
|
||||
|
||||
await restart(CONFIG_GRID_ONLY);
|
||||
await restart();
|
||||
|
||||
// restart done
|
||||
await expect(restartButton).not.toBeVisible();
|
||||
|
|
@ -86,7 +85,8 @@ grid:
|
|||
|
||||
test("tariffs from evcc.yaml", async ({ page }) => {
|
||||
await start(CONFIG_WITH_TARIFFS);
|
||||
await goToConfig(page);
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("tariffs")).toBeVisible();
|
||||
await expect(page.getByTestId("tariffs")).toContainText(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {
|
|||
expectModalVisible,
|
||||
} from "./utils";
|
||||
|
||||
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
|
||||
const CONFIG_WITH_VEHICLE = "config-with-vehicle.evcc.yaml";
|
||||
|
||||
test.use({ baseURL: baseUrl() });
|
||||
|
|
@ -22,10 +21,10 @@ const GENERIC_VEHICLE = "Generic vehicle (without API)";
|
|||
|
||||
test.describe("vehicles", async () => {
|
||||
test("create, edit and delete vehicles", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("vehicle")).toHaveCount(0);
|
||||
const vehicleModal = page.getByTestId("vehicle-modal");
|
||||
|
|
@ -81,7 +80,7 @@ test.describe("vehicles", async () => {
|
|||
});
|
||||
|
||||
test("config should survive restart", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
|
|
@ -109,7 +108,7 @@ test.describe("vehicles", async () => {
|
|||
await expect(page.getByTestId("vehicle")).toHaveCount(2);
|
||||
|
||||
// restart evcc
|
||||
await restart(CONFIG_GRID_ONLY);
|
||||
await restart();
|
||||
await page.reload();
|
||||
|
||||
await expect(page.getByTestId("vehicle")).toHaveCount(2);
|
||||
|
|
@ -121,7 +120,7 @@ test.describe("vehicles", async () => {
|
|||
await start(CONFIG_WITH_VEHICLE);
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("vehicle")).toHaveCount(1);
|
||||
const vehicleModal = page.getByTestId("vehicle-modal");
|
||||
|
|
@ -140,7 +139,7 @@ test.describe("vehicles", async () => {
|
|||
});
|
||||
|
||||
test("advanced fields", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
|
|
@ -179,7 +178,7 @@ test.describe("vehicles", async () => {
|
|||
});
|
||||
|
||||
test("save and restore rfid identifiers", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
|
|
@ -198,7 +197,7 @@ test.describe("vehicles", async () => {
|
|||
await expect(page.getByTestId("restart-needed")).toBeVisible();
|
||||
|
||||
// restart evcc
|
||||
await restart(CONFIG_GRID_ONLY);
|
||||
await restart();
|
||||
await page.reload();
|
||||
|
||||
await expect(page.getByTestId("vehicle")).toHaveCount(1);
|
||||
|
|
@ -212,10 +211,10 @@ test.describe("vehicles", async () => {
|
|||
});
|
||||
|
||||
test("user-defined vehicle", async ({ page }) => {
|
||||
await start(CONFIG_GRID_ONLY);
|
||||
await start();
|
||||
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await page.getByTestId("add-vehicle").click();
|
||||
const modal = page.getByTestId("vehicle-modal");
|
||||
|
|
@ -250,7 +249,7 @@ soc:
|
|||
await expect(page.getByTestId("vehicle")).toHaveCount(1);
|
||||
|
||||
// restart evcc
|
||||
await restart(CONFIG_GRID_ONLY);
|
||||
await restart();
|
||||
await page.reload();
|
||||
|
||||
await expect(page.getByTestId("vehicle")).toHaveCount(1);
|
||||
|
|
@ -291,7 +290,7 @@ soc:
|
|||
await expect(page.getByTestId("vehicle")).toHaveCount(0);
|
||||
|
||||
// restart evcc
|
||||
await restart(CONFIG_GRID_ONLY);
|
||||
await restart();
|
||||
await page.reload();
|
||||
|
||||
await expect(page.getByTestId("vehicle")).toHaveCount(0);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ test.describe("general", async () => {
|
|||
|
||||
// change value in config
|
||||
await page.goto("/#/config");
|
||||
await enableExperimental(page);
|
||||
await enableExperimental(page, false);
|
||||
|
||||
await expect(page.getByTestId("generalconfig-title")).toContainText("Hello World");
|
||||
await page.getByTestId("generalconfig-title").getByRole("button", { name: "edit" }).click();
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
import { expect, type Page, type Locator } from "@playwright/test";
|
||||
|
||||
export async function enableExperimental(page: Page): Promise<void> {
|
||||
await expect(page.getByTestId("topnavigation-button")).toBeVisible();
|
||||
await page.getByTestId("topnavigation-button").click();
|
||||
await page.getByTestId("topnavigation-settings").click();
|
||||
const modal = page.getByTestId("global-settings-modal");
|
||||
await expectModalVisible(modal);
|
||||
await modal.getByLabel("Experimental 🧪").click();
|
||||
await modal.getByRole("button", { name: "Close" }).click();
|
||||
await expectModalHidden(modal);
|
||||
await expect(page.locator(".modal-backdrop")).not.toBeVisible();
|
||||
export async function enableExperimental(page: Page, inline = true): Promise<void> {
|
||||
if (inline) {
|
||||
await page.getByRole("button", { name: "Enable Experimental Features" }).click();
|
||||
} else {
|
||||
await expect(page.getByTestId("topnavigation-button")).toBeVisible();
|
||||
await page.getByTestId("topnavigation-button").click();
|
||||
await page.getByTestId("topnavigation-settings").click();
|
||||
const modal = page.getByTestId("global-settings-modal");
|
||||
await expectModalVisible(modal);
|
||||
await modal.getByLabel("Experimental 🧪").click();
|
||||
await modal.getByRole("button", { name: "Close" }).click();
|
||||
await expectModalHidden(modal);
|
||||
await expect(page.locator(".modal-backdrop")).not.toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export async function expectModalVisible(modal: Locator): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -174,8 +174,8 @@ params:
|
|||
de: Minimale Stromstärke
|
||||
en: Minimum amperage
|
||||
help:
|
||||
de: Definiert die minimale Stromstärke pro angeschlossener Phase mit welcher das Fahrzeug geladen werden soll
|
||||
en: The minimum amperage per connected phase with which the car should be charged
|
||||
de: Definiert die minimale Stromstärke pro angeschlossener Phase die genutzt werden kann
|
||||
en: The minimum amperage per connected phase that can be used
|
||||
example: 6
|
||||
type: int
|
||||
- name: maxcurrent
|
||||
|
|
@ -184,8 +184,8 @@ params:
|
|||
de: Maximale Stromstärke
|
||||
en: Maximum amperage
|
||||
help:
|
||||
de: Definiert die maximale Stromstärke pro angeschlossener Phase mit welcher das Fahrzeug geladen werden soll
|
||||
en: The maximum amperage per connected phase with which the car shuold be charged
|
||||
de: Definiert die maximale Stromstärke pro angeschlossener Phase die genutzt werden kann
|
||||
en: The maximum amperage per connected phase that can be used
|
||||
example: 16
|
||||
type: int
|
||||
- name: identifiers
|
||||
|
|
@ -755,6 +755,9 @@ devicegroups:
|
|||
heating:
|
||||
de: Wärmeerzeuger
|
||||
en: Heating devices
|
||||
heatinggeneric:
|
||||
de: Generische Unterstützung
|
||||
en: Generic support
|
||||
switchsockets:
|
||||
de: Schaltbare Steckdosen
|
||||
en: Switchable sockets
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue