项目需要对频谱仪远程操作,因此初步写了几个功能,不完善,有空继续添加
罗德频谱仪相关
"""An SignalAnalyzer class and some helper functions. NOTE: The ROHDE&SCHWARZ SignalAnalzer's port is 5025, different from Aglinet's port 5023 Only tested on Agilent N9000A CXA Signal Analyzer. Example: >>> from signalanalyzerlib import SA >>> sa = SA('192.168.1.3', 5023) # connect to the signal analyzer, using port 5023 >>> sa.getwelcome() # check if connect success 'Welcome to A-N9000A-10507' >>> sa.set_freq_cent(440, 'M') # set center freq to 440MHz True >>> # call other functions ... >>> sa.close() >>> Note: It's user's responsibility adding delay between calling these helper functions Here is a nice test: python signalanalyzerlib.py 192.168.1.3 5023 """ # # Create by zhuzhenyu @ 2012.12.27 # import sys import os try: import SOCKS; socket = SOCKS; del SOCKS except ImportError: import socket __all__ = ["SA"] __version__ = '0.1' # Line terminators (we always output CRLF, but accept any of CRLF, CR, LF) CRLF = '\r\n' # The class itself class SA: '''An Signal Analyzer connection class. To create a connection, call the class using these arguments: host, port ''' debugging = 0 host = '' port = 0 sock = None file = None welcome = None # Initialization method (called by class instantiation). def __init__(self, host='', port=0): if host: self.connect(host, port) def connect(self, host='', port=0): '''Connect to host(SA). Arguments are: - host: hostname to connect to (string) - port: port to connect to (integer)''' if host != '': self.host = host if port > 0: self.port = port self.sock = socket.create_connection((self.host, self.port)) self.file = self.sock.makefile('rb') #self.welcome = self.getresp() #return self.welcome def getwelcome(self): '''Get the welcome messgage from the analyzer. (this is read and squirreled away by connect())''' if self.debugging: print '*welcome*', repr(self.welcome) return self.welcome def set_debuglevel(self, level): '''Set the debugging level. The required argument level means: 0: no debugging output(default) 1: print commands and responses but not body text etc. 2: also print raw lines read and sent before stripping CR/LF''' self.debugging = level debug = set_debuglevel # Internal: return one line from the analyzer, stripping CRLF. # Raise EOFError if the connection is closed. def getline(self): line = self.file.readline() if self.debugging > 1: print '*get*', repr(line) if not line: raise EOFError if line[-2:] == CRLF: line = line[:-2] elif line[-1:] in CRLF: line = line[:-1] return line # Internal: get a response from the analyzer, which may possibly # consist of multiple lines. Return a single string with no # trailing CRLF. If the response consists of multiple lines, # these are separated by '\n' characters in the string def getmultiline(self): line = self.getline() if '?' in line: # query cmd contains a '?', so does the response nextline = self.getline() line = line + ('\n' + nextline) return line # Internal: get a response from the analyzer. def getresp(self): resp = self.getmultiline() if self.debugging: print '*resp*', repr(resp) return resp # Internal: send one line to the analyzer, appending CRLF def putline(self, line): line = line + CRLF if self.debugging > 1: print '*put*', repr(line) self.sock.sendall(line) # Internal: send one command to the analyzer (through putline()) def putcmd(self, line): if self.debugging: print '*cmd*', repr(line) self.putline(line) def sendcmd(self, cmd): '''Send a command and return the response.''' self.putcmd(cmd) return self.getresp() # Internal: skip 'SCPI>' prompt in the response and strip def skipprompt(self, s): if s[:6] == 'SCPI> ' or s[:6] == 'scpi> ': s = s[6:] # FIXME: Don't know why such strange bytes always in the first response if '\xff\xfb\x01\xff\xfb\x03' == s[:6]: s = s[6:] return s.strip() # Internal: get result from multiline response def extractresult(self, s): return s def voidcmd(self, cmd): '''Send a command and expect a response equal with the command.''' self.putcmd(cmd) #self.skipprompt(self.getresp()) == cmd) def resultcmd(self, cmd): '''Send a command and expect a response which is a number.''' self.putcmd(cmd) return self.extractresult(self.skipprompt(self.getresp())) def close(self): '''Close the connection without assuming anything about it.''' if self.file: self.file.close() self.sock.close() self.file = self.sock = None # Check "Agilent X-Series Signal Analyzer User's and Programmer's Reference" # for the details of the following helper functions def freq_cent(self, freq, unit='M'): cmd = 'FREQ:CENT ' + str(freq) + unit + 'Hz' self.voidcmd(cmd) def freq_span(self, span, unit='M'): cmd = 'FREQ:SPAN ' + str(span) + unit + 'Hz' self.voidcmd(cmd) def disp_wind_trac_y_rlev(self, lev): cmd = 'DISP:WIND:TRAC:Y:RLEV ' + str(lev) + 'dBm' self.voidcmd(cmd) def band(self, width, unit='K'): cmd = 'BAND ' + str(width) + unit + 'Hz' self.voidcmd(cmd) def band_vid(self, width, unit='K'): cmd = 'BAND:VID ' + str(width) + unit + 'Hz' self.voidcmd(cmd) def calc_mark_mode_pos(self): cmd = 'CALC:MARK:MODE POS' self.voidcmd(cmd) def calc_mark_max(self): cmd = 'CALC:MARK:MAX' self.voidcmd(cmd) def set_harm_num(self, num): cmd = 'CALC:MARK:FUNC:HARM:NHAR ' + str(num) self.voidcmd(cmd) def set_harm_on_off(self, switch): if switch == 'ON': cmd = 'CALC:MARK:FUNC:HARM:STAT ' + switch self.voidcmd(cmd) elif switch == 'OFF': cmd = 'CALC:MARK:FUNC:HARM:STAT ' + switch self.voidcmd(cmd) else: pass def read_harm_value(self): cmd = 'CALC:MARK:FUNC:HARM:LIST?' return self.resultcmd(cmd) def calc_mark_x(self): cmd = 'CALC:MARK:X?' return self.resultcmd(cmd) def calc_mark_y(self): cmd = 'CALC:MARK:Y?' return self.resultcmd(cmd) def calc_mark_aoff(self): cmd = 'CALC:MARK:AOFF' self.voidcmd(cmd) # TODO: add other functions here def test(): '''Test program. Usage: sa [-d] host port -d debug This test program will set the analyzer's center freq to 456MHz, set the freq span to 20MHz... and output measured freq and power. ''' import time if len(sys.argv) < 3: print test.__doc__ sys.exit(0) debugging = 0 while sys.argv[1] == '-d': debugging = debugging + 1 del sys.argv[1] host = sys.argv[1] port = sys.argv[2] sa = SA(host, port) sa.set_debuglevel(debugging) #print sa.getwelcome() sa.freq_cent(456, 'M') sa.freq_span(20, 'M') sa.disp_wind_trac_y_rlev(20) sa.band(10, 'K') sa.band_vid(10, 'K') sa.calc_mark_mode_pos() # must sleep here after calc_mark_mode_pos and calc_mark_max time.sleep(2) sa.calc_mark_max() time.sleep(5) currentfreq = sa.calc_mark_x() currentpower = sa.calc_mark_y() sa.calc_mark_aoff() sa.close() print 'Current Freq:', currentfreq print 'Current Power:', currentpower if __name__ == '__main__': test()