Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signal vehicle detection and send message on guest vehicle #4139

Merged
merged 4 commits into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions assets/js/components/Vehicle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,6 @@ export default {
</script>

<style scoped>
.car-icon {
width: 1.75rem;
}
.details > div {
flex-grow: 1;
flex-basis: 0;
Expand Down
88 changes: 67 additions & 21 deletions assets/js/components/VehicleTitle.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
<template>
<div class="d-flex justify-content-between mb-3 align-items-center">
<VehicleOptions
v-if="showOptions"
class="options"
:vehicles="otherVehicles"
:is-unknown="isUnknown"
@change-vehicle="changeVehicle"
@remove-vehicle="removeVehicle"
>
<h4 class="d-flex align-items-center m-0 flex-grow-1 overflow-hidden">
<shopicon-regular-car3
v-if="carIcon"
class="me-2 flex-shrink-0 car-icon"
></shopicon-regular-car3>
<shopicon-regular-cablecharge
v-else
class="me-2 flex-shrink-0 car-icon"
></shopicon-regular-cablecharge>
<h4 class="d-flex align-items-center m-0 flex-grow-1 overflow-hidden">
<shopicon-regular-refresh
v-if="icon === 'refresh'"
ref="refresh"
data-bs-toggle="tooltip"
:title="$t('main.vehicle.detectionActive')"
class="me-2 flex-shrink-0 spin"
></shopicon-regular-refresh>
<shopicon-regular-car3
v-else-if="icon === 'car'"
class="me-2 flex-shrink-0"
></shopicon-regular-car3>
<shopicon-regular-cablecharge
v-else
class="me-2 flex-shrink-0"
></shopicon-regular-cablecharge>
<VehicleOptions
v-if="showOptions"
class="options"
:vehicles="otherVehicles"
:is-unknown="isUnknown"
@change-vehicle="changeVehicle"
@remove-vehicle="removeVehicle"
>
<span class="flex-grow-1 text-truncate vehicle-name">
{{ name }}
</span>
</h4>
</VehicleOptions>
</VehicleOptions>
</h4>
</div>
</template>

<script>
import "@h2d2/shopicons/es/regular/car3";
import "@h2d2/shopicons/es/regular/refresh";
import "@h2d2/shopicons/es/regular/cablecharge";
import { Tooltip } from "bootstrap";

import VehicleOptions from "./VehicleOptions.vue";

Expand All @@ -37,14 +46,21 @@ export default {
props: {
vehiclePresent: Boolean,
vehicleTitle: String,
vehicleDetectionActive: Boolean,
parked: Boolean,
connected: Boolean,
vehicles: { type: Array, default: () => [] },
},
emits: ["change-vehicle", "remove-vehicle"],
computed: {
carIcon() {
return this.connected || this.parked;
icon() {
if (this.vehicleDetectionActive) {
return "refresh";
}
if (this.connected || this.parked) {
return "car";
}
return null;
},
name() {
if (this.vehiclePresent || this.parked) {
Expand All @@ -70,13 +86,28 @@ export default {
return !this.isUnknown || this.vehicles.length;
},
},
watch: {
icon: function () {
this.tooltip();
},
},
mounted: function () {
this.tooltip();
},
methods: {
changeVehicle(index) {
this.$emit("change-vehicle", index);
},
removeVehicle() {
this.$emit("remove-vehicle");
},
tooltip() {
this.$nextTick(() => {
if (this.$refs.refresh) {
new Tooltip(this.$refs.refresh);
}
});
},
},
};
</script>
Expand All @@ -89,4 +120,19 @@ export default {
text-decoration: underline;
text-decoration-color: var(--evcc-gray);
}
.spin {
animation: rotation 1s infinite cubic-bezier(0.37, 0, 0.63, 1);
}
.spin >>> svg {
/* workaround to fix the not perfectly centered shopicon. Remove once its fixed in @h2d2/shopicons */
transform: translateY(-0.7px);
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
1 change: 1 addition & 0 deletions assets/js/i18n/de.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export default {
none: "Kein Fahrzeug",
unknown: "Gastfahrzeug",
changeVehicle: "Fahrzeug ändern",
detectionActive: "Fahrzeugerkennung läuft ...",
},
vehicleSoC: {
disconnected: "getrennt",
Expand Down
1 change: 1 addition & 0 deletions assets/js/i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export default {
none: "No vehicle",
unknown: "Guest vehicle",
changeVehicle: "Change Vehicle",
detectionActive: "Detecting vehicle ...",
},
vehicleSoC: {
disconnected: "disconnected",
Expand Down
2 changes: 2 additions & 0 deletions core/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ const (
phasesConfigured = "phasesConfigured" // configured phases (1/3, 0 for 1p3p chargers)
phasesEnabled = "phasesEnabled" // enabled phases (1/3)
phasesActive = "phasesActive" // active phases as used by vehicle (1/2/3)

vehicleDetectionActive = "vehicleDetectionActive" // vehicle detection is active (bool)
)
33 changes: 23 additions & 10 deletions core/loadpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ import (
)

const (
evChargeStart = "start" // update chargeTimer
evChargeStop = "stop" // update chargeTimer
evChargeCurrent = "current" // update fakeChargeMeter
evChargePower = "power" // update chargeRater
evVehicleConnect = "connect" // vehicle connected
evVehicleDisconnect = "disconnect" // vehicle disconnected
evVehicleSoC = "soc" // vehicle soc progress
evChargeStart = "start" // update chargeTimer
evChargeStop = "stop" // update chargeTimer
evChargeCurrent = "current" // update fakeChargeMeter
evChargePower = "power" // update chargeRater
evVehicleConnect = "connect" // vehicle connected
evVehicleDisconnect = "disconnect" // vehicle disconnected
evVehicleSoC = "soc" // vehicle soc progress
evVehicleUnidentified = "guest" // vehicle unidentified

pvTimer = "pv"
pvEnable = "enable"
Expand Down Expand Up @@ -418,8 +419,9 @@ func (lp *LoadPoint) evVehicleDisconnectHandler() {

lp.pushEvent(evVehicleDisconnect)

// remove charger vehicle id
// remove charger vehicle id and stop potential detection
lp.setVehicleIdentifier("")
lp.stopVehicleDetection()

// remove active vehicle if not default
if lp.vehicle != lp.defaultVehicle {
Expand Down Expand Up @@ -526,6 +528,7 @@ func (lp *LoadPoint) Prepare(uiChan chan<- util.Param, pushChan chan<- push.Even
lp.Unlock()

// set default or start detection
lp.publish(vehicleDetectionActive, false)
lp.vehicleDefaultOrDetect()

// read initial charger state to prevent immediately disabling charger
Expand Down Expand Up @@ -738,6 +741,8 @@ func (lp *LoadPoint) identifyVehicle() {
lp.setVehicleIdentifier(id)

if id != "" {
lp.stopVehicleDetection()

lp.log.DEBUG.Println("charger vehicle id:", id)

if vehicle := lp.selectVehicleByID(id); vehicle != nil {
Expand Down Expand Up @@ -857,11 +862,16 @@ func (lp *LoadPoint) unpublishVehicle() {

// vehicleUnidentified checks if there are associated vehicles and starts discovery period
func (lp *LoadPoint) vehicleUnidentified() bool {
res := len(lp.coordinatedVehicles()) > 0 && lp.vehicle == nil &&
lp.clock.Since(lp.vehicleDetect) < vehicleDetectDuration
res := len(lp.coordinatedVehicles()) > 0 && lp.vehicle == nil

// request vehicle api refresh while waiting to identify
if res {
if lp.clock.Since(lp.vehicleDetect) > vehicleDetectDuration {
lp.stopVehicleDetection()
lp.pushEvent(evVehicleUnidentified)
return false
}

select {
case <-lp.vehicleDetectTicker.C:
lp.log.DEBUG.Println("vehicle api refresh")
Expand Down Expand Up @@ -891,6 +901,7 @@ func (lp *LoadPoint) vehicleDefaultOrDetect() {
// reset connection timer and starts api refresh timer
lp.vehicleDetect = lp.clock.Now()
lp.vehicleDetectTicker = lp.clock.Ticker(vehicleDetectInterval)
lp.publish(vehicleDetectionActive, true)
}
}

Expand All @@ -900,6 +911,7 @@ func (lp *LoadPoint) stopVehicleDetection() {
if lp.vehicleDetectTicker != nil {
lp.vehicleDetectTicker.Stop()
}
lp.publish(vehicleDetectionActive, false)
}

// identifyVehicleByStatus validates if the active vehicle is still connected to the loadpoint
Expand All @@ -911,6 +923,7 @@ func (lp *LoadPoint) identifyVehicleByStatus() {
_, ok := lp.charger.(api.Identifier)

if vehicle := lp.coordinator.IdentifyVehicleByStatus(!ok); vehicle != nil {
lp.stopVehicleDetection()
lp.setActiveVehicle(vehicle)
return
}
Expand Down
40 changes: 20 additions & 20 deletions dist/assets/index.f014e26a.js → dist/assets/index.9738d453.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<meta name="theme-color" content="#020318" />

<title>evcc</title>
<script type="module" crossorigin src="./assets/index.f014e26a.js"></script>
<link rel="stylesheet" href="./assets/index.c0100ffd.css">
<script type="module" crossorigin src="./assets/index.9738d453.js"></script>
<link rel="stylesheet" href="./assets/index.fb2bc24b.css">
</head>
<body>
<script>
Expand Down
3 changes: 3 additions & 0 deletions evcc.dist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ messaging:
soc: # vehicle soc update event
title: SoC updated
msg: Battery charged to ${vehicleSoC:%.0f}%
guest: # vehicle could not be identified
title: Unknown vehicle
msg: Unknown vehicle, guest connected?
services:
# - type: pushover
# app: # app id
Expand Down