|
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: |
|
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() |
|
|
|
|
|
part_id += 1 |
|
await asyncio.sleep(0.2) |
|
|
|
current_time += timedelta(seconds=1) |
|
|
|
state["date"] = current_time |
|
state["part_id"] = part_id |