Skip to content

Commit 583e014

Browse files
authored
Merge branch 'main' into sgbaird/add-iolt-docs
2 parents ffb0d08 + 1a55b57 commit 583e014

File tree

6 files changed

+220
-3
lines changed

6 files changed

+220
-3
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
platform:
6666
- ubuntu-latest
6767
# - macos-latest
68-
- windows-latest
68+
# - windows-latest
6969
runs-on: ${{ matrix.platform }}
7070
steps:
7171
- uses: actions/checkout@v3

docs/conf.py

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175

176176
# The theme to use for HTML and HTML Help pages. See the documentation for
177177
# a list of builtin themes.
178+
# html_theme = "sphinx_rtd_theme"
178179
html_theme = "sphinx_book_theme"
179180

180181
# Theme options are theme-specific and customize the look and feel of a theme

docs/requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ sphinx>=3.2.1
33
# Requirements file for ReadTheDocs, check .readthedocs.yml.
44
# To build the module reference correctly, make sure every external package
55
# under `install_requires` in `setup.cfg` is also listed here!
6-
sphinx_rtd_theme
6+
# sphinx_rtd_theme
7+
sphinx_book_theme
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# generate a jwt
2+
# hive mq api to add this jwt to the list of tokens
3+
# expire this token after a given timeframe with api
4+
5+
# mqtt to the microscope commands with attached credentials
6+
# recieve returned mqtt/stored images
7+
8+
# recieve the payload
9+
# execute the command
10+
# return the images/store them etc
11+
12+
import base64
13+
import json
14+
import time
15+
from io import BytesIO
16+
from queue import Queue
17+
18+
import paho.mqtt.client as mqtt
19+
from PIL import Image
20+
21+
# microscope1
22+
# microscope2
23+
# deltastagereflection
24+
# deltastagetransmission
25+
26+
27+
class MicroscopeDemo:
28+
def __init__(self, host, port, username, password, microscope):
29+
self.host = host
30+
self.port = port
31+
self.username = username
32+
self.password = password
33+
self.microscope = microscope
34+
35+
self.client = mqtt.Client()
36+
self.client.tls_set()
37+
self.client.username_pw_set(self.username, self.password)
38+
39+
self.receiveq = Queue()
40+
41+
def on_message(client, userdata, message):
42+
received = json.loads(message.payload.decode("utf-8"))
43+
self.receiveq.put(received)
44+
if len(json.dumps(received)) <= 300:
45+
print(received)
46+
else:
47+
try:
48+
print(json.dumps(received)[:300] + "...")
49+
except Exception as e:
50+
print(f"Command printing error (program will continue): {e}")
51+
52+
self.client.on_message = on_message
53+
54+
self.client.connect(self.host, port=self.port, keepalive=60, bind_address="")
55+
56+
self.client.loop_start()
57+
58+
self.client.subscribe(self.microscope + "/return", qos=2)
59+
60+
def scan_and_stitch(self, c1, c2, ov=1200, foc=0): # WIP
61+
command = json.dumps(
62+
{"command": "scan_and_stitch", "c1": c1, "c2": c2, "ov": ov, "foc": foc}
63+
)
64+
self.client.publish(
65+
self.microscope + "/command", payload=command, qos=2, retain=False
66+
)
67+
while self.receiveq.empty():
68+
time.sleep(0.05)
69+
image = self.receiveq.get()
70+
image_string = image["image"]
71+
image_bytes = base64.b64decode(image_string)
72+
image_object = Image.open(BytesIO(image_bytes))
73+
return image_object
74+
75+
def move(self, x, y, z=False, relative=False):
76+
"""moves to given coordinates x, y (and z if it is set to any integer
77+
value, if it is set to False the z value wont change). If relative is
78+
True, then it will move relative to the current position instead of
79+
moving to the absolute coordinates"""
80+
command = json.dumps(
81+
{"command": "move", "x": x, "y": y, "z": z, "relative": relative}
82+
)
83+
self.client.publish(
84+
self.microscope + "/command", payload=command, qos=2, retain=False
85+
)
86+
while self.receiveq.empty():
87+
time.sleep(0.05)
88+
return self.receiveq.get()
89+
90+
def scan(self, c1, c2, ov=1200, foc=0):
91+
"""returns a list of image objects. Takes images to scan an entire area
92+
specified by two corners. you can input the corner coordinates as "x1
93+
y1", "x2, y2" or [x1, y1], [x2, y2]. ov refers to the overlap between
94+
the images (useful for stitching) and foc refers to how much the
95+
microscope should focus between images (0 to disable)"""
96+
command = json.dumps(
97+
{"command": "scan", "c1": c1, "c2": c2, "ov": ov, "foc": foc}
98+
)
99+
self.client.publish(
100+
self.microscope + "/command", payload=command, qos=2, retain=False
101+
)
102+
while self.receiveq.empty():
103+
time.sleep(0.05)
104+
image_l = self.receiveq.get()
105+
image_list = image_l["images"]
106+
for i in range(len(image_list)):
107+
image = image_list[i]
108+
image_bytes = base64.b64decode(image)
109+
image_object = Image.open(BytesIO(image_bytes))
110+
image_list[i] = image_object
111+
return image_list
112+
113+
def focus(
114+
self, amount="fast"
115+
): # focuses by different amounts: huge, fast, medium, fine, or any integer value
116+
command = json.dumps({"command": "focus", "amount": amount})
117+
self.client.publish(
118+
self.microscope + "/command", payload=command, qos=2, retain=False
119+
)
120+
while self.receiveq.empty():
121+
time.sleep(0.05)
122+
return self.receiveq.get()
123+
124+
def get_pos(
125+
self,
126+
): # returns a dictionary with x, y, and z coordinates eg. {'x':1,'y':2,'z':3}
127+
command = json.dumps({"command": "get_pos"})
128+
self.client.publish(
129+
self.microscope + "/command", payload=command, qos=2, retain=False
130+
)
131+
while self.receiveq.empty():
132+
time.sleep(0.05)
133+
pos = self.receiveq.get()
134+
return pos["pos"]
135+
136+
def take_image(self): # returns an image object
137+
command = json.dumps({"command": "take_image"})
138+
self.client.publish(
139+
self.microscope + "/command", payload=command, qos=2, retain=False
140+
)
141+
while self.receiveq.empty():
142+
time.sleep(0.05)
143+
image = self.receiveq.get()
144+
image_string = image["image"]
145+
image_bytes = base64.b64decode(image_string)
146+
image_object = Image.open(BytesIO(image_bytes))
147+
return image_object
148+
149+
def end_connection(self): # ends the connection
150+
self.client.loop_stop()
151+
self.client.disconnect()
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# DEMO USE
2+
#
3+
# move(x,y) required
4+
#
5+
# move(x,y,z,relative) optional
6+
#
7+
# moves to given coordinates x, y (and z if it is set to any integer value, if
8+
# it is set to False which is the default setting, the z value wont change). If
9+
# relative is True, then it will move relative to the current position instead
10+
# of moving to the absolute coordinates
11+
#
12+
# take_image() returns an image object
13+
#
14+
# get_pos() returns a dictionary with x, y, and z coordinates eg.
15+
# {'x':1,'y':2,'z':3}
16+
#
17+
# focus()
18+
19+
# focus(amount) optional
20+
#
21+
# focuses by different amounts: huge, fast, medium, fine, or any integer value
22+
# (default is fast)
23+
#
24+
# end_connection()
25+
#
26+
# ends the connection
27+
#
28+
# scan(c1,c2) required
29+
#
30+
# scan(c1,c2,ov,foc) optional
31+
#
32+
# returns a list of image objects. Takes images to scan an entire area specified
33+
# by two corners. you can input the corner coordinates as "x1 y1", "x2, y2" or
34+
# [x1, y1], [x2, y2]. ov refers to the overlap between the images (useful for
35+
# stitching) and foc refers to how much the microscope should focus between
36+
# images (0 to disable)
37+
38+
39+
# EXAMPLE CODE
40+
41+
from microscope_demo_client import MicroscopeDemo
42+
from my_secrets import (
43+
HIVEMQ_HOST,
44+
HIVEMQ_PASSWORD,
45+
HIVEMQ_PORT,
46+
HIVEMQ_USERNAME,
47+
MICROSCOPE_NAME,
48+
)
49+
50+
microscope = MicroscopeDemo(
51+
HIVEMQ_HOST, HIVEMQ_PORT, HIVEMQ_USERNAME, HIVEMQ_PASSWORD, MICROSCOPE_NAME
52+
)
53+
54+
55+
microscope.move(0, 0)
56+
microscope.take_image().show()
57+
microscope.move(3000, 3000)
58+
microscope.move(0, 0)
59+
print(microscope.get_pos())
60+
microscope.focus()
61+
microscope.take_image().show()
62+
for i in microscope.scan([2000, 2000], [-2000, -2000]):
63+
i.show()
64+
microscope.move(0, 0)
65+
microscope.end_connection()

0 commit comments

Comments
 (0)