diff --git a/assets/js/components/Loadpoint.vue b/assets/js/components/Loadpoint.vue index 31fbdc608c..90042216cc 100644 --- a/assets/js/components/Loadpoint.vue +++ b/assets/js/components/Loadpoint.vue @@ -28,6 +28,7 @@ @maxcurrent-updated="setMaxCurrent" @mincurrent-updated="setMinCurrent" @phasesconfigured-updated="setPhasesConfigured" + @batteryboost-updated="setBatteryBoost" />
+
+
+ {{ $t("main.loadpointSettings.batteryUsage") }} +
+ +
+ +
+
+ + +
+
+
+
+ + + diff --git a/assets/js/components/LoadpointSettingsModal.vue b/assets/js/components/LoadpointSettingsModal.vue index 4bde012ef9..49c17eb9fa 100644 --- a/assets/js/components/LoadpointSettingsModal.vue +++ b/assets/js/components/LoadpointSettingsModal.vue @@ -30,6 +30,12 @@ v-bind="smartCostLimitProps" class="mt-2" /> +
{{ $t("main.loadpointSettings.currents") }}
@@ -153,6 +159,7 @@ import collector from "../mixins/collector"; import formatter from "../mixins/formatter"; import SmartCostLimit from "./SmartCostLimit.vue"; import smartCostAvailable from "../utils/smartCostAvailable"; +import LoadpointSettingsBatteryBoost from "./LoadpointSettingsBatteryBoost.vue"; const V = 230; @@ -172,13 +179,16 @@ const insertSorted = (arr, num) => { export default { name: "LoadpointSettingsModal", mixins: [formatter, collector], - components: { SmartCostLimit }, + components: { SmartCostLimit, LoadpointSettingsBatteryBoost }, props: { id: [String, Number], phasesConfigured: Number, phasesActive: Number, chargerPhases1p3p: Boolean, chargerPhysicalPhases: Number, + batteryBoost: Boolean, + batteryBoostAvailable: Boolean, + mode: String, minSoc: Number, maxCurrent: Number, minCurrent: Number, @@ -189,8 +199,13 @@ export default { currency: String, multipleLoadpoints: Boolean, }, - emits: ["phasesconfigured-updated", "maxcurrent-updated", "mincurrent-updated"], - data: function () { + emits: [ + "phasesconfigured-updated", + "maxcurrent-updated", + "mincurrent-updated", + "batteryboost-updated", + ], + data() { return { selectedMaxCurrent: this.maxCurrent, selectedMinCurrent: this.minCurrent, @@ -199,7 +214,7 @@ export default { }; }, computed: { - phasesOptions: function () { + phasesOptions() { if (this.chargerPhysicalPhases == 1) { // known fixed phase configuration, no settings required return []; @@ -211,7 +226,10 @@ export default { // 1p or 3p possible return [PHASES_3, PHASES_1]; }, - maxPower: function () { + batteryBoostProps() { + return this.collectProps(LoadpointSettingsBatteryBoost); + }, + maxPower() { if (this.chargerPhases1p3p) { if (this.phasesConfigured === PHASES_AUTO) { return this.maxPowerPhases(3); @@ -222,7 +240,7 @@ export default { } return this.fmtW(this.maxCurrent * V * this.phasesActive); }, - minPower: function () { + minPower() { if (this.chargerPhases1p3p) { if (this.phasesConfigured === PHASES_AUTO) { return this.minPowerPhases(1); @@ -233,22 +251,22 @@ export default { } return this.fmtW(this.minCurrent * V * this.phasesActive); }, - minCurrentOptions: function () { + minCurrentOptions() { const opt1 = [...range(Math.floor(this.maxCurrent), 1), 0.5, 0.25, 0.125]; // ensure that current value is always included const opt2 = insertSorted(opt1, this.minCurrent); return opt2.map((value) => this.currentOption(value, value === 6)); }, - maxCurrentOptions: function () { + maxCurrentOptions() { const opt1 = range(32, Math.ceil(this.minCurrent)); // ensure that current value is always included const opt2 = insertSorted(opt1, this.maxCurrent); return opt2.map((value) => this.currentOption(value, value === 16)); }, - smartCostLimitProps: function () { + smartCostLimitProps() { return this.collectProps(SmartCostLimit); }, - loadpointId: function () { + loadpointId() { return this.id; }, smartCostAvailable() { @@ -256,16 +274,16 @@ export default { }, }, watch: { - maxCurrent: function (value) { + maxCurrent(value) { this.selectedMaxCurrent = value; }, - minCurrent: function (value) { + minCurrent(value) { this.selectedMinCurrent = value; }, - phasesConfigured: function (value) { + phasesConfigured(value) { this.selectedPhases = value; }, - minSoc: function (value) { + minSoc(value) { this.selectedMinSoc = value; }, }, @@ -278,37 +296,40 @@ export default { this.$refs.modal?.removeEventListener("hidden.bs.modal", this.modalInvisible); }, methods: { - maxPowerPhases: function (phases) { + maxPowerPhases(phases) { return this.fmtW(this.maxCurrent * V * phases); }, - minPowerPhases: function (phases) { + minPowerPhases(phases) { return this.fmtW(this.minCurrent * V * phases); }, - formId: function (name) { + formId(name) { return `loadpoint_${this.id}_${name}`; }, - changeMaxCurrent: function () { + changeMaxCurrent() { this.$emit("maxcurrent-updated", this.selectedMaxCurrent); }, - changeMinCurrent: function () { + changeMinCurrent() { this.$emit("mincurrent-updated", this.selectedMinCurrent); }, - changePhasesConfigured: function () { + changePhasesConfigured() { this.$emit("phasesconfigured-updated", this.selectedPhases); }, - currentOption: function (value, isDefault) { + currentOption(value, isDefault) { let name = `${this.fmtNumber(value)} A`; if (isDefault) { name += ` (${this.$t("main.loadpointSettings.default")})`; } return { value, name }; }, - modalVisible: function () { + modalVisible() { this.isModalVisible = true; }, - modalInvisible: function () { + modalInvisible() { this.isModalVisible = false; }, + changeBatteryBoost(boost) { + this.$emit("batteryboost-updated", boost); + }, }, }; @@ -321,4 +342,8 @@ export default { .container h4:first-child { margin-top: 0 !important; } + +.custom-select-inline { + display: inline-block !important; +} diff --git a/assets/js/components/Loadpoints.vue b/assets/js/components/Loadpoints.vue index 1c16858b98..5e932cb536 100644 --- a/assets/js/components/Loadpoints.vue +++ b/assets/js/components/Loadpoints.vue @@ -24,6 +24,7 @@ :multipleLoadpoints="loadpoints.length > 1" :gridConfigured="gridConfigured" :pvConfigured="pvConfigured" + :batteryConfigured="batteryConfigured" class="h-100" :class="{ 'loadpoint-unselected': !selected(index) }" @click="scrollTo(index)" @@ -60,7 +61,7 @@ import "@h2d2/shopicons/es/filled/lightning"; import Loadpoint from "./Loadpoint.vue"; export default { - name: "Site", + name: "Loadpoints", components: { Loadpoint }, props: { loadpoints: Array, @@ -71,6 +72,7 @@ export default { currency: String, gridConfigured: Boolean, pvConfigured: Boolean, + batteryConfigured: Boolean, }, data() { return { selectedIndex: 0, snapTimeout: null }; diff --git a/assets/js/components/MaterialIcon/BatteryBoost.vue b/assets/js/components/MaterialIcon/BatteryBoost.vue new file mode 100644 index 0000000000..7eaab0c49b --- /dev/null +++ b/assets/js/components/MaterialIcon/BatteryBoost.vue @@ -0,0 +1,23 @@ + + + diff --git a/assets/js/components/Site.vue b/assets/js/components/Site.vue index f53260ea11..57aad54d2c 100644 --- a/assets/js/components/Site.vue +++ b/assets/js/components/Site.vue @@ -31,6 +31,8 @@ :currency="currency" :gridConfigured="gridConfigured" :pvConfigured="pvConfigured" + :batteryConfigured="batteryConfigured" + :batterySoc="batterySoc" />
diff --git a/assets/js/components/Vehicle.vue b/assets/js/components/Vehicle.vue index 3c54dfffeb..6f4aa92ee9 100644 --- a/assets/js/components/Vehicle.vue +++ b/assets/js/components/Vehicle.vue @@ -101,6 +101,7 @@ export default { effectiveLimitSoc: Number, effectivePlanSoc: Number, effectivePlanTime: String, + batteryBoostActive: Boolean, enabled: Boolean, heating: Boolean, id: [String, Number], diff --git a/assets/js/components/VehicleStatus.vue b/assets/js/components/VehicleStatus.vue index 37eaaa10b1..1da4bb8c3b 100644 --- a/assets/js/components/VehicleStatus.vue +++ b/assets/js/components/VehicleStatus.vue @@ -103,6 +103,7 @@ :class="smartCostClass" data-testid="vehicle-status-smartcost" data-bs-toggle="tooltip" + data-bs-trigger="hover" @click="smartCostClicked" > @@ -116,6 +117,18 @@ + +