linx5o commited on
Commit
acb53e4
·
1 Parent(s): 0edaf9d

added ability to create change and delete experiments

Browse files
Files changed (1) hide show
  1. app.py +171 -56
app.py CHANGED
@@ -24,6 +24,7 @@ all_graph = False
24
  temp_mqtt_auto = None
25
  rpm_mqtt = None
26
  led_mqtt = None
 
27
 
28
  # if st.session_state.get("channels", None) is not None:
29
  # st.session_state["channel_a"] = int(st.session_state["channels"].get("A", 0))
@@ -79,7 +80,6 @@ else:
79
  submit_button = st.button("Reconnect")
80
 
81
 
82
-
83
  # Create the MQTT client
84
  # @st.cache_resource
85
  def create_mqtt_client(hivemq_host, hivemq_port, hivemq_username, hivemq_password):
@@ -108,11 +108,13 @@ def on_message_worker(client, userdata, message):
108
  global temp_mqtt_auto
109
  global rpm_mqtt
110
  global led_mqtt
 
111
  experiment = data.get("experiment", None)
112
  running = data.get("running", [])
113
  temp_mqtt_auto = data.get("temperature_automation", None)
114
  rpm_mqtt = data.get("stirring", None)
115
  led_mqtt = data.get("leds", None)
 
116
 
117
  def on_message(client, userdata, message):
118
  payload = message.payload.decode("utf-8")
@@ -165,7 +167,7 @@ def get_running_jobs(client, reactor):
165
  }
166
  payload_str = json.dumps(payload)
167
  client.publish("pioreactor/control", payload_str)
168
-
169
  experiment = None
170
  running = []
171
 
@@ -177,6 +179,15 @@ def get_running_jobs(client, reactor):
177
 
178
  while experiment is None and (time.time() - start_time) < timeout:
179
  time.sleep(1)
 
 
 
 
 
 
 
 
 
180
 
181
  if st.session_state["jobs"]["temperature_automation"]:
182
  if temp_mqtt_auto == "thermostat":
@@ -192,10 +203,16 @@ def get_running_jobs(client, reactor):
192
 
193
  # st.session_state["channels"] = led_mqtt
194
 
195
- st.session_state["channel_a"] = int(led_mqtt.get("A", 0))
196
- st.session_state["channel_b"] = int(led_mqtt.get("B", 0))
197
- st.session_state["channel_c"] = int(led_mqtt.get("C", 0))
198
- st.session_state["channel_d"] = int(led_mqtt.get("D", 0))
 
 
 
 
 
 
199
 
200
  async def get_graph(placeholder):
201
  try:
@@ -245,7 +262,6 @@ if submit_button:
245
 
246
  if st.session_state["experiment"] is None:
247
  st.error("No experiment assigned to the reactor.")
248
- st.stop()
249
 
250
  for run in running:
251
  st.session_state["jobs"][run] = True
@@ -266,6 +282,8 @@ if submit_button:
266
  st.session_state["channel_b"] = int(led_mqtt.get("B", 0))
267
  st.session_state["channel_c"] = int(led_mqtt.get("C", 0))
268
  st.session_state["channel_d"] = int(led_mqtt.get("D", 0))
 
 
269
 
270
  # Save the client to the session state
271
  st.session_state["client"] = client
@@ -275,6 +293,102 @@ if submit_button:
275
  if st.session_state["experiment"] is not None:
276
  st.title(f"Experiment: {st.session_state['experiment']}")
277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  st.header("Running Jobs")
279
 
280
  cols = st.columns(5)
@@ -1176,59 +1290,60 @@ if st.session_state["experiment"] is not None:
1176
  st.error("Failed to retrieve data.")
1177
  st.stop()
1178
 
1179
-
1180
- for temp in temp_graph:
1181
- utc_time = datetime.strptime(temp["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1182
- local_tz = pytz.timezone("America/New_York")
1183
- utc_time = utc_time.replace(tzinfo=pytz.utc)
1184
- local_time = utc_time.astimezone(local_tz)
1185
- temp["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
1186
-
1187
- for od in od_graph:
1188
- utc_time = datetime.strptime(od["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1189
- local_tz = pytz.timezone("America/New_York")
1190
- utc_time = utc_time.replace(tzinfo=pytz.utc)
1191
- local_time = utc_time.astimezone(local_tz)
1192
- od["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
 
 
 
 
 
 
 
 
 
 
 
 
 
1193
 
1194
- for norm_od in norm_od_graph:
1195
- utc_time = datetime.strptime(norm_od["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1196
- local_tz = pytz.timezone("America/New_York")
1197
- utc_time = utc_time.replace(tzinfo=pytz.utc)
1198
- local_time = utc_time.astimezone(local_tz)
1199
- norm_od["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
1200
-
1201
- for growth_rate in growth_rate_graph:
1202
- utc_time = datetime.strptime(growth_rate["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1203
- local_tz = pytz.timezone("America/New_York")
1204
- utc_time = utc_time.replace(tzinfo=pytz.utc)
1205
- local_time = utc_time.astimezone(local_tz)
1206
- growth_rate["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
 
 
 
 
 
 
 
 
 
 
1207
 
1208
  # Filter the data based on the amount of data requested
1209
  # Data is in 4 minute intervals
1210
-
1211
- df = pd.DataFrame(temp_graph)
1212
- df = df.set_index("x")
1213
-
1214
- df2 = pd.DataFrame(od_graph)
1215
- df2 = df2.set_index("x")
1216
-
1217
- df3 = pd.DataFrame(norm_od_graph)
1218
- df3 = df3.set_index("x")
1219
-
1220
- df4 = pd.DataFrame(growth_rate_graph)
1221
- df4 = df4.set_index("x")
1222
-
1223
- placeholder.line_chart(df, x_label="Time", y_label="Temperature (°C)")
1224
- placeholder2.line_chart(df2, x_label="Time", y_label="OD Reading")
1225
- placeholder3.line_chart(df3, x_label="Time", y_label="Normalized OD Reading")
1226
- placeholder4.line_chart(df4, x_label="Time", y_label="Growth Rate")
1227
-
1228
- st.session_state["df"] = df
1229
- st.session_state["df2"] = df2
1230
- st.session_state["df3"] = df3
1231
- st.session_state["df4"] = df4
1232
 
1233
  time.sleep(REQUEST_INTERVAL)
1234
 
 
24
  temp_mqtt_auto = None
25
  rpm_mqtt = None
26
  led_mqtt = None
27
+ experiments = []
28
 
29
  # if st.session_state.get("channels", None) is not None:
30
  # st.session_state["channel_a"] = int(st.session_state["channels"].get("A", 0))
 
80
  submit_button = st.button("Reconnect")
81
 
82
 
 
83
  # Create the MQTT client
84
  # @st.cache_resource
85
  def create_mqtt_client(hivemq_host, hivemq_port, hivemq_username, hivemq_password):
 
108
  global temp_mqtt_auto
109
  global rpm_mqtt
110
  global led_mqtt
111
+ global experiments
112
  experiment = data.get("experiment", None)
113
  running = data.get("running", [])
114
  temp_mqtt_auto = data.get("temperature_automation", None)
115
  rpm_mqtt = data.get("stirring", None)
116
  led_mqtt = data.get("leds", None)
117
+ experiments = data.get("experiments", [])
118
 
119
  def on_message(client, userdata, message):
120
  payload = message.payload.decode("utf-8")
 
167
  }
168
  payload_str = json.dumps(payload)
169
  client.publish("pioreactor/control", payload_str)
170
+ global experiment
171
  experiment = None
172
  running = []
173
 
 
179
 
180
  while experiment is None and (time.time() - start_time) < timeout:
181
  time.sleep(1)
182
+
183
+ if experiment is None:
184
+ st.error("Failed to get info")
185
+ st.session_state["experiment"] = None
186
+ time.sleep(3)
187
+ st.rerun()
188
+
189
+ if experiment != st.session_state["experiment"]:
190
+ st.session_state["experiment"] = experiment
191
 
192
  if st.session_state["jobs"]["temperature_automation"]:
193
  if temp_mqtt_auto == "thermostat":
 
203
 
204
  # st.session_state["channels"] = led_mqtt
205
 
206
+ if led_mqtt is not None:
207
+ st.session_state["channel_a"] = int(led_mqtt.get("A", 0))
208
+ st.session_state["channel_b"] = int(led_mqtt.get("B", 0))
209
+ st.session_state["channel_c"] = int(led_mqtt.get("C", 0))
210
+ st.session_state["channel_d"] = int(led_mqtt.get("D", 0))
211
+
212
+ st.session_state["experiments"] = experiments
213
+
214
+ for run in running:
215
+ st.session_state["jobs"][run] = True
216
 
217
  async def get_graph(placeholder):
218
  try:
 
262
 
263
  if st.session_state["experiment"] is None:
264
  st.error("No experiment assigned to the reactor.")
 
265
 
266
  for run in running:
267
  st.session_state["jobs"][run] = True
 
282
  st.session_state["channel_b"] = int(led_mqtt.get("B", 0))
283
  st.session_state["channel_c"] = int(led_mqtt.get("C", 0))
284
  st.session_state["channel_d"] = int(led_mqtt.get("D", 0))
285
+
286
+ st.session_state["experiments"] = experiments
287
 
288
  # Save the client to the session state
289
  st.session_state["client"] = client
 
293
  if st.session_state["experiment"] is not None:
294
  st.title(f"Experiment: {st.session_state['experiment']}")
295
 
296
+ with st.form("experiment_form"):
297
+ new_name = st.text_input("New Experiment Name")
298
+ submit_new_experiment = st.form_submit_button("Create New Experiment")
299
+
300
+ change_experiment_submit = False
301
+ delete_experiment = False
302
+
303
+ with st.form("experiment_edit"):
304
+ if len(st.session_state["experiments"]) > 0:
305
+ experiment_change = st.selectbox("Select Experiment", st.session_state["experiments"])
306
+ cols = st.columns(2)
307
+ with cols[0]:
308
+ change_experiment_submit = st.form_submit_button("Change Experiment")
309
+ with cols[1]:
310
+ delete_experiment = st.form_submit_button("Delete Experiment")
311
+ else:
312
+ st.write("No experiments available.")
313
+ st.form_submit_button("Nothing Button")
314
+
315
+ if submit_new_experiment:
316
+ payload = {
317
+ "command": "new_experiment",
318
+ "experiment": new_name,
319
+ "reactor": reactor
320
+ }
321
+ payload_str = json.dumps(payload)
322
+
323
+ st.session_state["client"].loop_start()
324
+ st.session_state["client"].publish("pioreactor/control", payload_str, qos=1)
325
+
326
+ get_running_jobs(st.session_state["client"], reactor)
327
+
328
+ if new_name in st.session_state["experiments"]:
329
+ st.success("Experiment created successfully!")
330
+ else:
331
+ st.error("Failed to create experiment.")
332
+
333
+
334
+ st.session_state["client"].loop_stop()
335
+
336
+ time.sleep(3)
337
+ st.rerun()
338
+
339
+ if change_experiment_submit:
340
+ payload = {
341
+ "command": "change_experiment",
342
+ "experiment": st.session_state["experiment"],
343
+ "experiment_new": experiment_change,
344
+ "reactor": reactor
345
+ }
346
+ payload_str = json.dumps(payload)
347
+
348
+ st.session_state["client"].loop_start()
349
+ st.session_state["client"].publish("pioreactor/control", payload_str, qos=1)
350
+
351
+ time.sleep(3)
352
+
353
+ get_running_jobs(st.session_state["client"], reactor)
354
+
355
+ if experiment_change == st.session_state["experiment"]:
356
+ st.success("Experiment changed successfully!")
357
+
358
+ else:
359
+ st.error("Failed to change experiment.")
360
+
361
+ st.info(f"Experiment name changed to {experiment_change} from {st.session_state['experiment']}")
362
+
363
+ st.session_state["client"].loop_stop()
364
+
365
+ time.sleep(3)
366
+ st.rerun()
367
+
368
+ if delete_experiment:
369
+ payload = {
370
+ "command": "delete_experiment",
371
+ "experiment": experiment_change,
372
+ "reactor": reactor
373
+ }
374
+ payload_str = json.dumps(payload)
375
+
376
+ time.sleep(1)
377
+
378
+ st.session_state["client"].loop_start()
379
+ st.session_state["client"].publish("pioreactor/control", payload_str, qos=1)
380
+
381
+ get_running_jobs(st.session_state["client"], reactor)
382
+
383
+ if experiment_change not in st.session_state["experiments"]:
384
+ st.success("Experiment deleted successfully!")
385
+ else:
386
+ st.error("Failed to delete experiment.")
387
+
388
+ st.session_state["client"].loop_stop()
389
+ time.sleep(3)
390
+ st.rerun()
391
+
392
  st.header("Running Jobs")
393
 
394
  cols = st.columns(5)
 
1290
  st.error("Failed to retrieve data.")
1291
  st.stop()
1292
 
1293
+ if len(temp_graph) != 0:
1294
+
1295
+ for temp in temp_graph:
1296
+ utc_time = datetime.strptime(temp["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1297
+ local_tz = pytz.timezone("America/New_York")
1298
+ utc_time = utc_time.replace(tzinfo=pytz.utc)
1299
+ local_time = utc_time.astimezone(local_tz)
1300
+ temp["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
1301
+ df = pd.DataFrame(temp_graph)
1302
+ df = df.set_index("x")
1303
+ placeholder.line_chart(df, x_label="Time", y_label="Temperature (°C)")
1304
+ st.session_state["df"] = df
1305
+
1306
+ if len(od_graph) != 0:
1307
+
1308
+ for od in od_graph:
1309
+ utc_time = datetime.strptime(od["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1310
+ local_tz = pytz.timezone("America/New_York")
1311
+ utc_time = utc_time.replace(tzinfo=pytz.utc)
1312
+ local_time = utc_time.astimezone(local_tz)
1313
+ od["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
1314
+ df2 = pd.DataFrame(od_graph)
1315
+ df2 = df2.set_index("x")
1316
+ placeholder2.line_chart(df2, x_label="Time", y_label="OD Reading")
1317
+ st.session_state["df2"] = df2
1318
+
1319
+ if len(norm_od_graph) != 0:
1320
 
1321
+ for norm_od in norm_od_graph:
1322
+ utc_time = datetime.strptime(norm_od["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1323
+ local_tz = pytz.timezone("America/New_York")
1324
+ utc_time = utc_time.replace(tzinfo=pytz.utc)
1325
+ local_time = utc_time.astimezone(local_tz)
1326
+ norm_od["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
1327
+ df3 = pd.DataFrame(norm_od_graph)
1328
+ df3 = df3.set_index("x")
1329
+ placeholder3.line_chart(df3, x_label="Time", y_label="Normalized OD Reading")
1330
+ st.session_state["df3"] = df3
1331
+
1332
+ if len(growth_rate_graph) != 0:
1333
+
1334
+ for growth_rate in growth_rate_graph:
1335
+ utc_time = datetime.strptime(growth_rate["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
1336
+ local_tz = pytz.timezone("America/New_York")
1337
+ utc_time = utc_time.replace(tzinfo=pytz.utc)
1338
+ local_time = utc_time.astimezone(local_tz)
1339
+ growth_rate["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
1340
+ df4 = pd.DataFrame(growth_rate_graph)
1341
+ df4 = df4.set_index("x")
1342
+ placeholder4.line_chart(df4, x_label="Time", y_label="Growth Rate")
1343
+ st.session_state["df4"] = df4
1344
 
1345
  # Filter the data based on the amount of data requested
1346
  # Data is in 4 minute intervals
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1347
 
1348
  time.sleep(REQUEST_INTERVAL)
1349