EU Data Act: prefer valid battery_level_HV.value for SoC (#31092)
This commit is contained in:
parent
be75289a3b
commit
c837c1e281
3 changed files with 39 additions and 5 deletions
|
|
@ -142,16 +142,16 @@ func TestSocFreshestField(t *testing.T) {
|
|||
// first datasets carry both SoC fields at 57, the high-priority field winning
|
||||
deliver(map[string]point{
|
||||
FieldBatteryStateReportSoc: {Value: "57"},
|
||||
FieldHvBatteryLevel: {Value: "57.0"},
|
||||
FieldHvBatteryLevelValue: {Value: "57.0"},
|
||||
})
|
||||
deliver(map[string]point{
|
||||
FieldBatteryStateReportSoc: {Value: "57"},
|
||||
FieldHvBatteryLevel: {Value: "57.0"},
|
||||
FieldHvBatteryLevelValue: {Value: "57.0"},
|
||||
})
|
||||
|
||||
// later datasets only refresh the fallback field as the car charges
|
||||
for _, v := range []string{"58.0", "59.0", "61.0"} {
|
||||
deliver(map[string]point{FieldHvBatteryLevel: {Value: v}})
|
||||
deliver(map[string]point{FieldHvBatteryLevelValue: {Value: v}})
|
||||
}
|
||||
|
||||
soc, err := testProvider(data).Soc()
|
||||
|
|
@ -159,6 +159,28 @@ func TestSocFreshestField(t *testing.T) {
|
|||
assert.Equal(t, 61.0, soc, "the still-updating fallback wins over the stale high-priority field")
|
||||
}
|
||||
|
||||
// TestSocHvBatteryLevelValid reproduces #31084: battery_level_HV.value (74) is
|
||||
// preferred over ambiguous battery_state_report.soc (45) only when state is VALID.
|
||||
func TestSocHvBatteryLevelValid(t *testing.T) {
|
||||
raw := []dataPoint{
|
||||
{DataFieldName: FieldBatteryStateReportSoc, Value: "74"},
|
||||
{DataFieldName: FieldBatteryStateReportSoc, Value: "45"},
|
||||
{DataFieldName: FieldBatteryStateReportSoc, Value: "45"},
|
||||
{DataFieldName: FieldHvBatteryLevelValue, Value: "74.0"},
|
||||
}
|
||||
|
||||
// without a VALID flag the ambiguous battery_state_report.soc still wins (45)
|
||||
soc, err := testProvider(points(raw)).Soc()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 45.0, soc, "prior behaviour kept when HV level is not flagged valid")
|
||||
|
||||
// with battery_level_HV.state VALID, battery_level_HV.value (74) is preferred
|
||||
valid := append(raw, dataPoint{DataFieldName: FieldHvBatteryLevelState, Value: hvBatteryLevelValid})
|
||||
soc, err = testProvider(points(valid)).Soc()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 74.0, soc, "battery_level_HV.value wins when flagged VALID")
|
||||
}
|
||||
|
||||
// TestPoints guards that a data point with a generic field name ("value") is
|
||||
// indexed by its unique key while the name stays indexed (and thus logged).
|
||||
func TestPoints(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,14 @@ func (v *Provider) Soc() (float64, error) {
|
|||
return 0, err
|
||||
}
|
||||
|
||||
if p := lookup(data, FieldBatteryStateReportSoc, FieldSoc, FieldHvSoc, FieldHvBatteryLevel); p != nil {
|
||||
// use battery_level_HV.value when its state reports valid
|
||||
if s, ok := data[FieldHvBatteryLevelState]; ok && s.Value == hvBatteryLevelValid {
|
||||
if p, ok := data[FieldHvBatteryLevelValue]; ok {
|
||||
return strconv.ParseFloat(p.Value, 64)
|
||||
}
|
||||
}
|
||||
|
||||
if p := lookup(data, FieldBatteryStateReportSoc, FieldSoc, FieldHvSoc, FieldHvBatteryLevelValue); p != nil {
|
||||
return strconv.ParseFloat(p.Value, 64)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ const (
|
|||
FieldBatteryStateReportSoc = "battery_state_report.soc"
|
||||
FieldSoc = "state_of_charge"
|
||||
FieldHvSoc = "hv_soc"
|
||||
FieldHvBatteryLevel = "battery_level_HV.value"
|
||||
FieldHvBatteryLevelValue = "battery_level_HV.value"
|
||||
FieldHvBatteryLevelState = "battery_level_HV.state"
|
||||
|
||||
// target soc
|
||||
FieldTargetSoc = "settings.target_soc"
|
||||
|
|
@ -129,6 +130,10 @@ const (
|
|||
FieldRemainingTime = "remaining_charging_time"
|
||||
)
|
||||
|
||||
// hvBatteryLevelValid is the battery_level_HV.state value that marks
|
||||
// battery_level_HV.value as a trustworthy SoC reading
|
||||
const hvBatteryLevelValid = "VALID"
|
||||
|
||||
// knownKeys lists data point GUIDs that are indexed by their key instead of the
|
||||
// generic, non-unique DataFieldName they are delivered with
|
||||
var knownKeys = map[string]struct{}{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue