Repository navigation
Add a new scenario: meter-value-zero #108
Description
Good First Issue
Add a new scenario meter-value-zero: a transaction where the meter register
reads zero throughout. This is a negative control. A flat register is not by
itself a detectable fault today, and the scenario pins that down so a future
change to METER_VALUE_ANOMALY cannot start reporting it by accident.
METER_VALUE_ANOMALY fires only on negative or decreasing cumulative readings.
An all-zero series is neither, so this trace must come back clean. Whether a
stuck register deserves its own rule is tracked separately in #144.
What to do
- Create
packages/toolkit/src/scenarios/__scenarios__/meter-value-zero.ts - Build a synthetic trace of a transaction whose meter never advances:
BootNotificationat2026-01-15T09:00:00.000Z, and itsCallResultwith
interval: 300AuthorizewithidTag: 'SYNTHETIC-TAG-021'at09:00:30.000Z, acceptedStartTransactionon connector 1 at09:01:00.000ZwithmeterStart: 0,
answered withtransactionId: 100021MeterValuesat09:02:00.000Z,09:03:00.000Zand09:04:00.000Z, each
carrying a singlesampledValueof'0'with measurand
Energy.Active.Import.Registerand unitWhStopTransactionat09:05:00.000ZwithmeterStop: 0and
reason: 'Local'- A
CallResultfor every Call
- Set
expectedFailures: [] - Add
{ type: 'no_failures', params: {} }as the assertion - Import and register in
packages/toolkit/src/scenarios/index.ts - Update the scenario count in every place that states it, see "Files to modify"
- Run
ocpp-debugkit cito verify all scenarios pass, then run the full local
check from
Verify Locally.
ocpp-debugkit cicovers neither formatting nor lint nor types, and CI stops
at the first failure. - Add a changeset with
pnpm changeset, and pick patch. Scenario additions
are patch releases, see
Adding a Scenario.
Why those timestamps
The transaction runs four minutes, comfortably past the sixty second floor that
SUSPICIOUS_SESSION_DURATION watches for. The whole trace also finishes inside
twice the three hundred second heartbeat interval, so TIMEOUT_NO_HEARTBEAT
stays silent without needing a heartbeat in the trace. This trace was run against
the detection engine and reports no failures.
Files to modify
packages/toolkit/src/scenarios/__scenarios__/meter-value-zero.ts(new)packages/toolkit/src/scenarios/index.ts(register, and add toscenarioNames)packages/toolkit/src/scenarios/index.test.ts(count, name order,getScenario)tests/external-fixture/test.mjs(count)README.md(count)packages/toolkit/README.md(count).changeset/(new changeset file)
The first two of the count files fail the test suite when they drift. The two
READMEs do not, so they are easy to miss.
Guidelines
- All data must be synthetic. This scenario reserves station ID
CS-SYNTHETIC-021, so please use that one. - Follow the pattern in an existing scenario file.
meter-anomaly.tsis the
closest match for shape, andnormal-sessionis the closest for a scenario
that expects no failures. - Verify with
ocpp-debugkit scenario run meter-value-zerothat no failures are
reported. If a rule does fire, adjust the trace rather than adding the code to
expectedFailures, since the whole point of this scenario is that it stays
clean. - The scenario count depends on what has merged ahead of you. Run the suite and
use the number it reports rather than assuming.
How to claim
Comment "I'd like to work on this" and it will be assigned to you.
Please hold one open claim at a time. Once the pull request for it is merged,
say which issue you want next and it will be assigned. That keeps issues from
sitting claimed while another is still in review, so other newcomers can see
what is genuinely free.
Activity
YANGCHUNHONG3000 commentedon Jul 26, 2026
I'd like to work on this meter-value-zero scenario.
sepehr-safari commentedon Jul 26, 2026
Thanks for the interest. I am assigning these one at a time, and #104 is with you
now, so I am leaving this one open for the moment. Once #133 merges, say the word
and it is yours.
docs: bring CURRENT_STATE up to date with 0.4.3 and the scenario corp…
docs: bring CURRENT_STATE up to date with 0.4.4 and today's work (#150)
YANGCHUNHONG3000 commentedon Aug 2, 2026
Hi sepehr-safari,
Checking back in on this one — the firmware-update-success scenario (#133) has now merged (thanks for that!), and I'd like to pick this up next if it's still available.
I have the plan clear from the issue body: build the
meter-value-zerosynthetic trace (flat register, zero throughout), assertexpectedFailures: []with ano_failuresassertion, register it inscenarios/index.ts, and update the scenario count + changeset. I've got the workflow down from the scenario work I did in #133/#147.Happy to take it if you're good with that. Thanks!
sepehr-safari commentedon Aug 8, 2026
Yes, it is yours, and sorry for the slow reply.
One thing to flag before you start, because the issue body changed after it was
first written and your summary above matches the original rather than the current
version. The scenario is now a negative control:
expectedFailures: []with ano_failuresassertion, exactly as you describe, and the reason matters. A flatmeter register is not a detectable fault today.
METER_VALUE_ANOMALYonly fires onreadings that go negative or decrease, and an all-zero series does neither, so this
trace has to come back completely clean. The scenario exists to pin that down, so a
future change to the rule cannot start reporting it by accident. Whether a stuck
register deserves a rule of its own is a separate question, tracked in #144.
One correction to the issue body before you start, which is on me. It reserves
CS-SYNTHETIC-017, and that ID is no longer free:refused-authorization.tstookit when it shipped in 0.4.5, after this issue was written. Please use
CS-SYNTHETIC-021. I have updated the issue body to match, so it now says 021rather than 017. Everything else in the trace stands, and I checked that exact
trace against the detection engine before writing it up, so it is known to produce
no failures rather than assumed to.
Two small things worth carrying over from #147: the changeset is
patch, notminor, and please branch off current
mainrather than off a previous scenariobranch, which is what tangled the last one.
docs: bring CURRENT_STATE forward after #161 and fix the stale ID all…
fix(scenarios): align idTag and transactionId with station 021
feat(scenarios): add meter-value-zero negative control scenario (ocpp…
docs: record complete rule coverage and the corpus reaching 21 (#172)