Skip to content

fix(serviceMgr): change filter never fires for boolean-valued signals - #209

Merged
UlfBj merged 1 commit into
masterfrom
fix/change-filter-boolean-datatype
Sep 18, 2026
Merged

UlfBj merged 1 commit into
masterfrom
fix/change-filter-boolean-datatype

Conversation

@UlfBj

@UlfBj UlfBj commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Problem

Subscribing to a boolean-valued signal with a "change" filter never fires a subscription event, e.g.:

{"action":"subscribe","path":"Vehicle.Cabin.Door.Row1.DriverSide.IsOpen","filter":{"variant":"change","parameter":{"logic-op":"gt", "diff":"0"}},"requestId":"233"}

This was tested with logic-op values gt, ne, and lt against a feeder (feederv4) simulating the signal from tripdata.json with alternating true/false values -- the underlying data does change, but no events are ever received, for any logic-op.

Root cause

evaluateChangeFilter (server/vissv2server/serviceMgr/serviceMgr.go) decides whether compareValues should use its "bool" or "number" comparison branch by calling utils.IsBoolean() on the filter's diff parameter, instead of on the signal's own value:

datatype := "number"
if utils.IsBoolean(changeFilter.Diff) {
	datatype = "bool"
}

Per VISS CORE's Change Filter Operation, a boolean signal's diff is conventionally the numeric-looking string "0" -- compareValues' "bool" branch itself requires diff == "0". So utils.IsBoolean("0") is always false for a real boolean-signal subscription, datatype is always forced to "number", and compareValues then tries strconv.ParseFloat("true"/"false", ...), which always fails and silently returns false -- so every change-filter subscription on a boolean path never fires, regardless of logic-op.

This regressed in commit 9714661 ("Subscribe change/range refactoring"), which replaced a previous utils.AnalyzeValueType() call on the signal's own value (which correctly detected bool) with the IsBoolean(diff) check above.

The existing test suite did not catch this: TestCompareValues_Bool* tests call compareValues directly with datatype="bool" hardcoded, bypassing the buggy classification in evaluateChangeFilter entirely; and the one test that did go through evaluateChangeFilter with a boolean signal (TestEvaluateChangeFilter_BoolNe) used an unrealistic diff="false" (which happens to make IsBoolean(diff) true, masking the bug) and asserted nothing about the result (_ = ok // just ensure no panic).

Fix

Classify datatype from the signal's current/latest value instead of from diff:

datatype := "number"
if utils.IsBoolean(currentValue) || utils.IsBoolean(latestValue) {
	datatype = "bool"
}

Testing

  • Tightened TestEvaluateChangeFilter_BoolNe to actually assert on the outcome (it previously asserted nothing).
  • Added TestEvaluateChangeFilter_BoolWithConformantDiff, a table-driven regression test covering gt/lt/ne/eq with the VISS-conformant diff="0" on true/false transitions -- exactly the bug-report scenario. All 10 subcases pass with the fix (and would have failed before it).
  • go test ./server/vissv2server/serviceMgr passes in full.
  • go vet ./server/vissv2server/... passes.

evaluateChangeFilter decided whether compareValues should use the
'bool' or 'number' datatype branch by calling utils.IsBoolean on the
filter's diff parameter, not on the signal's own value. Per VISS
CORE's Change Filter Operation, a boolean signal's diff is
conventionally the numeric-looking string "0" (compareValues' bool
branch itself requires diff=="0"), so IsBoolean(diff) was always
false for a real boolean-signal subscription. That forced datatype to
"number", and compareValues then tried
strconv.ParseFloat("true"/"false", ...), which always fails and
silently returns false -- so a change-filter subscription on any
boolean path (e.g. Vehicle.Cabin.Door.Row1.DriverSide.IsOpen) never
fired a notification, regardless of logic-op (gt/lt/ne/eq).

This regressed in commit 9714661 ("Subscribe change/range
refactoring"), which replaced the previous utils.AnalyzeValueType
call on the signal's own latestValue (which correctly detected bool)
with the IsBoolean(diff) check.

Fix: classify datatype from the signal's current/latest value instead
of from diff.

Adds TestEvaluateChangeFilter_BoolWithConformantDiff, exercising the
exact gt/lt/ne/eq scenarios from the bug report with the
VISS-conformant diff="0", which the existing test suite did not
cover (the one prior bool-oriented test, TestEvaluateChangeFilter_
BoolNe, used an unrealistic diff="false" and asserted nothing on the
result).
@UlfBj
UlfBj merged commit 49fb59e into master Sep 18, 2026
6 checks passed
@UlfBj
UlfBj deleted the fix/change-filter-boolean-datatype branch September 18, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant