Bootstrap material state across production runs

This commit is contained in:
2026-09-05 15:50:45 +02:00
parent ae13c3c35a
commit b89d57d1c1
4 changed files with 235 additions and 46 deletions
@@ -77,7 +77,26 @@ class MaterialPollingService:
)
if saved_polling_state is None:
initial_state = None
initial_state = MaterialIntegrationState()
historical_runs = sorted(
(
previous for previous in self._gateway.get_production_runs(self._machine_id)
if previous.production_order == run.production_order
and previous.uuid != run.uuid
and previous.start <= run.start
),
key=lambda previous: previous.start,
)
for previous in historical_runs:
if previous.end is None or previous.end > run.start:
raise ValueError("Historical production run overlaps the current open run")
integrated = self._integrate(
initial_state, start=previous.start, end=previous.end,
)
initial_state = MaterialIntegrationState(
cumulative_consumption_kg=integrated.cumulative_consumption_kg,
integrated_running_seconds=integrated.integrated_running_seconds,
)
start = run.start
elif saved_polling_state.run_id == run.uuid:
initial_state = saved_polling_state.integration_state
@@ -97,31 +116,31 @@ class MaterialPollingService:
if now < start:
return None
integrator = MaterialConsumptionIntegrator(
self._config,
initial_state=initial_state,
)
samples = self._gateway.get_material_samples(
machine_id=self._machine_id,
rate_variable_id=self._rate_variable_id,
gate_variable_id=self._gate_variable_id,
start=start,
end=now,
)
integrator.process_many(samples)
state = self._integrate(initial_state, start=start, end=now)
self._state_store.save(
self._machine_id,
run.production_order,
MaterialPollingState(
run_id=run.uuid,
integration_state=integrator.state,
integration_state=state,
),
)
return MaterialPollResult(
run=run,
state=integrator.state,
state=state,
)
def _integrate(
self, initial_state: MaterialIntegrationState, *, start: datetime, end: datetime,
) -> MaterialIntegrationState:
integrator = MaterialConsumptionIntegrator(self._config, initial_state=initial_state)
samples = self._gateway.get_material_samples(
machine_id=self._machine_id,
rate_variable_id=self._rate_variable_id,
gate_variable_id=self._gate_variable_id,
start=start,
end=end,
)
return integrator.process_many(samples)