graphs?
Browse files- app.py +168 -1
- requirements.txt +2 -0
app.py
CHANGED
@@ -3,6 +3,11 @@ import paho.mqtt.client as mqtt
|
|
3 |
import os
|
4 |
import json
|
5 |
import time
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
HOST = os.environ.get("host")
|
8 |
PORT = int(os.environ.get("port"))
|
@@ -20,6 +25,11 @@ rpm_mqtt = None
|
|
20 |
led_mqtt = None
|
21 |
experiments = []
|
22 |
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
def on_connect(client, userdata, flags, rc):
|
25 |
print("Connected with result code "+str(rc))
|
@@ -609,7 +619,145 @@ def change_experiment(ch_exp, host, port, username, password, pioreactor, exp):
|
|
609 |
"reactor": pioreactor,
|
610 |
}
|
611 |
client_custom.publish(f"pioreactor/control", json.dumps(payload))
|
612 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
613 |
# Define the interface components
|
614 |
with gr.Blocks() as demo:
|
615 |
with gr.Tab("Default"):
|
@@ -813,6 +961,25 @@ with gr.Blocks() as demo:
|
|
813 |
fn=cycle_media_default,
|
814 |
inputs=[cycle_media_sec, experiment_input]
|
815 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
816 |
|
817 |
with gr.Tab("Custom"):
|
818 |
# Input components
|
|
|
3 |
import os
|
4 |
import json
|
5 |
import time
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
import numpy as np
|
8 |
+
import datetime
|
9 |
+
import pytz
|
10 |
+
import pandas as pd
|
11 |
|
12 |
HOST = os.environ.get("host")
|
13 |
PORT = int(os.environ.get("port"))
|
|
|
25 |
led_mqtt = None
|
26 |
experiments = []
|
27 |
|
28 |
+
temp_graph = None
|
29 |
+
od_graph = None
|
30 |
+
norm_od_graph = None
|
31 |
+
growth_rate_graph = None
|
32 |
+
|
33 |
|
34 |
def on_connect(client, userdata, flags, rc):
|
35 |
print("Connected with result code "+str(rc))
|
|
|
619 |
"reactor": pioreactor,
|
620 |
}
|
621 |
client_custom.publish(f"pioreactor/control", json.dumps(payload))
|
622 |
+
|
623 |
+
def on_message(client, userdata, message):
|
624 |
+
payload = message.payload.decode("utf-8")
|
625 |
+
data = json.loads(payload)
|
626 |
+
global temp_graph
|
627 |
+
global od_graph
|
628 |
+
global norm_od_graph
|
629 |
+
global growth_rate_graph
|
630 |
+
temp_graph = data.get("temperature", None)
|
631 |
+
od_graph = data.get("od", None)
|
632 |
+
norm_od_graph = data.get("normalized_od", None)
|
633 |
+
growth_rate_graph = data.get("growth_rate", None)
|
634 |
+
|
635 |
+
def get_data_default(time_scale, exp):
|
636 |
+
global client
|
637 |
+
|
638 |
+
payload = {
|
639 |
+
"command": "get_readings",
|
640 |
+
"experiment": exp,
|
641 |
+
"filter_mod": 1,
|
642 |
+
"lookback": 1000000,
|
643 |
+
"filter_mod2": 1,
|
644 |
+
"lookback2": 1000000,
|
645 |
+
"filter_mod3": 1,
|
646 |
+
"lookback3": 1000000,
|
647 |
+
"filter_mod4": 1,
|
648 |
+
"lookback4": 1000000,
|
649 |
+
"amount": time_scale,
|
650 |
+
"amount2": time_scale,
|
651 |
+
"amount3": time_scale,
|
652 |
+
"amount4": time_scale,
|
653 |
+
}
|
654 |
+
|
655 |
+
client.publish(f"pioreactor/control", json.dumps(payload))
|
656 |
+
|
657 |
+
client.on_message = on_message
|
658 |
+
client.subscribe(f"pioreactor/{PIOREACTOR}/readings")
|
659 |
+
|
660 |
+
timeout = 10
|
661 |
+
start = time.time()
|
662 |
+
|
663 |
+
global temp_graph
|
664 |
+
global od_graph
|
665 |
+
global norm_od_graph
|
666 |
+
global growth_rate_graph
|
667 |
+
|
668 |
+
temp_graph = None
|
669 |
+
od_graph = None
|
670 |
+
norm_od_graph = None
|
671 |
+
growth_rate_graph = None
|
672 |
+
|
673 |
+
while temp_graph is None and (time.time() - start) < timeout:
|
674 |
+
time.sleep(0.1)
|
675 |
+
|
676 |
+
client.unsubscribe(f"pioreactor/{PIOREACTOR}/readings")
|
677 |
+
|
678 |
+
if len(temp_graph) != 0:
|
679 |
+
for temp in temp_graph:
|
680 |
+
utc_time = datetime.strptime(temp["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
681 |
+
local_tz = pytz.timezone("America/New_York")
|
682 |
+
utc_time = utc_time.replace(tzinfo=pytz.utc)
|
683 |
+
local_time = utc_time.astimezone(local_tz)
|
684 |
+
temp["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
|
685 |
+
df = pd.DataFrame(temp_graph)
|
686 |
+
df = df.set_index("x")
|
687 |
+
|
688 |
+
plt.figure()
|
689 |
+
plt.plot(df)
|
690 |
+
plt.xlabel("Time")
|
691 |
+
plt.ylabel("Temperature (C)")
|
692 |
+
plt.title("Temperature vs Time")
|
693 |
+
plt.legend()
|
694 |
+
plot1 = plt.gcf()
|
695 |
+
else:
|
696 |
+
plot1 = None
|
697 |
+
|
698 |
+
if len(od_graph) != 0:
|
699 |
+
for od in od_graph:
|
700 |
+
utc_time = datetime.strptime(od["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
701 |
+
local_tz = pytz.timezone("America/New_York")
|
702 |
+
utc_time = utc_time.replace(tzinfo=pytz.utc)
|
703 |
+
local_time = utc_time.astimezone(local_tz)
|
704 |
+
od["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
|
705 |
+
df = pd.DataFrame(od_graph)
|
706 |
+
df = df.set_index("x")
|
707 |
+
|
708 |
+
plt.figure()
|
709 |
+
plt.plot(df)
|
710 |
+
plt.xlabel("Time")
|
711 |
+
plt.ylabel("OD")
|
712 |
+
plt.title("OD vs Time")
|
713 |
+
plt.legend()
|
714 |
+
plot2 = plt.gcf()
|
715 |
+
else:
|
716 |
+
plot2 = None
|
717 |
+
|
718 |
+
if len(norm_od_graph) != 0:
|
719 |
+
for od in norm_od_graph:
|
720 |
+
utc_time = datetime.strptime(od["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
721 |
+
local_tz = pytz.timezone("America/New_York")
|
722 |
+
utc_time = utc_time.replace(tzinfo=pytz.utc)
|
723 |
+
local_time = utc_time.astimezone(local_tz)
|
724 |
+
od["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
|
725 |
+
df = pd.DataFrame(norm_od_graph)
|
726 |
+
df = df.set_index("x")
|
727 |
+
|
728 |
+
plt.figure()
|
729 |
+
plt.plot(df)
|
730 |
+
plt.xlabel("Time")
|
731 |
+
plt.ylabel("Normalized OD")
|
732 |
+
plt.title("Normalized OD vs Time")
|
733 |
+
plt.legend()
|
734 |
+
plot3 = plt.gcf()
|
735 |
+
else:
|
736 |
+
plot3 = None
|
737 |
+
|
738 |
+
if len(growth_rate_graph) != 0:
|
739 |
+
for gr in growth_rate_graph:
|
740 |
+
utc_time = datetime.strptime(gr["x"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
741 |
+
local_tz = pytz.timezone("America/New_York")
|
742 |
+
utc_time = utc_time.replace(tzinfo=pytz.utc)
|
743 |
+
local_time = utc_time.astimezone(local_tz)
|
744 |
+
gr["x"] = local_time.strftime("%Y-%m-%d %H:%M:%S")
|
745 |
+
df = pd.DataFrame(growth_rate_graph)
|
746 |
+
df = df.set_index("x")
|
747 |
+
|
748 |
+
plt.figure()
|
749 |
+
plt.plot(df)
|
750 |
+
plt.xlabel("Time")
|
751 |
+
plt.ylabel("Growth Rate")
|
752 |
+
plt.title("Growth Rate vs Time")
|
753 |
+
plt.legend()
|
754 |
+
plot4 = plt.gcf()
|
755 |
+
else:
|
756 |
+
plot4 = None
|
757 |
+
|
758 |
+
return plot1, plot2, plot3, plot4
|
759 |
+
|
760 |
+
|
761 |
# Define the interface components
|
762 |
with gr.Blocks() as demo:
|
763 |
with gr.Tab("Default"):
|
|
|
961 |
fn=cycle_media_default,
|
962 |
inputs=[cycle_media_sec, experiment_input]
|
963 |
)
|
964 |
+
|
965 |
+
with gr.Tab("Default Graphs"):
|
966 |
+
with gr.Row():
|
967 |
+
time_scale = gr.RadioButton(label="Time Scale", choices=["1 hour", "24 hour", "All Data"], default="24 hour")
|
968 |
+
get_graphs = gr.Button("Get Graphs")
|
969 |
+
|
970 |
+
with gr.Row():
|
971 |
+
plot1 = gr.Plot()
|
972 |
+
plot2 = gr.Plot()
|
973 |
+
with gr.Row():
|
974 |
+
plot3 = gr.Plot()
|
975 |
+
plot4 = gr.Plot()
|
976 |
+
|
977 |
+
get_graphs.click(
|
978 |
+
fn=get_data_default,
|
979 |
+
inputs=[time_scale, experiment_input],
|
980 |
+
outputs=[plot1, plot2, plot3, plot4]
|
981 |
+
)
|
982 |
+
|
983 |
|
984 |
with gr.Tab("Custom"):
|
985 |
# Input components
|
requirements.txt
CHANGED
@@ -1 +1,3 @@
|
|
1 |
paho-mqtt>=1.6.1
|
|
|
|
|
|
1 |
paho-mqtt>=1.6.1
|
2 |
+
matplotlib>=3.3.4
|
3 |
+
numpy>=1.20.1
|