Add incremental material consumption integrator
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Replay common timestamps from ignored K7 run 00842 captures, without network access."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
from production_analytics.calculations import (
|
||||
MaterialConsumptionIntegrator,
|
||||
MaterialIntegratorConfig,
|
||||
MaterialSample,
|
||||
)
|
||||
|
||||
RATE_UUID = "c9d06af5-f6d6-4ede-b6c4-5a98bac77129" # Stundenleistung Anlage [kg/h]
|
||||
GATE_UUID = "823867bb-f5d2-40eb-b875-657155addfd0" # Geschwindigkeit Gesamtanlage [m/min]
|
||||
CAPTURE_DIRECTORY = Path("data/raw/enlyze")
|
||||
|
||||
|
||||
def read_capture(path: Path, variable_uuid: str) -> dict[datetime, float]:
|
||||
"""Read unique, ordered observations; refuse ambiguous duplicate source records."""
|
||||
data = json.loads(path.read_text(encoding="utf-8"))["response"]["body"]["data"]
|
||||
time_index = data["columns"].index("time")
|
||||
value_index = data["columns"].index(variable_uuid)
|
||||
values = {}
|
||||
previous = None
|
||||
for record in data["records"]:
|
||||
timestamp = datetime.fromisoformat(record[time_index].replace("Z", "+00:00"))
|
||||
if timestamp.utcoffset() is None:
|
||||
raise ValueError(f"Naive timestamp in {path}")
|
||||
timestamp = timestamp.astimezone(UTC)
|
||||
if previous is not None and timestamp <= previous:
|
||||
raise ValueError(f"Capture timestamps must be strictly increasing: {path}")
|
||||
previous = timestamp
|
||||
if record[value_index] is not None:
|
||||
values[timestamp] = float(record[value_index])
|
||||
return values
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--max-sample-gap-seconds", type=float, default=20.0)
|
||||
args = parser.parse_args()
|
||||
integrator = MaterialConsumptionIntegrator(
|
||||
MaterialIntegratorConfig(0.5, args.max_sample_gap_seconds)
|
||||
)
|
||||
try:
|
||||
rates = read_capture(CAPTURE_DIRECTORY / "k7-00842-throughput.raw.json", RATE_UUID)
|
||||
gates = read_capture(CAPTURE_DIRECTORY / "k7-00842-speed.raw.json", GATE_UUID)
|
||||
except (OSError, ValueError, KeyError) as error:
|
||||
parser.exit(1, f"Cannot replay K7 captures: {error}\n")
|
||||
# Dict insertion order preserves validated capture order. No resampling or filling.
|
||||
samples = [MaterialSample(t, rate, gates[t]) for t, rate in rates.items() if t in gates]
|
||||
if len(samples) < 2:
|
||||
parser.exit(1, "Need at least two common non-null samples\n")
|
||||
state = integrator.process_many(samples)
|
||||
print(f"Common samples: {len(samples)}")
|
||||
print(f"Maximum sample gap: {integrator.config.max_sample_gap_seconds:g} s")
|
||||
print(f"Integrated running time: {state.integrated_running_seconds / 3600:.9f} h")
|
||||
print(f"Cumulative material consumption: {state.cumulative_consumption_kg:.9f} kg")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user