Costs: what a finding costs¶
A finding's cost is one of four kinds of figure, and the kinds are never added together. A plant manager
should be able to check every dollar against their own records, so each figure says what it is and the finding page
shows the arithmetic behind it. Give the collection's context model a costs block, and an asset its own rate where
it differs:
"costs": { "currency": "USD", "perMinuteDown": 40, "perScrappedPart": 3.5,
"products": [ { "name": "Cap 38mm", "perScrappedPart": 0.8 } ],
"runningStates": ["Running"],
"attribution": [ { "family": "drift", "asset": "ct1", "downtimeReasons": ["cooling water"] } ] },
"assets": [ { "id": "press4", "name": "Press 4", "costPerMinuteDown": 95 } ],
"relations": [ { "from": "ct1", "to": "press4", "type": "feeds" } ]
The editor's collection form holds the costs rates and the asset form holds costPerMinuteDown (section 7.1);
attribution is edited in the model's JSON.
The four kinds
- Attributed: the stops your own records tie to the problem. When
costs.attributionhas an entry for the finding's kind (itsfamily:drift,band,setpoint,first-out-alarm, anmes-check, ...; optionally only on oneassetor onetag), the finding is charged the downtime whose reason is one ofdowntimeReasons(compared without case, as the state-periodsreasoncolumn carries it), on its own machine and every machine itsfeedsrelations reach (a cooling tower feeds the presses it cools), during the finding's active span (the start and end its evidence names, not the whole time it stayed open). Each machine's minutes are priced at its owncostPerMinuteDown, elseperMinuteDown. It reads "USD 719 attributed", the figure "11 stops, 20.6 min". When such a finding has mapped stops, excess over normal is not added to it (excess scrap on those machines is not counted there); when it has none, it is priced as excess instead and says so. Two attributed findings on one source with overlapping spans each price their own span and each names the other as an overlap. - Above normal (estimated): for any other process finding on a machine: only what is above that machine's own usual rate.
- Scrap, per product: (reject rate in the finding's hours − the same product's reject rate in the baseline) ×
parts made in the finding's hours × the product's price (its
productsentry, elseperScrappedPart; the arithmetic names which). Parts made = good + rejected from thecountsshape; a count bucket the window cuts counts in proportion to its overlap. A figure can therefore differ by a part or two from a raw shot count: on Whitfield, A13's window cuts the hourly buckets at 4:24 PM, so it shows 190.6 WD-4510-VB rejected of 1,671.6 made where the shot table counts 191 of 1,670. - Downtime: (unplanned minutes per running hour in the finding's hours − the baseline's) × running hours ×
the per-minute rate. Running hours are the hours less every period that is not running (planned or not);
unplanned minutes are periods whose
plannedis not true and whose state is not inrunningStates. - The baseline is the 28 days before the finding began.
- Stops the map ties to a cause are left out of the downtime, in the finding's hours and in the baseline:
every stop whose reason a
costs.attributionentry names for this machine (an entry with anassetreaches that machine and every machine it feeds; one without reaches all). This is decided by the map alone, and the arithmetic says "N stops with reasons mapped to a cause are left out". - Guards: "not priced" beats an invented number. A product is priced only with at least 200 parts made in the finding's hours and 1,000 in the baseline; downtime only with 8 running hours in the finding's hours, 48 in the baseline and 5 unplanned stops there. The difference must be at least 3 standard errors (scrap: a two-proportion test; stop minutes: a compound-Poisson test using the baseline's stop rate and stop lengths). The label names the reason that binds: a product well above normal but made in too few parts is "Not priced: too few parts"; a smaller difference is "Not priced: could be chance"; a rate at or below normal is "No excess over normal"; too few parts or hours otherwise is "Not priced: too little data". Rates in the arithmetic are shown to the cent so every line multiplies out.
- Each finding is priced on its own: its own window against its own baseline, whatever other findings exist,
so its figure is the same on the list, a filtered list, its page, the digest and Ask. When another finding that
is open, judged a real issue, or resolved from open or a real issue (its resolve note records the status it had
before; one resolved from hidden or suppressed is never named), on the same machine or one related by
feeds, has an attributed or above-normal figure over an overlapping window, the arithmetic adds "Overlaps with '' ( to ): these figures are not additive" and the cost JSON lists it in overlaps; it never changes the figure. A dismissed (not an issue), known, suppressed or hidden finding is never named. Findings resolved before this version carry no record of their earlier status, so they are never named as overlaps; their cost figures are unaffected. Two findings that list each other inoverlapsare never added, even when they are the same kind. - A finding shape attributes is not shape-priced as well; an MES Watch finding keeps its own measured excess (below).
- Risk if left alone: a slow trend (Anomaly Watch's
trendfamily) whose evidence forecasts reaching a limit shows how soon: "reaches its high alarm limit (140 degF) in about 2.3 days at this rate", as of the last run, with the level and rate in its arithmetic. It is never dollars and never added to a dollar figure, and says "not priced: no recorded event of this kind to price". A trend with no limit in sight reads "No limit in sight". - Not priced: with why. Alarm Health and Gateway Health setup findings read "Not counted: alarm setup" / "system setup" and, where the evidence measures it, show the operator burden instead: "about 11 activations a day (74 in 7 days)", or "25 alarms trip at once on each restart". Data-health findings (ticket 181) read "a data problem, not a machine cost". Every other unpriced finding says what is missing: no asset, the asset not in the model, no shapes mapped, a rate to set, a read that failed, or nothing recorded.
MES Watch findings keep the excess their own check measured since the pattern began, as kind
above normal: stop minutes and slow-running minutes at the per-minute rate, rejects and failed checks at the one
part price: the product's products entry where the check names a product (waste after planned stops names it when
one product ran after the stops), else perScrappedPart (the arithmetic says the check did not split by product) ,
the same lookup the shape findings use, in the finding and in MES Watch's ranking. A drift has no cost until parts fail.
When the window starts and ends. A finding's hours run from first seen to resolved, else last seen, else now ,
from when it began where it knows (an Anomaly Watch span start, an Incident's look-back
windowMinutes, default 30, before first seen), and to the end of the span it names when that is more than an hour
before its last sighting. The arithmetic states the hours compared.
Where the figure shows. The Findings list's Cost column shows the figure and its kind ("USD 9,005 above
normal", "USD 719 attributed", "reaches its high alarm limit ... in about 2.3 days", "Not priced: could be chance").
A group row (a detector's fires, or several findings grouped) never adds findings that overlap each other: it shows
each one's figure on its own line (kind overlapping, no amount). Otherwise it adds like with like only: one
kind gives one amount; an
attributed and an above-normal member show each kind on its own line ("USD 100 attributed", "USD 300 above
normal"; kind mixed, the sums in byKind, no single amount). The list sorts by severity; sort: "cost" ranks attributed, then above normal, each
by its own amount, then mixed groups, risks and the rest. The finding page's Cost card shows the figure, what it
counts and every step. The digest's cost line names the kind. Ask's findings tool carries each finding's
cost.kind, label, amount, currency, reason, figure, basis, arithmetic and overlaps, so Ask quotes
and explains the page's figure and never adds kinds or overlapping findings; its downtime tool says its totals are gross downtime by reason over the asked
window, not a finding's cost.
The cost JSON (on each row of getFindings/getFinding, and as cost in MQTT messages and callbacks, section
9): amount (null unless attributed or above normal), currency, kind (attributed, excess, risk,
notPriced, mixed, overlapping), kindText, label, text, basis, reason (and its older name missing), figure (a
time to a limit or an operator burden), arithmetic (the steps, plain words), overlaps (the ids of findings it overlaps), downtimeMinutes and scrapParts
(above normal or attributed), scrapByProduct, byKind, since, until, measure (MES Watch), partial. MQTT
and callbacks carry kind, label, amount, currency, reason, figure, arithmetic and overlaps; a resolved notice
carries no cost.
Checks on save. Rates are numbers of zero or more, currency at most 8 characters, product names set and
distinct. Each attribution entry needs a family Artekis files (an unknown one is refused with the list), at
least one reason (every reason a non-blank string), an asset of the model when set, and a non-blank tag when
set. Changing a rate or the map re-prices every finding at once: no cost is stored.
Reads are bounded: one read of each mapped shape per collection per request, from 28 days and 24 hours before
the earliest finding being priced (the baseline, plus a day so a period or bucket that began before still counts its
overlap) to the latest end, through the shape reader's paging and row cap; one read of the findings' metric evidence;
one read of the open, confirmed and resolved findings on their machines and related machines, for the overlap lines.
When a list's read hits the row cap (a long list reaches further back than one finding's page), each finding in it
is priced again with its own read, exactly as its page prices it, so a figure never depends on the caller. A
finding whose own read hits the row cap is marked partial, its baseline starts where the read does, and the
arithmetic states that start and the days actually compared.