1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python 2*cfb92d14SAndroid Build Coastguard Worker# 3*cfb92d14SAndroid Build Coastguard Worker# Copyright (c) 2016, The OpenThread Authors. 4*cfb92d14SAndroid Build Coastguard Worker# All rights reserved. 5*cfb92d14SAndroid Build Coastguard Worker# 6*cfb92d14SAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without 7*cfb92d14SAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions are met: 8*cfb92d14SAndroid Build Coastguard Worker# 1. Redistributions of source code must retain the above copyright 9*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer. 10*cfb92d14SAndroid Build Coastguard Worker# 2. Redistributions in binary form must reproduce the above copyright 11*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer in the 12*cfb92d14SAndroid Build Coastguard Worker# documentation and/or other materials provided with the distribution. 13*cfb92d14SAndroid Build Coastguard Worker# 3. Neither the name of the copyright holder nor the 14*cfb92d14SAndroid Build Coastguard Worker# names of its contributors may be used to endorse or promote products 15*cfb92d14SAndroid Build Coastguard Worker# derived from this software without specific prior written permission. 16*cfb92d14SAndroid Build Coastguard Worker# 17*cfb92d14SAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18*cfb92d14SAndroid Build Coastguard Worker# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*cfb92d14SAndroid Build Coastguard Worker# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*cfb92d14SAndroid Build Coastguard Worker# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21*cfb92d14SAndroid Build Coastguard Worker# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22*cfb92d14SAndroid Build Coastguard Worker# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23*cfb92d14SAndroid Build Coastguard Worker# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*cfb92d14SAndroid Build Coastguard Worker# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25*cfb92d14SAndroid Build Coastguard Worker# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26*cfb92d14SAndroid Build Coastguard Worker# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27*cfb92d14SAndroid Build Coastguard Worker# POSSIBILITY OF SUCH DAMAGE. 28*cfb92d14SAndroid Build Coastguard Worker# 29*cfb92d14SAndroid Build Coastguard Worker 30*cfb92d14SAndroid Build Coastguard Workerimport logging 31*cfb92d14SAndroid Build Coastguard Workerimport os 32*cfb92d14SAndroid Build Coastguard Workerimport re 33*cfb92d14SAndroid Build Coastguard Workerimport telnetlib 34*cfb92d14SAndroid Build Coastguard Workerimport time 35*cfb92d14SAndroid Build Coastguard Worker 36*cfb92d14SAndroid Build Coastguard Workertry: 37*cfb92d14SAndroid Build Coastguard Worker # python 2 38*cfb92d14SAndroid Build Coastguard Worker from urllib2 import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener 39*cfb92d14SAndroid Build Coastguard Workerexcept ImportError: 40*cfb92d14SAndroid Build Coastguard Worker # python 3 41*cfb92d14SAndroid Build Coastguard Worker from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener 42*cfb92d14SAndroid Build Coastguard Worker 43*cfb92d14SAndroid Build Coastguard Workerlogger = logging.getLogger(__name__) 44*cfb92d14SAndroid Build Coastguard Worker 45*cfb92d14SAndroid Build Coastguard Workertry: 46*cfb92d14SAndroid Build Coastguard Worker from pysnmp.hlapi import SnmpEngine, CommunityData, UdpTransportTarget, ContextData, getCmd, setCmd, ObjectType, ObjectIdentity, Integer32 47*cfb92d14SAndroid Build Coastguard Workerexcept ImportError: 48*cfb92d14SAndroid Build Coastguard Worker logger.warning('PySNMP module is not installed. Install if EATON_PDU_CONTROLLER is used') 49*cfb92d14SAndroid Build Coastguard Worker 50*cfb92d14SAndroid Build Coastguard Worker 51*cfb92d14SAndroid Build Coastguard Workerclass PduController(object): 52*cfb92d14SAndroid Build Coastguard Worker 53*cfb92d14SAndroid Build Coastguard Worker def open(self, **params): 54*cfb92d14SAndroid Build Coastguard Worker """Open PDU controller connection""" 55*cfb92d14SAndroid Build Coastguard Worker raise NotImplementedError 56*cfb92d14SAndroid Build Coastguard Worker 57*cfb92d14SAndroid Build Coastguard Worker def reboot(self, **params): 58*cfb92d14SAndroid Build Coastguard Worker """Reboot an outlet or a board passed as params""" 59*cfb92d14SAndroid Build Coastguard Worker raise NotImplementedError 60*cfb92d14SAndroid Build Coastguard Worker 61*cfb92d14SAndroid Build Coastguard Worker def close(self): 62*cfb92d14SAndroid Build Coastguard Worker """Close PDU controller connection""" 63*cfb92d14SAndroid Build Coastguard Worker raise NotImplementedError 64*cfb92d14SAndroid Build Coastguard Worker 65*cfb92d14SAndroid Build Coastguard Worker 66*cfb92d14SAndroid Build Coastguard Workerclass DummyPduController(PduController): 67*cfb92d14SAndroid Build Coastguard Worker """Dummy implementation which only says that PDU controller is not connected""" 68*cfb92d14SAndroid Build Coastguard Worker 69*cfb92d14SAndroid Build Coastguard Worker def open(self, **params): 70*cfb92d14SAndroid Build Coastguard Worker pass 71*cfb92d14SAndroid Build Coastguard Worker 72*cfb92d14SAndroid Build Coastguard Worker def reboot(self, **params): 73*cfb92d14SAndroid Build Coastguard Worker logger.info('No PDU controller connected.') 74*cfb92d14SAndroid Build Coastguard Worker 75*cfb92d14SAndroid Build Coastguard Worker def close(self): 76*cfb92d14SAndroid Build Coastguard Worker pass 77*cfb92d14SAndroid Build Coastguard Worker 78*cfb92d14SAndroid Build Coastguard Worker 79*cfb92d14SAndroid Build Coastguard Workerclass ApcPduController(PduController): 80*cfb92d14SAndroid Build Coastguard Worker 81*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 82*cfb92d14SAndroid Build Coastguard Worker self.tn = None 83*cfb92d14SAndroid Build Coastguard Worker 84*cfb92d14SAndroid Build Coastguard Worker def __del__(self): 85*cfb92d14SAndroid Build Coastguard Worker self.close() 86*cfb92d14SAndroid Build Coastguard Worker 87*cfb92d14SAndroid Build Coastguard Worker def _init(self): 88*cfb92d14SAndroid Build Coastguard Worker """Initialize the telnet connection 89*cfb92d14SAndroid Build Coastguard Worker """ 90*cfb92d14SAndroid Build Coastguard Worker self.tn = telnetlib.Telnet(self.ip, self.port) 91*cfb92d14SAndroid Build Coastguard Worker self.tn.read_until('User Name') 92*cfb92d14SAndroid Build Coastguard Worker self.tn.write('apc\r\n') 93*cfb92d14SAndroid Build Coastguard Worker self.tn.read_until('Password') 94*cfb92d14SAndroid Build Coastguard Worker self.tn.write('apc\r\n') 95*cfb92d14SAndroid Build Coastguard Worker self.until_done() 96*cfb92d14SAndroid Build Coastguard Worker 97*cfb92d14SAndroid Build Coastguard Worker def open(self, **params): 98*cfb92d14SAndroid Build Coastguard Worker """Open telnet connection 99*cfb92d14SAndroid Build Coastguard Worker 100*cfb92d14SAndroid Build Coastguard Worker Args: 101*cfb92d14SAndroid Build Coastguard Worker params (dict), must contain two parameters "ip" - ip address or hostname and "port" - port number 102*cfb92d14SAndroid Build Coastguard Worker 103*cfb92d14SAndroid Build Coastguard Worker Example: 104*cfb92d14SAndroid Build Coastguard Worker params = {'port': 23, 'ip': 'localhost'} 105*cfb92d14SAndroid Build Coastguard Worker """ 106*cfb92d14SAndroid Build Coastguard Worker logger.info('opening telnet') 107*cfb92d14SAndroid Build Coastguard Worker self.port = params['port'] 108*cfb92d14SAndroid Build Coastguard Worker self.ip = params['ip'] 109*cfb92d14SAndroid Build Coastguard Worker self.tn = None 110*cfb92d14SAndroid Build Coastguard Worker self._init() 111*cfb92d14SAndroid Build Coastguard Worker 112*cfb92d14SAndroid Build Coastguard Worker def close(self): 113*cfb92d14SAndroid Build Coastguard Worker """Close telnet connection""" 114*cfb92d14SAndroid Build Coastguard Worker logger.info('closing telnet') 115*cfb92d14SAndroid Build Coastguard Worker if self.tn: 116*cfb92d14SAndroid Build Coastguard Worker self.tn.close() 117*cfb92d14SAndroid Build Coastguard Worker 118*cfb92d14SAndroid Build Coastguard Worker def until_done(self): 119*cfb92d14SAndroid Build Coastguard Worker """Wait until the prompt encountered 120*cfb92d14SAndroid Build Coastguard Worker """ 121*cfb92d14SAndroid Build Coastguard Worker self.until(r'^>') 122*cfb92d14SAndroid Build Coastguard Worker 123*cfb92d14SAndroid Build Coastguard Worker def until(self, regex): 124*cfb92d14SAndroid Build Coastguard Worker """Wait until the regex encountered 125*cfb92d14SAndroid Build Coastguard Worker """ 126*cfb92d14SAndroid Build Coastguard Worker logger.debug('waiting for %s', regex) 127*cfb92d14SAndroid Build Coastguard Worker r = re.compile(regex, re.M) 128*cfb92d14SAndroid Build Coastguard Worker self.tn.expect([r]) 129*cfb92d14SAndroid Build Coastguard Worker 130*cfb92d14SAndroid Build Coastguard Worker def reboot(self, **params): 131*cfb92d14SAndroid Build Coastguard Worker """Reboot outlet 132*cfb92d14SAndroid Build Coastguard Worker 133*cfb92d14SAndroid Build Coastguard Worker Args: 134*cfb92d14SAndroid Build Coastguard Worker params (dict), must contain parameter "outlet" - outlet number 135*cfb92d14SAndroid Build Coastguard Worker 136*cfb92d14SAndroid Build Coastguard Worker Example: 137*cfb92d14SAndroid Build Coastguard Worker params = {'outlet': 1} 138*cfb92d14SAndroid Build Coastguard Worker """ 139*cfb92d14SAndroid Build Coastguard Worker outlet = params['outlet'] 140*cfb92d14SAndroid Build Coastguard Worker 141*cfb92d14SAndroid Build Coastguard Worker # main menu 142*cfb92d14SAndroid Build Coastguard Worker self.tn.write('\x1b\r\n') 143*cfb92d14SAndroid Build Coastguard Worker self.until_done() 144*cfb92d14SAndroid Build Coastguard Worker # Device Manager 145*cfb92d14SAndroid Build Coastguard Worker self.tn.write('1\r\n') 146*cfb92d14SAndroid Build Coastguard Worker self.until_done() 147*cfb92d14SAndroid Build Coastguard Worker # Outlet Management 148*cfb92d14SAndroid Build Coastguard Worker self.tn.write('2\r\n') 149*cfb92d14SAndroid Build Coastguard Worker self.until_done() 150*cfb92d14SAndroid Build Coastguard Worker # Outlet Control 151*cfb92d14SAndroid Build Coastguard Worker self.tn.write('1\r\n') 152*cfb92d14SAndroid Build Coastguard Worker self.until_done() 153*cfb92d14SAndroid Build Coastguard Worker # Select outlet 154*cfb92d14SAndroid Build Coastguard Worker self.tn.write('%d\r\n' % outlet) 155*cfb92d14SAndroid Build Coastguard Worker self.until_done() 156*cfb92d14SAndroid Build Coastguard Worker # Control 157*cfb92d14SAndroid Build Coastguard Worker self.tn.write('1\r\n') 158*cfb92d14SAndroid Build Coastguard Worker self.until_done() 159*cfb92d14SAndroid Build Coastguard Worker # off 160*cfb92d14SAndroid Build Coastguard Worker self.tn.write('2\r\n') 161*cfb92d14SAndroid Build Coastguard Worker self.until('to cancel') 162*cfb92d14SAndroid Build Coastguard Worker self.tn.write('YES\r\n') 163*cfb92d14SAndroid Build Coastguard Worker self.until('to continue') 164*cfb92d14SAndroid Build Coastguard Worker self.tn.write('\r\n') 165*cfb92d14SAndroid Build Coastguard Worker self.until_done() 166*cfb92d14SAndroid Build Coastguard Worker 167*cfb92d14SAndroid Build Coastguard Worker time.sleep(5) 168*cfb92d14SAndroid Build Coastguard Worker # on 169*cfb92d14SAndroid Build Coastguard Worker self.tn.write('1\r\n') 170*cfb92d14SAndroid Build Coastguard Worker self.until('to cancel') 171*cfb92d14SAndroid Build Coastguard Worker self.tn.write('YES\r\n') 172*cfb92d14SAndroid Build Coastguard Worker self.until('to continue') 173*cfb92d14SAndroid Build Coastguard Worker self.tn.write('\r\n') 174*cfb92d14SAndroid Build Coastguard Worker self.until_done() 175*cfb92d14SAndroid Build Coastguard Worker 176*cfb92d14SAndroid Build Coastguard Worker 177*cfb92d14SAndroid Build Coastguard Workerclass NordicBoardPduController(PduController): 178*cfb92d14SAndroid Build Coastguard Worker 179*cfb92d14SAndroid Build Coastguard Worker def open(self, **params): 180*cfb92d14SAndroid Build Coastguard Worker pass 181*cfb92d14SAndroid Build Coastguard Worker 182*cfb92d14SAndroid Build Coastguard Worker def _pin_reset(self, serial_number): 183*cfb92d14SAndroid Build Coastguard Worker os.system('nrfjprog -f NRF52 --snr {} -p'.format(serial_number)) 184*cfb92d14SAndroid Build Coastguard Worker 185*cfb92d14SAndroid Build Coastguard Worker def reboot(self, **params): 186*cfb92d14SAndroid Build Coastguard Worker boards_serial_numbers = params['boards_serial_numbers'] 187*cfb92d14SAndroid Build Coastguard Worker 188*cfb92d14SAndroid Build Coastguard Worker for serial_number in boards_serial_numbers: 189*cfb92d14SAndroid Build Coastguard Worker logger.info('Resetting board with the serial number: %s', serial_number) 190*cfb92d14SAndroid Build Coastguard Worker self._pin_reset(serial_number) 191*cfb92d14SAndroid Build Coastguard Worker 192*cfb92d14SAndroid Build Coastguard Worker def close(self): 193*cfb92d14SAndroid Build Coastguard Worker pass 194*cfb92d14SAndroid Build Coastguard Worker 195*cfb92d14SAndroid Build Coastguard Worker 196*cfb92d14SAndroid Build Coastguard Workerclass EatonPduController(PduController): 197*cfb92d14SAndroid Build Coastguard Worker 198*cfb92d14SAndroid Build Coastguard Worker outlet_oid_cmd_get_state_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.2.0.' 199*cfb92d14SAndroid Build Coastguard Worker outlet_oid_cmd_set_on_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.4.0.' 200*cfb92d14SAndroid Build Coastguard Worker outlet_oid_cmd_set_off_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.3.0.' 201*cfb92d14SAndroid Build Coastguard Worker outlet_oid_cmd_reboot_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.5.0.' 202*cfb92d14SAndroid Build Coastguard Worker outlet_oid_cmd_set_reboot_delay_seconds_base = '1.3.6.1.4.1.534.6.6.7.6.6.1.8.0.' 203*cfb92d14SAndroid Build Coastguard Worker 204*cfb92d14SAndroid Build Coastguard Worker PDU_COMMAND_TIMEOUT = 5 205*cfb92d14SAndroid Build Coastguard Worker 206*cfb92d14SAndroid Build Coastguard Worker def open(self, **params): 207*cfb92d14SAndroid Build Coastguard Worker missing_fields = ['ip', 'port'] 208*cfb92d14SAndroid Build Coastguard Worker missing_fields = [field for field in missing_fields if field not in params.keys()] 209*cfb92d14SAndroid Build Coastguard Worker if missing_fields: 210*cfb92d14SAndroid Build Coastguard Worker raise KeyError('Missing keys in PDU params: {}'.format(missing_fields)) 211*cfb92d14SAndroid Build Coastguard Worker self.params = params 212*cfb92d14SAndroid Build Coastguard Worker self.type = 'pdu' 213*cfb92d14SAndroid Build Coastguard Worker self.ip = self.params['ip'] 214*cfb92d14SAndroid Build Coastguard Worker self.snmp_agent_port = int(self.params['port']) 215*cfb92d14SAndroid Build Coastguard Worker self._community = 'public' 216*cfb92d14SAndroid Build Coastguard Worker self._snmp_engine = SnmpEngine() 217*cfb92d14SAndroid Build Coastguard Worker self._community_data = CommunityData(self._community, mpModel=0) 218*cfb92d14SAndroid Build Coastguard Worker self._udp_transport_target = UdpTransportTarget((self.ip, self.snmp_agent_port)) 219*cfb92d14SAndroid Build Coastguard Worker self._context = ContextData() 220*cfb92d14SAndroid Build Coastguard Worker 221*cfb92d14SAndroid Build Coastguard Worker def _outlet_oid_get(self, param, socket): 222*cfb92d14SAndroid Build Coastguard Worker """ 223*cfb92d14SAndroid Build Coastguard Worker Translates command to the OID number representing a command for the specific power socket. 224*cfb92d14SAndroid Build Coastguard Worker 225*cfb92d14SAndroid Build Coastguard Worker Args: 226*cfb92d14SAndroid Build Coastguard Worker param (str), command string 227*cfb92d14SAndroid Build Coastguard Worker socket (int), socket index 228*cfb92d14SAndroid Build Coastguard Worker 229*cfb92d14SAndroid Build Coastguard Worker Return: 230*cfb92d14SAndroid Build Coastguard Worker full OID identifying the SNMP object (str) 231*cfb92d14SAndroid Build Coastguard Worker """ 232*cfb92d14SAndroid Build Coastguard Worker parameters = { 233*cfb92d14SAndroid Build Coastguard Worker 'get_state': self.outlet_oid_cmd_get_state_base, 234*cfb92d14SAndroid Build Coastguard Worker 'set_on': self.outlet_oid_cmd_set_on_base, 235*cfb92d14SAndroid Build Coastguard Worker 'set_off': self.outlet_oid_cmd_set_off_base, 236*cfb92d14SAndroid Build Coastguard Worker 'set_reboot_delay': self.outlet_oid_cmd_set_reboot_delay_seconds_base, 237*cfb92d14SAndroid Build Coastguard Worker 'reboot': self.outlet_oid_cmd_reboot_base 238*cfb92d14SAndroid Build Coastguard Worker } 239*cfb92d14SAndroid Build Coastguard Worker 240*cfb92d14SAndroid Build Coastguard Worker return parameters[param.lower()] + str(socket) 241*cfb92d14SAndroid Build Coastguard Worker 242*cfb92d14SAndroid Build Coastguard Worker # Performs set command to specific OID with a given value by sending a SNMP Set message. 243*cfb92d14SAndroid Build Coastguard Worker def _oid_set(self, oid, value): 244*cfb92d14SAndroid Build Coastguard Worker """ 245*cfb92d14SAndroid Build Coastguard Worker Performs set command to specific OID with a given value by sending a SNMP Set message. 246*cfb92d14SAndroid Build Coastguard Worker 247*cfb92d14SAndroid Build Coastguard Worker Args: 248*cfb92d14SAndroid Build Coastguard Worker oid (str): Full OID identifying the object to be read. 249*cfb92d14SAndroid Build Coastguard Worker value (int): Value to be written to the OID as Integer32. 250*cfb92d14SAndroid Build Coastguard Worker """ 251*cfb92d14SAndroid Build Coastguard Worker errorIndication, errorStatus, errorIndex, varBinds = next( 252*cfb92d14SAndroid Build Coastguard Worker setCmd(self._snmp_engine, self._community_data, self._udp_transport_target, self._context, 253*cfb92d14SAndroid Build Coastguard Worker ObjectType(ObjectIdentity(oid), Integer32(value)))) 254*cfb92d14SAndroid Build Coastguard Worker 255*cfb92d14SAndroid Build Coastguard Worker if errorIndication: 256*cfb92d14SAndroid Build Coastguard Worker msg = 'Found PDU errorIndication: {}'.format(errorIndication) 257*cfb92d14SAndroid Build Coastguard Worker logger.exception(msg) 258*cfb92d14SAndroid Build Coastguard Worker raise RuntimeError(msg) 259*cfb92d14SAndroid Build Coastguard Worker elif errorStatus: 260*cfb92d14SAndroid Build Coastguard Worker msg = 'Found PDU errorStatus: {}'.format(errorStatus) 261*cfb92d14SAndroid Build Coastguard Worker logger.exception(msg) 262*cfb92d14SAndroid Build Coastguard Worker raise RuntimeError(msg) 263*cfb92d14SAndroid Build Coastguard Worker 264*cfb92d14SAndroid Build Coastguard Worker def _oid_get(self, oid): 265*cfb92d14SAndroid Build Coastguard Worker """ 266*cfb92d14SAndroid Build Coastguard Worker Performs SNMP get command and returns OID value by sending a SNMP Get message. 267*cfb92d14SAndroid Build Coastguard Worker 268*cfb92d14SAndroid Build Coastguard Worker Args: 269*cfb92d14SAndroid Build Coastguard Worker oid (str): Full OID identifying the object to be read. 270*cfb92d14SAndroid Build Coastguard Worker 271*cfb92d14SAndroid Build Coastguard Worker Return: 272*cfb92d14SAndroid Build Coastguard Worker OID value (int) 273*cfb92d14SAndroid Build Coastguard Worker """ 274*cfb92d14SAndroid Build Coastguard Worker errorIndication, errorStatus, errorIndex, varBinds = next( 275*cfb92d14SAndroid Build Coastguard Worker getCmd(self._snmp_engine, self._community_data, self._udp_transport_target, self._context, 276*cfb92d14SAndroid Build Coastguard Worker ObjectType(ObjectIdentity(oid)))) 277*cfb92d14SAndroid Build Coastguard Worker 278*cfb92d14SAndroid Build Coastguard Worker if errorIndication: 279*cfb92d14SAndroid Build Coastguard Worker msg = 'Found PDU errorIndication: {}'.format(errorIndication) 280*cfb92d14SAndroid Build Coastguard Worker logger.exception(msg) 281*cfb92d14SAndroid Build Coastguard Worker raise RuntimeError(msg) 282*cfb92d14SAndroid Build Coastguard Worker elif errorStatus: 283*cfb92d14SAndroid Build Coastguard Worker msg = 'Found PDU errorStatus: {}'.format(errorStatus) 284*cfb92d14SAndroid Build Coastguard Worker logger.exception(msg) 285*cfb92d14SAndroid Build Coastguard Worker raise RuntimeError(msg) 286*cfb92d14SAndroid Build Coastguard Worker 287*cfb92d14SAndroid Build Coastguard Worker return int(str(varBinds[-1]).partition('= ')[-1]) 288*cfb92d14SAndroid Build Coastguard Worker 289*cfb92d14SAndroid Build Coastguard Worker def _outlet_value_set(self, cmd, socket, value=1): 290*cfb92d14SAndroid Build Coastguard Worker """ 291*cfb92d14SAndroid Build Coastguard Worker Sets outlet parameter value. 292*cfb92d14SAndroid Build Coastguard Worker 293*cfb92d14SAndroid Build Coastguard Worker Args: 294*cfb92d14SAndroid Build Coastguard Worker cmd (str): OID base 295*cfb92d14SAndroid Build Coastguard Worker socket (int): socket index (last OID number) 296*cfb92d14SAndroid Build Coastguard Worker value (int): value to be set 297*cfb92d14SAndroid Build Coastguard Worker """ 298*cfb92d14SAndroid Build Coastguard Worker oid = self._outlet_oid_get(cmd, socket) 299*cfb92d14SAndroid Build Coastguard Worker 300*cfb92d14SAndroid Build Coastguard Worker # Values other than 1 does not make sense with commands other than "set_reboot_delay". 301*cfb92d14SAndroid Build Coastguard Worker if cmd != 'set_reboot_delay': 302*cfb92d14SAndroid Build Coastguard Worker value = 1 303*cfb92d14SAndroid Build Coastguard Worker 304*cfb92d14SAndroid Build Coastguard Worker self._oid_set(oid, value) 305*cfb92d14SAndroid Build Coastguard Worker 306*cfb92d14SAndroid Build Coastguard Worker def _outlet_value_get(self, cmd, socket): 307*cfb92d14SAndroid Build Coastguard Worker """ 308*cfb92d14SAndroid Build Coastguard Worker Read outlet parameter value. 309*cfb92d14SAndroid Build Coastguard Worker 310*cfb92d14SAndroid Build Coastguard Worker Args: 311*cfb92d14SAndroid Build Coastguard Worker cmd (str): OID base 312*cfb92d14SAndroid Build Coastguard Worker socket (int): socket index (last OID number) 313*cfb92d14SAndroid Build Coastguard Worker 314*cfb92d14SAndroid Build Coastguard Worker Return: 315*cfb92d14SAndroid Build Coastguard Worker parameter value (int) 316*cfb92d14SAndroid Build Coastguard Worker """ 317*cfb92d14SAndroid Build Coastguard Worker oid = self._outlet_oid_get(cmd, socket) 318*cfb92d14SAndroid Build Coastguard Worker 319*cfb92d14SAndroid Build Coastguard Worker return self._oid_get(oid) 320*cfb92d14SAndroid Build Coastguard Worker 321*cfb92d14SAndroid Build Coastguard Worker def validate_state(self, socket, state): 322*cfb92d14SAndroid Build Coastguard Worker return (self._outlet_value_get('get_state', socket) == state) 323*cfb92d14SAndroid Build Coastguard Worker 324*cfb92d14SAndroid Build Coastguard Worker def turn_off(self, sockets): 325*cfb92d14SAndroid Build Coastguard Worker """ 326*cfb92d14SAndroid Build Coastguard Worker Turns the specified socket off. 327*cfb92d14SAndroid Build Coastguard Worker 328*cfb92d14SAndroid Build Coastguard Worker Args: 329*cfb92d14SAndroid Build Coastguard Worker sockets (list(int)): sockets to be turned off 330*cfb92d14SAndroid Build Coastguard Worker """ 331*cfb92d14SAndroid Build Coastguard Worker logger.info('Executing turn OFF for: {}'.format(sockets)) 332*cfb92d14SAndroid Build Coastguard Worker 333*cfb92d14SAndroid Build Coastguard Worker for socket in sockets: 334*cfb92d14SAndroid Build Coastguard Worker self._outlet_value_set('set_off', socket) 335*cfb92d14SAndroid Build Coastguard Worker time.sleep(2) 336*cfb92d14SAndroid Build Coastguard Worker 337*cfb92d14SAndroid Build Coastguard Worker timeout = time.time() + self.PDU_COMMAND_TIMEOUT 338*cfb92d14SAndroid Build Coastguard Worker while ((time.time() < timeout) and not self.validate_state(socket, 0)): 339*cfb92d14SAndroid Build Coastguard Worker time.sleep(0.1) 340*cfb92d14SAndroid Build Coastguard Worker 341*cfb92d14SAndroid Build Coastguard Worker if self.validate_state(socket, 0): 342*cfb92d14SAndroid Build Coastguard Worker logger.debug('Turned OFF socket {} at {}'.format(socket, self.ip)) 343*cfb92d14SAndroid Build Coastguard Worker else: 344*cfb92d14SAndroid Build Coastguard Worker logger.error('Failed to turn OFF socket {} at {}'.format(socket, self.ip)) 345*cfb92d14SAndroid Build Coastguard Worker 346*cfb92d14SAndroid Build Coastguard Worker def turn_on(self, sockets): 347*cfb92d14SAndroid Build Coastguard Worker """ 348*cfb92d14SAndroid Build Coastguard Worker Turns the specified socket on. 349*cfb92d14SAndroid Build Coastguard Worker 350*cfb92d14SAndroid Build Coastguard Worker Args: 351*cfb92d14SAndroid Build Coastguard Worker sockets (list(int)): sockets to be turned on 352*cfb92d14SAndroid Build Coastguard Worker """ 353*cfb92d14SAndroid Build Coastguard Worker 354*cfb92d14SAndroid Build Coastguard Worker logger.info('Executing turn ON for: {}'.format(sockets)) 355*cfb92d14SAndroid Build Coastguard Worker 356*cfb92d14SAndroid Build Coastguard Worker for socket in sockets: 357*cfb92d14SAndroid Build Coastguard Worker self._outlet_value_set('set_on', socket) 358*cfb92d14SAndroid Build Coastguard Worker time.sleep(2) 359*cfb92d14SAndroid Build Coastguard Worker 360*cfb92d14SAndroid Build Coastguard Worker timeout = time.time() + self.PDU_COMMAND_TIMEOUT 361*cfb92d14SAndroid Build Coastguard Worker while ((time.time() < timeout) and not self.validate_state(socket, 1)): 362*cfb92d14SAndroid Build Coastguard Worker time.sleep(0.1) 363*cfb92d14SAndroid Build Coastguard Worker 364*cfb92d14SAndroid Build Coastguard Worker if self.validate_state(socket, 1): 365*cfb92d14SAndroid Build Coastguard Worker logger.debug('Turned ON socket {} at {}'.format(socket, self.ip)) 366*cfb92d14SAndroid Build Coastguard Worker else: 367*cfb92d14SAndroid Build Coastguard Worker logger.error('Failed to turn ON socket {} at {}'.format(socket, self.ip)) 368*cfb92d14SAndroid Build Coastguard Worker 369*cfb92d14SAndroid Build Coastguard Worker def close(self): 370*cfb92d14SAndroid Build Coastguard Worker self._community = None 371*cfb92d14SAndroid Build Coastguard Worker self._snmp_engine = None 372*cfb92d14SAndroid Build Coastguard Worker self._community_data = None 373*cfb92d14SAndroid Build Coastguard Worker self._udp_transport_target = None 374*cfb92d14SAndroid Build Coastguard Worker self._context = None 375*cfb92d14SAndroid Build Coastguard Worker 376*cfb92d14SAndroid Build Coastguard Worker def reboot(self, **params): 377*cfb92d14SAndroid Build Coastguard Worker """ 378*cfb92d14SAndroid Build Coastguard Worker Reboots the sockets specified in the constructor with off and on delays. 379*cfb92d14SAndroid Build Coastguard Worker 380*cfb92d14SAndroid Build Coastguard Worker Args: 381*cfb92d14SAndroid Build Coastguard Worker sockets (list(int)): sockets to reboot 382*cfb92d14SAndroid Build Coastguard Worker """ 383*cfb92d14SAndroid Build Coastguard Worker 384*cfb92d14SAndroid Build Coastguard Worker logger.info('Executing power cycle for: {}'.format(params['sockets'])) 385*cfb92d14SAndroid Build Coastguard Worker self.turn_off(params['sockets']) 386*cfb92d14SAndroid Build Coastguard Worker time.sleep(10) 387*cfb92d14SAndroid Build Coastguard Worker self.turn_on(params['sockets']) 388*cfb92d14SAndroid Build Coastguard Worker time.sleep(5) 389*cfb92d14SAndroid Build Coastguard Worker 390*cfb92d14SAndroid Build Coastguard Worker 391*cfb92d14SAndroid Build Coastguard Workerclass IpPowerSocketPduController(PduController): 392*cfb92d14SAndroid Build Coastguard Worker 393*cfb92d14SAndroid Build Coastguard Worker def open(self, **params): 394*cfb92d14SAndroid Build Coastguard Worker self._base_url = 'http://{}/outs.cgi?out'.format(params['ip']) 395*cfb92d14SAndroid Build Coastguard Worker password_manager = HTTPPasswordMgrWithDefaultRealm() 396*cfb92d14SAndroid Build Coastguard Worker password_manager.add_password(None, self._base_url, params['user'], params['pass']) 397*cfb92d14SAndroid Build Coastguard Worker authentication_handler = HTTPBasicAuthHandler(password_manager) 398*cfb92d14SAndroid Build Coastguard Worker self._opener = build_opener(authentication_handler) 399*cfb92d14SAndroid Build Coastguard Worker 400*cfb92d14SAndroid Build Coastguard Worker def reboot(self, **params): 401*cfb92d14SAndroid Build Coastguard Worker logger.info('Executing power cycle') 402*cfb92d14SAndroid Build Coastguard Worker for socket in params['sockets']: 403*cfb92d14SAndroid Build Coastguard Worker self._turn_off(socket) 404*cfb92d14SAndroid Build Coastguard Worker time.sleep(2) 405*cfb92d14SAndroid Build Coastguard Worker self._turn_on(socket) 406*cfb92d14SAndroid Build Coastguard Worker time.sleep(2) 407*cfb92d14SAndroid Build Coastguard Worker 408*cfb92d14SAndroid Build Coastguard Worker def _change_state(self, socket, state): 409*cfb92d14SAndroid Build Coastguard Worker self._opener.open('{}{}={}'.format(self._base_url, socket, state)) 410*cfb92d14SAndroid Build Coastguard Worker 411*cfb92d14SAndroid Build Coastguard Worker def _turn_off(self, socket): 412*cfb92d14SAndroid Build Coastguard Worker self._change_state(socket, 1) 413*cfb92d14SAndroid Build Coastguard Worker 414*cfb92d14SAndroid Build Coastguard Worker def _turn_on(self, socket): 415*cfb92d14SAndroid Build Coastguard Worker self._change_state(socket, 0) 416*cfb92d14SAndroid Build Coastguard Worker 417*cfb92d14SAndroid Build Coastguard Worker def close(self): 418*cfb92d14SAndroid Build Coastguard Worker self._base_url = None 419*cfb92d14SAndroid Build Coastguard Worker self._opener = None 420*cfb92d14SAndroid Build Coastguard Worker 421*cfb92d14SAndroid Build Coastguard Worker 422*cfb92d14SAndroid Build Coastguard Workerclass ManualPduController(PduController): 423*cfb92d14SAndroid Build Coastguard Worker 424*cfb92d14SAndroid Build Coastguard Worker def open(self, **kwargs): 425*cfb92d14SAndroid Build Coastguard Worker pass 426*cfb92d14SAndroid Build Coastguard Worker 427*cfb92d14SAndroid Build Coastguard Worker def reboot(self, **kwargs): 428*cfb92d14SAndroid Build Coastguard Worker input('Reset all devices and press enter to continue..') 429*cfb92d14SAndroid Build Coastguard Worker 430*cfb92d14SAndroid Build Coastguard Worker def close(self): 431*cfb92d14SAndroid Build Coastguard Worker pass 432