mriusero
core: data shape
f5f591a
import asyncio
import random
from datetime import datetime, timedelta
import numpy as np
import pandas as pd
from .downtime import machine_errors
TOOLS_COUNT = 2
async def generate_data(state):
"""
Generate synthetic production data for a manufacturing process.
"""
current_time = state["date"] if state["date"] else datetime.now()
part_id = state["part_id"] if state["part_id"] else 0
non_compliance_rates = {
1: 0.05,
2: 0.10,
}
if 'raw_df' not in state['data']:
state['data']['raw_df'] = pd.DataFrame(columns=[
"Part ID", "Timestamp", "Position", "Orientation", "Tool ID",
"Compliance", "Event", "Error Code", "Error Description",
"Downtime Start", "Downtime End"
])
for _ in range(1000):
if not state["running"]:
break
if random.random() < 0.01: # 0.005
error_key = random.choice(list(machine_errors.keys()))
error = machine_errors[error_key]
downtime = error["downtime"]
new_row = pd.DataFrame([{
"Part ID": "N/A",
"Timestamp": current_time.strftime("%Y-%m-%d %H:%M:%S"),
"Position": "N/A",
"Orientation": "N/A",
"Tool ID": "N/A",
"Compliance": "N/A",
"Event": "Machine Error",
"Error Code": error_key,
"Error Description": error["description"],
"Downtime Start": current_time.strftime("%Y-%m-%d %H:%M:%S"),
"Downtime End": (current_time + downtime).strftime("%Y-%m-%d %H:%M:%S")
}])
state['data']['raw_df'] = pd.concat([state['data']['raw_df'], new_row], ignore_index=True)
current_time += downtime
else:
position = np.random.normal(loc=0.4, scale=0.03)
orientation = np.random.normal(loc=0.4, scale=0.06)
tool_id = (part_id % TOOLS_COUNT) + 1
if random.random() < non_compliance_rates[tool_id]:
position = np.random.normal(loc=0.4, scale=0.2)
orientation = np.random.normal(loc=0.4, scale=0.3)
compliance = 'OK' if (0.3 <= position <= 0.5) and (0.2 <= orientation <= 0.6) else 'NOK'
new_row = pd.DataFrame([{
"Part ID": part_id,
"Timestamp": current_time.strftime("%Y-%m-%d %H:%M:%S"),
"Position": round(position, 4),
"Orientation": round(orientation, 4),
"Tool ID": tool_id,
"Compliance": compliance,
"Event": "N/A",
"Error Code": "N/A",
"Error Description": "N/A",
"Downtime Start": "N/A",
"Downtime End": "N/A"
}])
if (
(not new_row.empty and not new_row.isna().all().all())
and \
(not state['data']['raw_df'].empty and not state['data']['raw_df'].isna().all().all())
):
state['data']['raw_df'] = pd.concat([state['data']['raw_df'], new_row], ignore_index=True)
elif not new_row.empty and not new_row.isna().all().all():
state['data']['raw_df'] = new_row.copy()
#print(f"- part {part_id} data generated")
part_id += 1
await asyncio.sleep(0.2)
current_time += timedelta(seconds=1)
state["date"] = current_time
state["part_id"] = part_id