Skip to content

Commit

Permalink
Persist targetSoc/Energy, minSoc, targetTime per vehicle, add minSoc …
Browse files Browse the repository at this point in the history
…to UI (#8115)

* Plugins: make javascript return values more permissive

* Persist targetSoc/Energy, minSoc and target time, remove experimental from minSoc UI

* go generate

* Fix tests

* Update minSoc description

* Store settings by index. Show plan outside pv mode. Add help texts.

* remove slug

* go mock

* lint

* chore: simplify templates (#8304)

* Add e2e tests with playwright (#8123)

* Revert "1p3p: let charger handle session stop/restart (#7723)"

This reverts commit dd787ce.

* mazda2mqtt: document vin required (#8319)

* FoxESS: split H1/H3 devices (#7376)

Co-authored-by: premultiply <4681172+premultiply@users.noreply.github.com>

* Translations update from Hosted Weblate (#8124)

* Translated using Weblate (Czech)

Currently translated at 37.3% (99 of 265 strings)

Co-authored-by: Dusan Suja <bc.suja.dusan@googlemail.com>
Translate-URL: https://hosted.weblate.org/projects/evcc/evcc/cs/
Translation: evcc/evcc

* Translated using Weblate (Finnish)

Currently translated at 100.0% (265 of 265 strings)

Co-authored-by: Arna Lepikkö <arna.lepikko@telemail.fi>
Translate-URL: https://hosted.weblate.org/projects/evcc/evcc/fi/
Translation: evcc/evcc

* Translated using Weblate (German)

Currently translated at 100.0% (265 of 265 strings)

Co-authored-by: ThinkEV <claas@rootdir.de>
Translate-URL: https://hosted.weblate.org/projects/evcc/evcc/de/
Translation: evcc/evcc

* Translated using Weblate (Croatian)

Currently translated at 100.0% (265 of 265 strings)

Translated using Weblate (Slovenian)

Currently translated at 100.0% (265 of 265 strings)

Co-authored-by: Žiga Deisinger <ziga@deisinger.si>
Translate-URL: https://hosted.weblate.org/projects/evcc/evcc/hr/
Translate-URL: https://hosted.weblate.org/projects/evcc/evcc/sl/
Translation: evcc/evcc

* Translated using Weblate (Catalan)

Currently translated at 100.0% (265 of 265 strings)

Co-authored-by: Norbert Poch <npoch@yahoo.com>
Translate-URL: https://hosted.weblate.org/projects/evcc/evcc/ca/
Translation: evcc/evcc

* Translated using Weblate (Dutch)

Currently translated at 76.6% (203 of 265 strings)

Translated using Weblate (Dutch)

Currently translated at 74.3% (197 of 265 strings)

Co-authored-by: Ruben Van Boxem <vanboxem.ruben@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/evcc/evcc/nl/
Translation: evcc/evcc

* fix toml

---------

Co-authored-by: Dusan Suja <bc.suja.dusan@googlemail.com>
Co-authored-by: Arna Lepikkö <arna.lepikko@telemail.fi>
Co-authored-by: ThinkEV <claas@rootdir.de>
Co-authored-by: Žiga Deisinger <ziga@deisinger.si>
Co-authored-by: Norbert Poch <npoch@yahoo.com>
Co-authored-by: Ruben Van Boxem <vanboxem.ruben@gmail.com>
Co-authored-by: premultiply <4681172+premultiply@users.noreply.github.com>

* Add OBO Betterman Ion (#8321)

Also aligns heartbeat implementations

* Enphase: add token auth (firmware D7.x.xxx) and grid (#8247)

* Mqtt: fix smartCostLimit topic case (#8328)

* Add ISO15118 vehicle template (#8302)

* Mqtt: simplify setters

* Mqtt: disable message ordering to improve performance

* chore: simplify random state generation

* Porsche: remove deprecated mobile api (#8349)

* Porsche: remove remaining mobile api types

* Cupra: add odometer (#8340)

* chore: refactor go-stylish

* chore: fix stale handler

* mazda2mqtt: longer timeout (#8364)

* chore: pre-process toml

* chore: prevent toml double quotes

* Audi: temporarily switch to etron (#8374)

* Fix nightly build (#8384)

* Update SunSpec templates (#8270)

* Revert "Fix nightly build (#8384)"

This reverts commit 536dbc9.

* Revert "Add e2e tests with playwright (#8123)"

This reverts commit 0df8157.

* Easee: update Observation IDs (#8391)

* Easee: handle smartCharging errors (#8389)

* TWC: add non-Tesla vehicle warning (#8329)

* TWC: allow loadpoint to wakeup vehicle (#8284)

* chore: use gridx consts

* Fix ISO15118 vehicle (#8402)

Such vehicles would be reported as `(Offline)` previously, as no Soc can be fetched and thus needs to behave as the `offline` template.

The SoC is fetched via the charger, so hardcode it to 0 in here

* Modbus: add coils  (#8385)

* OpenEVSE: fix api (#8415)

* chore: refactor offline vehicles (#8404)

* Easee: wait for api confirmation (#8307)

* Revert "Easee: wait for api confirmation (#8307)"

This reverts commit ce0e427.

* automatically switch session log energy unit (#8371)

Show the charged energy in the session log table and details in Wh for
values below 1 kWh and in kWh for larger values

* Fix nightly/release + integration workflow  (#8450)

* Revert "Add e2e tests with playwright (#8123)"

This reverts commit 0df8157.

* Revert "Revert "Add e2e tests with playwright (#8123)""

This reverts commit 2299306.

* fix nightly/release

* fix nightly/release

* fix nightly/release

---------

Co-authored-by: andig <cpuidle@gmx.de>

* chore: no integration on nightly

* chore: no integration on nightly

* chore: no integration on nightly

* Sessions: filter, monthly sums, paging (#8278)

* fmt

* Update i18n/en.toml

Co-authored-by: Simon Riepl <43091717+savus4@users.noreply.github.com>

* Use exp/slices

* Use mux consistently

* add integration tests

---------

Co-authored-by: andig <cpuidle@gmx.de>
Co-authored-by: C64Axel <33828760+C64Axel@users.noreply.github.com>
Co-authored-by: premultiply <4681172+premultiply@users.noreply.github.com>
Co-authored-by: Weblate (bot) <hosted@weblate.org>
Co-authored-by: Dusan Suja <bc.suja.dusan@googlemail.com>
Co-authored-by: Arna Lepikkö <arna.lepikko@telemail.fi>
Co-authored-by: ThinkEV <claas@rootdir.de>
Co-authored-by: Žiga Deisinger <ziga@deisinger.si>
Co-authored-by: Norbert Poch <npoch@yahoo.com>
Co-authored-by: Ruben Van Boxem <vanboxem.ruben@gmail.com>
Co-authored-by: salz3n <79696598+salz3n@users.noreply.github.com>
Co-authored-by: Daniel Paschke <paschdan@gmail.com>
Co-authored-by: Andreas Linde <42185+DerAndereAndi@users.noreply.github.com>
Co-authored-by: lex777777 <84906358+lex777777@users.noreply.github.com>
Co-authored-by: Oscar <OAltr@users.noreply.github.com>
Co-authored-by: Michael Heß <GrimmiMeloni@users.noreply.github.com>
Co-authored-by: RTTTC <94727758+RTTTC@users.noreply.github.com>
Co-authored-by: kscholty <47229207+kscholty@users.noreply.github.com>
Co-authored-by: Jan Alexander <jan.alexander@posteo.de>
Co-authored-by: Simon Riepl <43091717+savus4@users.noreply.github.com>
  • Loading branch information
1 parent e6b88f7 commit 7de4849
Show file tree
Hide file tree
Showing 19 changed files with 437 additions and 52 deletions.
18 changes: 7 additions & 11 deletions assets/js/components/ChargingPlan.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<LabelAndValue
class="root flex-grow-1"
:label="title"
:class="disabled ? 'opacity-0' : 'opacity-1'"
:class="disabled ? 'opacity-25' : 'opacity-100'"
data-testid="charging-plan"
>
<h3 class="value m-0 d-block d-sm-flex align-items-baseline justify-content-center">
<button
class="value-button p-0"
:class="enabled ? 'evcc-default-text' : 'text-gray'"
:disabled="disabled"
@click="openModal"
>
<strong v-if="minSocEnabled">{{ minSocLabel }}</strong>
Expand Down Expand Up @@ -43,7 +43,7 @@
></button>
</div>
<div class="modal-body pt-2">
<ul v-if="showTabs" class="nav nav-tabs">
<ul class="nav nav-tabs">
<li class="nav-item">
<a
class="nav-link"
Expand All @@ -61,7 +61,7 @@
href="#"
@click.prevent="showArrivalTab"
>
{{ $t("main.chargingPlan.arrivalTab") }} 🧪
{{ $t("main.chargingPlan.arrivalTab") }}
</a>
</li>
</ul>
Expand Down Expand Up @@ -113,6 +113,7 @@ export default {
smartCostLimit: Number,
smartCostType: String,
currency: String,
mode: String,
},
emits: ["target-time-updated", "target-time-removed", "minsoc-updated"],
data: function () {
Expand Down Expand Up @@ -145,7 +146,7 @@ export default {
return this.$t("main.chargingPlan.title");
},
minSocEnabled: function () {
return this.minSoc >= this.vehicleSoc && this.$hiddenFeatures();
return this.minSoc > this.vehicleSoc;
},
departureTabActive: function () {
return this.activeTab === "departure";
Expand All @@ -159,9 +160,6 @@ export default {
chargingPlanArrival: function () {
return this.collectProps(ChargingPlanArrival);
},
showTabs: function () {
return this.$hiddenFeatures();
},
},
mounted() {
this.modal = Modal.getOrCreateInstance(this.$refs.modal);
Expand All @@ -180,12 +178,10 @@ export default {
this.isModalVisible = false;
},
openModal() {
this.showDeatureTab();
if (this.minSocEnabled) {
this.showArrivalTab();
}
if (this.targetChargeEnabled) {
this.showDeatureTab();
}
this.modal.show();
},
// not computed because it needs to update over time
Expand Down
52 changes: 30 additions & 22 deletions assets/js/components/ChargingPlanArrival.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
<template>
<div class="root mt-4">
<div class="d-flex justify-content-between align-items-baseline mb-2">
<label :for="formId('minsoc')" class="pt-1">
{{ $t("main.loadpointSettings.minSoc.label") }}
</label>
<select
:id="formId('minsoc')"
v-model.number="selectedMinSoc"
class="minSocSelect form-select mb-2"
@change="changeMinSoc"
>
<option
v-for="soc in [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]"
:key="soc"
:value="soc"
<div class="mt-4 container">
<div class="row">
<div class="col-12 col-md-6">
<div
class="minsoc d-flex justify-content-between align-items-baseline mb-2 me-sm-4"
>
{{ soc ? `${soc}%` : "--" }}
</option>
</select>
<label :for="formId('minsoc')" class="pt-1">
{{ $t("main.loadpointSettings.minSoc.label") }}
</label>
<select
:id="formId('minsoc')"
v-model.number="selectedMinSoc"
class="minSocSelect form-select mb-2"
:disabled="!socBasedCharging"
@change="changeMinSoc"
>
<option
v-for="soc in [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]"
:key="soc"
:value="soc"
>
{{ soc ? `${soc}%` : "--" }}
</option>
</select>
</div>
</div>
<small class="col-12 col-md-6 ps-md-4">
{{ $t("main.loadpointSettings.minSoc.description", [selectedMinSoc || "x"]) }}
</small>
</div>
<small>
{{ $t("main.loadpointSettings.minSoc.description", [selectedMinSoc || "x"]) }}
</small>
</div>
</template>

Expand All @@ -32,6 +39,7 @@ export default {
id: [String, Number],
minSoc: Number,
vehicleName: String,
socBasedCharging: Boolean,
},
emits: ["minsoc-updated"],
data: function () {
Expand All @@ -54,7 +62,7 @@ export default {
</script>

<style scoped>
.root {
.minsoc {
max-width: 300px;
}
.minSocSelect {
Expand Down
30 changes: 24 additions & 6 deletions assets/js/components/TargetCharge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="mt-4">
<div class="form-group d-lg-flex align-items-baseline mb-2 justify-content-between">
<!-- eslint-disable vue/no-v-html -->
<label for="targetTimeLabel" class="mb-3 me-3">
<label :for="`targetTimeLabel${id}`" class="mb-3 me-3">
<span v-if="socBasedCharging">
{{
$t("main.targetCharge.descriptionSoc", {
Expand All @@ -21,7 +21,12 @@
</label>
<!-- eslint-enable vue/no-v-html -->
<div class="d-flex justify-content-between date-selection">
<select v-model="selectedDay" class="form-select me-2">
<select
:id="`targetTimeLabel${id}`"
v-model="selectedDay"
class="form-select me-2"
data-testid="target-day"
>
<option v-for="opt in dayOptions()" :key="opt.value" :value="opt.value">
{{ opt.name }}
</option>
Expand All @@ -32,23 +37,30 @@
class="form-control ms-2 time-selection"
:step="60 * 5"
required
data-testid="target-time"
/>
</div>
</div>
<p class="mb-0">
<span v-if="timeInThePast" class="d-block text-danger">
<span v-if="timeInThePast" class="d-block text-danger mb-1">
{{ $t("main.targetCharge.targetIsInThePast") }}
</span>
<span v-else-if="timeTooFarInTheFuture" class="d-block text-secondary">
<span v-if="!socBasedCharging && !targetEnergy" class="d-block text-danger mb-1">
{{ $t("main.targetCharge.targetEnergyRequired") }}
</span>
<span v-if="timeTooFarInTheFuture" class="d-block text-secondary mb-1">
{{ $t("main.targetCharge.targetIsTooFarInTheFuture") }}
</span>
<span v-if="costLimitExists" class="d-block text-secondary">
<span v-if="costLimitExists" class="d-block text-secondary mb-1">
{{
$t("main.targetCharge.costLimitIgnore", {
limit: costLimitText,
})
}}
</span>
<span v-if="['off', 'now'].includes(mode)" class="d-block text-secondary mb-1">
{{ $t("main.targetCharge.onlyInPvMode") }}
</span>
&nbsp;
</p>
<TargetChargePlan v-if="targetChargePlanProps" v-bind="targetChargePlanProps" />
Expand Down Expand Up @@ -101,6 +113,7 @@ export default {
smartCostLimit: Number,
smartCostType: String,
currency: String,
mode: String,
},
emits: ["target-time-updated", "target-time-removed"],
data: function () {
Expand All @@ -110,6 +123,7 @@ export default {
plan: {},
tariff: {},
activeTab: "time",
loading: false,
};
},
computed: {
Expand Down Expand Up @@ -200,9 +214,11 @@ export default {
if (
!this.timeInThePast &&
(this.targetEnergy || this.targetSoc) &&
!isNaN(this.selectedTargetTime)
!isNaN(this.selectedTargetTime) &&
!this.loading
) {
try {
this.loading = true;
this.plan = (
await api.get(`loadpoints/${this.id}/target/plan`, {
params: { targetTime: this.selectedTargetTime },
Expand All @@ -217,6 +233,8 @@ export default {
this.tariff = tariffRes.status === 404 ? { rates: [] } : tariffRes.data.result;
} catch (e) {
console.error(e);
} finally {
this.loading = false;
}
}
},
Expand Down
8 changes: 7 additions & 1 deletion assets/js/components/TargetEnergySelect.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<template>
<LabelAndValue class="flex-grow-1" :label="$t('main.targetEnergy.label')" align="end">
<LabelAndValue
class="flex-grow-1"
:label="$t('main.targetEnergy.label')"
align="end"
data-testid="target-energy"
>
<h3 class="value m-0 d-block d-sm-flex align-items-baseline justify-content-end">
<label class="position-relative">
<select :value="targetEnergy" class="custom-select" @change="change">
Expand All @@ -15,6 +20,7 @@
<span
class="text-decoration-underline"
:class="{ 'text-gray fw-normal': !targetEnergy }"
data-testid="target-energy-value"
>
<AnimatedNumber :to="targetEnergy" :format="fmtEnergy" />
</span>
Expand Down
9 changes: 7 additions & 2 deletions assets/js/components/TargetSocSelect.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<template>
<LabelAndValue class="flex-grow-1" :label="$t('main.vehicle.targetSoc')" align="end">
<LabelAndValue
class="flex-grow-1"
:label="$t('main.vehicle.targetSoc')"
align="end"
data-testid="target-soc"
>
<h3 class="value m-0 d-block d-sm-flex align-items-baseline justify-content-end">
<label class="position-relative">
<select :value="targetSoc" class="custom-select" @change="change">
<option v-for="{ soc, text } in options" :key="soc" :value="soc">
{{ text }}
</option>
</select>
<span class="text-decoration-underline">
<span class="text-decoration-underline" data-testid="target-soc-value">
<AnimatedNumber :to="targetSoc" :format="formatSoc" />
</span>
</label>
Expand Down
2 changes: 1 addition & 1 deletion assets/js/components/VehicleStatus.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="d-block evcc-gray">{{ message }}&nbsp;</div>
<div class="d-block evcc-gray" data-testid="vehicle-status">{{ message }}&nbsp;</div>
</template>

<script>
Expand Down
2 changes: 1 addition & 1 deletion assets/js/components/VehicleTitle.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="d-flex justify-content-between mb-3 align-items-center">
<div class="d-flex justify-content-between mb-3 align-items-center" data-testid="vehicle-title">
<h4 class="d-flex align-items-center m-0 flex-grow-1 overflow-hidden">
<shopicon-regular-refresh
v-if="icon === 'refresh'"
Expand Down
5 changes: 5 additions & 0 deletions core/coordinator/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package coordinator
import (
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/core/loadpoint"
"golang.org/x/exp/slices"
)

type adapter struct {
Expand All @@ -23,6 +24,10 @@ func (a *adapter) GetVehicles() []api.Vehicle {
return a.c.GetVehicles()
}

func (a *adapter) GetVehicleIndex(v api.Vehicle) int {
return slices.Index(a.c.vehicles, v)
}

func (a *adapter) Acquire(v api.Vehicle) {
a.c.acquire(a.lp, v)
}
Expand Down
1 change: 1 addition & 0 deletions core/coordinator/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ type API interface {
Acquire(api.Vehicle)
Release(api.Vehicle)
IdentifyVehicleByStatus() api.Vehicle
GetVehicleIndex(api.Vehicle) int
}
1 change: 1 addition & 0 deletions core/coordinator/coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func New(log *util.Logger, vehicles []api.Vehicle) *Coordinator {
}
}

// GetVehicles returns the list of all vehicles
func (c *Coordinator) GetVehicles() []api.Vehicle {
return c.vehicles
}
Expand Down
4 changes: 4 additions & 0 deletions core/coordinator/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ func (a *dummy) Release(v api.Vehicle) {}
func (a *dummy) IdentifyVehicleByStatus() api.Vehicle {
return nil
}

func (a *dummy) GetVehicleIndex(v api.Vehicle) int {
return -1
}
4 changes: 4 additions & 0 deletions core/loadpoint_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (lp *Loadpoint) SetTargetEnergy(energy float64) {
if lp.targetEnergy != energy {
lp.setTargetEnergy(energy)
lp.requestUpdate()
lp.persistVehicleSettings()
}
}

Expand Down Expand Up @@ -141,6 +142,7 @@ func (lp *Loadpoint) SetTargetSoc(soc int) {
if lp.Soc.target != soc {
lp.setTargetSoc(soc)
lp.requestUpdate()
lp.persistVehicleSettings()
}
}

Expand Down Expand Up @@ -168,6 +170,7 @@ func (lp *Loadpoint) SetMinSoc(soc int) {
if lp.Soc.min != soc {
lp.setMinSoc(soc)
lp.requestUpdate()
lp.persistVehicleSettings()
}
}

Expand Down Expand Up @@ -219,6 +222,7 @@ func (lp *Loadpoint) SetTargetTime(finishAt time.Time) error {
lp.Lock()
defer lp.Unlock()
lp.setTargetTime(finishAt)
lp.persistVehicleSettings()

return nil
}
Expand Down
Loading

0 comments on commit 7de4849

Please sign in to comment.