Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Stuff
Monday, October 16th, 2006 at 5:33:33pm MDT 

  1. #!/usr/bin/python
  2. #
  3. #   battstat
  4. #
  5. #   Copyright (C) 2006 by Tyler Gates <TGates81@gmail.com>
  6. #   This program is free software; you can redistribute it and/or modify
  7. #   it under the terms of the GNU General Public License as published by
  8. #   the Free Software Foundation; either version 2 of the License, or
  9. #   (at your option) any later version.
  10. #
  11. #   This program is distributed in the hope that it will be useful,
  12. #   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. #   GNU General Public License for more details.
  15. #   You should have received a copy of the GNU General Public License
  16. #   along with this program; if not, write to the Free Software
  17. #   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  18. #   USA.
  19. #
  20.  
  21. import os, sys, re
  22.  
  23. # globals
  24. if os.path.isdir("/proc/acpi/battery"): batt_basedir = "/proc/acpi/battery"
  25. else: batt_basedir = "/proc/apm/battery"
  26.  
  27. def get_batts():
  28.         """ return an array of all available batteries in batt_basedir """
  29.         try:
  30.                 return os.listdir(batt_basedir)
  31.         except Exception, e:
  32.                 print >>sys.stderr.write("Unable to find a battery in '"+batt_basedir+"'")
  33.                 return None
  34.  
  35. def read_lines(file):
  36.         """ read file contents and return readlines() """
  37.         try:
  38.                 f = open(file)
  39.                 string = f.readlines()
  40.                 f.close()
  41.                 return string
  42.         except Exception, e:
  43.                 print >>sys.stderr.write("Unable to open '"+file+"':\n" +str(e))
  44.                 return None
  45.  
  46. def get_value(contents, property):
  47.         """ return value of property from file contents (readlines) """
  48.         for c in contents:
  49.                 if property in c:
  50.                         try:
  51.                                 return c.split(':')[1].strip()
  52.                         except IndexError, e:
  53.                                 print >>sys.stderr.write("Unable to parse file contents: "+str(e))
  54.                                 return None
  55.         return None
  56.  
  57. def batt_percent(capacity, remaining_capacity):
  58.         """ calculate and return remaining battery percentage as a string """
  59.         # strip out units
  60.         try:
  61.                 capacity = float(re.sub('\D', '', capacity))
  62.                 remaining_capacity = float(re.sub('\D', '', remaining_capacity))
  63.         except:
  64.                 # must be 'unknown' values, i.e. a bad battery return N/A
  65.                 return 'N/A'
  66.         # convert to float and calculate
  67.         percent = float((remaining_capacity * 100) / capacity)
  68.         # round to hundredths. 23.3524 || 23.3245 -> 23.35999 || 23.35000 + 0.001 = 23.360 || 23.351
  69.         percent = round(percent, 2) + 0.001
  70.         percent = str(percent)
  71.         # remove extra thousandths place from rounding
  72.         percent = percent[:(len(percent)-1)]
  73.         return percent
  74.  
  75. def time_left(remaining_capacity, present_rate):
  76.         """ calculate and return remaining time in 00:00 hours units """
  77.         # strip units
  78.         try:
  79.                 remaining_capacity = float(re.sub('\D', '', remaining_capacity))
  80.                 present_rate = float(re.sub('\D', '', present_rate))
  81.         except:
  82.                 return 'N/A'
  83.         # get decimal time i.e. 1.34 hours
  84.         decimal_time = remaining_capacity / present_rate
  85.         # round to hundreths (see batt_percent() for more info)
  86.         decimal_time = round(decimal_time, 2) + 0.001
  87.         decimal_time = str(decimal_time)
  88.         decimal_time = decimal_time[:(len(decimal_time)-1)]
  89.         # split to the left and right of the decimal and convert the right (hundredths) to minutes
  90.         whole = decimal_time.split('.')[0]
  91.         # pad <num> to 0<num>
  92.         if len(whole) == 1: whole = '0'+whole
  93.         hundredths = decimal_time.split('.')[1]
  94.         # convert hundredths place to minutes
  95.         minutes = (int(hundredths) * 60) / 100
  96.         minutes = str(minutes)
  97.         if len(minutes) == 1: minutes = '0'+minutes
  98.         return whole+':'+minutes
  99.  
  100. def capacity_deviation(capacity, design_capacity):
  101.         """ calculate and return the gain or loss of capacity based on spec and last charge """
  102.         try:
  103.                 int_capacity = int(re.sub('\D', '', capacity))
  104.                 int_design_capacity = int(re.sub('\D', '', design_capacity))
  105.                 if int_capacity > int_design_capacity:
  106.                         diff = int_capacity - int_design_capacity
  107.                         diff = str(diff)
  108.                         return '+'+batt_percent(capacity, diff)
  109.                 elif int_capacity < int_design_capacity:
  110.                         diff = int_design_capacity - int_capacity
  111.                         diff = str(diff)
  112.                         return '-'+batt_percent(design_capacity, diff)
  113.                 else: return '0.00'
  114.         except:
  115.                 return 'N/A'
  116.  
  117. def main(battery):
  118.         batt_dir = os.path.join(batt_basedir, battery)
  119.         # info data
  120.         info_file = os.path.join(batt_dir, 'info')
  121.         info_contents = read_lines(info_file)
  122.         if not info_contents: sys.exit(1)
  123.  
  124.         # state data
  125.         state_file = os.path.join(batt_dir, 'state')
  126.         state_contents = read_lines(state_file)
  127.         if not state_contents: sys.exit(1)
  128.        
  129.         charging_state          = get_value(state_contents, 'charging state')
  130.         remaining_capacity      = get_value(state_contents, 'remaining capacity')
  131.         present_rate            = get_value(state_contents, 'present rate')
  132.         capacity_low            = get_value(info_contents, 'design capacity low')
  133.         capacity_warning        = get_value(info_contents, 'design capacity warning')
  134.         manufacturer            = get_value(info_contents, 'OEM info')
  135.         model_number            = get_value(info_contents, 'model number')
  136.         battery_type            = get_value(info_contents, 'battery type')
  137.         battery_tech            = get_value(info_contents, 'battery technology')
  138.         design_capacity         = get_value(info_contents, 'design capacity')
  139.         last_full_capacity      = get_value(info_contents, 'last full capacity')
  140.        
  141.         if last_full_capacity != '':
  142.                 capacity = last_full_capacity
  143.         else:
  144.                 capacity = design_capacity
  145.  
  146.         # calculate percent left on battery
  147.         percent_left            = batt_percent(capacity, remaining_capacity)
  148.  
  149.         # calculate capacity gain or loss
  150.         capacity_dev        = capacity_deviation(capacity, design_capacity)
  151.        
  152.         # determine time remaining based on charging state
  153.         if charging_state == 'discharging':
  154.                 # time left to discharge
  155.                 time_remaining = time_left(remaining_capacity, present_rate)
  156.         elif charging_state == 'charging':
  157.                 # time left to charge
  158.                 # use the difference between total capacity and remaining capacity
  159.                 try:
  160.                         remaining = int(re.sub('\D', '', remaining_capacity))
  161.                         capy = int(re.sub('\D', '', capacity))
  162.                         net = capy - remaining
  163.                         net = str(net)
  164.                         time_remaining = time_left(net, present_rate)
  165.                 except:
  166.                         time_remaining = 'N/A'
  167.         else:
  168.                 # must be charged: nothing to calculate; ACPWR
  169.                 time_remaining = "--:--"
  170.  
  171.         # determine alert status
  172.         try:
  173.                 if int(re.sub('\D', '', remaining_capacity)) <= int(re.sub('\D', '', capacity_low)): alert = 'LOW!'
  174.                 elif int(re.sub('\D', '', remaining_capacity)) <= int(re.sub('\D', '', capacity_warning)): alert = 'WARNING!'
  175.                 else: alert = 'ok'
  176.         except:
  177.                 alert = 'N/A'
  178.        
  179.         # manufacturer, model number and battery technology may not have values; use N/A for screen output
  180.         if not manufacturer: manufacturer = 'N/A'
  181.         if not model_number: model_number = 'N/A'
  182.         if not battery_tech: batter_tech = 'N/A'
  183.        
  184.         # don't display anything larger than 100.00%
  185.         try:
  186.                 if float(percent_left) > 100.00: percent_left = '100.00'
  187.         except:
  188.                 pass
  189.  
  190.         # output 100.00% if we have a 'charged' state
  191.         if charging_state == 'charged': percent_left = '100.00'
  192.  
  193.         # output to screen
  194.         print "         << "+battery+" >>"
  195.         print manufacturer+' - '+model_number+' | '+battery_type+' | '+battery_tech
  196.         print "Remaining Charge           : "+percent_left+" %"
  197.         print "Time Left                  : "+time_remaining+' Hrs'
  198.         print "Charging State             : "+charging_state
  199.         print "Rated Capacity Deviation   : "+capacity_dev+" %"
  200.         print "Charge Alert               : "+alert
  201.  
  202. if __name__ == "__main__":
  203.         batteries = get_batts()
  204.         if not batteries: sys.exit(1)
  205.         for battery in batteries:
  206.                 main(battery)

advertising

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.

worth-right
worth-right
fantasy-obligation