UC2-REST 0.2.0.32__tar.gz → 0.2.0.34__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.
Files changed (48) hide show
  1. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/PKG-INFO +1 -1
  2. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/UC2_REST.egg-info/PKG-INFO +1 -1
  3. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/UC2_REST.egg-info/SOURCES.txt +1 -0
  4. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/UC2Client.py +28 -51
  5. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/__version__.py +1 -1
  6. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/can.py +20 -6
  7. uc2_rest-0.2.0.34/uc2rest/canota.py +588 -0
  8. uc2_rest-0.2.0.34/uc2rest/fan.py +86 -0
  9. uc2_rest-0.2.0.34/uc2rest/galvo.py +312 -0
  10. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/home.py +44 -3
  11. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/ledmatrix.py +1 -1
  12. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/motor.py +144 -25
  13. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/mserial.py +127 -61
  14. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/objective.py +16 -9
  15. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/rotator.py +1 -1
  16. uc2_rest-0.2.0.34/uc2rest/state.py +222 -0
  17. uc2_rest-0.2.0.34/uc2rest/wifi.py +44 -0
  18. uc2_rest-0.2.0.32/uc2rest/canota.py +0 -256
  19. uc2_rest-0.2.0.32/uc2rest/galvo.py +0 -116
  20. uc2_rest-0.2.0.32/uc2rest/state.py +0 -99
  21. uc2_rest-0.2.0.32/uc2rest/wifi.py +0 -98
  22. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/LICENSE +0 -0
  23. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/README.md +0 -0
  24. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/UC2_REST.egg-info/dependency_links.txt +0 -0
  25. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/UC2_REST.egg-info/not-zip-safe +0 -0
  26. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/UC2_REST.egg-info/requires.txt +0 -0
  27. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/UC2_REST.egg-info/top_level.txt +0 -0
  28. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/setup.cfg +0 -0
  29. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/setup.py +0 -0
  30. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/MockSerial.py +0 -0
  31. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/__init__.py +0 -0
  32. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/analog.py +0 -0
  33. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/camera.py +0 -0
  34. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/camera_trigger.py +0 -0
  35. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/cmdrecorder.py +0 -0
  36. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/digitalin.py +0 -0
  37. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/digitalout.py +0 -0
  38. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/gripper.py +0 -0
  39. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/laser.py +0 -0
  40. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/lcddisplay.py +0 -0
  41. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/logger.py +0 -0
  42. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/message.py +0 -0
  43. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/modules.py +0 -0
  44. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/motor_config.py +0 -0
  45. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/pid.py +0 -0
  46. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/slm.py +0 -0
  47. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/temperature.py +0 -0
  48. {uc2_rest-0.2.0.32 → uc2_rest-0.2.0.34}/uc2rest/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UC2-REST
3
- Version: 0.2.0.32
3
+ Version: 0.2.0.34
4
4
  Summary: This pacage will help you to drive the ESP32-driven microscopy control modules from UC2
5
5
  Home-page: https://github.com/openUC2/UC2-REST
6
6
  Author: Benedict Diederich
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UC2-REST
3
- Version: 0.2.0.32
3
+ Version: 0.2.0.34
4
4
  Summary: This pacage will help you to drive the ESP32-driven microscopy control modules from UC2
5
5
  Home-page: https://github.com/openUC2/UC2-REST
6
6
  Author: Benedict Diederich
@@ -19,6 +19,7 @@ uc2rest/canota.py
19
19
  uc2rest/cmdrecorder.py
20
20
  uc2rest/digitalin.py
21
21
  uc2rest/digitalout.py
22
+ uc2rest/fan.py
22
23
  uc2rest/galvo.py
23
24
  uc2rest/gripper.py
24
25
  uc2rest/home.py
@@ -26,22 +26,24 @@ from .rotator import Rotator
26
26
  from .logger import Logger
27
27
  from .cmdrecorder import cmdRecorder
28
28
  from .temperature import Temperature
29
+ from .fan import Fan
29
30
  from .message import Message
30
31
  from .can import CAN
31
32
  from .canota import CANOTA
32
33
  from .camera_trigger import CameraTrigger
34
+
35
+ # requests is no longer used for direct ESP communication (serial-only).
36
+ # Kept as optional import for other modules that may need HTTP (e.g. firmware downloads).
33
37
  try:
34
38
  import requests
35
- except:
36
- print("No requests available - running on pyscript?")
39
+ except Exception:
40
+ requests = None
37
41
 
38
42
  class UC2Client(object):
39
- # headers = {'ESP32-version': '*'}
40
43
  headers={"Content-Type":"application/json"}
41
44
  getmessage = ""
42
45
  is_connected = False
43
46
 
44
- is_wifi = False
45
47
  is_serial = False
46
48
  BAUDRATE = 115200
47
49
 
@@ -52,12 +54,13 @@ class UC2Client(object):
52
54
  This client connects to the UC2-REST microcontroller that can be found here
53
55
  https://github.com/openUC2/UC2-REST
54
56
 
57
+ Communication is via USB/serial only.
58
+ The host/port parameters are deprecated and will be ignored.
59
+
55
60
  generally speaking you send/receive JSON documents that will cause an:
56
61
  1. action => "/XXX_act"
57
62
  2. getting => "/XXX_get"
58
63
  3. setting => "/XXX_set"
59
-
60
- you can send commands through wifi/http or usb/serial
61
64
  '''
62
65
  if True: #logger is None:
63
66
  self.logger = Logger()
@@ -67,28 +70,27 @@ class UC2Client(object):
67
70
  # perhaps we are in the browser?
68
71
  self.isPyScript = isPyScript
69
72
 
70
- # initialize communication channel (# connect to wifi or usb)
73
+ # Deprecation notice for WiFi mode
74
+ if host is not None and serialport is None and SerialManager is None:
75
+ self.logger.warning(
76
+ "WiFi/HTTP communication has been removed. "
77
+ "Please use serialport= instead. Ignoring host parameter."
78
+ )
79
+
80
+ # initialize communication channel (serial only)
71
81
  if serialport is not None:
72
82
  # use USB connection
73
83
  self.serial = Serial(serialport, baudrate, parent=self, identity=identity, DEBUG=DEBUG, skipFirmwareCheck=skipFirmwareCheck)
74
84
  self.is_serial = True
75
85
  self.is_connected = self.serial.is_connected
76
86
  self.serial.DEBUG = DEBUG
77
- elif host is not None:
78
- # use client in wireless mode
79
- self.is_wifi = True
80
- self.host = host
81
- self.port = port
82
-
83
- # check if host is up
84
- self.logger.debug(f"Connecting to microscope {self.host}:{self.port}")
85
- #self.is_connected = self.isConnected()
86
87
  elif SerialManager is not None:
87
- # we are trying to access the controller from .a web browser
88
+ # we are trying to access the controller from a web browser
88
89
  self.serial = SerialManagerWrapper(SerialManager, parent=self)
89
90
  self.isPyScript = True
91
+ self.is_serial = True
90
92
  else:
91
- self.logger.error("No ESP32 device is connected - check IP or Serial port!")
93
+ self.logger.error("No ESP32 device is connected - please provide a serialport!")
92
94
 
93
95
 
94
96
  # import libraries depending on API version
@@ -130,8 +132,8 @@ class UC2Client(object):
130
132
  # initialize temperature
131
133
  self.temperature = Temperature(self)
132
134
 
133
- # initialize laser
134
- self.state = State(self)
135
+ # initialize fan controller
136
+ self.fan = Fan(self)
135
137
 
136
138
  # initialize galvo
137
139
  self.galvo = Galvo(self)
@@ -164,42 +166,17 @@ class UC2Client(object):
164
166
  self.modules = Modules(parent=self)
165
167
 
166
168
  def post_json(self, path, payload, getReturn=True, nResponses=1, timeout=1):
167
- if self.is_wifi:
168
- # FIXME: this is not working
169
- url = f"http://{self.host}:{self.port}{path}"
170
- try:
171
- if timeout==0: timeout=.2
172
- r = requests.post(url, json=payload, headers=self.headers, timeout=timeout)
173
- returnMessage = r.json()
174
- returnMessage["success"] = r.status_code==200
175
- except Exception as e:
176
- print(e)
177
- returnMessage = {}
178
- returnMessage["error"] = str(e)
179
- returnMessage["success"] = 0
180
- return returnMessage
181
- elif self.is_serial or self.isPyScript:
182
- if timeout <=0:
183
- getReturn = False
184
- return self.serial.post_json(path, payload, getReturn=getReturn, nResponses=nResponses, timeout=timeout)
185
- else:
186
- self.logger.error("No ESP32 device is connected - check IP or Serial port!")
187
- return None
169
+ if timeout <=0:
170
+ getReturn = False
171
+ return self.serial.post_json(path, payload, getReturn=getReturn, nResponses=nResponses, timeout=timeout)
188
172
 
189
173
  def get_json(self, path, getReturn=True, timeout=1):
190
- if self.is_wifi:
191
- # FIXME: this is not working
192
- url = f"http://{self.host}:{self.port}{path}"
193
- r = requests.get(url, headers=self.headers, timeout=timeout)
194
- return r.json()
195
- elif self.is_serial or self.isPyScript:
196
- # timeout is not used anymore
197
- if timeout <=0:
174
+ if self.is_serial or self.isPyScript:
175
+ if timeout <= 0:
198
176
  getReturn = False
199
177
  return self.serial.post_json(path, payload=None, getReturn=getReturn, nResponses=1, timeout=timeout)
200
- #return self.serial.read_json()<
201
178
  else:
202
- self.logger.error("No ESP32 device is connected - check IP or Serial port!")
179
+ self.logger.error("No ESP32 device is connected - serial not initialized!")
203
180
  return None
204
181
 
205
182
  def setDebugging(self, debug=False):
@@ -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.32"
9
+ __version__ = "v0.2.0.34"
10
10
  __author__ = 'Benedict Diederich'
11
11
  __author_email__ = 'benedictdied@gmail.com'
12
12
  __license__ = 'GPL v3'
@@ -57,15 +57,29 @@ class CAN(object):
57
57
  """Register a callback function for a specific key."""
58
58
  self._callbackPerKey[key] = callbackfct
59
59
 
60
+ def get_can_ids(self):
61
+ """Return CAN node IDs from the latest scan (e.g. for OTA flashing)."""
62
+ return [entry.get("canId") for entry in self.scanResults
63
+ if entry.get("canId") is not None]
64
+
60
65
  def reboot_remote(self, qid=1, can_address=0, isBlocking=False, timeout=2):
61
66
  """
62
- Send a reboot signal to the remote CAN device.
67
+ Reboot a CAN device.
63
68
 
64
- :param qid: Query ID for the CAN command (default: 1)
69
+ - ``can_address == 0`` reboots the master (this ESP32) itself.
70
+ - ``can_address in 1..127`` reboots a remote slave by SDO-writing 1
71
+ to OD index 0x2507 sub 0 on the target node. The slave's
72
+ CO_tmr_task observes the write and calls ESP.restart() ~200 ms
73
+ later.
74
+
75
+ :param qid: Query ID for the CAN command (unused by firmware, kept
76
+ for API compatibility)
77
+ :param can_address: 0 = master, 1..127 = remote slave nodeId
65
78
  :param isBlocking: If True, wait for response
66
79
  :param timeout: Timeout for the command in seconds
67
- :param can_address: Address of the CAN device to reboot (0 is master)
68
- :return: Response from the device
80
+ :return: Response from the device, e.g.
81
+ ``{"status":"ok","nodeId":11}`` or
82
+ ``{"status":"error","error":"SDO write failed","nodeId":11}``.
69
83
  """
70
84
  path = "/can_act"
71
85
  payload = {
@@ -98,7 +112,7 @@ class CAN(object):
98
112
  "count": 2
99
113
  }
100
114
  """
101
- path = "/can_act"
115
+ path = "/can_act" # {"task":"/can_act", "scan": true}
102
116
  payload = {
103
117
  "task": path,
104
118
  "scan": True,
@@ -109,7 +123,7 @@ class CAN(object):
109
123
  payload,
110
124
  getReturn=True,
111
125
  timeout=timeout,
112
- nResponses=2
126
+ nResponses=1
113
127
  )
114
128
 
115
129
  def get_available_devices(self, timeout=2):