Skip to content

Commit aba7193

Browse files
dccoteclaude
andcommitted
Add Verdi-G / HOPS monitor examples
Two read-only status monitors under examples/verdig/ (stream once per second, Ctrl-C to stop; neither takes remote control, so the front panel stays usable): - temperature_monitor_native.py: main temperature over native pyftdi I2C (no DLL). - status_monitor_dll.py: full status (four servo temperatures, power, shutter, emission, interlock/faults) over Coherent's CohrHOPS.dll. Plus a short README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01841beMNdCw3zYf6fdBUoy7
1 parent 1a4e721 commit aba7193

3 files changed

Lines changed: 109 additions & 0 deletions

File tree

examples/verdig/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Verdi-G / HOPS examples
2+
3+
Read-only monitors for a Coherent HOPS-supply laser (Genesis / Verdi-G). Both
4+
stream once per second and stop on Ctrl-C. Neither takes remote control, so the
5+
front-panel wheel keeps working while they run.
6+
7+
- `temperature_monitor_native.py` — main temperature over **native pyftdi I2C**
8+
(no DLL). macOS/Linux; needs pyftdi + libusb and the laser on this host.
9+
- `status_monitor_dll.py` — full status (all four servo temperatures, power,
10+
shutter, emission, interlock/faults) over **Coherent's `CohrHOPS.dll`**.
11+
Windows/Linux; needs the DLLs (see `../../hardwarelibrary/manuals/`
12+
`Coherent-HOPS-2-USB-and-DLL-Protocol.md`).
13+
14+
For the full driver and the two transports, see
15+
`hardwarelibrary/sources/verdig.py` (`VerdiGDevice`) and the `Coherent-HOPS-*`
16+
docs under `hardwarelibrary/manuals/`.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""Stream full Verdi-G / HOPS status over Coherent's CohrHOPS.dll (Windows/Linux).
2+
3+
Read-only: it does not change the laser state or take remote control (the front
4+
panel stays usable). Unlike the native transport, the DLL path also reads all
5+
four thermal-servo temperatures and the interlock/fault state.
6+
7+
Setup: place CohrHOPS.dll and CohrFTCI2C.dll (matching your Python's bitness)
8+
next to hardwarelibrary/sources/hopsdll.py, or pass dllDirectory=... below.
9+
10+
Run: python examples/verdig/status_monitor_dll.py [count]
11+
"""
12+
import datetime
13+
import sys
14+
import time
15+
16+
from hardwarelibrary.sources.hopsdll import HOPSDLLInterface
17+
18+
19+
def main():
20+
count = int(sys.argv[1]) if len(sys.argv) > 1 else None
21+
interface = HOPSDLLInterface() # or HOPSDLLInterface(dllDirectory=r"C:\dlls")
22+
interface.open()
23+
24+
identity = interface.identity()
25+
print("Connected via CohrHOPS.dll: {0} (head {1}, s/n {2}, max {3:.3f} W)".format(
26+
identity["model"], identity["headType"], identity["serialNumber"],
27+
identity["maxPower"]))
28+
29+
read = 0
30+
try:
31+
while count is None or read < count:
32+
diag = interface.diagnostics() # includes the four servo temperatures
33+
temps = ("main={mainTemperature:.1f} SHG={shgTemperature:.1f} "
34+
"BRF={brfTemperature:.1f} etalon={etalonTemperature:.1f}").format(**diag)
35+
faults = interface.faults()
36+
interlock = "ok" if interface.interlockOk() else "FAULT"
37+
stamp = datetime.datetime.now().strftime("%H:%M:%S")
38+
print("{0} {1} C | P={2:.3f} W shutter={3} emission={4} interlock={5}{6}".format(
39+
stamp, temps, interface.getPower(),
40+
"open" if interface.shutterOpen() else "closed",
41+
"ON" if interface.emissionOn() else "off", interlock,
42+
(" faults=" + ",".join(faults)) if faults else ""))
43+
read += 1
44+
if count is None or read < count:
45+
time.sleep(1.0)
46+
except KeyboardInterrupt:
47+
print()
48+
finally:
49+
interface.close()
50+
51+
52+
if __name__ == "__main__":
53+
main()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Stream the Verdi-G / HOPS main temperature over native pyftdi I2C (no DLL).
2+
3+
Read-only: it does not change the laser state or take remote control (so the
4+
front panel stays usable). Works on macOS/Linux with the laser attached and
5+
pyftdi + libusb available.
6+
7+
Run: python examples/verdig/temperature_monitor_native.py [count]
8+
On macOS, put the directory that holds libusb-1.0 on the loader path, e.g.:
9+
DYLD_LIBRARY_PATH=/opt/homebrew/lib python examples/verdig/temperature_monitor_native.py
10+
"""
11+
import datetime
12+
import sys
13+
import time
14+
15+
from hardwarelibrary.sources.hopsnative import HOPSNativeInterface
16+
17+
18+
def main():
19+
count = int(sys.argv[1]) if len(sys.argv) > 1 else None
20+
interface = HOPSNativeInterface() # or HOPSNativeInterface(url="ftdi://...")
21+
interface.open()
22+
print("Verdi-G / HOPS main-temperature monitor (Ctrl-C to stop). "
23+
"Native calibration valid ~32-40 C.")
24+
read = 0
25+
try:
26+
while count is None or read < count:
27+
celsius = interface.mainTemperature()
28+
stamp = datetime.datetime.now().strftime("%H:%M:%S")
29+
print("{0} TMAIN = {1:6.2f} C".format(stamp, celsius))
30+
read += 1
31+
if count is None or read < count:
32+
time.sleep(1.0)
33+
except KeyboardInterrupt:
34+
print()
35+
finally:
36+
interface.close()
37+
38+
39+
if __name__ == "__main__":
40+
main()

0 commit comments

Comments
 (0)