Spaces:
Sleeping
Sleeping
maybe
Browse files
app.py
CHANGED
@@ -5,45 +5,40 @@ from PIL import Image
|
|
5 |
|
6 |
@st.cache_resource
|
7 |
def create_paho_client(tls=True):
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
try:
|
32 |
-
response = response_queue.get(block=True, timeout=10)
|
33 |
-
except queue.Empty:
|
34 |
-
response = None
|
35 |
-
return response
|
36 |
|
37 |
def handle_image_display(image):
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
|
43 |
st.title("MyCobot280 Pi control demo")
|
44 |
|
45 |
st.markdown("""
|
46 |
-
|
47 |
""")
|
48 |
|
49 |
use_own_creds = st.checkbox("Use your own credentials", value=False)
|
@@ -53,91 +48,122 @@ if use_own_creds:
|
|
53 |
HIVEMQ_PASSWORD = st.text_input("HIVEMQ Password", type="password")
|
54 |
HIVEMQ_HOST = st.text_input("HIVEMQ Host", type="password")
|
55 |
DEVICE_ID = st.text_input("Device ID", type="password")
|
56 |
-
PORT = st.number_input("Port", min_value=1, step=1)
|
57 |
else:
|
58 |
HIVEMQ_USERNAME = os.environ.get("HIVEMQ_USERNAME")
|
59 |
HIVEMQ_PASSWORD = os.environ.get("HIVEMQ_PASSWORD")
|
60 |
HIVEMQ_HOST = os.environ.get("HIVEMQ_HOST")
|
61 |
DEVICE_ID = os.environ.get("DEVICE_ID")
|
62 |
-
PORT = int(os.environ.get("PORT"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
st.markdown("## Commands")
|
65 |
commands = [
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
]
|
74 |
selected = st.selectbox("Select command: ", commands, key="selected_command", disabled=False)
|
75 |
|
76 |
args = {}
|
77 |
if st.session_state.selected_command == "query/angles":
|
78 |
-
|
79 |
elif st.session_state.selected_command == "query/coords":
|
80 |
-
|
81 |
elif st.session_state.selected_command == "query/gripper":
|
82 |
-
|
83 |
elif st.session_state.selected_command == "query/camera":
|
84 |
-
|
85 |
-
|
86 |
elif st.session_state.selected_command == "control/angles":
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
elif st.session_state.selected_command == "control/coords":
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
elif st.session_state.selected_command == "control/gripper":
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
|
117 |
with st.form("mqtt_form"):
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
handle_image_display(image)
|
140 |
-
else:
|
141 |
-
st.write(response)
|
142 |
-
else:
|
143 |
-
st.write("Timed out waiting for response. Is the on-device server running?")
|
|
|
5 |
|
6 |
@st.cache_resource
|
7 |
def create_paho_client(tls=True):
|
8 |
+
client = mqtt.Client(client_id="", userdata=None, protocol=mqtt.MQTTv5)
|
9 |
+
if tls:
|
10 |
+
client.tls_set(tls_version=mqtt.ssl.PROTOCOL_TLS_CLIENT)
|
11 |
+
return client
|
12 |
+
|
13 |
+
def setup_paho_client(client, username, password, cloud, port, device_id, response_queue):
|
14 |
+
def on_message(client, userdata, msg):
|
15 |
+
payload_dict = json.loads(msg.payload)
|
16 |
+
response_queue.put(payload_dict)
|
17 |
+
|
18 |
+
client.username_pw_set(username, password)
|
19 |
+
client.connect(cloud, port)
|
20 |
+
client.subscribe(device_id + "/response")
|
21 |
+
client.on_message = on_message
|
22 |
+
client.loop_start()
|
23 |
+
|
24 |
+
def publish_and_wait(client, device_id, payload, response_queue):
|
25 |
+
client.publish(device_id, payload=json.dumps(payload), qos=2)
|
26 |
+
try:
|
27 |
+
response = response_queue.get(block=True, timeout=10)
|
28 |
+
except queue.Empty:
|
29 |
+
response = None
|
30 |
+
return response
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
def handle_image_display(image):
|
33 |
+
b64_bytes = base64.b64decode(image)
|
34 |
+
img_bytes = io.BytesIO(b64_bytes)
|
35 |
+
img = Image.open(img_bytes)
|
36 |
+
st.image(img, caption="Cobot camera view")
|
37 |
|
38 |
st.title("MyCobot280 Pi control demo")
|
39 |
|
40 |
st.markdown("""
|
41 |
+
This app is a public demo of ...
|
42 |
""")
|
43 |
|
44 |
use_own_creds = st.checkbox("Use your own credentials", value=False)
|
|
|
48 |
HIVEMQ_PASSWORD = st.text_input("HIVEMQ Password", type="password")
|
49 |
HIVEMQ_HOST = st.text_input("HIVEMQ Host", type="password")
|
50 |
DEVICE_ID = st.text_input("Device ID", type="password")
|
51 |
+
PORT = st.number_input("Port", min_value=1, step=1, value=8883)
|
52 |
else:
|
53 |
HIVEMQ_USERNAME = os.environ.get("HIVEMQ_USERNAME")
|
54 |
HIVEMQ_PASSWORD = os.environ.get("HIVEMQ_PASSWORD")
|
55 |
HIVEMQ_HOST = os.environ.get("HIVEMQ_HOST")
|
56 |
DEVICE_ID = os.environ.get("DEVICE_ID")
|
57 |
+
PORT = int(os.environ.get("PORT", 8883))
|
58 |
+
|
59 |
+
# Initialize or update the MQTT client and response queue in session state
|
60 |
+
if 'client' not in st.session_state:
|
61 |
+
st.session_state['client'] = None
|
62 |
+
st.session_state['response_queue'] = None
|
63 |
+
st.session_state['HIVEMQ_USERNAME'] = None
|
64 |
+
st.session_state['HIVEMQ_PASSWORD'] = None
|
65 |
+
st.session_state['HIVEMQ_HOST'] = None
|
66 |
+
st.session_state['DEVICE_ID'] = None
|
67 |
+
st.session_state['PORT'] = None
|
68 |
+
|
69 |
+
credentials_changed = (
|
70 |
+
st.session_state['HIVEMQ_USERNAME'] != HIVEMQ_USERNAME or
|
71 |
+
st.session_state['HIVEMQ_PASSWORD'] != HIVEMQ_PASSWORD or
|
72 |
+
st.session_state['HIVEMQ_HOST'] != HIVEMQ_HOST or
|
73 |
+
st.session_state['DEVICE_ID'] != DEVICE_ID or
|
74 |
+
st.session_state['PORT'] != PORT
|
75 |
+
)
|
76 |
+
|
77 |
+
if st.session_state['client'] is None or credentials_changed:
|
78 |
+
st.session_state['HIVEMQ_USERNAME'] = HIVEMQ_USERNAME
|
79 |
+
st.session_state['HIVEMQ_PASSWORD'] = HIVEMQ_PASSWORD
|
80 |
+
st.session_state['HIVEMQ_HOST'] = HIVEMQ_HOST
|
81 |
+
st.session_state['DEVICE_ID'] = DEVICE_ID
|
82 |
+
st.session_state['PORT'] = PORT
|
83 |
+
st.session_state['response_queue'] = queue.Queue()
|
84 |
+
st.session_state['client'] = create_paho_client()
|
85 |
+
setup_paho_client(
|
86 |
+
st.session_state['client'],
|
87 |
+
HIVEMQ_USERNAME,
|
88 |
+
HIVEMQ_PASSWORD,
|
89 |
+
HIVEMQ_HOST,
|
90 |
+
PORT,
|
91 |
+
DEVICE_ID,
|
92 |
+
st.session_state['response_queue']
|
93 |
+
)
|
94 |
|
95 |
st.markdown("## Commands")
|
96 |
commands = [
|
97 |
+
"query/angles",
|
98 |
+
"query/coords",
|
99 |
+
"query/gripper",
|
100 |
+
"query/camera",
|
101 |
+
"control/angles",
|
102 |
+
"control/coords",
|
103 |
+
"control/gripper"
|
104 |
]
|
105 |
selected = st.selectbox("Select command: ", commands, key="selected_command", disabled=False)
|
106 |
|
107 |
args = {}
|
108 |
if st.session_state.selected_command == "query/angles":
|
109 |
+
pass
|
110 |
elif st.session_state.selected_command == "query/coords":
|
111 |
+
pass
|
112 |
elif st.session_state.selected_command == "query/gripper":
|
113 |
+
pass
|
114 |
elif st.session_state.selected_command == "query/camera":
|
115 |
+
quality = st.slider("Image quality", 1, 100, 50)
|
116 |
+
args = {"quality": quality}
|
117 |
elif st.session_state.selected_command == "control/angles":
|
118 |
+
col1, col2, col3 = st.columns(3)
|
119 |
+
with col1:
|
120 |
+
angle_1 = st.number_input("Angle 1", format="%.2f")
|
121 |
+
angle_4 = st.number_input("Angle 4", format="%.2f")
|
122 |
+
with col2:
|
123 |
+
angle_2 = st.number_input("Angle 2", format="%.2f")
|
124 |
+
angle_5 = st.number_input("Angle 5", format="%.2f")
|
125 |
+
with col3:
|
126 |
+
angle_3 = st.number_input("Angle 3", format="%.2f")
|
127 |
+
angle_6 = st.number_input("Angle 6", format="%.2f")
|
128 |
+
speed = st.slider("Speed", 1, 100, 50)
|
129 |
+
args = {"angles": [angle_1, angle_2, angle_3, angle_4, angle_5, angle_6], "speed": speed}
|
130 |
elif st.session_state.selected_command == "control/coords":
|
131 |
+
col1, col2, col3 = st.columns(3)
|
132 |
+
with col1:
|
133 |
+
x = st.number_input("x", format="%.2f")
|
134 |
+
rx = st.number_input("rx (Rotation x)", format="%.2f")
|
135 |
+
with col2:
|
136 |
+
y = st.number_input("y", format="%.2f")
|
137 |
+
ry = st.number_input("ry (Rotation y)", format="%.2f")
|
138 |
+
with col3:
|
139 |
+
z = st.number_input("z", format="%.2f")
|
140 |
+
rz = st.number_input("rz (Rotation z)", format="%.2f")
|
141 |
+
speed = st.slider("Speed", 1, 100, 50)
|
142 |
+
args = {"coords": [x, y, z, rx, ry, rz], "speed": speed}
|
143 |
elif st.session_state.selected_command == "control/gripper":
|
144 |
+
gripper_value = st.slider("Gripper value", 1, 100, 50)
|
145 |
+
speed = st.slider("Speed", 1, 100, 50)
|
146 |
+
args = {"gripper_value": gripper_value, "speed": speed}
|
147 |
|
148 |
with st.form("mqtt_form"):
|
149 |
+
if st.form_submit_button("Send Command"):
|
150 |
+
payload = {"command": st.session_state.selected_command, "args": args}
|
151 |
+
st.markdown("### Payload")
|
152 |
+
st.write(payload)
|
153 |
+
|
154 |
+
response = publish_and_wait(
|
155 |
+
st.session_state['client'],
|
156 |
+
DEVICE_ID,
|
157 |
+
payload,
|
158 |
+
st.session_state['response_queue']
|
159 |
+
)
|
160 |
+
st.markdown("### Response")
|
161 |
+
if response is not None:
|
162 |
+
if "image" in response:
|
163 |
+
image = response.pop("image")
|
164 |
+
st.write(response)
|
165 |
+
handle_image_display(image)
|
166 |
+
else:
|
167 |
+
st.write(response)
|
168 |
+
else:
|
169 |
+
st.write("Timed out waiting for response. Is the on-device server running?")
|
|
|
|
|
|
|
|
|
|