title: APC PDU CLI automation over telnet
body: <p>I have seen numerous posts online about logging into an APC PDU over telnet using Python pexpect, PHP, etc. However, all of the examples are like this:</p>
  
  <p><a href="https://stackoverflow.com/questions/10306410/python-telnet-automation-apc-pdu">Python - telnet - automation APC PDU</a></p>
  
  <p><a href="https://github.com/quackenbush/APC" rel="nofollow noreferrer">https://github.com/quackenbush/APC</a></p>
  
  <p>They log in using the Control Console, which I don't think offers as many metrics. I'm looking for a way to automate the command line interface and send various commands to check metrics.</p>
  
  <p>I've learned this is possible by appending <code>-c</code> to your password at the login prompt (from this source: <a href="https://www.apc.com/us/en/faqs/FA156163/" rel="nofollow noreferrer">https://www.apc.com/us/en/faqs/FA156163/</a>):</p>
  
  <pre><code>APC_DEFAULT_USER     = 'apc'
  APC_DEFAULT_PASSWORD = 'apc -c'
  self.child.expect('User Name : ')
  self.child.send(APC_DEFAULT_USER + '\r\n')
  self.child.expect('Password  : ')
  self.child.send(APC_DEFAULT_PASSWORD + '\r\n')
  </code></pre>
  
  <p>But this is where I get stuck. I'd like a generic solution to allow me to specify different PDU commands as command line args like this:</p>
  
  <pre><code>--command power
  --command current
  etc.
  </code></pre>
  
  <p>I am using argparse to get the arguments from the user, so args.command looks like this:</p>
  
  <pre><code>parser.add_argument('--command', action='store', default='',
                      help='The command to run')
  </code></pre>
  
  <p>I also have no strong feelings about doing this in Python. I'm more than happy to use another language if it's more intuitive. I'm just trying to base my script on the quankenbush/APC script.</p>
  
  <p>I've tried doing expects for the <code>APC&gt;</code> prompt like this:</p>
  
  <pre><code>self.info("Attempting to run command: {}".format(self.command))
  self.child.expect('APC&gt; ')
  self.sendnl(self.command)
  self.child.expect(' OK')
  self.child.expect('APC&gt; ')
  </code></pre>
  
  <p>But I end up getting </p>
  
  <blockquote>
    <p>"Command does not exist"</p>
  </blockquote>
  
  <p>errors, even though I know the "power" and "current" commands do exist. </p>
  
  <p>Here is the complete output (using --verbose mode):</p>
  
  <pre><code>$ python apc_metrics.py --host &lt;my.ip.addr&gt; --command power -v
  Acquiring lock /tmp/apc.lock
  Connecting to APC @ &lt;my.ip.addr&gt;
  Logged in as user apc
  Attempting to run command: power
  apc    
  ******
  
  American Power Conversion
  Rack PDU AP7930 v3.7.3
  AOS v3.7.3
  Outlets: 24
  (c) 2008 All Rights Reserved
  Unit ID: RackPDU
  
   1: ON    : Outlet 1
   2: ON    : Outlet 2
   3: ON    : Outlet 3
   4: ON    : Outlet 4
   5: ON    : Outlet 5
   6: ON    : Outlet 6
   7: ON    : Outlet 7
   8: ON    : Outlet 8
   9: ON    : Outlet 9
  10: ON    : Outlet 10
  11: ON    : Outlet 11
  12: ON    : Outlet 12
  13: ON    : Outlet 13
  14: ON    : Outlet 14
  15: ON    : Outlet 15
  16: ON    : Outlet 16
  17: ON    : Outlet 17
  18: ON    : Outlet 18
  19: ON    : Outlet 19
  20: ON    : Outlet 20
  21: ON    : Outlet 21
  22: ON    : Outlet 22
  23: ON    : Outlet 23
  24: ON    : Outlet 24
  
  APC&gt; 
  power
  
  DISCONNECTED from &lt;my.ip.addr&gt;
  [
   E100 : Command does not exist
  APC&gt; 
  4
   OK
   E100 : Command does not exist
  APC&gt; 
  
  
  Bye.
  
  Connection Closed - Bye
  Connection closed by foreign host.
  ]
  </code></pre>
  
  <p>For completeness, my end goal is to run this script every minute or few minutes and write the data to a file to track power usage over time and eventually create some graph of this data. </p>