Menu
Meter and Counter Reading Data Model for Maintenance

Meter and Counter Reading Data Model for Maintenance

How a plant stores what a machine has done: meter fields, reading records, rollover and reset maths, estimated readings and three ways to compute a due date.
Meter and Counter Reading Data Model for Maintenance

Key takeaways

  • A meter is a record in its own right, separate from the asset and the plan that watches it. One field, accumulation, decides every later calculation: cumulative readings are subtracted, incremental added, spot neither.
  • Three events break a plain subtraction: a wrap, a replaced controller, a counter cleared during a service. Worked below: 93,180 to 300 gives a naive delta of minus 92,880 where the truth is 7,120 strokes.
  • An estimated reading must carry a flag, never be stored as if a person read it. Worked below: 28 days of estimates at 985 strokes a day against a real 700 pulls a due date from 2026-11-11 to 2026-10-28.
  • A plan set to whichever comes first must write back every trigger on completion, not only the one that fired. Miss one and the same job is raised again ten days later.
  • Worked below: the same press on the same day is due 2026-10-18 on hours, 2026-10-28 on cycles and 2026-11-17 on the calendar. The planner acts on the earliest, and names it.

The record that makes usage based maintenance possible

A plan that fires at 500 operating hours or 100,000 cycles needs somewhere to keep what the machine has done. That is a meter and a stream of readings.

The plan consuming these numbers belongs to our preventive maintenance plan data model, and the level a meter hangs off to the asset hierarchy data model.

Four objects, and why they are not one

Plants that struggle with meters keep them as one column on the asset record, called something like current hours. It can be overwritten, has no history and cannot be audited.

ObjectWhat it is
MeterA named counter on one asset, with a unit and a rule
ReadingOne value at one moment, kept forever
SourceThe device or person the reading came from
TriggerThe link from a meter to a plan and its interval

The reading stream is append only: a wrong reading is corrected by a new row that supersedes it, so the correction stays visible.

Cumulative, incremental or spot

A cumulative meter is an odometer, so usage is the difference between two readings. An incremental meter is a tally, so usage is the sum of the rows.

A spot meter is neither: a filter differential of 0.42 bar is a state, so subtracting two of them says nothing about wear.

Accumu­lationUsage ruleExample
Cumu­lativecurrent minus previousRun hours 41,250 h
Incre­mentalsum of the rows7.5 h this shift
Spotno delta, compare to a limit0.42 bar across a filter

Four shift entries of 7.5, 8.0, 7.0 and 8.5 hours are 31.0 hours of work read as incremental.

Read as cumulative they give deltas of plus 0.5, minus 1.0 and plus 1.5, netting to 1.0 hour, so a 500 hour service arrives thirty one times later than it should.

Meter types and units of measure

Six families cover almost every counter a plant will put on a plan, and the unit matters as much as the type.

Meter typeUnitDrives
Running hourshBearings, oil, belts, drives
Cycles or strokescountPresses, dies, moulds, valves
Units producedpcs, kg, mWeb tooling, knives, nozzles
DistancekmForklifts, AGVs, conveyors
Energy or fuelkWh, LCom­pres­sors, gen­sets
Con­ditionbar, °C, µmFilters, hy­draul­ics, bearings

A press standing idle with a tool mounted burns hours and no tool life, so hours are the wrong meter for wear per operation.

A die hit counter is one cycle meter with a complication of its own: it belongs to the tool, not the press it sits in (see die maintenance tracking).

Units produced carries a trap: a scrapped part wears the tool as much as a good one. Feed the meter total parts, and keep good parts for the OEE data model.

The meter definition record

The fields a meter needs before a single reading can be trusted.

FieldTypeReq.
meter_idkeyYes
asset_idrefYes
meter_typeenumYes
uomenumYes
accumu­lationenumYes
decimalsintYes
rollover_maxintNo
wrap_countintNo
offsetnumNo
era_start_valuenumNo
reset_attsNo
max_ratenumYes
read_intervalintYes
stale_afterintYes
primary_sourcerefYes
is_activeboolYes

Six of them carry the weight.

FieldWhy it exists
accumu­lationDecides whether usage is a sub­traction or a sum
rollover_maxHighest value the counter shows before it wraps to zero
offsetLifetime total at the moment the current counter started
max_rateFastest credible gain per hour, used to reject bad rows
stale_afterDays of silence before the meter is called untrust­worthy
decimals0 for strokes, 1 for hours, so rounding is a decision

Tenths stored as an integer lose up to 0.9 hours per reading, which at one reading a day is up to 328 hours a year.

stale_after stops silence reading as health: a meter unread past its limit should mark its plans unverified, not comfortably not yet due.

The reading record

One row per value, written once, never updated. These columns are the minimum for recalculating a due date from scratch a year later.

FieldTypeReq.
reading_idkeyYes
meter_idrefYes
reading_valuenumYes
reading_attsYes
recorded_attsYes
recorded_byrefYes
source_idrefYes
entry_methodenumYes
is_esti­matedboolYes
estimate_methodenumNo
statusenumYes
super­sedes_idrefNo
void_reasontextNo
usage_deltanumDerived
lifetime_valuenumDerived
notetextNo

Two timestamps, not one: reading_at is when the counter showed the value, recorded_at when the row landed. A technician who reads at 06:10 and types at 14:40 moves a usage rate by half a shift.

The last two columns are derived and never typed: when a correction arrives you replay them forward from that point and touch nothing before it.

Status, and why you never delete a reading

A reading has three legitimate states and no fourth. Deleting rows is what makes a meter history impossible to audit.

StatusMeaning
ValidCounts towards usage
Super­sededReplaced by a later, corrected row
VoidKept, excluded from usage, reason stored

Void is for the impossible reading, such as a typo of 412,500 for 41,250, kept with its reason so a changed usage total can be explained.

Where a reading comes from

Counters reach a CMMS two ways, both normal: a machine connection reads the value, or a person types it in.

FieldWhat it holds
source_idThe key
source_typePLC tag, IoT sensor, vision count, manual, import
addressTag name, register or device id
scale_factorRaw units to meter units, for example 0.1
poll_intervalHow often the value is pulled
priorityWhich source wins when two disagree
last_seen_atLast time the source answered at all
is_trustedMay write without review

scale_factor is where quiet disasters live. A PLC publishing tenths of an hour as an integer needs 0.1, and without it every run hours plan fires ten times too late.

priority decides which wins once a machine is connected and both hand entry and the connection write to it (see machine monitoring system).

Rollover, replacement and reset

A naive usage calculation is current minus previous. It is correct until one of three things happens, and then it is not just wrong but confidently wrong.

All three examples use press PRS‑04 and its stroke counter MTR‑1181, a five digit register with rollover_max 99,999.

1. The counter wraps at 99,999

On 2026-07-01 the counter reads 93,180, and on 2026-07-08 it reads 300.

The naive delta is minus 92,880. Some systems store it, most drop it, a few take the absolute value.

  • usage = (current minus previous plus 100,000) modulo 100,000.
  • = (300 minus 93,180 plus 100,000) modulo 100,000 = 7,120 strokes.
  • The long way: 100,000 minus 93,180 = 6,820 to reach the wrap, plus 300 after it = 7,120.

Store rollover_max as the highest value displayed, not the capacity: a five digit counter is 99,999 while the modulus is 100,000.

The formula assumes at most one wrap between readings, since a counter round twice looks like one round once.

So it sets a reading frequency rule. PRS‑04 averages 985 strokes a day, and 100,000 divided by 985 is 101.5 days of headroom.

2. The controller is replaced

On 2026-10-05 the press controller fails and is swapped. The old one last showed 87,740 and the new one starts at zero.

On 2026-10-12, after a normal week, the new counter shows 6,895, so the naive delta is minus 80,845.

A system that sees a negative delta and applies the rollover fix returns minus 80,845 plus 100,000 = 19,155 strokes. That is positive, plausible and 12,260 too high.

Nobody notices: the machine appears to work harder than it does, and every cycle based plan comes due early forever.

The fix is an era: a stretch of readings from one physical counter, closed and reopened when the device changes.

Era fieldValue on 2026-10-05
era_start_at2026-10-05 11:20
era_start_value0
offset1,987,740
wrap_count0, reset with the device
reasonCon­troller replace­ment

The offset is the lifetime total reached when the new counter started, here 1,987,740 strokes.

So 6,895 on 2026-10-12 means a lifetime of 1,987,740 plus 6,895 = 1,994,635, and the week's usage is 6,895, not 19,155.

3. The counter is cleared after an overhaul

The third case looks like the second and is not: nothing was replaced, and somebody pressed reset on a working counter.

During the clutch service on 2026-10-18 an engineer clears run hours counter MTR‑1180, which read 41,500 h. A week later it shows 70 h, right for a week at ten hours a day and nonsense as a lifetime.

Without a reset_at record the consequence is not a wrong usage number. It is a plan that never speaks again.

After the resetValue
last_done_meter written41,500 h
next_due_meter, plus 1,50043,000 h
Counter now reads70 h
Plan waits for42,930 h
At 10 h a day4,293 days, 11.8 years

The plan is not overdue, not red and not on anybody's list, just not yet due, the most expensive state a preventive plan can be in.

Record reset_at and the value at the reset and the lifetime carries on: 41,500 plus 70 = 41,570 h. Better still, never reset a lifetime counter.

The formula that survives all three

Order matters more than any single line: check the era before the rollover, or case two silently becomes case one.

StepRule
1Different era? usage = (era end minus prev) plus (current minus era start)
2Same era, current below prev, rollover_max set? add rollover_max plus 1
3Same era, current below prev, no rollover_max? reject the row
4Other­wise usage = current minus previous
5Reject if usage is above max_rate times hours elapsed

lifetime = offset + wrap_count × (rollover_max + 1) + (reading_value minus era_start_value).

On 2026-07-01 that is 0 + 18 × 100,000 + 93,180 = 1,893,180. On 2026-09-23, after the July wrap, it is 0 + 19 × 100,000 + 75,920 = 1,975,920.

Plausibility limits

Every meter needs a ceiling on credible speed.

MeterCeiling per hour elapsed
Run hours1.0 h, by physics
StrokesRated strokes per minute times 60
UnitsIdeal cycle rate, no more
DistanceRated speed of the truck

Between 2026-09-16 and 2026-09-23 there are 168 elapsed hours, and MTR‑1180 gained 70 of them, which is 41.7% utilisation and believable.

A gain of 190 hours over the same 168 is impossible, and belongs in a review queue rather than in four plans.

Estimated readings

Readings get missed, and the hole has to be filled, because a due date calculation needs a value for the day it runs. The question is how it is labelled.

One rule, not negotiable: an estimate is written as a reading with is_estimated true and an estimate_method beside it, so it can be replaced the moment a real reading arrives.

Back-fill and forward estimate are different jobs

A back-fill happens after the next real reading lands, so the gap is bounded and the arithmetic is interpolation.

A forward estimate happens while the gap is open, so it extrapolates from a rolling average and will be wrong.

Take the missed week: no reading on 2026-08-19, with 35,100 on 2026-08-12 and 47,500 on 2026-08-26 either side.

MethodValue for 08-19
Gap, 14 days47,500 minus 35,100 = 12,400
Back-fill, half of it35,100 + 6,200 = 41,300
28 day rate to 08-1227,860 ÷ 28 = 995.0 a day
Forward, 7 at 995.035,100 + 6,965 = 42,065
Forward minus back-fill765 high, 12.3% of the week

Both are defensible and they disagree, which is the argument for the flag. When the real reading lands, the estimated row is superseded and the derived columns replayed from 2026-08-12.

An estimate does not break the total, which telescopes either way. It corrupts the series: the weekly rate, the rolling average and every forecast using it.

What a run of estimates does to a due date

One estimate is a rounding error. A run of them is a forecast built entirely on the assumption that nothing changed.

Suppose the reader is absent for four weeks from 2026-09-23 and the system fills the gap at 985 strokes a day, while the press moves onto a slower job and genuinely runs 700 a day.

On 2026-10-21Strokes
Lifetime on 2026-09-231,975,920
Esti­mated, 28 at 98527,580
Real, 28 at 70019,600
Esti­mated lifetime2,003,500
Real lifetime1,995,520
Over­stated by7,980

The cycle plan is due at 2,010,000 strokes, and each forecast continues at the rate it believes in.

From 2026-10-21Crosses 2,010,000
Esti­mates: 6,500 at 9856.6 days, 2026-10-28
Reality: 14,480 at 70020.7 days, 2026-11-11
Service pulled early14 days, 9,800 strokes

So carry the estimate rate on every forecast: in the quarter below, 1 of 13 readings was estimated, which is 7.7%.

Past a threshold, suppress the date and show the last real reading and its age. A date nobody can defend is worse than no date.

Several meters on one asset

An asset with one meter is the exception. PRS‑04 carries four, and each answers a different question about wear.

MeterType and unit
MTR-1180Run hours, h, cumu­lative
MTR-1181Strokes, count, cumu­lative
MTR-1182Units made, pcs, incre­mental
MTR-1183Filter drop, bar, spot

So meter_id must be a first class key. The stroke counter belongs to the press and the filter differential to the hydraulic unit under it, and a meter on the wrong level is invisible to its plans.

Whichever comes first

A plan on a real machine needs more than one trigger: hours for time driven wear, cycles for operation driven wear, a date for the asset that barely runs.

So the trigger is not a field on the plan but a child table, and the plan carries a combine_rule of first or all.

Trigger fieldWhat it holds
trigger_idThe key
plan_idPlan it belongs to
meter_idEmpty for a calendar trigger
interval_value1,500
interval_uomrun hours
last_done_value40,000 h, written on com­ple­tion
next_due_value41,500 h, derived
lead_days10
avg_window84 days
combine_ruleFirst

Each trigger produces a forecast date from its own meter and window. The plan's due date is the minimum of them under first and the maximum under all.

The lead time converts per trigger, and this is where meter plans fall over: ten days means nothing to a counter until you multiply it by a rate.

10 day leadRaise point
Calendar, already days10 days before due
Hours: 10 × 10.0 = 100 h41,400 h
Cycles: 10 × 985 = 9,8502,000,150

Store avg_window on the trigger, because a 28 day window and an 84 day window give different rates and different dates.

The tie-break, and the write-back that stops a double job

When two triggers fall due within days of each other the team should do the work once, which needs a combine_window on the plan.

With a 14 day window, an hours trigger due 2026-10-18 and a cycles trigger due 2026-10-28 are one job, on the earlier date.

Then comes the rule almost every implementation gets wrong. Completing a plan writes back every trigger on it, not only the one that fired.

Written on 2026-10-18Next due
Date, 180 days2027-04-16
Hours 41,500, plus 1,50043,000 h
Strokes 2,000,545, plus 160,0002,160,545

Write the real reading at completion into each trigger, never the due value: writing 41,500 when the counter said 41,562 hides the drift.

Skip the write-back on the cycles trigger and it still sits at 2,010,000, which the press crosses ten days later, so the team redoes a service it just finished.

Worked example: one press, one quarter

Press PRS‑04, quarter three of 2026, read every Wednesday. Every figure below reconciles with the ones above it.

1. The register

The counter is MTR‑1181, cumulative, rollover_max 99,999. Thirteen readings, twelve intervals, 84 days from 2026-07-01 to 2026-09-23.

DateCounterUsed
07-0193,180start
07-083007,120
07-157,2406,940
07-2214,5507,310
07-2921,2306,680
08-0528,2807,050
08-1235,1006,820
08-1941,300est.
08-2647,50012,400
09-0254,6807,180
09-0961,6306,950
09-1668,8707,240
09-2375,9207,050

Two rows are not ordinary. The 2026-07-08 row is lower than the one before because the counter wrapped, and the 2026-08-19 row is a back-filled estimate flagged is_estimated.

The 12,400 on 2026-08-26 covers 14 days, not 7, so it must never enter a weekly average as one week.

2. Reconciling the usage total

Add the usage figures, treating the estimated row as part of the 14 day block it sits in.

  • 7,120 + 6,940 + 7,310 + 6,680 + 7,050 + 6,820 = 41,920 to 2026-08-12.
  • Plus 12,400 across the missed week = 54,320 to 2026-08-26.
  • Plus 7,180 + 6,950 + 7,240 + 7,050 = 82,740 to 2026-09-23.

Now check it from the lifetime values instead of the deltas, which is the check that catches a missed wrap.

LifetimeStrokes
07-01: 18 wraps + 93,1801,893,180
09-23: 19 wraps + 75,9201,975,920
Difference82,740

Two independent routes to 82,740, which is the point of the exercise.

Window to 09-23Strokes a day
84 days, 82,740985.0
28 days, 28,4201,015.0

Thirty strokes a day is a 3.0% difference, small because this press ran steadily. Where the product mix changes the two windows can differ by a third.

The run hours meter over the same 84 days went from 40,410 h to 41,250 h, which is 840 hours, or 10.0 hours a day.

3. Three due dates from the same day

Plan PM‑4120 is the slide and clutch service on PRS‑04, last completed on 2026-05-21 at 40,000 h and 1,850,000 strokes.

TriggerDue pointLeft
Calendar, 180 d2026-11-1755 d
Hours, 1,500 h41,500 h250 h
Cycles, 160,0002,010,00034,080

Stand on 2026-09-23, at 41,250 h and 1,975,920 strokes, and convert each gap into a date at the quarter's rates.

ArithmeticDate
2026-05-21 plus 180 days2026-11-17
250 ÷ 10.0 a day = 25.0 d2026-10-18
34,080 ÷ 985 a day = 34.6 d2026-10-28

Three triggers on one plan, one asset, one day, and three answers spread across 30 days.

Swap the cycle forecast onto the 28 day rate of 1,015 a day and it becomes 33.6 days, or 2026-10-27, one day of movement from a choice of window.

4. Which answer the planner acts on

Under combine_rule first the plan is due on 2026-10-18, the hours trigger, the earliest of the three.

With a 10 day lead the job appears on 2026-10-08, or at 41,400 h, whichever comes first.

The cycles trigger at 2026-10-28 falls inside the 14 day combine_window, so it is folded into the same job.

The calendar date of 2026-11-17 is not wrong, just last, and its job is to catch the quarter when the press barely runs.

So print the trigger, the meter, the reading, the rate and the window on the work order. All three dates are true, and a due date with no trigger name is the one to never act on.

The rest of the plan sits in the CMMS data model, the failures it prevents in the equipment failure record data model.

Five questions to ask a vendor about meter data

Ask for a demonstration, not an answer.

  1. Show me a rollover. Enter 93,180 then 300 on a five digit counter and read out the usage stored. If it is negative, zero or 92,880, the model is wrong.
  2. Replace a controller in front of me. Record an old final value and a new counter starting at zero, then show lifetime total and weekly usage separately.
  3. Where does an estimated reading live? Fill a missed week, then show the flag, the method, and what happens when the real reading arrives.
  4. Put two meters and a date on one plan. Set 1,500 hours or 160,000 cycles or 180 days, complete it once, and show all three next due points moving.
  5. Export twelve months of one meter. Ask for raw values, timestamps, source and the estimate flag as columns. If the flag is not exportable, it is not really stored.

Before a shortlist, read what is a CMMS and equipment maintenance software, then the preventive maintenance schedule and condition based maintenance.

How Fabrico helps

Fabrico is an OEE platform with a full CMMS built in. Everything above is a specification to test a shortlist against, not one product's feature list.

On the machine side Fabrico has PLC connectivity, IoT sensors and computer vision, with real-time OEE, downtime and micro-stop detection built on them.

On the maintenance side: recurring templates, conditional tasks, an annual PM plan view, approvals and work shifts, plus push, in-app and email notifications.

Work orders are raised and confirmed by your team, never by the system alone. Technicians use the iOS, Android or web app and scan the QR code on a machine or part.

Inventory holds min and max levels and books consumption against the work order (see spare parts management).

Failure forecasting is not a standard feature, and production planning is not part of it. Put the rollover rule, the era fields and the estimate flag to every vendor you shortlist.

Want your machine data, plans and work orders in one place? Book a 30 minute demo with a Fabrico consultant, no commitment, or contact us with your questions.

Frequently asked questions

What fields does a meter reading record need?

reading_id, meter_id, reading_value, reading_at, recorded_at, recorded_by, source_id, entry_method, is_estimated, estimate_method, status and note. usage_delta and lifetime_value are derived from the stream and should never be typed by hand.

What is the difference between a cumulative and an incremental meter?

A cumulative meter is an odometer, so usage is the current reading minus the previous one. An incremental meter records the amount used since the last entry, so usage is the sum of the rows, and confusing the two can understate usage by a factor of thirty.

How do you handle a counter that rolls over at 99,999?

Store rollover_max as 99,999 and compute usage as current minus previous plus 100,000, modulo 100,000, so a move from 93,180 to 300 is 7,120 strokes rather than minus 92,880. Read the counter often enough that it can never wrap twice between readings.

Should estimated meter readings be stored?

Yes, but only with is_estimated set to true and the method recorded, so the row can be superseded when a real reading arrives. Twenty eight days of estimates at 985 strokes a day against a real 700 moved the worked example's due date fourteen days early.

How does a PM plan use hours or cycles instead of a date?

Each trigger stores a meter, an interval and the reading at the last completion, so next due is last done plus the interval, with the lead time converted into meter units by a rolling daily average. With combine_rule set to first, the plan is due on the earliest of its triggers, which in the worked example was 2026-10-18 and not the calendar date of 2026-11-17.

Последно от блога

Начертайте вашата пътна карта за надеждност
Изчислете потенциалната възвръщаемост: запазете час за демонстрация
Начертайте вашата пътна карта за надеждност
Като натиснете бутона Приемам, вие давате съгласието си за използването на `бисквитки`, докато ползвате до този уебсайт. За да научите повече за това как `бисквитките` се използват и управляват, моля, вижте нашата Политика за поверителност и Декларация за Бисквитките