"""
Python Interchangeable Virtual Instrument Library
Copyright (c) 2012-2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from . import ivi
# Parameter Values
CurrentLimitBehavior = set(['regulate', 'trip'])
RangeType = set(['current', 'voltage'])
OutputState = set(['constant_voltage', 'constant_current', 'over_voltage',
'over_current', 'unregulated'])
MeasurementType = set(['current', 'voltage'])
def get_range(range_list, offset, val):
l = list()
for i in range_list:
l.append((i, abs(range_list[i][offset])))
l.sort(key=lambda x: x[1], reverse=True)
k = None
for i in range(len(l)):
if l[i][1] >= val:
k = l[i][0]
return k
[docs]class Base(ivi.IviContainer):
"Base IVI methods for all DC power supplies"
def __init__(self, *args, **kwargs):
# needed for _init_outputs calls from other __init__ methods
self._output_count = 1
super(Base, self).__init__(*args, **kwargs)
cls = 'IviDCPwr'
grp = 'Base'
ivi.add_group_capability(self, cls+grp)
self._output_current_limit = list()
self._output_current_limit_behavior = list()
self._output_enabled = list()
self._output_ovp_enabled = list()
self._output_ovp_limit = list()
self._output_voltage_level = list()
self._output_name = list()
self._output_count = 1
self._output_spec = [
{
'range': {
'P0V': (0, 0)
},
'ovp_max': 0,
'voltage_max': 0,
'current_max': 0
}
]
self._add_property('outputs[].current_limit',
self._get_output_current_limit,
self._set_output_current_limit,
None,
ivi.Doc("""
Specifies the output current limit. The units are Amps.
The value of the Current Limit Behavior attribute determines the behavior
of the power supply when the output current is equal to or greater than
the value of this attribute.
""", cls, grp, '4.2.1'))
self._add_property('outputs[].current_limit_behavior',
self._get_output_current_limit_behavior,
self._set_output_current_limit_behavior,
None,
ivi.Doc("""
Specifies the behavior of the power supply when the output current is
equal to or greater than the value of the Current Limit attribute.
Values
* 'trip' - The power supply disables the output when the output current is
equal to or greater than the value of the Current Limit attribute.
* 'regulate' - The power supply restricts the output voltage such that the
output current is not greater than the value of the Current Limit
attribute.
""", cls, grp, '4.2.2'))
self._add_property('outputs[].enabled',
self._get_output_enabled,
self._set_output_enabled,
None,
ivi.Doc("""
If true, the signal the power supply produces appears at the output
connector. If false, the signal the power supply produces does not appear
at the output connector.
""", cls, grp, '4.2.3'))
self._add_property('outputs[].ovp_enabled',
self._get_output_ovp_enabled,
self._set_output_ovp_enabled,
None,
ivi.Doc("""
Specifies whether the power supply provides over-voltage protection. If
this attribute is set to True, the power supply disables the output when
the output voltage is greater than or equal to the value of the OVP
Limit attribute.
""", cls, grp, '4.2.4'))
self._add_property('outputs[].ovp_limit',
self._get_output_ovp_limit,
self._set_output_ovp_limit,
None,
ivi.Doc("""
Specifies the voltage the power supply allows. The units are Volts.
If the OVP Enabled attribute is set to True, the power supply disables the
output when the output voltage is greater than or equal to the value of
this attribute.
If the OVP Enabled is set to False, this attribute does not affect the
behavior of the instrument.
""", cls, grp, '4.2.5'))
self._add_property('outputs[].voltage_level',
self._get_output_voltage_level,
self._set_output_voltage_level,
None,
ivi.Doc("""
Specifies the voltage level the DC power supply attempts to generate. The
units are Volts.
""", cls, grp, '4.2.6'))
self._add_property('outputs[].name',
self._get_output_name,
None,
None,
ivi.Doc("""
This attribute returns the repeated capability identifier defined by
specific driver for the output channel that corresponds to the index that
the user specifies. If the driver defines a qualified Output Channel name,
this property returns the qualified name.
If the value that the user passes for the Index parameter is less than
zero or greater than the value of the Output Channel Count, the attribute
raises a SelectorRangeException.
""", cls, grp, '4.2.9'))
self._add_method('outputs[].configure_current_limit',
self._output_configure_current_limit,
ivi.Doc("""
This function configures the current limit. It specifies the output
current limit value and the behavior of the power supply when the output
current is greater than or equal to that value.
See the definition of the Current Limit Behavior attribute for defined
values for the behavior parameter.
""", cls, grp, '4.3.1'))
self._add_method('outputs[].configure_range',
self._output_configure_range,
ivi.Doc("""
Configures the power supply's output range on an output. One parameter
specifies whether to configure the voltage or current range, and the other
parameter is the value to which to set the range.
Setting a voltage range can invalidate a previously configured current
range. Setting a current range can invalidate a previously configured
voltage range.
""", cls, grp, '4.3.3'))
self._add_method('outputs[].configure_ovp',
self._output_configure_ovp,
ivi.Doc("""
Configures the over-voltage protection. It specifies the over-voltage
limit and the behavior of the power supply when the output voltage is
greater than or equal to that value.
When the Enabled parameter is False, the Limit parameter does not affect
the instrument's behavior, and the driver does not set the OVP Limit
attribute.
""", cls, grp, '4.3.4'))
self._add_method('outputs[].query_current_limit_max',
self._output_query_current_limit_max,
ivi.Doc("""
This function returns the maximum programmable current limit that the
power supply accepts for a particular voltage level on an output.
""", cls, grp, '4.3.7'))
self._add_method('outputs[].query_voltage_level_max',
self._output_query_voltage_level_max,
ivi.Doc("""
This function returns the maximum programmable voltage level that the
power supply accepts for a particular current limit on an output.
""", cls, grp, '4.3.8'))
self._add_method('outputs[].query_output_state',
self._output_query_output_state,
ivi.Doc("""
This function returns whether the power supply is in a particular output
state.
A constant voltage condition occurs when the output voltage is equal to
the value of the Voltage Level attribute and the current is less than or
equal to the value of the Current Limit attribute.
A constant current condition occurs when the output current is equal to
the value of the Current Limit attribute and the Current Limit Behavior
attribute is set to the Current Regulate defined value.
An unregulated condition occurs when the output voltage is less than the
value of the Voltage Level attribute and the current is less than the
value of the Current Limit attribute.
An over-voltage condition occurs when the output voltage is equal to or
greater than the value of the OVP Limit attribute and the OVP Enabled
attribute is set to True.
An over-current condition occurs when the output current is equal to or
greater than the value of the Current Limit attribute and the Current
Limit Behavior attribute is set to the Current Trip defined value.
When either an over-voltage condition or an over-current condition
occurs, the power supply's output protection disables the output. If the
power supply is in an over-voltage or over-current state, it does not
produce power until the output protection is reset. The Reset Output
Protection function resets the output protection. Once the output
protection is reset, the power supply resumes generating a power signal.
Values for output_state:
* 'constant_voltage'
* 'constant_current'
* 'over_voltage'
* 'over_current'
* 'unregulated'
""", cls, grp, '4.3.9'))
self._add_method('outputs[].reset_output_protection',
self._output_reset_output_protection,
ivi.Doc("""
This function resets the power supply output protection after an
over-voltage or over-current condition occurs.
An over-voltage condition occurs when the output voltage is equal to or
greater than the value of the OVP Limit attribute and the OVP Enabled
attribute is set to True.
An over-current condition occurs when the output current is equal to or
greater than the value of the Current Limit attribute and the Current
Limit Behavior attribute is set to Current Trip.
When either an over-voltage condition or an over-current condition
occurs, the output protection of the power supply disables the output.
Once the output protection is reset, the power supply resumes generating
a power signal.
Use the Query Output State function to determine if the power supply is in
an over-voltage or over-current state.
""", cls, grp, '4.3.10'))
self._init_outputs()
def _init_outputs(self):
try:
super(Base, self)._init_outputs()
except AttributeError:
pass
self._output_name = list()
self._output_current_limit = list()
self._output_current_limit_behavior = list()
self._output_enabled = list()
self._output_ovp_enabled = list()
self._output_ovp_limit = list()
self._output_voltage_level = list()
for i in range(self._output_count):
self._output_name.append("output%d" % (i+1))
self._output_current_limit.append(0)
self._output_current_limit_behavior.append('regulate')
self._output_enabled.append(False)
self._output_ovp_enabled.append(True)
self._output_ovp_limit.append(0)
self._output_voltage_level.append(0)
self.outputs._set_list(self._output_name)
def _get_output_current_limit(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_current_limit[index]
def _set_output_current_limit(self, index, value):
index = ivi.get_index(self._output_name, index)
value = float(value)
if value < 0 or value > self._output_spec[index]['current_max']:
raise ivi.OutOfRangeException()
self._output_current_limit[index] = value
def _get_output_current_limit_behavior(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_current_limit_behavior[index]
def _set_output_current_limit_behavior(self, index, value):
index = ivi.get_index(self._output_name, index)
if value not in CurrentLimitBehavior:
raise ivi.ValueNotSupportedException()
self._output_current_limit_behavior[index] = value
def _get_output_enabled(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_enabled[index]
def _set_output_enabled(self, index, value):
index = ivi.get_index(self._output_name, index)
value = bool(value)
self._output_enabled[index] = value
def _get_output_ovp_enabled(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_ovp_enabled[index]
def _set_output_ovp_enabled(self, index, value):
index = ivi.get_index(self._output_name, index)
value = bool(value)
self._output_ovp_enabled[index] = value
def _get_output_ovp_limit(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_ovp_limit[index]
def _set_output_ovp_limit(self, index, value):
index = ivi.get_index(self._output_name, index)
value = float(value)
if value < 0 or value > self._output_spec[index]['ovp_max']:
raise ivi.OutOfRangeException()
self._output_ovp_limit[index] = value
def _get_output_voltage_level(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_voltage_level[index]
def _set_output_voltage_level(self, index, value):
index = ivi.get_index(self._output_name, index)
value = float(value)
if value < 0 or value > self._output_spec[index]['voltage_max']:
raise ivi.OutOfRangeException()
self._output_voltage_level[index] = value
def _get_output_name(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_name[index]
def _output_configure_current_limit(self, index, behavior, limit):
self._set_output_current_limit_behavior(index, behavior)
self._set_output_current_limit(index, limit)
def _output_configure_range(self, index, range_type, range_val):
index = ivi.get_index(self._output_name, index)
if range_type not in RangeType:
raise ivi.ValueNotSupportedException()
if range_type == 'voltage':
t = 0
elif range_type == 'current':
t = 1
k = dcpwr.get_range(self._output_range[index], t, range_val)
if k < 0:
raise ivi.OutOfRangeException()
self._output_spec[index]['voltage_max'] = self._output_range[index][k][0]
self._output_spec[index]['current_max'] = self._output_range[index][k][1]
pass
def _output_configure_ovp(self, index, enabled, limit):
self._set_output_ovp_enabled(index, enabled)
if enabled:
self._set_output_ovp_limit(index, limit)
def _output_query_current_limit_max(self, index, voltage_level):
index = ivi.get_index(self._output_name, index)
if voltage_level < 0 or voltage_level > self._output_spec[index]['voltage_max']:
raise ivi.OutOfRangeException()
return self._output_spec[index]['current_max']
def _output_query_voltage_level_max(self, index, current_limit):
index = ivi.get_index(self._output_name, index)
if current_limit < 0 or current_limit > self._output_spec[index]['current_limit_max']:
raise ivi.OutOfRangeException()
return self._output_spec[index]['voltage_max']
def _output_query_output_state(self, index, state):
index = ivi.get_index(self._output_name, index)
if state not in OutputState:
raise ivi.ValueNotSupportedException()
return False
def _output_reset_output_protection(self, index):
pass
[docs]class Trigger(ivi.IviContainer):
"Extension IVI methods for power supplies supporting trigger based output changes"
def __init__(self, *args, **kwargs):
super(Trigger, self).__init__(*args, **kwargs)
cls = 'IviDCPwr'
grp = 'Trigger'
ivi.add_group_capability(self, cls+grp)
self._output_trigger_source = list()
self._output_triggered_current_limit = list()
self._output_triggered_voltage_level = list()
self._add_property('outputs[].trigger_source',
self._get_output_trigger_source,
self._set_output_trigger_source,
None,
ivi.Doc("""
Specifies the trigger source. After an Initiate call, the power supply
waits for a trigger event from the source specified with this attribute.
After a trigger event occurs, the power supply changes the voltage level
to the value of the Triggered Voltage Level attribute and the current
limit to the value of the Triggered Current Limit attribute.
""", cls, grp, '5.2.1'))
self._add_property('outputs[].triggered_current_limit',
self._get_output_triggered_current_limit,
self._set_output_triggered_current_limit,
None,
ivi.Doc("""
Specifies the value to which the power supply sets the current limit after
a trigger event occurs. The units are Amps.
After an Initiate call, the power supply waits for a trigger event from
the source specified with the Trigger Source attribute. After a trigger
event occurs, the power supply sets the current limit to the value of this
attribute.
After a trigger occurs, the value of the Current Limit attribute reflects
the new value to which the current limit has been set.
""", cls, grp, '5.2.2'))
self._add_property('outputs[].triggered_voltage_level',
self._get_output_triggered_voltage_level,
self._set_output_triggered_voltage_level,
None,
ivi.Doc("""
Specifies the value to which the power supply sets the voltage level
after a trigger event occurs. The units are Volts.
After an Initiate call, the power supply waits for a trigger event from
the source specified with the Trigger Source attribute. After a trigger
event occurs, the power supply sets the voltage level to the value of this
attribute.
After a trigger occurs, the value of the Voltage Level attribute reflects
the new value to which the voltage level has been set.
""", cls, grp, '5.2.3'))
self._add_method('trigger.abort',
self._trigger_abort,
ivi.Doc("""
If the power supply is currently waiting for a trigger to change the
output signal, this function returns the power supply to the ignore
triggers state.
If the power supply is not waiting for a trigger, this function does
nothing and returns Success.
""", cls, grp, '5.3.1'))
self._add_method('trigger.initiate',
self._trigger_initiate,
ivi.Doc("""
If the power supply is not currently waiting for a trigger, this function
causes the power supply to wait for a trigger.
If the power supply is already waiting for a trigger, this function does
nothing and returns Success.
""", cls, grp, '5.3.5'))
def _init_outputs(self):
try:
super(Trigger, self)._init_outputs()
except AttributeError:
pass
self._output_trigger_source = list()
self._output_triggered_current_limit = list()
self._output_triggered_voltage_level = list()
for i in range(self._output_count):
self._output_trigger_source.append('')
self._output_triggered_current_limit.append(0)
self._output_triggered_voltage_level.append(0)
def _get_output_trigger_source(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_trigger_source[index]
def _set_output_trigger_source(self, index, value):
index = ivi.get_index(self._output_name, index)
value = str(value)
self._output_trigger_source[index] = value
def _get_output_triggered_current_limit(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_triggered_current_limit[index]
def _set_output_triggered_current_limit(self, index, value):
index = ivi.get_index(self._output_name, index)
value = float(value)
self._output_triggered_current_limit[index] = value
def _get_output_triggered_voltage_level(self, index):
index = ivi.get_index(self._output_name, index)
return self._output_triggered_voltage_level[index]
def _set_output_triggered_voltage_level(self, index, value):
index = ivi.get_index(self._output_name, index)
value = float(value)
self._output_triggered_voltage_level[index] = value
def _trigger_abort(self):
pass
def _trigger_initiate(self):
pass
[docs]class SoftwareTrigger(ivi.IviContainer):
"Extension IVI methods for power supplies supporting software triggering"
def __init__(self, *args, **kwargs):
super(SoftwareTrigger, self).__init__(*args, **kwargs)
cls = 'IviDCPwr'
grp = 'SoftwareTrigger'
ivi.add_group_capability(self, cls+grp)
self._add_method('send_software_trigger',
self._send_software_trigger,
ivi.Doc("""
This function sends a software-generated trigger to the instrument. It is
only applicable for instruments using interfaces or protocols which
support an explicit trigger function. For example, with GPIB this function
could send a group execute trigger to the instrument. Other
implementations might send a ``*TRG`` command.
Since instruments interpret a software-generated trigger in a wide variety
of ways, the precise response of the instrument to this trigger is not
defined. Note that SCPI details a possible implementation.
This function should not use resources which are potentially shared by
other devices (for example, the VXI trigger lines). Use of such shared
resources may have undesirable effects on other devices.
This function should not check the instrument status. Typically, the
end-user calls this function only in a sequence of calls to other
low-level driver functions. The sequence performs one operation. The
end-user uses the low-level functions to optimize one or more aspects of
interaction with the instrument. To check the instrument status, call the
appropriate error query function at the conclusion of the sequence.
The trigger source attribute must accept Software Trigger as a valid
setting for this function to work. If the trigger source is not set to
Software Trigger, this function does nothing and returns the error Trigger
Not Software.
""", cls, grp, '6.2.1', 'send_software_trigger'))
def _send_software_trigger(self):
pass
[docs]class Measurement(ivi.IviContainer):
"Extension IVI methods for power supplies supporting measurement of the output signal"
def __init__(self, *args, **kwargs):
super(Measurement, self).__init__(*args, **kwargs)
cls = 'IviDCPwr'
grp = 'Measurement'
ivi.add_group_capability(self, cls+grp)
self._add_method('outputs[].measure',
self._output_measure,
ivi.Doc("""
Takes a measurement on the output signal and returns the measured value.
Values for measurement_type:
* 'voltage'
* 'current'
""", cls, grp, '7.2.1'))
def _output_measure(self, index, type):
index = ivi.get_index(self._output_name, index)
if type not in MeasurementType:
raise ivi.ValueNotSupportedException()
return 0