Fix removing target charge time (#2066)
This commit is contained in:
parent
5ca18306c4
commit
57f5a72055
14 changed files with 69 additions and 43 deletions
|
|
@ -17,6 +17,7 @@
|
|||
v-bind="vehicle"
|
||||
@target-soc-updated="setTargetSoC"
|
||||
@target-time-updated="setTargetTime"
|
||||
@target-time-removed="removeTargetTime"
|
||||
/>
|
||||
</div>
|
||||
<LoadpointDetails v-bind="details" />
|
||||
|
|
@ -57,8 +58,7 @@ export default {
|
|||
vehiclePresent: Boolean,
|
||||
vehicleRange: Number,
|
||||
minSoC: Number,
|
||||
timerSet: Boolean,
|
||||
timerActive: Boolean,
|
||||
targetTimeActive: Boolean,
|
||||
targetTime: String,
|
||||
|
||||
// details
|
||||
|
|
@ -124,6 +124,9 @@ export default {
|
|||
.post(this.api("targetcharge") + "/" + this.targetSoC + "/" + formattedDate)
|
||||
.catch(window.app.error);
|
||||
},
|
||||
removeTargetTime: function () {
|
||||
axios.delete(this.api("targetcharge")).catch(window.app.error);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
class="target-time-button btn btn-link btn-sm pe-0"
|
||||
:class="{
|
||||
invisible: !targetSoC,
|
||||
'text-dark': timerActive,
|
||||
'text-secondary': !timerActive,
|
||||
'text-dark': targetTimeActive,
|
||||
'text-secondary': !targetTimeActive,
|
||||
}"
|
||||
data-bs-toggle="modal"
|
||||
:data-bs-target="`#${modalId}`"
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<form @submit.prevent="saveTargetTime">
|
||||
<form @submit.prevent="setTargetTime">
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
|
|
@ -113,8 +113,7 @@ export default {
|
|||
mixins: [formatter],
|
||||
props: {
|
||||
id: Number,
|
||||
timerActive: Boolean,
|
||||
timerSet: Boolean,
|
||||
targetTimeActive: Boolean,
|
||||
targetTime: String,
|
||||
targetSoC: Number,
|
||||
},
|
||||
|
|
@ -123,7 +122,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
targetChargeEnabled: function () {
|
||||
return this.targetTime && this.timerSet;
|
||||
return this.targetTime;
|
||||
},
|
||||
selectedTargetTimeValid: function () {
|
||||
const now = new Date();
|
||||
|
|
@ -197,12 +196,12 @@ export default {
|
|||
minTime: function () {
|
||||
return new Date().toISOString().split("T")[1].slice(0, -8);
|
||||
},
|
||||
removeTargetTime: function () {
|
||||
this.$emit("target-time-updated", new Date(null));
|
||||
},
|
||||
saveTargetTime: function () {
|
||||
setTargetTime: function () {
|
||||
this.$emit("target-time-updated", this.selectedTargetTime);
|
||||
},
|
||||
removeTargetTime: function () {
|
||||
this.$emit("target-time-removed");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@ TargetChargePlanned.args = {
|
|||
vehicleSoC: 31,
|
||||
minSoC: 20,
|
||||
charging: false,
|
||||
timerSet: true,
|
||||
timerActive: false,
|
||||
targetTimeActive: false,
|
||||
targetSoC: 45,
|
||||
targetTime: hoursFromNow(14),
|
||||
id: 0,
|
||||
|
|
@ -92,8 +91,7 @@ TargetChargeActive.args = {
|
|||
vehicleSoC: 66,
|
||||
minSoC: 30,
|
||||
charging: true,
|
||||
timerSet: true,
|
||||
timerActive: true,
|
||||
targetTimeActive: true,
|
||||
targetSoC: 80,
|
||||
targetTime: hoursFromNow(2),
|
||||
id: 0,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
<VehicleSubline
|
||||
v-bind="vehicleSubline"
|
||||
class="my-1"
|
||||
@target-time-updated="targetTimeUpdated"
|
||||
@target-time-updated="setTargetTime"
|
||||
@target-time-removed="removeTargetTime"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -31,8 +32,7 @@ export default {
|
|||
charging: Boolean,
|
||||
minSoC: Number,
|
||||
vehicleTitle: String,
|
||||
timerActive: Boolean,
|
||||
timerSet: Boolean,
|
||||
targetTimeActive: Boolean,
|
||||
targetTime: String,
|
||||
targetSoC: Number,
|
||||
},
|
||||
|
|
@ -48,9 +48,12 @@ export default {
|
|||
targetSocUpdated: function (targetSoC) {
|
||||
this.$emit("target-soc-updated", targetSoC);
|
||||
},
|
||||
targetTimeUpdated: function (targetTime) {
|
||||
setTargetTime: function (targetTime) {
|
||||
this.$emit("target-time-updated", targetTime);
|
||||
},
|
||||
removeTargetTime: function () {
|
||||
this.$emit("target-time-removed");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@
|
|||
{{ $t("main.vehicleSubline.mincharge", { soc: minSoC }) }}
|
||||
</span>
|
||||
</small>
|
||||
<TargetCharge v-bind="targetCharge" @target-time-updated="targetTimeUpdated" />
|
||||
<TargetCharge
|
||||
v-bind="targetCharge"
|
||||
@target-time-updated="setTargetTime"
|
||||
@target-time-removed="removeTargetTime"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -22,8 +26,7 @@ export default {
|
|||
id: Number,
|
||||
vehicleSoC: Number,
|
||||
minSoC: Number,
|
||||
timerActive: Boolean,
|
||||
timerSet: Boolean,
|
||||
targetTimeActive: Boolean,
|
||||
targetTime: String,
|
||||
targetSoC: Number,
|
||||
},
|
||||
|
|
@ -36,9 +39,12 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
targetTimeUpdated: function (targetTime) {
|
||||
setTargetTime: function (targetTime) {
|
||||
this.$emit("target-time-updated", targetTime);
|
||||
},
|
||||
removeTargetTime: function () {
|
||||
this.$emit("target-time-removed");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -118,11 +118,14 @@ func (lp *LoadPoint) SetTargetCharge(finishAt time.Time, soc int) {
|
|||
|
||||
// apply immediately
|
||||
if lp.socTimer.Time != finishAt || lp.SoC.Target != soc {
|
||||
lp.publish("targetTime", finishAt)
|
||||
lp.socTimer.Time = finishAt
|
||||
lp.publish("targetTime", finishAt)
|
||||
|
||||
lp.setTargetSoC(soc)
|
||||
lp.requestUpdate()
|
||||
// don't remove soc
|
||||
if !finishAt.IsZero() {
|
||||
lp.setTargetSoC(soc)
|
||||
lp.requestUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,9 +55,7 @@ func (lp *Timer) DemandActive() bool {
|
|||
}
|
||||
|
||||
defer func() {
|
||||
lp.Publish("timerSet", lp.Time.After(time.Now()))
|
||||
lp.Publish("timerActive", lp.active)
|
||||
lp.Publish("timerProjectedEnd", lp.finishAt)
|
||||
lp.Publish("targetTimeActive", lp.active)
|
||||
}()
|
||||
|
||||
// power
|
||||
|
|
|
|||
4
dist/index.html
vendored
4
dist/index.html
vendored
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE html><html lang="de"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="description" content="EV Charge Controller"><meta name="author" content="andig"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><link rel="apple-touch-icon" sizes="180x180" href="ico/apple-touch-icon.png?[[.Version]]"><link rel="icon" type="image/png" sizes="32x32" href="ico/favicon-32x32.png?[[.Version]]"><link rel="icon" type="image/png" sizes="16x16" href="ico/favicon-16x16.png?[[.Version]]"><link rel="manifest" href="ico/site.webmanifest"><link rel="mask-icon" href="ico/safari-pinned-tab.svg?[[.Version]]" color="#18191a"><link rel="shortcut icon" href="ico/favicon.ico?[[.Version]]"><meta name="apple-mobile-web-app-title" content="evcc"><meta name="application-name" content="evcc"><meta name="msapplication-TileColor" content="#18191a"><meta name="msapplication-config" content="ico/browserconfig.xml"><meta name="theme-color" content="#18191a"><title>evcc</title><link href="css/chunk-vendors.a7b690cd.css" rel="preload" as="style"><link href="css/index.801eac99.css" rel="preload" as="style"><link href="js/chunk-vendors.e8d8381a.js" rel="preload" as="script"><link href="js/index.089c55bd.js" rel="preload" as="script"><link href="css/chunk-vendors.a7b690cd.css" rel="stylesheet"><link href="css/index.801eac99.css" rel="stylesheet"></head><body><script>window.evcc = {
|
||||
<!DOCTYPE html><html lang="de"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="description" content="EV Charge Controller"><meta name="author" content="andig"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><link rel="apple-touch-icon" sizes="180x180" href="ico/apple-touch-icon.png?[[.Version]]"><link rel="icon" type="image/png" sizes="32x32" href="ico/favicon-32x32.png?[[.Version]]"><link rel="icon" type="image/png" sizes="16x16" href="ico/favicon-16x16.png?[[.Version]]"><link rel="manifest" href="ico/site.webmanifest"><link rel="mask-icon" href="ico/safari-pinned-tab.svg?[[.Version]]" color="#18191a"><link rel="shortcut icon" href="ico/favicon.ico?[[.Version]]"><meta name="apple-mobile-web-app-title" content="evcc"><meta name="application-name" content="evcc"><meta name="msapplication-TileColor" content="#18191a"><meta name="msapplication-config" content="ico/browserconfig.xml"><meta name="theme-color" content="#18191a"><title>evcc</title><link href="css/chunk-vendors.a7b690cd.css" rel="preload" as="style"><link href="css/index.801eac99.css" rel="preload" as="style"><link href="js/chunk-vendors.e8d8381a.js" rel="preload" as="script"><link href="js/index.b8b64f9b.js" rel="preload" as="script"><link href="css/chunk-vendors.a7b690cd.css" rel="stylesheet"><link href="css/index.801eac99.css" rel="stylesheet"></head><body><script>window.evcc = {
|
||||
version: "[[.Version]]",
|
||||
configured: "[[.Configured]]",
|
||||
};</script><div id="app"></div><script src="js/chunk-vendors.e8d8381a.js"></script><script src="js/index.089c55bd.js"></script></body></html>
|
||||
};</script><div id="app"></div><script src="js/chunk-vendors.e8d8381a.js"></script><script src="js/index.b8b64f9b.js"></script></body></html>
|
||||
1
dist/js/index.089c55bd.js.map
vendored
1
dist/js/index.089c55bd.js.map
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
dist/js/index.b8b64f9b.js.map
vendored
Normal file
1
dist/js/index.b8b64f9b.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -81,14 +81,15 @@ func NewHTTPd(url string, site site.API, hub *SocketHub, cache *util.Cache) *HTT
|
|||
lpAPI := api.PathPrefix(fmt.Sprintf("/loadpoints/%d", id)).Subrouter()
|
||||
|
||||
routes := map[string]route{
|
||||
"mode": {[]string{"POST", "OPTIONS"}, "/mode/{value:[a-z]+}", chargeModeHandler(lp)},
|
||||
"targetsoc": {[]string{"POST", "OPTIONS"}, "/targetsoc/{value:[0-9]+}", targetSoCHandler(lp)},
|
||||
"minsoc": {[]string{"POST", "OPTIONS"}, "/minsoc/{value:[0-9]+}", minSoCHandler(lp)},
|
||||
"mincurrent": {[]string{"POST", "OPTIONS"}, "/mincurrent/{value:[0-9]+}", minCurrentHandler(lp)},
|
||||
"maxcurrent": {[]string{"POST", "OPTIONS"}, "/maxcurrent/{value:[0-9]+}", maxCurrentHandler(lp)},
|
||||
"phases": {[]string{"POST", "OPTIONS"}, "/phases/{value:[0-9]+}", phasesHandler(lp)},
|
||||
"targetcharge": {[]string{"POST", "OPTIONS"}, "/targetcharge/{soc:[0-9]+}/{time:[0-9TZ:-]+}", targetChargeHandler(lp)},
|
||||
"remotedemand": {[]string{"POST", "OPTIONS"}, "/remotedemand/{demand:[a-z]+}/{source::[0-9a-zA-Z_-]+}", remoteDemandHandler(lp)},
|
||||
"mode": {[]string{"POST", "OPTIONS"}, "/mode/{value:[a-z]+}", chargeModeHandler(lp)},
|
||||
"targetsoc": {[]string{"POST", "OPTIONS"}, "/targetsoc/{value:[0-9]+}", targetSoCHandler(lp)},
|
||||
"minsoc": {[]string{"POST", "OPTIONS"}, "/minsoc/{value:[0-9]+}", minSoCHandler(lp)},
|
||||
"mincurrent": {[]string{"POST", "OPTIONS"}, "/mincurrent/{value:[0-9]+}", minCurrentHandler(lp)},
|
||||
"maxcurrent": {[]string{"POST", "OPTIONS"}, "/maxcurrent/{value:[0-9]+}", maxCurrentHandler(lp)},
|
||||
"phases": {[]string{"POST", "OPTIONS"}, "/phases/{value:[0-9]+}", phasesHandler(lp)},
|
||||
"targetcharge": {[]string{"POST", "OPTIONS"}, "/targetcharge/{soc:[0-9]+}/{time:[0-9TZ:-]+}", targetChargeHandler(lp)},
|
||||
"targetcharge2": {[]string{"DELETE", "OPTIONS"}, "/targetcharge", targetChargeRemoveHandler(lp)},
|
||||
"remotedemand": {[]string{"POST", "OPTIONS"}, "/remotedemand/{demand:[a-z]+}/{source::[0-9a-zA-Z_-]+}", remoteDemandHandler(lp)},
|
||||
}
|
||||
|
||||
for _, r := range routes {
|
||||
|
|
|
|||
|
|
@ -265,6 +265,15 @@ func targetChargeHandler(loadpoint loadpoint.API) http.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
// targetChargeRemoveHandler removes target soc
|
||||
func targetChargeRemoveHandler(loadpoint loadpoint.API) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
loadpoint.SetTargetCharge(time.Time{}, 0)
|
||||
res := struct{}{}
|
||||
jsonResult(w, res)
|
||||
}
|
||||
}
|
||||
|
||||
// socketHandler attaches websocket handler to uri
|
||||
func socketHandler(hub *SocketHub) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,12 @@ func NewSocketHub() *SocketHub {
|
|||
func encode(v interface{}) (string, error) {
|
||||
var s string
|
||||
switch val := v.(type) {
|
||||
case time.Time:
|
||||
var b []byte
|
||||
if !val.IsZero() {
|
||||
b, _ = val.MarshalText()
|
||||
}
|
||||
s = fmt.Sprintf(`"%s"`, string(b))
|
||||
case time.Duration:
|
||||
// must be before stringer to convert to seconds instead of string
|
||||
s = fmt.Sprintf("%d", int64(val.Seconds()))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue