UC2-REST 0.2.0.29__tar.gz → 0.2.0.30__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/PKG-INFO +1 -1
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/UC2_REST.egg-info/PKG-INFO +1 -1
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/UC2Client.py +1 -1
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/__version__.py +1 -1
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/home.py +21 -1
- uc2_rest-0.2.0.30/uc2rest/logger.py +45 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/motor.py +30 -5
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/mserial.py +3 -2
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/state.py +1 -0
- uc2_rest-0.2.0.29/uc2rest/logger.py +0 -9
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/LICENSE +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/README.md +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/UC2_REST.egg-info/SOURCES.txt +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/UC2_REST.egg-info/dependency_links.txt +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/UC2_REST.egg-info/not-zip-safe +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/UC2_REST.egg-info/requires.txt +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/UC2_REST.egg-info/top_level.txt +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/setup.cfg +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/setup.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/MockSerial.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/__init__.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/analog.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/camera.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/can.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/cmdrecorder.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/digitalout.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/galvo.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/gripper.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/laser.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/lcddisplay.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/ledmatrix.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/message.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/modules.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/objective.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/pid.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/rotator.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/slm.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/temperature.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/utils.py +0 -0
- {uc2_rest-0.2.0.29 → uc2_rest-0.2.0.30}/uc2rest/wifi.py +0 -0
|
@@ -6,7 +6,7 @@ __version__.py
|
|
|
6
6
|
|
|
7
7
|
__title__ = 'UC2-REST'
|
|
8
8
|
__description__ = 'This pacage will help you to drive the ESP32-driven microscopy control modules from UC2'
|
|
9
|
-
__version__ = "v0.2.0.
|
|
9
|
+
__version__ = "v0.2.0.30"
|
|
10
10
|
__author__ = 'Benedict Diederich'
|
|
11
11
|
__author_email__ = 'benedictdied@gmail.com'
|
|
12
12
|
__license__ = 'GPL v3'
|
|
@@ -55,13 +55,14 @@ class Home(object):
|
|
|
55
55
|
endstoppolarity=endstoppolarity,
|
|
56
56
|
isBlocking=isBlocking)
|
|
57
57
|
|
|
58
|
-
def home(self, axis=None, timeout=None, speed=None, direction=None, endposrelease=None, endstoppolarity=None, endstoptimeout=10000, isBlocking=False):
|
|
58
|
+
def home(self, axis=None, timeout=None, speed=None, direction=None, endposrelease=None, endstoppolarity=None, endstoptimeout=10000, isBlocking=False, preMove=True):
|
|
59
59
|
'''
|
|
60
60
|
axis = 0,1,2,3 or 'A, 'X','Y','Z'
|
|
61
61
|
timeout => when to stop homing (it's a while loop on the MCU)
|
|
62
62
|
speed => speed of homing (0...15000)
|
|
63
63
|
direction => 1,-1 (left/right)
|
|
64
64
|
endposrelease => how far to move after homing (0...3000)
|
|
65
|
+
preMove => the motor will first move by some steps in the opposite direction before homing, this is useful to avoid false triggering of the endstop
|
|
65
66
|
'''
|
|
66
67
|
|
|
67
68
|
# default values
|
|
@@ -79,6 +80,25 @@ class Home(object):
|
|
|
79
80
|
if direction not in [-1,1]:
|
|
80
81
|
direction = 1
|
|
81
82
|
|
|
83
|
+
if preMove:
|
|
84
|
+
# first move in the opposite direction
|
|
85
|
+
if direction == 1:
|
|
86
|
+
preMoveDirection = -1
|
|
87
|
+
else:
|
|
88
|
+
preMoveDirection = 1
|
|
89
|
+
|
|
90
|
+
# move away from endstop
|
|
91
|
+
if axis == 1 or axis == "X":
|
|
92
|
+
self._parent.motor.move_x(steps=preMoveDirection*100, speed=self.speed, is_blocking=True, is_absolute=False, is_enabled=True)
|
|
93
|
+
elif axis == 2 or axis == "Y":
|
|
94
|
+
self._parent.motor.move_y(steps=preMoveDirection*100, speed=self.speed, is_blocking=True, is_absolute=False, is_enabled=True)
|
|
95
|
+
elif axis == 3 or axis == "Z":
|
|
96
|
+
self._parent.motor.move_z(steps=preMoveDirection*100, speed=self.speed, is_blocking=True, is_absolute=False, is_enabled=True)
|
|
97
|
+
elif axis == 0 or axis == "A":
|
|
98
|
+
self._parent.motor.move_a(steps=preMoveDirection*100, speed=self.speed, is_blocking=True, is_absolute=False, is_enabled=True)
|
|
99
|
+
else:
|
|
100
|
+
raise ValueError("Invalid axis. Use 'X', 'Y', 'Z', or 'A'.")
|
|
101
|
+
time.sleep(0.5)
|
|
82
102
|
# construct json string
|
|
83
103
|
path = "/home_act"
|
|
84
104
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Logger(object):
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
name=__name__,
|
|
8
|
+
log_to_file=False,
|
|
9
|
+
filename='uc2rest.log'
|
|
10
|
+
):
|
|
11
|
+
# Create a logger with the given name
|
|
12
|
+
self.logger = logging.getLogger(name)
|
|
13
|
+
self.logger.setLevel(logging.DEBUG)
|
|
14
|
+
formatter = logging.Formatter(
|
|
15
|
+
'%(asctime)s [%(levelname)s] %(name)s: %(message)s'
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# Console handler
|
|
19
|
+
ch = logging.StreamHandler()
|
|
20
|
+
ch.setLevel(logging.DEBUG)
|
|
21
|
+
ch.setFormatter(formatter)
|
|
22
|
+
self.logger.addHandler(ch)
|
|
23
|
+
|
|
24
|
+
# Optional file handler
|
|
25
|
+
if log_to_file:
|
|
26
|
+
fh = logging.FileHandler(filename)
|
|
27
|
+
fh.setLevel(logging.DEBUG)
|
|
28
|
+
fh.setFormatter(formatter)
|
|
29
|
+
self.logger.addHandler(fh)
|
|
30
|
+
|
|
31
|
+
def error(self, message):
|
|
32
|
+
# Log an error message
|
|
33
|
+
self.logger.error(message)
|
|
34
|
+
|
|
35
|
+
def debug(self, message):
|
|
36
|
+
# Log a debug message
|
|
37
|
+
self.logger.debug(message)
|
|
38
|
+
|
|
39
|
+
def info(self, message):
|
|
40
|
+
# Log an info message
|
|
41
|
+
self.logger.info(message)
|
|
42
|
+
|
|
43
|
+
def warning(self, message):
|
|
44
|
+
# Log a warning message
|
|
45
|
+
self.logger.warning(message)
|
|
@@ -23,7 +23,6 @@ class Motor(object):
|
|
|
23
23
|
self.minStep = np.ones((self.nMotors))*(-np.inf)
|
|
24
24
|
self.currentDirection = np.zeros((self.nMotors))
|
|
25
25
|
self.currentPosition = np.zeros((self.nMotors))
|
|
26
|
-
self._position = np.zeros((self.nMotors)) # position from the last motor status update
|
|
27
26
|
|
|
28
27
|
self.minPosX = -np.inf
|
|
29
28
|
self.minPosY = -np.inf
|
|
@@ -84,9 +83,9 @@ class Motor(object):
|
|
|
84
83
|
for iMotor in range(nSteppers):
|
|
85
84
|
stepperID = data["steppers"][iMotor]["stepperid"]
|
|
86
85
|
# FIXME: smart to re-update this variable? Will be updated by motor-sender too
|
|
87
|
-
self.
|
|
86
|
+
self.currentPosition[stepperID] = data["steppers"][iMotor]["position"] * stepSizes[stepperID] - offSets[stepperID]
|
|
88
87
|
if callable(self._callbackPerKey[0]):
|
|
89
|
-
self._callbackPerKey[0](self.
|
|
88
|
+
self._callbackPerKey[0](self.currentPosition) # we call the function with the value
|
|
90
89
|
except Exception as e:
|
|
91
90
|
print("Error in _callback_motor_status: ", e)
|
|
92
91
|
|
|
@@ -654,9 +653,9 @@ class Motor(object):
|
|
|
654
653
|
_physicalOffsets = np.array((self.offsetA, self.offsetX, self.offsetY, self.offsetZ))
|
|
655
654
|
|
|
656
655
|
# this may be an asynchronous call.. #FIXME!
|
|
657
|
-
r = self._parent.post_json(path, payload, getReturn = True, nResponses=1, timeout=timeout)
|
|
656
|
+
r = self._parent.post_json(path, payload, getReturn = True, nResponses=1, timeout=timeout)[0]
|
|
658
657
|
# returns {"motor": }
|
|
659
|
-
if "motor" in r:
|
|
658
|
+
if "motor" in r :
|
|
660
659
|
for index, istepper in enumerate(r["motor"]["steppers"]):
|
|
661
660
|
if index >3: break # TODO: We would need to handle other values too soon
|
|
662
661
|
_position[istepper["stepperid"]]=istepper["position"]*_physicalStepSizes[self.motorAxisOrder[index]]-_physicalOffsets[self.motorAxisOrder[index]]
|
|
@@ -775,6 +774,32 @@ class Motor(object):
|
|
|
775
774
|
r = self._parent.post_json(path, payload)
|
|
776
775
|
return r
|
|
777
776
|
|
|
777
|
+
def start_stage_scanning_by_coordinates(self, coordinates, tPre=50, tPost=50, led=100, illumination=[50, 75, 100, 125], stopped=0):
|
|
778
|
+
'''
|
|
779
|
+
Example: {"task": "/motor_act", "stagescan": {"coordinates": [{"x": 100, "y": 200}, {"x": 300, "y": 400}, {"x": 500, "y": 600}], "tPre": 50, "tPost": 50, "led": 100, "illumination": [50, 75, 100, 125], "stopped": 0}}
|
|
780
|
+
|
|
781
|
+
coordinates: list of dictionaries with x and y coordinates
|
|
782
|
+
tPre: time before exposure in ms
|
|
783
|
+
tPost: exposure time - time after action
|
|
784
|
+
led: led value for illumination
|
|
785
|
+
illumination: list of values for each channel of the illumination
|
|
786
|
+
stopped: 0 for start, 1 for stop
|
|
787
|
+
'''
|
|
788
|
+
path = "/motor_act"
|
|
789
|
+
payload = {
|
|
790
|
+
"task": path,
|
|
791
|
+
"stagescan": {
|
|
792
|
+
"coordinates": coordinates,
|
|
793
|
+
"tPre": tPre,
|
|
794
|
+
"tPost": tPost,
|
|
795
|
+
"led": led,
|
|
796
|
+
"illumination": illumination,
|
|
797
|
+
"stopped": stopped
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
r = self._parent.post_json(path, payload)
|
|
801
|
+
return r
|
|
802
|
+
|
|
778
803
|
def set_tmc_parameters(self, axis=0, msteps=None, rms_current=None, stall_value=None, sgthrs=None, semin=None, semax=None, blank_time=None, toff=None, timeout=1):
|
|
779
804
|
''' set the TMC parameters for a specific axis
|
|
780
805
|
msteps: microsteps
|
|
@@ -387,9 +387,10 @@ class Serial:
|
|
|
387
387
|
except: pass
|
|
388
388
|
|
|
389
389
|
with self.lock:
|
|
390
|
-
try:
|
|
390
|
+
try: # TODO: THis looks fishy an
|
|
391
391
|
self.responses[currentIdentifier].append(json_response.copy())
|
|
392
|
-
except:
|
|
392
|
+
except Exception as e:
|
|
393
|
+
#self._logger.error("Failed to append the response: "+str(e))
|
|
393
394
|
self.responses[currentIdentifier] = list()
|
|
394
395
|
self.responses[currentIdentifier].append(json_response.copy())
|
|
395
396
|
buffer = "" # reset buffer
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|