| | 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 |