1a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu# Copyright (c) 2017 The Chromium OS Authors. All rights reserved. 2a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu# Use of this source code is governed by a BSD-style license that can be 3a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu# found in the LICENSE file. 4a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 5a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu"""Interface to control RF Switch. 6a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 7a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj VeluHelper module to control RF Switch. Common commands to control the relays 8a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Veluare made available as methods that can be called. 9a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 10a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj VeluPlease refer go/rf-switch for more info on the switch. 11a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu""" 12a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Veluimport contextlib 13a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Veluimport logging 14a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 15a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velufrom autotest_lib.server.cros.network.rf_switch import scpi 16a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 17a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 18a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Veluclass RfSwitchException(Exception): 19a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Exception for RfSwitch Errors.""" 20a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 21a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 22a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Veluclass RfSwitch(scpi.Scpi): 23a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """RF Switch Controller.""" 24a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 25a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _ALL_AP_RELAYS = 'k1_1:k1_24' # Each AP uses 6 relays 26a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _ALL_CLIENT_RELAYS = 'k1_25:k1_48' # Each client uses 6 relays 27a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _MIN_ENCLOSURE = 1 # Starting enclosure number 28a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _MAX_ENCLOSURE = 4 # Last enclosure number 29a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _ALL_ENCLOSURE = 0 # All the enclosures 30a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _RELAYS_PER_ENCLOSURE = 6 # Number of relays in an enclosure 31a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 32a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # Each AP enclosure uses 6 relays and a R relay to set attenuation 33a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _AP_ATTENUATOR_RELAYS = { 34a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 1: ['k1_49', 'k1_50', 'k1_51', 'k1_52', 'k1_53', 'k1_54', 'R1_9'], 35a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 2: ['k1_55', 'k1_56', 'k1_57', 'k1_58', 'k1_59', 'k1_60', 'R1_10'], 36a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 3: ['k1_61', 'k1_62', 'k1_63', 'k1_64', 'k1_65', 'k1_66', 'R1_11'], 37a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 4: ['k1_67', 'k1_68', 'k1_69', 'k1_70', 'k1_71', 'k1_72', 'R1_12'], 38a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu } 39a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # Shorter version 40a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _AP_ATTENUATOR_RELAYS_SHORT = { 41a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 1: 'k1_49:k1_54,R1_9', 42a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 2: 'k1_55:k1_60,R1_10', 43a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 3: 'k1_61:k1_66,R1_11', 44a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 4: 'k1_67:k1_72,R1_12', 45a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu } 46a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 47a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_CLOSE_RELAYS = 'ROUT:CLOS' 48a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_CHECK_RELAYS_CLOSED = 'ROUT:CLOS?' 49a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_OPEN_RELAYS = 'ROUT:OPEN' 50a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_OPEN_ALL_RELAYS = 'ROUT:OPEN:ALL' 51a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_SET_VERIFY = 'ROUT:CHAN:VER' 52a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_GET_VERIFY = 'ROUT:CHAN:VER?' 53a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_SET_VERIFY_INVERTED = 'ROUT:CHAN:VER:POL' 54a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_GET_VERIFY_INVERTED = 'ROUT:CHAN:VER:POL?' 55a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_GET_VERIFY_STATE = 'ROUT:CHAN:VER:POS:STAT?' 56a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_CHECK_BUSY = 'ROUT:MOD:BUSY?' 57a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu _CMD_WAIT = 'ROUT:MOD:WAIT' 58a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 59a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def __init__(self, host, port=scpi.Scpi.SCPI_PORT): 60a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Controller for RF Switch. 61a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 62a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param host: Hostname or IP address of RF Switch 63a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param port: Int SCPI port number (default 5025) 64a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 65a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 66a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu scpi.Scpi.__init__(self, host, port) 67a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 68a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def send_cmd_check_error(self, cmd): 69a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Send command to switch and check for any error. 70a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 71a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param cmd: string cmd to send to switch 72a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 73a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 74a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.write(cmd) 75a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu code, error = self.error_query() 76a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu if code: 77a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu raise RfSwitchException('Error on command: "%s" - code: %s,' 78a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu ' message: %s', cmd, code, error) 79a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.wait() 80a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 81a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def close_relays(self, relays): 82a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Close relays. 83a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 84a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: relays to close (, to separate and : for range) 85a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 86a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 87a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.send_cmd_check_error('%s (@%s)\n' 88a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu % (self._CMD_CLOSE_RELAYS, relays)) 89a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 90a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def relays_closed(self, relays): 91a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Get open/closed status of relays. 92a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 93a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: relays to check (, to separate and : for range) 94a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 95a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns tuple of relay status, status is true if a relay is closed. 96a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 97a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 98a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 99a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu status = self.query('%s (@%s)\n' % (self._CMD_CHECK_RELAYS_CLOSED, 100a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu relays)).strip().split(',') 101a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return tuple(bool(int(x)) for x in status) 102a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 103a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def open_relays(self, relays): 104a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Open relays. 105a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 106a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: string relays to close (, to separate and : for range) 107a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 108a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 109a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.send_cmd_check_error('%s (@%s)\n' % ( 110a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self._CMD_OPEN_RELAYS, relays)) 111a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 112a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def open_all_relays(self): 113a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Open all relays. 114a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 115a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu This will open all relays including the attenuator, which will set it 116a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu to Max. Please remember to set your attenuation to right level after 117a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu this call. 118a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 119a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 120a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.send_cmd_check_error('%s\n' % self._CMD_OPEN_ALL_RELAYS) 121a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 122a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def set_verify(self, relays, on): 123a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Configure Close? to return indicator state instead of driven state. 124a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 125a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: relays to verify (, to separate and : for range) 126a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param on: string state to verify (on(True)/off(False)) 127a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 128a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 129a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.send_cmd_check_error('%s %s,(@%s)\n' % ( 130a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self._CMD_SET_VERIFY, int(bool(on)), relays)) 131a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 132a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def get_verify(self, relays): 133a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Get the verify mode of relays. 134a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 135a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: relays to verify (, to separate and : for range) 136a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns tuple of verify mode for relays 137a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 138a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 139a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu status = self.query('%s (@%s)\n' % ( 140a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self._CMD_GET_VERIFY, relays)).strip().split(',') 141a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return tuple(bool(int(x)) for x in status) 142a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 143a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def set_verify_inverted(self, relays, inverted): 144a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Set the polarity confidence of relay to be inverted. 145a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 146a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: relays to set (, to separate and : for range) 147a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param inverted: Boolean True if INV, False for NORM 148a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 149a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 150a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.send_cmd_check_error('%s %s,(@%s)\n' % ( 151a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self._CMD_SET_VERIFY_INVERTED, 152a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 'INV' if inverted else 'NORM', relays)) 153a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 154a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def get_verify_inverted(self, relays): 155a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Get the confidence polarity. 1 is inverted, 0 is value as-is. 156a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 157a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: relays to get (, to separate and : for range) 158a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns tuple of status where 1 in inverted and 0 for value as-is 159a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 160a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 161a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu status = self.query('%s (@%s)\n' % (self._CMD_GET_VERIFY_INVERTED, 162a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu relays)).strip().split(',') 163a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return tuple(bool(int(x)) for x in status) 164a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 165a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def get_verify_state(self, relays): 166a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """If verify set get driven state, else confidence state. 167a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 168a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param relays: relays to get (, to separate and : for range) 169a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 170a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns tuple of verify status for given relays 171a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 172a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 173a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu status = self.query('%s (@%s)\n' % (self._CMD_GET_VERIFY_STATE, 174a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu relays)).strip().split(',') 175a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return tuple(bool(int(x)) for x in status) 176a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 177a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @property 178a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def busy(self): 179a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Check relays are still settling. 180a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 181a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns Boolean True if relays are settling, False if not. 182a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 183a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 184a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return bool(int(self.query('%s\n' % self._CMD_CHECK_BUSY).strip())) 185a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 186a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def wait(self): 187a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Wait for relays to debounce.""" 188a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.write('%s\n' % self._CMD_WAIT) 189a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 190a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def get_attenuation(self, ap_enclosure): 191a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Get Attenuation for an AP enclosure. 192a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 193a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu Attenuation is set by turning on/off the relays. Each relay specifies 194a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu a bit in the binary value of attenuation. Find the relay status and 195a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu build the binary value, then find the decimal value from it. 196a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 197a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param ap_enclosure: Int 1/2/3/4 (AP enclosure index) 198a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 199a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns attenuation value in int 200a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 201a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @raises ValueError: on bad ap_enclosure value 202a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 203a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 204a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu if (ap_enclosure < self._MIN_ENCLOSURE or 205a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu ap_enclosure > self._MAX_ENCLOSURE): 206a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu raise ValueError('Invalid AP enclosure number: %s.', ap_enclosure) 207a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu else: 208a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu a_status = self.relays_closed( 209a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self._AP_ATTENUATOR_RELAYS_SHORT[ap_enclosure]) 210a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu status = a_status[::-1] # reverse for Endian transform 211a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu logging.debug('attenuator status: %s', status) 212a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 213a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # build the binary value 214a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu binary = ''.join(['0' if x else '1' for x in status]) 215a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return int(binary, 2) 216a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 217a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def get_all_attenuation(self): 218a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Get attenuation value for all AP enclosures. 219a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 220a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns tuple of attenuation value for each enclosure 221a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 222a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 223a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu attenuations = [] 224a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu for x in xrange(self._MIN_ENCLOSURE, self._MAX_ENCLOSURE + 1): 225a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu attenuations.append(self.get_attenuation(x)) 226a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return tuple(attenuations) 227a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 228a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def set_attenuation(self, ap_enclosure, attenuation): 229a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Set attenuation for an AP enclosure. 230a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 231a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param ap_enclosure: Int 0,1,2,3,4 AP enclosure number. 0 for all 232a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param attenuation: Int Attenuation value to set 233a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 234a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @raises ValueError: on bad ap_enclosure value 235a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 236a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 237a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu if ap_enclosure == self._ALL_ENCLOSURE: 238a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # set attenuation on all 239a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu for x in xrange(self._MIN_ENCLOSURE, self._MAX_ENCLOSURE + 1): 240a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.set_attenuation(x, attenuation) 241a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu elif (ap_enclosure < self._MIN_ENCLOSURE or 242a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu ap_enclosure > self._MAX_ENCLOSURE): 243a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu raise ValueError('Bad AP enclosure value: %s' % ap_enclosure) 244a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu else: 245a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # convert attenuation decimal value to binary 246a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu bin_array = [int(x) for x in list('{0:07b}'.format(attenuation))] 247a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # For endian 248a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu reverse_bits = self._AP_ATTENUATOR_RELAYS[ap_enclosure][:: -1] 249a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 250a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # determine which bits should be set 251a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu relays_to_close = [ 252a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu reverse_bits[i] for i, j in enumerate(bin_array) if not j 253a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu ] 254a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 255a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # open all relay for attenuator & then close the ones we need 256a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu relays = ','.join(self._AP_ATTENUATOR_RELAYS[ap_enclosure]) 257a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.open_relays(relays) 258a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu logging.debug('Attenuator relays opened: %s', relays) 259a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu relays = ','.join(relays_to_close) 260a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.close_relays(relays) 261a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu logging.debug('Attenuator relays closed: %s', relays) 262a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 263a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def get_ap_connections(self): 264a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Get a list of AP to client connections. 265a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 266a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns tuple of dict of connections ({'AP': 1, 'Client': 1}, ...) 267a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 268a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 269a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # Get the closed status for relays connected to AP enclosures. 270a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu ap_connections = self.relays_closed(self._ALL_AP_RELAYS) 271a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 272a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # Find out the connections 273a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu connections = [] 274a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu for index, relay_num in enumerate(ap_connections): 275a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # if the relay is closed, there is a connection 276a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu if relay_num: 277a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu connection = { 278a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 'AP': (index / self._RELAYS_PER_ENCLOSURE) + 1, 279a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 'Client': (index % self._RELAYS_PER_ENCLOSURE) + 1 280a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu } 281a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu connections.append(connection) 282a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return tuple(connections) 283a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 284a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def get_client_connections(self): 285a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Get a list of AP to client connections. 286a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 287a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @returns tuple of dict of connections ({'AP': 1, 'Client': 1}, ...) 288a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 289a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 290a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # Get the closed status for relays connected to client enclosures. 291a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu c_connections = self.relays_closed(self._ALL_CLIENT_RELAYS) 292a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 293a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # Find out the connections 294a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu connections = [] 295a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu for index, relay_num in enumerate(c_connections): 296a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # if the relay is closed, there is a connection 297a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu if relay_num: 298a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu connection = { 299a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 'AP': (index % self._RELAYS_PER_ENCLOSURE) + 1, 300a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 'Client': (index / self._RELAYS_PER_ENCLOSURE) + 1 301a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu } 302a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu connections.append(connection) 303a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu return tuple(connections) 304a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 305a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu def connect_ap_client(self, ap, client): 306a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Connect AP and a Client enclosure. 307a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 308a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param ap: Int 1/2/3/4 AP enclosure index 309a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param client: Int 1/2/3/4 Client enclosure index 310a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 311a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @raises ValueError: when ap / client value is not 1/2/3/4 312a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 313a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 314a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu if (ap < self._MIN_ENCLOSURE or ap > self._MAX_ENCLOSURE): 315a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu raise ValueError( 316a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 'AP enclosure should be 1/2/3/4. Given: %s' % ap) 317a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu if (client < self._MIN_ENCLOSURE or 318a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu client > self._MAX_ENCLOSURE): 319a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu raise ValueError('Client enclosure should be 1/2/3/4. Given: %s' % 320a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu client) 321a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 322a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu # Relay index start from 0 so subtract 1 for index 323a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu relays = 'k1_%s,k1_%s' % ( 324a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu ((int(ap) - 1) * self._RELAYS_PER_ENCLOSURE) + int(client), 325a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu (((int(client) - 1) + self._MAX_ENCLOSURE) * 326a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self._RELAYS_PER_ENCLOSURE) + int(ap)) 327a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu logging.debug('Relays to close: %s', relays) 328a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu self.close_relays(relays) 329a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 330a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 331a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu@contextlib.contextmanager 332a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Veludef RfSwitchSession(host, port=scpi.Scpi.SCPI_PORT): 333a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """Start a RF Switch session and close it when done. 334a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 335a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param host: Hostname or IP address of RF Switch 336a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @param port: Int SCPI port number (default 5025) 337a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu 338a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu @yields: an instance of InteractiveSsh 339a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu """ 340a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu session = RfSwitch(host, port) 341a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu try: 342a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu yield session 343a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu finally: 344a6c1bff74027ad7698a174298c19dd3674adfef7Kamesh Raj Velu session.close() 345