[Automated-testing] [PATCH] devauto: Method Implementation for np0801dt
Esquivel, Benjamin
benjamin.esquivel at intel.com
Thu Jun 23 09:19:33 PDT 2016
> -----Original Message-----
> From: automated-testing-bounces at yoctoproject.org [mailto:automated-
> testing-bounces at yoctoproject.org] On Behalf Of Joshua G Lock
> Sent: Thursday, June 23, 2016 5:53 AM
> To: Edwin Plauchu <edwin.plauchu.camacho at linux.intel.com>; automated-
> testing at yoctoproject.org
> Cc: Plauchu Camacho, Edwin <edwin.plauchu.camacho at intel.com>
> Subject: Re: [Automated-testing] [PATCH] devauto: Method Implementation
> for np0801dt
>
> Hi Edwin,
>
> On Wed, 2016-06-22 at 17:30 -0500, Edwin Plauchu wrote:
> > From: Edwin Plauchu <edwin.plauchu.camacho at intel.com>
> >
> > The remote power management system NP-0801D(T) has been
> implemented by
> > utilizing np0801dx.py which allows take over series T or B.
> >
> > Signed-off-by: Edwin Plauchu <edwin.plauchu.camacho at intel.com>
> > ---
> > devauto/rps/hw/np0801dt.py | 56 +++++++++++++++-
> > devauto/rps/hw/np0801dx.py | 164
> > +++++++++++++++++++++++++++++++++++++++++++++
> > devauto/rps/hw/rpsgen.py | 8 +--
> > 3 files changed, 221 insertions(+), 7 deletions(-)
> > create mode 100644 devauto/rps/hw/np0801dx.py
> >
> > diff --git a/devauto/rps/hw/np0801dt.py b/devauto/rps/hw/np0801dt.py
> > index b1a456d..b7e64ff 100644
> > --- a/devauto/rps/hw/np0801dt.py
> > +++ b/devauto/rps/hw/np0801dt.py
> > @@ -6,8 +6,58 @@ At the time of the implementation, the reference
> > website is:
> > http://www.synaccess-net.com/np-0801dt/
> > """
> > from rpsgen import RPSGen
> > +from np0801dx import Np0801Dx, NpCmdApplier, NpCmdMonitor from
> > +np0801dx import NpCmdAlterAllSlots, NpCmdAlterSlot,
> > NpCmdRebootSlot
> > +from np0801dx import NpSlotNumber, NpSlotStatus
> > +
> >
> > class np0801dt(RPSGen):
> > - outlet_count=8
> > - def __init__(self):
> > - super(outlet_count)
> > +
> > + def __init__( self ):
> > + super( np0801dt , self ).__init__( NpSlotNumber.EIGTH.value
> > )
>
> Typo in this constant name, should be EIGHT
>
> > + self.__applier = NpCmdApplier( Np0801Dx("192.168.1.100") )
>
> This hard-codes the IP address. Having a default IP address is not a bad idea
> but this should be easier to customise than modifying the class.
>
> > +
> > + def turn_all_on( self ):
> > + self.__applier.add( NpCmdAlterAllSlots( NpSlotStatus.ON ) )
> > + results = self.__applier.update()
> > + return results.pop()
> > +
> > + def turn_all_off( self ):
> > + self.__applier.add( NpCmdAlterAllSlots( NpSlotStatus.OFF ) )
> > + results = self.__applier.update()
> > + return results.pop()
> > +
> > + def turn_on_by_id( self, outlet_id ):
> > + if outlet_id > 0 and outlet_id <= self.outlet_count:
> > + return self.__ac_slot( self.__glue_enum_item(
> > NpSlotNumber, outlet_id ), NpSlotStatus.ON )
> > + return False
> > +
> > + def turn_off_by_id( self, outlet_id ):
> > + if outlet_id > 0 and outlet_id <= self.outlet_count:
> > + return self.__ac_slot( self.__glue_enum_item(
> > NpSlotNumber, outlet_id ), NpSlotStatus.OFF )
> > + return False
> > +
> > + def reboot_by_id( self, outlet_id ):
> > + if outlet_id > 0 and outlet_id <= self.outlet_count:
> > + slot = self.__glue_enum_item( NpSlotNumber, outlet_id )
> > + self.__applier.add( NpCmdRebootSlot( slot ) )
> > + results = self.__applier.update()
> > + return results.pop()
> > + return False
> > +
> > + def monitor( self ):
> > + self.__applier.add( NpCmdMonitor() )
> > + results = self.__applier.update()
> > + return results.pop()
> > +
> > + def __ac_slot( self, slot_number, status ):
> > + self.__applier.add( NpCmdAlterSlot( slot_number , status ) )
> > + results = self.__applier.update()
> > + return results.pop()
> > +
> > + def __glue_enum_item( self, enum_fam , number ):
> > + relement = None
> > + for name, member in enum_fam.__members__.items():
> > + if member.value == number:
> > + relement = member
> > + return relement
> > diff --git a/devauto/rps/hw/np0801dx.py b/devauto/rps/hw/np0801dx.py
> > new file mode 100644 index 0000000..9b9bb06
> > --- /dev/null
> > +++ b/devauto/rps/hw/np0801dx.py
> > @@ -0,0 +1,164 @@
> > +"""
> > +np0801d(t or b) Remote power switch control implementation
> > +
> > +At the time of the implementation, the reference website is:
> > +
> > +http://www.synaccess-net.com/np-0801dt/
> > +"""
> > +
> > +from enum import IntEnum, unique
> > +
> > + at unique
> > +class NpSlotNumber( IntEnum ):
> > + ONE = 1
> > + TWO = 2
> > + THREE = 3
> > + FOUR = 4
> > + FIVE = 5
> > + SIX = 6
> > + SEVEN = 7
> > + EIGTH = 8
>
> Typo here, should be EIGHT
>
> > +
> > + at unique
> > +class NpSlotStatus( IntEnum ):
> > + OFF = 0
> > + ON = 1
> > +
> > +
> > +class Np0801Dx():
> > +
> > + def __init__( self , hostname ):
> > + self.__host = hostname
> > +
> > + def do( self , data ):
> > + import urllib.request
> > + import base64
> > + from array import array
> > +
> > + username = 'admin'
> > + password = 'admin'
> > + auth_str = ( '%s:%s' % (username, password) )
>
> Presumably these are the default username and password? I really don't like
> the idea of hard-coding these. They should ideally be read from a
> configuration file, didn't I see a patch for devauto which adds an ini file?
I will check if the patch is there but in the branch that Edwin should have based his changes, there is the ini file:
http://git.yoctoproject.org/cgit/cgit.cgi/qa-tools/tree/devauto/rps/rpscli.ini?h=besquive/rps&id=8f688414086411f92cc88b0842d28305fb22a4e6
>
> > +
> > + answer = "http://{0}/cmd.cgi?{1}".format(self.__host ,
> > urllib.request.pathname2url(data))
> > + basic64 = b"Basic " +
> > base64.encodestring(auth_str.encode('ascii')).replace(b'\n', b'')
> > + req = urllib.request.Request( answer )
> > + req.add_header( "Authorization", basic64 )
> > + with urllib.request.urlopen(req) as response:
> > + return response.read().replace(b'\r\n', b'')
> > +
> > +class NpCmdApplier:
> > +
> > + def __init__( self , pms ):
> > + self.commands = []
> > +
> > + if not isinstance( pms , Np0801Dx ):
> > + raise ValueError('Not valid Np0801Dx instance')
> > +
> > + self.np_model = pms
> > +
> > + def add( self, command ):
> > + self.commands.append( command )
> > +
> > + def update(self):
>
> Coding style is fairly inconsistent. Sometimes you do:
>
> def method(foo):
>
> other times
>
> def method( foo )
>
> Please be consistent and consider following PEP-8:
> https://www.python.org/dev/peps/pep-0008/
>
> > + replies = []
> > + iter_obj = iter( self.commands )
>
> If you've got an iterator you should use the more idiomatic pattern:
>
> for element in iter_obj:
> replies.append(element.go(self.np_model))
> return replies
>
> > + while True:
> > + try:
> > + element = next( iter_obj )
> > + replies.append( element.go( self.np_model ) )
> > + except StopIteration:
> > + self.commands = []
> > + break
> > + return replies
> > +
> > +class NpMasterCmd:
> > +
> > + def __init__( self , ic, tc ):
> > + self.inst_code = ic
> > + self.breathe_time = tc
> > + self.cmd_arg_1 = None
> > + self.cmd_arg_2 = None
> > +
> > + def go( self , pms ):
> > + import urllib.parse
> > + import time
> > + url_params = [ self.inst_code ]
> > + args = [ d for d in ( self.cmd_arg_1 , self.cmd_arg_2 ) if d
> > or d == 0 ]
> > + for a in ( args ):
> > + arg_str = a if isinstance(a, str) else str(a)
> > + if arg_str:
> > + url_params.append( " " )
> > + url_params.append( arg_str )
>
> The indentation looks inconsistent here.
>
> > + data = urllib.parse.unquote(''.join( url_params ) )
> > + reply = pms.do( data )
> > + time.sleep( self.breathe_time )
> > + return self.parse_reply( reply )
> > +
> > + def parse_reply( self , reply ):
> > + pass
> > +
> > +
> > +class NpCmdAlterSlot( NpMasterCmd ):
> > +
> > + def __init__( self, socket , st ):
> > +
> > + super( NpCmdAlterSlot , self ).__init__( '$A3' , 3 )
> > +
> > + if not isinstance( socket , NpSlotNumber ):
> > + raise ValueError('Not valid socket selected')
> > +
> > + if not isinstance( st , NpSlotStatus ):
> > + raise ValueError('Not valid state selected')
> > +
> > + self.cmd_arg_1 = socket.value
> > + self.cmd_arg_2 = st.value
> > +
> > + def parse_reply( self , reply ):
> > + return True if reply == b'$A0' else False
>
> could just be:
>
> return reply == b'$A0'
>
> > +
> > +class NpCmdRebootSlot( NpMasterCmd ):
> > +
> > + def __init__( self, socket ):
> > +
> > + super( NpCmdRebootSlot , self ).__init__( '$A4', 4 )
> > +
> > + if not isinstance( socket , NpSlotNumber ):
> > + raise ValueError('Not valid socket selected')
> > +
> > + self.cmd_arg_1 = socket.value
> > +
> > + def parse_reply( self , reply ):
> > + return True if reply == b'$A0' else False
>
> same here:
>
> return reply == b'$A0'
>
> > +
> > +
> > +class NpCmdMonitor( NpMasterCmd ):
> > +
> > + def __init__( self ):
> > +
> > + super( NpCmdMonitor , self ).__init__( '$A5', 2 )
> > +
> > + def parse_reply( self , reply ):
> > + rv = None
> > + vals = (reply).decode('utf-8').split(',')
> > +
> > + if vals[0] == '$A0':
> > + if len(vals) == 4:
> > + rv = {}
> > + rv['amperes'] = vals[2]
> > + rv['temperature'] = vals[3]
> > + rv['slot_status'] = vals[1]
> > + return rv
> > +
> > +class NpCmdAlterAllSlots( NpMasterCmd ):
> > +
> > + def __init__( self, st ):
> > +
> > + super( NpCmdAlterAllSlots , self ).__init__('$A7', 7 )
> > +
> > + if not isinstance( st , NpSlotStatus ):
> > + raise ValueError('Not valid state selected')
> > +
> > + self.cmd_arg_1 = st.value
> > +
> > + def parse_reply( self , reply ):
> > + return True if reply == b'$A0' else False
> > diff --git a/devauto/rps/hw/rpsgen.py b/devauto/rps/hw/rpsgen.py index
> > dea0119..e91d832 100644
> > --- a/devauto/rps/hw/rpsgen.py
> > +++ b/devauto/rps/hw/rpsgen.py
> > @@ -13,11 +13,11 @@ class RPSGen:
> > def __init__(self, outlet_count):
> > self.outlet_count = outlet_count
> >
> > - def turn_all_on():
> > + def turn_all_on(self):
> > pass
> > - def turn_all_off():
> > + def turn_all_off(self):
> > pass
> > - def turn_on_by_id(outlet_id):
> > + def turn_on_by_id(self,outlet_id):
> > pass
> > - def turn_off_by_id(outlet_id):
> > + def turn_off_by_id(self,outlet_id):
> > pass
> > --
> > 1.9.1
> >
> --
> _______________________________________________
> automated-testing mailing list
> automated-testing at yoctoproject.org
> https://lists.yoctoproject.org/listinfo/automated-testing
More information about the automated-testing
mailing list