Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keithley3706A: improvements / warnings cleanup #2318

Merged
merged 7 commits into from Oct 21, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 45 additions & 16 deletions qcodes/instrument_drivers/tektronix/Keithley_3706A.py
Expand Up @@ -101,18 +101,7 @@ def open_channel(self, val: str) -> None:
val: A string representing the channels, channel ranges,
backplane relays, slots or channel patterns to be queried.
"""
states = self.get_interlock_state()
backplanes = self.get_analog_backplane_specifiers()
val_specifiers = val.split(',')
for item in val_specifiers:
if item in backplanes:
for element in states:
if element['state'] == 'Interlock is disengaged':
warnings.warn(f'The hardware interlock in Slot '
f'{element["slot_no"]} is disengaged. '
'The corresponding analog backplane '
'relays cannot be energized.',
UserWarning, 2)

if not self._validator(val):
raise InvalidValue(f'{val} is not a valid specifier. '
'The specifier should be channels, channel '
Expand All @@ -138,8 +127,47 @@ def close_channel(self, val: str) -> None:
if val in forbidden_channels.split(','):
warnings.warn('You are attempting to close channels that are '
'forbidden to close.', UserWarning, 2)

astafan8 marked this conversation as resolved.
Show resolved Hide resolved
self._warn_on_disengaged_interlocks(val)

self.write(f"channel.close('{val}')")

def _warn_on_disengaged_interlocks(self, val: str) -> None:
"""
Checks if backplance channels among the given specifiers can be
energized dependening on respective hardware interlocks being
engaged, and raises a warning for those backplane channels which
cannot be energized.

Args:
val: A string representing the channels, channel ranges,
backplane relays.
"""
states = self.get_interlock_state()
val_specifiers = val.split(",")
for channel in val_specifiers:
if self._is_backplane_channel(channel):
slot = channel[0]
interlock_state = [
state for state in states if state["slot_no"] == slot
][0]
if interlock_state["state"] == "Interlock is disengaged":
warnings.warn(
f"The hardware interlock in Slot "
f'{interlock_state["slot_no"]} is disengaged. '
f"The analog backplane relay {channel} "
"cannot be energized.",
UserWarning,
2,
)

def _is_backplane_channel(self, channel_id: str) -> bool:
if len(channel_id) != 4:
raise InvalidValue(f"{channel_id} is not a valid channel id")
if channel_id[1] == "9":
return True
return False

def exclusive_close(self, val: str) -> None:
"""
Closes the specified channels such that any presently closed channels
Expand Down Expand Up @@ -697,12 +725,13 @@ def get_interlock_state(self) -> Tuple[Dict[str, str], ...]:
1: 'Interlock is engaged'}
states: List[Dict[str, str]] = []
for i in slot_id:
state = self.ask(f'slot[{int(i)}].interlock.state')
state_dict = {'slot_no': i,
'state': interlock_status[int(float(state))]}
states.append(state_dict)
state = self.get_interlock_state_by_slot(i)
states.append({"slot_no": i, "state": interlock_status[state]})
return tuple(states)

def get_interlock_state_by_slot(self, slot) -> int:
return int(float(self.ask(f"slot[{int(slot)}].interlock.state")))

def get_ip_address(self) -> str:
"""
Returns the current IP address of the instrument.
Expand Down