Vehicle: add wakeupdisabled feature to suppress wake-up calls (#31461)
This commit is contained in:
parent
3a560d1254
commit
2bd319a361
10 changed files with 67 additions and 10 deletions
|
|
@ -18,4 +18,5 @@ const (
|
||||||
WelcomeCharge // vehicle
|
WelcomeCharge // vehicle
|
||||||
ClimaterDisabled // vehicle - ignore climater state for charge control
|
ClimaterDisabled // vehicle - ignore climater state for charge control
|
||||||
AutodetectDisabled // vehicle - do not try to identify vehicle by status
|
AutodetectDisabled // vehicle - do not try to identify vehicle by status
|
||||||
|
WakeUpDisabled // vehicle - do not send wake-up calls
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const _FeatureName = "CoarseCurrentIntegratedDeviceSwitchDeviceHeatingContinuousAverageCacheableOfflineRetryableStreamingWelcomeChargeClimaterDisabledAutodetectDisabled"
|
const _FeatureName = "CoarseCurrentIntegratedDeviceSwitchDeviceHeatingContinuousAverageCacheableOfflineRetryableStreamingWelcomeChargeClimaterDisabledAutodetectDisabledWakeUpDisabled"
|
||||||
|
|
||||||
var _FeatureIndex = [...]uint8{0, 13, 29, 41, 48, 58, 65, 74, 81, 90, 99, 112, 128, 146}
|
var _FeatureIndex = [...]uint8{0, 13, 29, 41, 48, 58, 65, 74, 81, 90, 99, 112, 128, 146, 160}
|
||||||
|
|
||||||
const _FeatureLowerName = "coarsecurrentintegrateddeviceswitchdeviceheatingcontinuousaveragecacheableofflineretryablestreamingwelcomechargeclimaterdisabledautodetectdisabled"
|
const _FeatureLowerName = "coarsecurrentintegrateddeviceswitchdeviceheatingcontinuousaveragecacheableofflineretryablestreamingwelcomechargeclimaterdisabledautodetectdisabledwakeupdisabled"
|
||||||
|
|
||||||
func (i Feature) String() string {
|
func (i Feature) String() string {
|
||||||
i -= 1
|
i -= 1
|
||||||
|
|
@ -38,9 +38,10 @@ func _FeatureNoOp() {
|
||||||
_ = x[WelcomeCharge-(11)]
|
_ = x[WelcomeCharge-(11)]
|
||||||
_ = x[ClimaterDisabled-(12)]
|
_ = x[ClimaterDisabled-(12)]
|
||||||
_ = x[AutodetectDisabled-(13)]
|
_ = x[AutodetectDisabled-(13)]
|
||||||
|
_ = x[WakeUpDisabled-(14)]
|
||||||
}
|
}
|
||||||
|
|
||||||
var _FeatureValues = []Feature{CoarseCurrent, IntegratedDevice, SwitchDevice, Heating, Continuous, Average, Cacheable, Offline, Retryable, Streaming, WelcomeCharge, ClimaterDisabled, AutodetectDisabled}
|
var _FeatureValues = []Feature{CoarseCurrent, IntegratedDevice, SwitchDevice, Heating, Continuous, Average, Cacheable, Offline, Retryable, Streaming, WelcomeCharge, ClimaterDisabled, AutodetectDisabled, WakeUpDisabled}
|
||||||
|
|
||||||
var _FeatureNameToValueMap = map[string]Feature{
|
var _FeatureNameToValueMap = map[string]Feature{
|
||||||
_FeatureName[0:13]: CoarseCurrent,
|
_FeatureName[0:13]: CoarseCurrent,
|
||||||
|
|
@ -69,6 +70,8 @@ var _FeatureNameToValueMap = map[string]Feature{
|
||||||
_FeatureLowerName[112:128]: ClimaterDisabled,
|
_FeatureLowerName[112:128]: ClimaterDisabled,
|
||||||
_FeatureName[128:146]: AutodetectDisabled,
|
_FeatureName[128:146]: AutodetectDisabled,
|
||||||
_FeatureLowerName[128:146]: AutodetectDisabled,
|
_FeatureLowerName[128:146]: AutodetectDisabled,
|
||||||
|
_FeatureName[146:160]: WakeUpDisabled,
|
||||||
|
_FeatureLowerName[146:160]: WakeUpDisabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
var _FeatureNames = []string{
|
var _FeatureNames = []string{
|
||||||
|
|
@ -85,6 +88,7 @@ var _FeatureNames = []string{
|
||||||
_FeatureName[99:112],
|
_FeatureName[99:112],
|
||||||
_FeatureName[112:128],
|
_FeatureName[112:128],
|
||||||
_FeatureName[128:146],
|
_FeatureName[128:146],
|
||||||
|
_FeatureName[146:160],
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeatureString retrieves an enum value from the enum constants string name.
|
// FeatureString retrieves an enum value from the enum constants string name.
|
||||||
|
|
|
||||||
|
|
@ -962,7 +962,7 @@ func (lp *Loadpoint) setLimit(current float64) error {
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v := lp.GetVehicle()
|
v := lp.GetVehicle()
|
||||||
if vv, ok := api.Cap[api.Resurrector](v); ok && errors.Is(err, api.ErrAsleep) {
|
if vv, ok := api.Cap[api.Resurrector](v); ok && errors.Is(err, api.ErrAsleep) && !hasFeature(v, api.WakeUpDisabled) {
|
||||||
// https://github.com/evcc-io/evcc/issues/8254
|
// https://github.com/evcc-io/evcc/issues/8254
|
||||||
// wakeup vehicle
|
// wakeup vehicle
|
||||||
lp.log.DEBUG.Printf("set charge current limit: waking up vehicle")
|
lp.log.DEBUG.Printf("set charge current limit: waking up vehicle")
|
||||||
|
|
@ -983,7 +983,7 @@ func (lp *Loadpoint) setLimit(current float64) error {
|
||||||
if enabled := current >= effMinCurrent; enabled != lp.enabled {
|
if enabled := current >= effMinCurrent; enabled != lp.enabled {
|
||||||
if err := lp.charger.Enable(enabled); err != nil {
|
if err := lp.charger.Enable(enabled); err != nil {
|
||||||
v := lp.GetVehicle()
|
v := lp.GetVehicle()
|
||||||
if vv, ok := api.Cap[api.Resurrector](v); enabled && ok && errors.Is(err, api.ErrAsleep) {
|
if vv, ok := api.Cap[api.Resurrector](v); enabled && ok && errors.Is(err, api.ErrAsleep) && !hasFeature(v, api.WakeUpDisabled) {
|
||||||
// https://github.com/evcc-io/evcc/issues/8254
|
// https://github.com/evcc-io/evcc/issues/8254
|
||||||
// wakeup vehicle
|
// wakeup vehicle
|
||||||
lp.log.DEBUG.Printf("charger %s: waking up vehicle", status[enabled])
|
lp.log.DEBUG.Printf("charger %s: waking up vehicle", status[enabled])
|
||||||
|
|
@ -1959,6 +1959,10 @@ func (lp *Loadpoint) processTasks() {
|
||||||
|
|
||||||
// startWakeUpTimer starts wakeUpTimer
|
// startWakeUpTimer starts wakeUpTimer
|
||||||
func (lp *Loadpoint) startWakeUpTimer() {
|
func (lp *Loadpoint) startWakeUpTimer() {
|
||||||
|
if lp.vehicleHasFeature(api.WakeUpDisabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
lp.log.DEBUG.Printf("wake-up timer: start")
|
lp.log.DEBUG.Printf("wake-up timer: start")
|
||||||
lp.wakeUpTimer.Start()
|
lp.wakeUpTimer.Start()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,7 @@ func TestPvScalePhases(t *testing.T) {
|
||||||
vehicle := api.NewMockVehicle(ctrl)
|
vehicle := api.NewMockVehicle(ctrl)
|
||||||
vehicle.EXPECT().Phases().Return(tc.vehicle).MinTimes(1)
|
vehicle.EXPECT().Phases().Return(tc.vehicle).MinTimes(1)
|
||||||
vehicle.EXPECT().OnIdentified().Return(api.ActionConfig{}).AnyTimes()
|
vehicle.EXPECT().OnIdentified().Return(api.ActionConfig{}).AnyTimes()
|
||||||
|
vehicle.EXPECT().Features().AnyTimes()
|
||||||
|
|
||||||
lp := &Loadpoint{
|
lp := &Loadpoint{
|
||||||
log: util.NewLogger("foo"),
|
log: util.NewLogger("foo"),
|
||||||
|
|
|
||||||
|
|
@ -353,6 +353,34 @@ func TestDisconnectIntegratedDeviceKeepsMode(t *testing.T) {
|
||||||
assert.Equal(t, api.ModeOff, lp.GetMode(), "integrated device disconnect must not reset mode")
|
assert.Equal(t, api.ModeOff, lp.GetMode(), "integrated device disconnect must not reset mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStartWakeUpTimerDisabled(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
features []api.Feature
|
||||||
|
wantRunning bool
|
||||||
|
}{
|
||||||
|
{"enabled", nil, true},
|
||||||
|
{"disabled", []api.Feature{api.WakeUpDisabled}, false},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
|
||||||
|
vehicle := api.NewMockVehicle(ctrl)
|
||||||
|
vehicle.EXPECT().Features().Return(tc.features).AnyTimes()
|
||||||
|
|
||||||
|
lp := &Loadpoint{
|
||||||
|
log: util.NewLogger("foo"),
|
||||||
|
vehicle: vehicle,
|
||||||
|
wakeUpTimer: NewTimer(),
|
||||||
|
}
|
||||||
|
|
||||||
|
lp.startWakeUpTimer()
|
||||||
|
|
||||||
|
assert.Equal(t, tc.wantRunning, lp.wakeUpTimer.Running())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestReconnectVehicle(t *testing.T) {
|
func TestReconnectVehicle(t *testing.T) {
|
||||||
tc := []struct {
|
tc := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ params:
|
||||||
deprecated: true
|
deprecated: true
|
||||||
- name: autodetectdisabled
|
- name: autodetectdisabled
|
||||||
deprecated: true
|
deprecated: true
|
||||||
|
- name: wakeupdisabled
|
||||||
|
deprecated: true
|
||||||
render: |
|
render: |
|
||||||
type: custom
|
type: custom
|
||||||
{{ include "vehicle-common" . }}
|
{{ include "vehicle-common" . }}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ params:
|
||||||
deprecated: true
|
deprecated: true
|
||||||
- name: autodetectdisabled
|
- name: autodetectdisabled
|
||||||
deprecated: true
|
deprecated: true
|
||||||
|
- name: wakeupdisabled
|
||||||
|
deprecated: true
|
||||||
render: |
|
render: |
|
||||||
type: custom
|
type: custom
|
||||||
{{- include "vehicle-common" . }}
|
{{- include "vehicle-common" . }}
|
||||||
|
|
|
||||||
|
|
@ -342,6 +342,14 @@ params:
|
||||||
help:
|
help:
|
||||||
en: Ignore the vehicle for auto detection of connected vehicles
|
en: Ignore the vehicle for auto detection of connected vehicles
|
||||||
de: Das Fahrzeug von der automatischen Erkennung beim Anschließen eines Fahrzeugs ausschließen
|
de: Das Fahrzeug von der automatischen Erkennung beim Anschließen eines Fahrzeugs ausschließen
|
||||||
|
- name: wakeupdisabled
|
||||||
|
type: bool
|
||||||
|
description:
|
||||||
|
en: Disable wake-up calls
|
||||||
|
de: Aufweck-Aufrufe deaktivieren
|
||||||
|
help:
|
||||||
|
en: Do not send wake-up calls to the vehicle or charger, useful for vehicles that refuse to charge after repeated wake-ups.
|
||||||
|
de: Keine Aufweck-Aufrufe an Fahrzeug oder Ladegerät senden, hilfreich bei Fahrzeugen, die nach wiederholtem Aufwecken das Laden verweigern.
|
||||||
- name: heating
|
- name: heating
|
||||||
type: bool
|
type: bool
|
||||||
description:
|
description:
|
||||||
|
|
@ -611,11 +619,15 @@ presets:
|
||||||
advanced: true
|
advanced: true
|
||||||
- name: autodetectdisabled
|
- name: autodetectdisabled
|
||||||
advanced: true
|
advanced: true
|
||||||
|
- name: wakeupdisabled
|
||||||
|
advanced: true
|
||||||
vehicle-online:
|
vehicle-online:
|
||||||
- name: climaterdisabled
|
- name: climaterdisabled
|
||||||
advanced: true
|
advanced: true
|
||||||
- name: autodetectdisabled
|
- name: autodetectdisabled
|
||||||
advanced: true
|
advanced: true
|
||||||
|
- name: wakeupdisabled
|
||||||
|
advanced: true
|
||||||
charger-features:
|
charger-features:
|
||||||
- name: heating
|
- name: heating
|
||||||
advanced: true
|
advanced: true
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{{ define "vehicle-features" }}
|
{{ define "vehicle-features" }}
|
||||||
{{- if or .basefeatures (eq .coarsecurrent "true") (eq .welcomecharge "true") (eq .streaming "true") (eq .climaterdisabled "true") (eq .autodetectdisabled "true") }}
|
{{- if or .basefeatures (eq .coarsecurrent "true") (eq .welcomecharge "true") (eq .streaming "true") (eq .climaterdisabled "true") (eq .autodetectdisabled "true") (eq .wakeupdisabled "true") }}
|
||||||
features:
|
features:
|
||||||
{{- range .basefeatures }}
|
{{- range .basefeatures }}
|
||||||
- {{ . }}
|
- {{ . }}
|
||||||
|
|
@ -19,5 +19,8 @@ features:
|
||||||
{{- if eq .autodetectdisabled "true" }}
|
{{- if eq .autodetectdisabled "true" }}
|
||||||
- autodetectdisabled
|
- autodetectdisabled
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if eq .wakeupdisabled "true" }}
|
||||||
|
- wakeupdisabled
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ func TestTemplates(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// universalVehicleFeatures render via the shared vehicle-features include, so a
|
// onlineVehicleFeatures render via the shared vehicle-features include, so a
|
||||||
// stored config may carry them; dropping the param breaks reload (discussion #31291).
|
// stored config may carry them; dropping the param breaks reload (discussion #31291).
|
||||||
var universalVehicleFeatures = []string{"climaterdisabled", "autodetectdisabled"}
|
var onlineVehicleFeatures = []string{"climaterdisabled", "autodetectdisabled", "wakeupdisabled"}
|
||||||
|
|
||||||
func TestVehicleFeatureParamsConsistent(t *testing.T) {
|
func TestVehicleFeatureParamsConsistent(t *testing.T) {
|
||||||
for _, tmpl := range templates.ByClass(templates.Vehicle, templates.WithDeprecated()) {
|
for _, tmpl := range templates.ByClass(templates.Vehicle, templates.WithDeprecated()) {
|
||||||
|
|
@ -52,7 +52,7 @@ func TestVehicleFeatureParamsConsistent(t *testing.T) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, feat := range universalVehicleFeatures {
|
for _, feat := range onlineVehicleFeatures {
|
||||||
values := tmpl.Defaults(templates.RenderModeUnitTest)
|
values := tmpl.Defaults(templates.RenderModeUnitTest)
|
||||||
values["template"] = tmpl.Template
|
values["template"] = tmpl.Template
|
||||||
values[feat] = true
|
values[feat] = true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue