1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
# -*- coding: utf-8 -*-
"""
pyvisa.ctwrapper.highlevel
~~~~~~~~~~~~~~~~~~~~~~~~~~
Highlevel wrapper of the VISA Library.
This file is part of PyVISA.
:copyright: 2014 by PyVISA Authors, see AUTHORS for more details.
:license: MIT, see LICENSE for more details.
"""
from __future__ import division, unicode_literals, print_function, absolute_import
from .. import constants, errors, highlevel, logger
from ..compat import integer_types
from . import Library
from . import functions
def add_visa_methods(aclass):
for method in functions.visa_functions:
setattr(aclass, method, getattr(functions, method))
return aclass
def _args_to_str(args):
out = []
for arg in args:
try:
# noinspection PyProtectedMember
out.append(str(arg._obj))
except Exception:
out.append(arg)
return tuple(out)
@add_visa_methods
class NIVisaLibrary(highlevel.VisaLibraryBase):
"""High level NI-VISA Library wrapper using ctypes.
The easiest way to instantiate the library is to let `pyvisa` find the
right one for you. This looks first in your configuration file (~/.pyvisarc).
If it fails, it uses `ctypes.util.find_library` to try to locate a library
in a way similar to what the compiler does:
>>> visa_library = NIVisaLibrary()
But you can also specify the path:
>>> visa_library = NIVisaLibrary('/my/path/visa.so')
:param library_path: path of the VISA library.
"""
def __new__(cls, library_path):
if library_path in cls._registry:
return cls._registry[library_path]
try:
lib = Library(library_path)
except OSError as exc:
raise errors.LibraryError.from_exception(exc, library_path)
obj = super(highlevel.VisaLibraryBase, cls).__new__(cls, library_path)
obj.lib = lib
# Set the argtypes, restype and errcheck for each function
# of the visa library. Additionally store in `_functions` the
# name of the functions.
functions.set_signatures(obj.lib, errcheck=obj._return_handler)
# Set the library functions as attributes of the object.
for method_name in getattr(obj.lib, '_functions', []):
setattr(obj, method_name, getattr(obj.lib, method_name))
return obj
def _return_handler(self, ret_value, func, arguments):
"""Check return values for errors and warnings.
"""
logger.debug('%s%s -> %r',
func.__name__, _args_to_str(arguments), ret_value,
extra=self._logging_extra)
try:
ret_value = constants.StatusCode(ret_value)
except ValueError:
pass
self._last_status = ret_value
# The first argument of almost all registered visa functions is a session.
# We store the error code per session
session = None
if func.__name__ not in ('viFindNext', ):
try:
session = arguments[0]
except KeyError:
raise Exception('Function %r does not seem to be a valid '
'visa function (len args %d)' % (func, len(arguments)))
# Functions that use the first parameter to get a session value.
if func.__name__ in ('viOpenDefaultRM', ):
# noinspection PyProtectedMember
session = session._obj.value
if isinstance(session, integer_types):
self._last_status_in_session[session] = ret_value
else:
# Functions that might or might have a session in the first argument.
if func.__name__ not in ('viClose', 'viGetAttribute', 'viSetAttribute', 'viStatusDesc'):
raise Exception('Function %r does not seem to be a valid '
'visa function (type args[0] %r)' % (func, type(session)))
if ret_value < 0:
raise errors.VisaIOError(ret_value)
if ret_value in self.issue_warning_on:
if session and ret_value not in self._ignore_warning_in_session[session]:
warnings.warn(errors.VisaIOWarning(ret_value), stacklevel=2)
return ret_value
|