Add ENLYZE live data gateway
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""Verified ENLYZE adapter for production-run and timeseries access."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from production_analytics.calculations.material_consumption import MaterialSample
|
||||
from production_analytics.enlyze.exploration import ExplorationClient
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class EnlyzeProductionRun:
|
||||
uuid: str
|
||||
machine_id: str
|
||||
product_id: str | None
|
||||
production_order: str
|
||||
start: datetime
|
||||
end: datetime | None
|
||||
|
||||
|
||||
class EnlyzeApiGateway:
|
||||
def __init__(self, client: ExplorationClient) -> None:
|
||||
self._client = client
|
||||
|
||||
def get_open_production_run(self, machine_id: str) -> EnlyzeProductionRun | None:
|
||||
response = self._client.get(
|
||||
"/v2/production-runs",
|
||||
{"machine": machine_id},
|
||||
)
|
||||
|
||||
for item in response.body.get("data", []):
|
||||
if item.get("end") is not None:
|
||||
continue
|
||||
|
||||
return EnlyzeProductionRun(
|
||||
uuid=str(item["uuid"]),
|
||||
machine_id=str(item["machine"]),
|
||||
product_id=(
|
||||
str(item["product"])
|
||||
if item.get("product") is not None
|
||||
else None
|
||||
),
|
||||
production_order=str(item["production_order"]),
|
||||
start=_parse_timestamp(item["start"]),
|
||||
end=None,
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
def get_material_samples(
|
||||
self,
|
||||
*,
|
||||
machine_id: str,
|
||||
rate_variable_id: str,
|
||||
gate_variable_id: str,
|
||||
start: datetime,
|
||||
end: datetime,
|
||||
) -> list[MaterialSample]:
|
||||
response = self._client.post_json(
|
||||
"/v2/timeseries",
|
||||
{
|
||||
"machine": machine_id,
|
||||
"start": start.astimezone(UTC).isoformat(),
|
||||
"end": end.astimezone(UTC).isoformat(),
|
||||
"variables": [
|
||||
{"uuid": rate_variable_id},
|
||||
{"uuid": gate_variable_id},
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
data = response.body["data"]
|
||||
columns = data["columns"]
|
||||
|
||||
time_index = columns.index("time")
|
||||
rate_index = columns.index(rate_variable_id)
|
||||
gate_index = columns.index(gate_variable_id)
|
||||
|
||||
return [
|
||||
MaterialSample(
|
||||
timestamp=_parse_timestamp(record[time_index]),
|
||||
material_rate_kg_per_hour=float(record[rate_index]),
|
||||
gate_value=float(record[gate_index]),
|
||||
)
|
||||
for record in data["records"]
|
||||
]
|
||||
|
||||
|
||||
def _parse_timestamp(value: str) -> datetime:
|
||||
return datetime.fromisoformat(value.replace("Z", "+00:00")).astimezone(UTC)
|
||||
Reference in New Issue
Block a user