mriusero commited on
Commit
4c16235
·
1 Parent(s): dff029f

feat: production data flow

Browse files
.gitignore CHANGED
@@ -1,3 +1,4 @@
1
  .DS_Store
 
2
  .venv
3
  __pycache__/
 
1
  .DS_Store
2
+ .idea/
3
  .venv
4
  __pycache__/
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import gradio as gr
2
 
3
  from src.chat import respond
 
4
 
5
  custom_theme = gr.themes.Base(
6
  primary_hue="blue",
@@ -28,21 +29,34 @@ with gr.Blocks(theme=custom_theme) as demo:
28
  with gr.Row():
29
  with gr.Column(scale=2):
30
  with gr.Group():
31
- button1 = gr.Button("Start Production")
32
- button2 = gr.Button("Restart Production")
33
- button3 = gr.Button("Stop Production")
34
-
35
- output1 = gr.Textbox(label="Sortie", visible=False)
36
- output2 = gr.Textbox(label="Sortie", visible=False)
37
- output3 = gr.Textbox(label="Sortie", visible=False)
38
-
39
- button1.click(fn=None, outputs=output1)
40
- button2.click(fn=None, outputs=output2)
41
- button3.click(fn=None, outputs=output3)
42
 
43
  with gr.Column(scale=2):
44
- with gr.Group():
45
- gr.Markdown('### Display Graphs here')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  with gr.Tab("Description"):
48
  gr.Markdown(
 
1
  import gradio as gr
2
 
3
  from src.chat import respond
4
+ from src.production.flow import play_fn, pause_fn, reset_fn
5
 
6
  custom_theme = gr.themes.Base(
7
  primary_hue="blue",
 
29
  with gr.Row():
30
  with gr.Column(scale=2):
31
  with gr.Group():
32
+ play = gr.Button("▶️ Play")
33
+ pause = gr.Button("⏸️ Pause")
34
+ reset = gr.Button("🔄 Reset")
 
 
 
 
 
 
 
 
35
 
36
  with gr.Column(scale=2):
37
+ display_df = gr.DataFrame(
38
+ label="Production Data",
39
+ headers=[
40
+ "Part ID", "Timestamp", "Position", "Orientation", "Tool ID",
41
+ "Compliance", "Event", "Error Code", "Error Description",
42
+ "Downtime Start", "Downtime End"
43
+ ]
44
+ )
45
+ play.click(
46
+ fn=play_fn,
47
+ inputs=None,
48
+ outputs=display_df,
49
+ )
50
+ pause.click(
51
+ fn=pause_fn,
52
+ inputs=None,
53
+ outputs=None
54
+ )
55
+ reset.click(
56
+ fn=reset_fn,
57
+ inputs=None,
58
+ outputs=None
59
+ )
60
 
61
  with gr.Tab("Description"):
62
  gr.Markdown(
requirements.txt CHANGED
@@ -1,2 +1,4 @@
1
  huggingface_hub==0.25.2
2
- gradio
 
 
 
1
  huggingface_hub==0.25.2
2
+ gradio
3
+ numpy
4
+ pandas
src/production/__init__.py ADDED
File without changes
src/production/downtime.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import timedelta
2
+
3
+ machine_errors = {
4
+ "E001": {
5
+ "description": "Calibration Error",
6
+ "cause": "The machine is not correctly calibrated.",
7
+ "solution": "Recalibrate the machine according to the manufacturer's specifications.",
8
+ "downtime": timedelta(hours=2)
9
+ },
10
+ "E002": {
11
+ "description": "Motor Overheating",
12
+ "cause": "The motor has exceeded the maximum operating temperature.",
13
+ "solution": "Stop the machine and let it cool down. Check the cooling system.",
14
+ "downtime": timedelta(hours=3)
15
+ },
16
+ "E003": {
17
+ "description": "Material Jam",
18
+ "cause": "Accumulation of material in the processing area.",
19
+ "solution": "Clean the processing area and check the feeding mechanisms.",
20
+ "downtime": timedelta(minutes=15)
21
+ },
22
+ "E004": {
23
+ "description": "Sensor Error",
24
+ "cause": "A sensor is not functioning correctly.",
25
+ "solution": "Check the sensor connections and replace if necessary.",
26
+ "downtime": timedelta(hours=1, minutes=30)
27
+ },
28
+ "E005": {
29
+ "description": "Power Failure",
30
+ "cause": "Electrical supply interrupted.",
31
+ "solution": "Check the electrical supply and fuses. Restart the machine.",
32
+ "downtime": timedelta(minutes=30)
33
+ },
34
+ "E006": {
35
+ "description": "Software Error",
36
+ "cause": "Bug in the machine control software.",
37
+ "solution": "Restart the software or update the firmware.",
38
+ "downtime": timedelta(hours=1)
39
+ },
40
+ "E007": {
41
+ "description": "Wear and Tear of Parts",
42
+ "cause": "The machine parts are worn out.",
43
+ "solution": "Inspect the parts and replace if necessary.",
44
+ "downtime": timedelta(hours=1)
45
+ },
46
+ "E008": {
47
+ "description": "Communication Error",
48
+ "cause": "Communication problem between different machine modules.",
49
+ "solution": "Check communication cables and protocols.",
50
+ "downtime": timedelta(hours=2)
51
+ },
52
+ "E009": {
53
+ "description": "Low Lubricant Level",
54
+ "cause": "The lubricant level is insufficient.",
55
+ "solution": "Refill the lubricant reservoir according to specifications.",
56
+ "downtime": timedelta(minutes=15)
57
+ },
58
+ "E010": {
59
+ "description": "Positioning Error",
60
+ "cause": "The tooling is not positioning correctly.",
61
+ "solution": "Check the positioning mechanisms and recalibrate if necessary.",
62
+ "downtime": timedelta(hours=1)
63
+ }
64
+ }
src/production/flow.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import random
3
+ import numpy as np
4
+ import pandas as pd
5
+ from datetime import datetime, timedelta
6
+
7
+ from .downtime import machine_errors
8
+
9
+ PRODUCTION = False
10
+ PROD_STATE = {
11
+ "current_time": None,
12
+ "part_id": None,
13
+ "data": None
14
+ }
15
+
16
+ def synthetic_data():
17
+ """
18
+ Generate synthetic production data for a manufacturing process.
19
+ """
20
+ global PROD_STATE
21
+ data = PROD_STATE["data"] if PROD_STATE["data"] else []
22
+ current_time = PROD_STATE["current_time"] if PROD_STATE["current_time"] else datetime.now()
23
+ part_id = PROD_STATE["part_id"] if PROD_STATE["part_id"] else 1
24
+ non_compliance_rates = {
25
+ 1: 0.05,
26
+ 2: 0.10,
27
+ 3: 0.03,
28
+ 4: 0.07
29
+ }
30
+
31
+ for _ in range(1000):
32
+ if not PRODUCTION:
33
+ break
34
+
35
+ if random.random() < 0.001:
36
+ error_key = random.choice(list(machine_errors.keys()))
37
+ error = machine_errors[error_key]
38
+ downtime = error["downtime"]
39
+
40
+ data.append({
41
+ "timestamp": current_time.strftime("%Y-%m-%d %H:%M:%S"),
42
+ "event": "Machine Error",
43
+ "error_code": error_key,
44
+ "error_description": error["description"],
45
+ "downtime_start": current_time.strftime("%Y-%m-%d %H:%M:%S"),
46
+ "downtime_end": (current_time + downtime).strftime("%Y-%m-%d %H:%M:%S")
47
+ })
48
+
49
+ current_time += downtime
50
+ else:
51
+ position = np.random.normal(loc=0.4, scale=0.03)
52
+ orientation = np.random.normal(loc=0.4, scale=0.06)
53
+ tool_id = (part_id % 4) + 1
54
+
55
+ if random.random() < non_compliance_rates[tool_id]:
56
+ position = np.random.normal(loc=0.4, scale=0.2)
57
+ orientation = np.random.normal(loc=0.4, scale=0.3)
58
+
59
+ compliance = 'OK' if (0.3 <= position <= 0.5) and (0.2 <= orientation <= 0.6) else 'NOK'
60
+
61
+ data.append({
62
+ "part_id": part_id,
63
+ "timestamp": current_time.strftime("%Y-%m-%d %H:%M:%S"),
64
+ "position": round(position, 4),
65
+ "orientation": round(orientation, 4),
66
+ "tool_id": tool_id,
67
+ "compliance": compliance
68
+ })
69
+
70
+ print(f" - part {part_id} data generated")
71
+ part_id += 1
72
+ time.sleep(1)
73
+
74
+ current_time += timedelta(seconds=1)
75
+
76
+ PROD_STATE["data"] = data
77
+ PROD_STATE["current_time"] = current_time
78
+ PROD_STATE["part_id"] = part_id
79
+
80
+ return data
81
+
82
+ def update_display(data):
83
+ """
84
+ Update production data in real-time.
85
+ """
86
+ display_data = []
87
+ for row in data:
88
+ display_data.append({
89
+ "Part ID": row.get("part_id", "N/A"),
90
+ "Timestamp": row.get("timestamp", "N/A"),
91
+ "Position": row.get("position", "N/A"),
92
+ "Orientation": row.get("orientation", "N/A"),
93
+ "Tool ID": row.get("tool_id", "N/A"),
94
+ "Compliance": row.get("compliance", "N/A"),
95
+ "Event": row.get("event", "N/A"),
96
+ "Error Code": row.get("error_code", "N/A"),
97
+ "Error Description": row.get("error_description", "N/A"),
98
+ "Downtime Start": row.get("downtime_start", "N/A"),
99
+ "Downtime End": row.get("downtime_end", "N/A")
100
+ })
101
+ return pd.DataFrame(display_data)
102
+
103
+
104
+ def play_fn():
105
+ """
106
+ Start the production simulation and generate synthetic data.
107
+ """
108
+ print("=== Continuation production ===")
109
+ global PRODUCTION
110
+ PRODUCTION = True
111
+ while PRODUCTION:
112
+ data = synthetic_data()
113
+ display_data = update_display(data)
114
+ yield display_data
115
+ time.sleep(1)
116
+
117
+
118
+ def pause_fn():
119
+ """
120
+ Pause the production simulation.
121
+ """
122
+ print("=== Stopping production ===")
123
+ global PRODUCTION
124
+ PRODUCTION = False
125
+
126
+
127
+ def reset_fn():
128
+ """
129
+ Reset the production state and clear the data.
130
+ """
131
+ print("=== RESET DONE ===")
132
+ global PRODUCTION, PROD_STATE
133
+ PRODUCTION = False
134
+ PROD_STATE = {
135
+ "current_time": None,
136
+ "part_id": None,
137
+ "data": None
138
+ }