YorkUphysLabAssistant 1.0.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bruce Howard
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,28 @@
1
+ Metadata-Version: 2.4
2
+ Name: YorkUphysLabAssistant
3
+ Version: 1.0.0
4
+ Summary: A Python package to provide control and readback related to YU physics labs equipment.
5
+ Author-email: Bruce Howard <blhoward@yorku.ca>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/brucehoward-physics/YorkUphysLabAssistant
8
+ Project-URL: Issues, https://github.com/brucehoward-physics/YorkUphysLabAssistant/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: nidaqmx
15
+ Requires-Dist: pyserial
16
+ Requires-Dist: pyvisa-py
17
+ Requires-Dist: numpy
18
+ Requires-Dist: pyttsx3
19
+ Requires-Dist: YorkUphysLab
20
+ Dynamic: license-file
21
+
22
+ This package is meant to be used alongside YorkUphysLab
23
+
24
+ See: https://github.com/m-kareem/YorkUphysLab
25
+
26
+ My fork: https://github.com/brucehoward-physics/YorkUphysLab
27
+
28
+ and provides additional functionality for interfacing with the hardware, including text-to-speech outputs.
@@ -0,0 +1,7 @@
1
+ This package is meant to be used alongside YorkUphysLab
2
+
3
+ See: https://github.com/m-kareem/YorkUphysLab
4
+
5
+ My fork: https://github.com/brucehoward-physics/YorkUphysLab
6
+
7
+ and provides additional functionality for interfacing with the hardware, including text-to-speech outputs.
@@ -0,0 +1,252 @@
1
+ import pyttsx3 as speak
2
+
3
+ import io
4
+ from contextlib import redirect_stdout
5
+
6
+ from YorkUphysLab.ScoutScale import ScoutSTX
7
+ from YorkUphysLab.GwINSTEK import GPD3303D
8
+ from YorkUphysLab.Actuator import Actuator
9
+ from YorkUphysLab.HVcontrol import HV_control
10
+ from YorkUphysLab.Utility import Utility
11
+
12
+ # See https://pypi.org/project/pyttsx3/ for details on ttsx3
13
+
14
+ # See https://stackoverflow.com/questions/1218933/can-i-redirect-the-stdout-into-some-sort-of-string-buffer
15
+ # for info about redirecting print outputs (i.e. stdout) to a buffer. Used to get TTS for the setup/close/etc.
16
+
17
+
18
+ # TODO: Add capability for OSCILLOSCOPE (TBS1000 e.g.)
19
+
20
+ def LookUpType(_key):
21
+ if _key==' grams':
22
+ return ' grams'
23
+ elif _key==' kilovolts':
24
+ return ' kilovolts'
25
+ elif _key==' millimetres':
26
+ return ' millimetres'
27
+ elif _key=='ES':
28
+ return ' grams'
29
+ elif _key=='PSU':
30
+ return ' kilovolts'
31
+ elif _key=='ACT':
32
+ return ' millimetres'
33
+ return ''
34
+
35
+ class DummyClass:
36
+ def __init__(self):
37
+ self.keyword='None'
38
+
39
+ dummyClass = DummyClass()
40
+
41
+ class MyLabMate:
42
+ def __init__(self, _voice=1, _rate='N',_class=dummyClass,_print=True,_comment=None):
43
+ self.engine = speak.init()
44
+ self.voice = _voice
45
+ self.rate = _rate
46
+ self.in_class = _class
47
+ # GET THE KEYWORD
48
+ _key='None'
49
+ if hasattr(self.in_class,'keyword'):
50
+ _key = self.in_class.keyword
51
+ elif hasattr(self.in_class,'HV_on'):
52
+ _key = 'PSU' #HV_Control
53
+ elif hasattr(self.in_class,'actuator_on'):
54
+ _key = 'ACT' #Actuator
55
+ self.config = {'keyword': _key} #For when configurations are used (function generator, oscilloscope, ...)
56
+ self.unit = LookUpType(_key)
57
+ ##################
58
+ self.print = _print
59
+ self.engine.setProperty('voice', self.engine.getProperty('voices')[_voice].id )
60
+ if _rate=='N':
61
+ self.engine.setProperty('rate', 175)
62
+ elif _rate=='S':
63
+ self.engine.setProperty('rate', 125)
64
+ elif _rate=='F':
65
+ self.engine.setProperty('rate', 225)
66
+ else:
67
+ self.engine.setProperty('rate', 175)
68
+ if _comment != None:
69
+ self.comment = _comment
70
+ else:
71
+ self.comment = ""
72
+ if self.config['keyword']=='None':
73
+ self.speak('Beware: you are making a Lab Mate associated with Dummy Class or a class unrecognized by the LabPartner software. Do not expect any further commands to do anything.')
74
+
75
+ def loadComment(self,_string,_isReadout=False,_override=None):
76
+ self.comment = str(_string)
77
+ if _isReadout and _override==None:
78
+ self.comment = self.comment+self.unit
79
+ elif _override!=None:
80
+ self.comment = self.comment+_override
81
+
82
+ def reset(self):
83
+ _voice = self.voice
84
+ _rate = self.rate
85
+ _unit = self.unit
86
+ del self.engine
87
+ # Set back up the engine
88
+ self.engine = speak.init()
89
+ self.engine.setProperty('voice', self.engine.getProperty('voices')[_voice].id )
90
+ if _rate=='N':
91
+ self.engine.setProperty('rate', 175)
92
+ elif _rate=='S':
93
+ self.engine.setProperty('rate', 125)
94
+ elif _rate=='F':
95
+ self.engine.setProperty('rate', 225)
96
+ else:
97
+ self.engine.setProperty('rate', 175)
98
+
99
+ def justspeak(self):
100
+ if self.print:
101
+ print(self.comment)
102
+ self.engine.say(self.comment)
103
+ self.engine.runAndWait()
104
+ self.engine.stop()
105
+ self.reset()
106
+
107
+ def speak(self, _string, _isReadout=False):
108
+ self.loadComment(_string, _isReadout)
109
+ self.justspeak()
110
+
111
+ def SETUP(self):
112
+ if self.config['keyword'] == 'ES':
113
+ # See StackOverflow link above on the stdout buffer
114
+ with io.StringIO() as buf, redirect_stdout(buf):
115
+ self.in_class.connect()
116
+ self.speak(buf.getvalue())
117
+ return
118
+ elif self.config['keyword'] == 'PSU':
119
+ with io.StringIO() as buf, redirect_stdout(buf):
120
+ self.in_class.switch_on()
121
+ #self.speak(buf.getvalue())
122
+ print(buf.getvalue())
123
+ self.speak('Power supply text-to-speech misbehaving. I have printed the output to the screen instead.')
124
+ return
125
+ elif self.config['keyword'] == 'ACT':
126
+ with io.StringIO() as buf, redirect_stdout(buf):
127
+ self.in_class.switch_on()
128
+ self.speak(buf.getvalue())
129
+ return
130
+ elif self.config['keyword'] == 'AFG':
131
+ with io.StringIO() as buf, redirect_stdout(buf):
132
+ self.in_class.connect()
133
+ self.speak(buf.getvalue())
134
+ return
135
+ else:
136
+ self.speak('I cannot run setup for the hardware class associated to this Lab Mate.')
137
+ return
138
+
139
+ def SET(self, _value):
140
+ if self.config['keyword'] == 'ES':
141
+ self.speak('I cannot run SET for the hardware class associated to this Lab Mate.')
142
+ return
143
+ elif self.config['keyword'] == 'PSU':
144
+ with io.StringIO() as buf, redirect_stdout(buf):
145
+ self.in_class.set_hv(_value)
146
+ self.speak(buf.getvalue())
147
+ return
148
+ elif self.config['keyword'] == 'ACT':
149
+ with io.StringIO() as buf, redirect_stdout(buf):
150
+ self.in_class.set_position(_value)
151
+ self.speak(buf.getvalue())
152
+ return
153
+ elif self.config['keyword'] == 'AFG':
154
+ try:
155
+ if _value[0]=='V' or _value[0]=='v':
156
+ with io.StringIO() as buf, redirect_stdout(buf):
157
+ self.in_class.set_amplitude(_value[1])
158
+ self.config['amplitude'] = str(_value[1])+' Volts'
159
+ self.speak(buf.getvalue())
160
+ return
161
+ if _value[0]=='F' or _value[0]=='f':
162
+ with io.StringIO() as buf, redirect_stdout(buf):
163
+ self.in_class.set_frequency(_value[1])
164
+ self.config['frequency'] = str(_value[1])+' Hertz'
165
+ self.speak(buf.getvalue())
166
+ return
167
+ if _value[0]=='W' or _value[0]=='w':
168
+ with io.StringIO() as buf, redirect_stdout(buf):
169
+ self.in_class.set_waveform(_value[1])
170
+ self.config['waveform'] = str(_value[1])
171
+ self.speak(buf.getvalue())
172
+ return
173
+ if _value[0]=='O' or _value[0]=='o':
174
+ with io.StringIO() as buf, redirect_stdout(buf):
175
+ self.in_class.set_DCoffset(_value[1])
176
+ self.config['offset'] = str(_value[1])+' Volts'
177
+ self.speak(buf.getvalue())
178
+ return
179
+ if _value[0]=='ON' or _value[0]=='on' or _value[0]=='On':
180
+ with io.StringIO() as buf, redirect_stdout(buf):
181
+ self.in_class.set_output("ON")
182
+ self.config['state'] = 'ON'
183
+ self.speak(buf.getvalue())
184
+ return
185
+ if _value[0]=='OFF' or _value[0]=='off' or _value[0]=='Off':
186
+ with io.StringIO() as buf, redirect_stdout(buf):
187
+ self.in_class.set_output("OFF")
188
+ self.config['state'] = 'OFF'
189
+ self.speak(buf.getvalue())
190
+ return
191
+ except:
192
+ self.speak('For the function generator, the input value to set should be a two item list. A character "V" to see amplitude, "F" to set frequency, "W" for waveform, and "O" for offset. Second value is the valuue to set. A list with "ON" as first element turns on the output, while "OFF" turns it off.')
193
+ return
194
+ else:
195
+ self.speak('I cannot run SET for the hardware class associated to this Lab Mate.')
196
+ return
197
+
198
+ def GET(self):
199
+ if self.config['keyword'] == 'ES':
200
+ # See StackOverflow link above on the stdout buffer
201
+ with io.StringIO() as buf, redirect_stdout(buf):
202
+ weight = self.in_class.read_weight()
203
+ self.speak(buf.getvalue())
204
+ self.speak( weight, True )
205
+ return
206
+ elif self.config['keyword'] == 'PSU':
207
+ with io.StringIO() as buf, redirect_stdout(buf):
208
+ voltage = self.in_class.get_hv()
209
+ self.speak(buf.getvalue())
210
+ self.speak( voltage, True )
211
+ return
212
+ elif self.config['keyword'] == 'ACT':
213
+ with io.StringIO() as buf, redirect_stdout(buf):
214
+ position = self.in_class.get_position()
215
+ self.speak(buf.getvalue())
216
+ self.speak( position, True )
217
+ return
218
+ elif self.config['keyword'] == 'AFG':
219
+ self.speak('The function generator, takes as input via SET the amplitude, frequency, waveform, and offset, as well as whether the output is on or off. The following statements will tell you the configuration.')
220
+ for key in self.config.keys():
221
+ statement = key + ' is ' + str(self.config[key])
222
+ self.speak(statement)
223
+ return
224
+ else:
225
+ self.speak('I cannot run GET for the hardware class associated to this Lab Mate.')
226
+ return
227
+
228
+ def CLOSE(self):
229
+ if self.config['keyword'] == 'ES':
230
+ # See StackOverflow link above on the stdout buffer
231
+ with io.StringIO() as buf, redirect_stdout(buf):
232
+ self.in_class.close_connection()
233
+ self.speak(buf.getvalue())
234
+ return
235
+ elif self.config['keyword'] == 'PSU':
236
+ with io.StringIO() as buf, redirect_stdout(buf):
237
+ self.in_class.switch_off()
238
+ self.speak(buf.getvalue())
239
+ return
240
+ elif self.config['keyword'] == 'ACT':
241
+ with io.StringIO() as buf, redirect_stdout(buf):
242
+ self.in_class.switch_off()
243
+ self.speak(buf.getvalue())
244
+ return
245
+ elif self.config['keyword'] == 'AFG':
246
+ with io.StringIO() as buf, redirect_stdout(buf):
247
+ self.in_class.close()
248
+ self.speak(buf.getvalue())
249
+ return
250
+ else:
251
+ self.speak('I cannot run GET for the hardware class associated to this Lab Mate.')
252
+ return
@@ -0,0 +1,28 @@
1
+ Metadata-Version: 2.4
2
+ Name: YorkUphysLabAssistant
3
+ Version: 1.0.0
4
+ Summary: A Python package to provide control and readback related to YU physics labs equipment.
5
+ Author-email: Bruce Howard <blhoward@yorku.ca>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/brucehoward-physics/YorkUphysLabAssistant
8
+ Project-URL: Issues, https://github.com/brucehoward-physics/YorkUphysLabAssistant/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: nidaqmx
15
+ Requires-Dist: pyserial
16
+ Requires-Dist: pyvisa-py
17
+ Requires-Dist: numpy
18
+ Requires-Dist: pyttsx3
19
+ Requires-Dist: YorkUphysLab
20
+ Dynamic: license-file
21
+
22
+ This package is meant to be used alongside YorkUphysLab
23
+
24
+ See: https://github.com/m-kareem/YorkUphysLab
25
+
26
+ My fork: https://github.com/brucehoward-physics/YorkUphysLab
27
+
28
+ and provides additional functionality for interfacing with the hardware, including text-to-speech outputs.
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ YorkUphysLabAssistant/LabPartner.py
5
+ YorkUphysLabAssistant/__init__.py
6
+ YorkUphysLabAssistant.egg-info/PKG-INFO
7
+ YorkUphysLabAssistant.egg-info/SOURCES.txt
8
+ YorkUphysLabAssistant.egg-info/dependency_links.txt
9
+ YorkUphysLabAssistant.egg-info/requires.txt
10
+ YorkUphysLabAssistant.egg-info/top_level.txt
@@ -0,0 +1,6 @@
1
+ nidaqmx
2
+ pyserial
3
+ pyvisa-py
4
+ numpy
5
+ pyttsx3
6
+ YorkUphysLab
@@ -0,0 +1,2 @@
1
+ YorkUphysLabAssistant
2
+ dist
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ['setuptools>=42']
3
+ build-backend = 'setuptools.build_meta'
4
+
5
+ [project]
6
+ name = "YorkUphysLabAssistant"
7
+ version = "1.0.0"
8
+ authors = [
9
+ { name="Bruce Howard", email="blhoward@yorku.ca" },
10
+ ]
11
+ description = "A Python package to provide control and readback related to YU physics labs equipment."
12
+ readme = "README.md"
13
+ requires-python = ">=3.7"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Operating System :: OS Independent",
17
+ ]
18
+ license = "MIT"
19
+ license-files = ["LICENSE"]
20
+ dependencies = [
21
+ "nidaqmx",
22
+ "pyserial",
23
+ "pyvisa-py",
24
+ "numpy",
25
+ "pyttsx3",
26
+ "YorkUphysLab",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/brucehoward-physics/YorkUphysLabAssistant"
31
+ Issues = "https://github.com/brucehoward-physics/YorkUphysLabAssistant/issues"
32
+
33
+ [tool.setuptools.packages]
34
+ find = {} # Copied from the YorkUphysLab setup.cfg
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+