Skip to content

Commit

Permalink
Scpi psu reconnect (#726)
Browse files Browse the repository at this point in the history
* Created a new agent.py which dynamically reconnects sometimes, but still has some errors

* Fixed the code to dynamically reconnect. See the relevant DAQ discussion for more.

* Removed numpy

* Removed the commented out call for psu.test() as it ended up being unnecessary

* Removed status messages and added logging as per daq-discussions#106

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Made the easy changes

* Made the easy changes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Merged main

* Changed the nested logic to use elif

* Finished requested changes

* Changed the reconnect logic again.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Uncommented the correct drivers.

* Remove extra local drivers import

* Remove extra word added to comment

I think this snuck in during a git merge, looks like a 'git' command got added
to the comment in 4567a0b.

---------

Co-authored-by: simonscryo <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 9, 2024
1 parent f1c537a commit 7d2f158
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 25 deletions.
67 changes: 42 additions & 25 deletions socs/agents/scpi_psu/agent.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import argparse
import socket
import time
from typing import Optional

from ocs import ocs_agent, site_config
from ocs.ocs_twisted import TimeoutLock
Expand All @@ -19,7 +20,7 @@ def __init__(self, agent, ip_address, gpib_slot):
self.gpib_slot = gpib_slot
self.monitor = False

self.psu = None
self.psu: Optional[ScpiPsuAgent] = None

# Registers Temperature and Voltage feeds
agg_params = {
Expand All @@ -41,16 +42,25 @@ def init(self, session, params=None):
if not acquired:
return False, "Could not acquire lock"

try:
self.psu = PsuInterface(self.ip_address, self.gpib_slot)
self.idn = self.psu.identify()
except socket.timeout as e:
self.log.error(f"PSU timed out during connect: {e}")
return False, "Timeout"
self.log.info("Connected to psu: {}".format(self.idn))

while not self._initialize_module():
time.sleep(5)
return True, 'Initialized PSU.'

def _initialize_module(self):
"""Initialize the ScpiPsu module."""
try:
self.psu = PsuInterface(self.ip_address, self.gpib_slot)
except (socket.timeout, OSError) as e:
self.log.warn(f"Error establishing connection: {e}")
self.psu = None
return False

self.idn = self.psu.identify()
self.log.info("Connected to psu: {}".format(self.idn))
self.log.info("Clearing event registers and error queue")
self.psu.clear()
return True

@ocs_agent.param('wait', type=float, default=1)
@ocs_agent.param('channels', type=list, default=[1, 2, 3])
@ocs_agent.param('test_mode', type=bool, default=False)
Expand All @@ -71,29 +81,36 @@ def monitor_output(self, session, params=None):
self.monitor = True

while self.monitor:
time.sleep(params['wait'])
with self.lock.acquire_timeout(1) as acquired:
if acquired:
data = {
'timestamp': time.time(),
'block_name': 'output',
'data': {}
}
if not acquired:
self.log.warn("Could not acquire in monitor_current")
continue

if not self.psu:
self._initialize_module()
continue

data = {
'timestamp': time.time(),
'block_name': 'output',
'data': {}
}

try:
for chan in params['channels']:
data['data']["Voltage_{}".format(chan)] = self.psu.get_volt(chan)
data['data']["Current_{}".format(chan)] = self.psu.get_curr(chan)
except socket.timeout as e:
self.log.warn(f"TimeoutError: {e}")
self.log.info("Attempting to reconnect")
self.psu = None
continue

# self.log.info(str(data))
# print(data)
self.agent.publish_to_feed('psu_output', data)

# Allow this process to be queried to return current data
session.data = data
self.agent.publish_to_feed('psu_output', data)

else:
self.log.warn("Could not acquire in monitor_current")

time.sleep(params['wait'])
# Allow this process to be queried to return current data
session.data = data

if params['test_mode']:
break
Expand Down
6 changes: 6 additions & 0 deletions socs/agents/scpi_psu/drivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,9 @@ def get_curr(self, ch):
self.write('MEAS:CURR? CH' + str(ch))
current = float(self.read())
return current

def clear(self):
# Clear all the event registers and error queue, using a query such as *ESR? or MEAS:X?
# instead of *CLS can confuse the PSU
self.write('*CLS')
return True

0 comments on commit 7d2f158

Please sign in to comment.