

# Tarnbeck Institute of Hydrology · Data Services


## Reloading a station export after a gauge reset


Operations note DS/OP/07 · Data services · Reviewed 14 January 2026


## Symptoms


The station's daily total is short and the loader's own log says nothing is wrong. In the log the day
looks like a clean run: the export was fetched, every block was read, and the summary line reports
fewer readings than the station's counter did. The gap is always at the end of the day rather than
the beginning, and it is always a whole number of blocks.


The other sign is a duplicate warning in the block log, with two entries carrying the same sequence
number and different checksums. One warning is normal after a reset. A run of them means the
reset happened part way through the day and everything after it is being rejected block by block.


## Why the loader rejects the second block


Block sequence numbers come from the station and not from the loader. The loader keeps the
highest number it has committed for the day and treats anything at or below it as a repeat, which is
the right thing to do on a poor link: a station that retransmits sends the same block twice, and the
loader must not count it twice.


A reset returns the counter to zero, so the blocks after it carry sequence numbers the loader has
already committed. Nothing about them looks new and the loader discards them for exactly the
reason it should. The reset time is the only thing that distinguishes a continuation from a repeat,
and the loader does not know it unless it is told.


## The fix


When a gauge is reset in the field the station's counter returns to zero, and the export for that day
contains two blocks carrying the same sequence number. The loader accepts the first and rejects the
second. That is the right behaviour for a duplicated transmission and the wrong behaviour here, and
the day's record ends up short by however much arrived after the reset.


The fix is to requeue the affected blocks with the reset time supplied, so that the loader treats the
second block as a continuation rather than a repeat. The function below is the one to call. It lives in
tarnbeck.stations.maintenance and is safe to run more than once: a block that already carries a
good checksum is skipped.


DS/OP/07 · Data services


Page 1 of 3




Tarnbeck Institute of Hydrology · Data Services


<table>
 <tr>
  <th>from tarnbeck.stations import Export, reload_window</th>
 </tr>
 <tr>
  <th>def reload_after_reset(station, reset_at):</th>
 </tr>
 <tr>
  <th>export = Export.open(station)</th>
 </tr>
 <tr>
  <th>window = reload_window(reset_at, margin_minutes=45)</th>
 </tr>
 <tr>
  <th>for block in export.blocks(window):</th>
 </tr>
 <tr>
  <th>if block.checksum_ok():</th>
 </tr>
 <tr>
  <th>continue</th>
 </tr>
 <tr>
  <th>export.requeue(block, reason="gauge reset")</th>
 </tr>
 <tr>
  <th>return export.commit(dry_run=False)</th>
 </tr>
 <tr>
  <th>Run it from the loader host and not from a workstation, and take the reset time from the field log</th>
 </tr>
 <tr>
  <th>rather than from the station clock, which is the thing that was wrong. The margin defaults to</th>
 </tr>
 <tr>
  <th>forty-five minutes either side of the reset; widen it only if the field log is vague about the time,</th>
 </tr>
 <tr>
  <th>because a wide window requeues blocks that were never in doubt.</th>
 </tr>
 <tr>
  <th>If commit returns a count lower than the number of blocks in the window, stop there and raise it</th>
 </tr>
 <tr>
  <th>with data services before running anything again. A short count means blocks were rejected for a</th>
 </tr>
 <tr>
  <th>second reason, and requeuing them repeatedly will not find out what it was.</th>
 </tr>
 <tr>
  <th>Running it</th>
 </tr>
 <tr>
  <th>Run it from the loader host, in the maintenance environment, with the station code and the reset</th>
 </tr>
 <tr>
  <th>time as they appear in the field log:</th>
 </tr>
 <tr>
  <th>$ ssh loader-01.tarnbeck.example</th>
 </tr>
 <tr>
  <th>$ tarnbeck-maint reload-after-reset --station VQ1 \</th>
 </tr>
 <tr>
  <th>--reset-at '2026-01-29T09:15' --confirm</th>
 </tr>
</table>


DS/OP/07


The command prints the window it will use, the number of blocks in it and the number it intends to
requeue, and then waits. Read the three numbers before answering. If the window is wider than the
field log justifies, stop and narrow it rather than letting it run.


Without --confirm the command does everything except commit, which is the safe way to see
what it would do. The dry run takes a few seconds and there is no reason to skip it.


## Afterwards


Check the day's totals against the gauge's own counter before closing the ticket. The loader reports
the number of blocks committed and not the number of readings, and a day can come back with
the right number of blocks and the wrong number of readings if a block was truncated in the field.


Note the reset in the station log, with the time taken from the field log and not the time the reload
ran. The next person to look at a gap in the series will look there first, and a reload with nothing
written beside it is indistinguishable from a gap nobody has dealt with.


DS/OP/07 · Data services


Page 2 of 3




Tarnbeck Institute of Hydrology · Data Services


DS/OP/07


SEQ is the station's counter and is the field a reset returns to zero. START is the station clock, which
is not to be trusted after a reset - which is why the reset time comes from the field log and not from
the export.


CRC covers the readings and not the header, so a block with a good checksum and a wrong
sequence number is possible and is exactly what a reset produces. Nothing in the header says a
reset happened.


## Rolling back


A committed reload can be undone within the same day by reverting the station's day to the
snapshot the loader takes before it commits. The snapshot is kept for seven days and is named for
the run.


After seven days the only route back is a fresh fetch of the export from the station, which is possible
while the station's own buffer still holds the day - about three weeks - and impossible afterwards. A
reload that has committed and cannot be rolled back is an incident and is raised as one, whatever
the size of the gap.


DS/OP/07 · Data services


Page 3 of 3


