1 2# Copyright 2016- The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15""" 16Class for Telnet control of Aeroflex 832X and 833X Series Attenuator Modules 17 18This class provides a wrapper to the Aeroflex attenuator modules for purposes 19of simplifying and abstracting control down to the basic necessities. It is 20not the intention of the module to expose all functionality, but to allow 21interchangeable HW to be used. 22 23See http://www.aeroflex.com/ams/weinschel/PDFILES/IM-608-Models-8320-&-8321-preliminary.pdf 24""" 25 26from vts.utils.python.controllers import attenuator 27from vts.utils.python.controllers.attenuator_lib import _tnhelper 28 29 30class AttenuatorInstrument(attenuator.AttenuatorInstrument): 31 def __init__(self, num_atten=0): 32 super().__init__(num_atten) 33 34 self._tnhelper = _tnhelper._TNHelper(tx_cmd_separator="\r\n", 35 rx_cmd_separator="\r\n", 36 prompt=">") 37 self.properties = None 38 39 def open(self, host, port=23): 40 r"""Opens a telnet connection to the desired AttenuatorInstrument and queries basic 41 information. 42 43 Parameters 44 ---------- 45 host : A valid hostname (IP address or DNS-resolvable name) to an MC-DAT attenuator 46 instrument. 47 port : An optional port number (defaults to telnet default 23) 48 """ 49 self._tnhelper.open(host, port) 50 51 # work around a bug in IO, but this is a good thing to do anyway 52 self._tnhelper.cmd("*CLS", False) 53 54 if self.num_atten == 0: 55 self.num_atten = int(self._tnhelper.cmd("RFCONFIG? CHAN")) 56 57 configstr = self._tnhelper.cmd("RFCONFIG? ATTN 1") 58 59 self.properties = dict(zip( 60 ['model', 'max_atten', 'min_step', 'unknown', 'unknown2', 'cfg_str' 61 ], configstr.split(", ", 5))) 62 63 self.max_atten = float(self.properties['max_atten']) 64 65 def is_open(self): 66 r"""This function returns the state of the telnet connection to the underlying 67 AttenuatorInstrument. 68 69 Returns 70 ------- 71 Bool 72 True if there is a successfully open connection to the AttenuatorInstrument 73 """ 74 75 return bool(self._tnhelper.is_open()) 76 77 def close(self): 78 r"""Closes a telnet connection to the desired AttenuatorInstrument. 79 80 This should be called as part of any teardown procedure prior to the attenuator 81 instrument leaving scope. 82 """ 83 84 self._tnhelper.close() 85 86 def set_atten(self, idx, value): 87 r"""This function sets the attenuation of an attenuator given its index in the instrument. 88 89 Parameters 90 ---------- 91 idx : This zero-based index is the identifier for a particular attenuator in an 92 instrument. 93 value : This is a floating point value for nominal attenuation to be set. 94 95 Raises 96 ------ 97 InvalidOperationError 98 This error occurs if the underlying telnet connection to the instrument is not open. 99 IndexError 100 If the index of the attenuator is greater than the maximum index of the underlying 101 instrument, this error will be thrown. Do not count on this check programmatically. 102 ValueError 103 If the requested set value is greater than the maximum attenuation value, this error 104 will be thrown. Do not count on this check programmatically. 105 """ 106 107 if not self.is_open(): 108 raise attenuator.InvalidOperationError("Connection not open!") 109 110 if idx >= self.num_atten: 111 raise IndexError("Attenuator index out of range!", self.num_atten, 112 idx) 113 114 if value > self.max_atten: 115 raise ValueError("Attenuator value out of range!", self.max_atten, 116 value) 117 118 self._tnhelper.cmd("ATTN " + str(idx + 1) + " " + str(value), False) 119 120 def get_atten(self, idx): 121 r"""This function returns the current attenuation from an attenuator at a given index in 122 the instrument. 123 124 Parameters 125 ---------- 126 idx : This zero-based index is the identifier for a particular attenuator in an instrument. 127 128 Raises 129 ------ 130 InvalidOperationError 131 This error occurs if the underlying telnet connection to the instrument is not open. 132 133 Returns 134 ------- 135 float 136 Returns a the current attenuation value 137 """ 138 if not self.is_open(): 139 raise attenuator.InvalidOperationError("Connection not open!") 140 141# Potentially redundant safety check removed for the moment 142# if idx >= self.num_atten: 143# raise IndexError("Attenuator index out of range!", self.num_atten, idx) 144 145 atten_val = self._tnhelper.cmd("ATTN? " + str(idx + 1)) 146 147 return float(atten_val) 148