forked from b.peck/BAT
Data seeding, filter overhaul, UI scaling fixes, sanitized AlarmAnalysis copy
Data & simulation: - simulation_tags.json: re-prioritize 10 tags to Medium so all four priorities appear in live data (backfilled journal history to match) - SimHarness probe P2: ack-user/includeData ground truth + filtered-bundle verification against the live journal Data layer (PrimeControls.calc/alarms): - filters now drive every metric: queryStatus rows (Active Now/Unacked/ Standing) filtered via calc.apply_status_filters; event_count counts only filtered instances (per-instance n_events); dropdown options enumerate unfiltered data so choices never collapse - build_bundle refactored into _assemble(); when filters are active an unfiltered mirror is attached as bundle.overview - the Overview tab stays a plant-wide summary while all other consumers bind filtered sections - _fetch_journal now honors includeData (required for ackUserName; without it ack attribution is always None); enabled for journal rows + source detail so Top Ack Users and the Ack By column populate FilterBar/Dashboard: - root-cause fix: bidirectional bindings never wrote dropdown selections back to session props, so filters silently did nothing; Apply now pulls values directly from the sibling controls, Clear resets both - multi-select dropdowns cap at 280px and wrap chips; filter bar row is auto-height so wrapped chips push tabs down instead of overlapping - filter bar hidden on the Overview tab (not applicable there) UI scaling: - Header: Prime logo added; KpiCard compacted to fit the 71px KPI row (basis-95% overflow fix, chip hugs text, embeds clipped) - no scrollbars - Overview timeline: thinned x labels (minDistance 140), labels anchored below the axis, smaller legend markers - Bad Actors focus chip shows the full source string with the clear X - popup repeaters (Daily Activity, ScoreBars) no longer overflow (useDefaultViewWidth/Height off, taller strip); 5px table cell padding Tooling/tests: - lint_project.py: accept propConfig params.* as param declarations (Designer saves strip null params entries) - tests: 31 -> 34 (status-filter semantics, overview mirror, filtered event counts) - .gitignore: runtime churn (valueStore.idb, local-system-properties, migration logs, thumbnails, .schemas) New project: AlarmAnalysis - submission copy of PrimeBAT with client-visible Prime Controls branding removed (logo, subtitle, project title, shift report heading); PrimeControls organizational namespaces retained per spec. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,91 @@
|
||||
import json
|
||||
|
||||
OUT_DIR = "/usr/local/bin/ignition/data/projects/.probe"
|
||||
PROBE_NAME = "P1"
|
||||
PROBE_NAME = "P2"
|
||||
|
||||
|
||||
def _load_pc():
|
||||
"""Exec PrimeBAT's real PrimeControls modules (calc/fmt/alarms) into a
|
||||
package object and return it (shared by _p1/_p2)."""
|
||||
import imp
|
||||
base = "/usr/local/bin/ignition/data/projects/PrimeBAT/ignition/script-python/PrimeControls/"
|
||||
pkg = imp.new_module("PrimeControls")
|
||||
pkg.__path__ = [base]
|
||||
sys_modules = __import__("sys").modules
|
||||
sys_modules["PrimeControls"] = pkg
|
||||
for name in ("calc", "fmt", "alarms"):
|
||||
m = imp.new_module("PrimeControls." + name)
|
||||
m.__dict__["system"] = system
|
||||
code = open(base + name + "/code.py").read()
|
||||
compiled = compile(code, name, "exec")
|
||||
exec compiled in m.__dict__
|
||||
sys_modules["PrimeControls." + name] = m
|
||||
setattr(pkg, name, m)
|
||||
return pkg
|
||||
|
||||
|
||||
def _p2():
|
||||
"""Ack-user visibility + filtered-bundle ground truth."""
|
||||
out = {}
|
||||
end = system.date.toMillis(system.date.now())
|
||||
start = end - 4 * 3600 * 1000
|
||||
|
||||
def ack_facts(entries):
|
||||
acks = []
|
||||
for e in entries:
|
||||
try:
|
||||
if e.getAckData() is None:
|
||||
continue
|
||||
except:
|
||||
continue
|
||||
f = {}
|
||||
try:
|
||||
f["ackUserName"] = repr(e.get("ackUserName"))[:80]
|
||||
except:
|
||||
f["ackUserName"] = "ERR"
|
||||
try:
|
||||
f["ackUser"] = repr(e.get("ackUser"))[:120]
|
||||
except:
|
||||
f["ackUser"] = "ERR"
|
||||
acks.append(f)
|
||||
named = [a for a in acks if a["ackUserName"] not in ("None", "ERR", "u''", "''")]
|
||||
return {"ack_count": len(acks), "named_count": len(named),
|
||||
"samples": named[:3] or acks[:3]}
|
||||
|
||||
try:
|
||||
r = system.alarm.queryJournal(startDate=start, endDate=end)
|
||||
out["no_includeData"] = ack_facts([e for e in r])
|
||||
except:
|
||||
out["no_includeData"] = "ERR"
|
||||
try:
|
||||
r = system.alarm.queryJournal(startDate=start, endDate=end, includeData=True)
|
||||
out["includeData_true"] = ack_facts([e for e in r])
|
||||
except:
|
||||
out["includeData_true"] = "ERR"
|
||||
|
||||
pkg = _load_pc()
|
||||
al = pkg.alarms
|
||||
|
||||
def pick(b):
|
||||
return {"event_count": b["meta"]["event_count"],
|
||||
"activation_count": b["meta"]["activation_count"],
|
||||
"areas_n": len(b["meta"]["areas"]),
|
||||
"prios_seen": [p["label"] for p in b["meta"]["priorities_seen"]],
|
||||
"kpis": dict((k, b["kpis"][k]["value"]) for k in b["kpis"]),
|
||||
"pareto_top": (b["pareto"]["rows"][0]["label"], b["pareto"]["rows"][0]["count"]) if b["pareto"]["rows"] else None,
|
||||
"overview_act": (b.get("overview") or {}).get("meta", {}).get("activation_count"),
|
||||
"overview_insights": len((b.get("overview") or {}).get("insights") or []),
|
||||
"error": b["meta"]["error"]}
|
||||
out["bundle_all"] = pick(al.getDashboardBundle(start, end, None))
|
||||
out["bundle_medium"] = pick(al.getDashboardBundle(start, end, {"priorities": [2]}))
|
||||
out["bundle_area_tankfarm"] = pick(al.getDashboardBundle(start, end, {"areas": ["TankFarm"]}))
|
||||
|
||||
d = al.getSourceDetail(
|
||||
"prov:default:/tag:BuildathonSim/Intake/ConveyorJam_Chatter:/alm:ConveyorJam_Chatter",
|
||||
start, end)
|
||||
out["source_detail_top_ack"] = d["stats"]["top_ack_users"]
|
||||
out["source_detail_error"] = d["error"]
|
||||
return out
|
||||
|
||||
|
||||
def _p1():
|
||||
@@ -227,6 +311,6 @@ def _p0():
|
||||
def run():
|
||||
result = {"probe": PROBE_NAME,
|
||||
"ranAt": str(system.date.now())}
|
||||
result["payload"] = _safe(_p1)
|
||||
result["payload"] = _safe(_p2)
|
||||
_write(result)
|
||||
system.util.getLogger("probe").info("probe %s written to %s" % (PROBE_NAME, OUT_DIR))
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
"fixedDelay": true,
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user