View Javadoc
1   /**
2    * Oshi (https://github.com/dblock/oshi)
3    * 
4    * Copyright (c) 2010 - 2015 The Oshi Project Team
5    * 
6    * All rights reserved. This program and the accompanying materials
7    * are made available under the terms of the Eclipse Public License v1.0
8    * which accompanies this distribution, and is available at
9    * http://www.eclipse.org/legal/epl-v10.html
10   * 
11   * Contributors:
12   * dblock[at]dblock[dot]org
13   * alessandro[at]perucchi[dot]org
14   * widdis[at]gmail[dot]com
15   * https://github.com/dblock/oshi/graphs/contributors
16   */
17  package oshi.software.os.linux.proc;
18  
19  import java.io.File;
20  import java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import oshi.hardware.PowerSource;
25  import oshi.util.FileUtil;
26  
27  /**
28   * A Power Source
29   * 
30   * @author widdis[at]gmail[dot]com
31   */
32  public class LinuxPowerSource implements PowerSource {
33  
34  	private static final String PS_PATH = "/sys/class/power_supply/";
35  
36  	private String name;
37  
38  	private double remainingCapacity;
39  
40  	private double timeRemaining;
41  
42  	public LinuxPowerSource(String name, double remainingCapacity,
43  			double timeRemaining) {
44  		this.name = name;
45  		this.remainingCapacity = remainingCapacity;
46  		this.timeRemaining = timeRemaining;
47  	}
48  
49  	@Override
50  	public String getName() {
51  		return this.name;
52  	}
53  
54  	@Override
55  	public double getRemainingCapacity() {
56  		return this.remainingCapacity;
57  	}
58  
59  	@Override
60  	public double getTimeRemaining() {
61  		return this.timeRemaining;
62  	}
63  
64  	/**
65  	 * Battery Information
66  	 */
67  	public static PowerSource[] getPowerSources() {
68  		// Get list of power source names
69  		File f = new File(PS_PATH);
70  		String[] psNames = f.list();
71  		// Empty directory will give null rather than empty array, so fix
72  		if (psNames == null)
73  			psNames = new String[0];
74  		List<LinuxPowerSource> psList = new ArrayList<>(
75  				psNames.length);
76  		// For each power source, output various info
77  		for (String psName : psNames) {
78  			// Skip if name is ADP* (AC power supply)
79  			if (psName.startsWith("ADP"))
80  				continue;
81  			// Skip if can't read uevent file
82  			List<String> psInfo;
83  			try {
84  				psInfo = FileUtil.readFile(PS_PATH + psName + "/uevent");
85  			} catch (IOException e) {
86  				continue;
87  			}
88  			// Initialize defaults
89  			boolean isPresent = false;
90  			boolean isCharging = false;
91  			String name = "Unknown";
92  			int energyNow = 0;
93  			int energyFull = 1;
94  			int powerNow = 1;
95  			for (String checkLine : psInfo) {
96  				if (checkLine.startsWith("POWER_SUPPLY_PRESENT")) {
97  					// Skip if not present
98  					String[] psSplit = checkLine.split("=");
99  					if (psSplit.length > 1)
100 						isPresent = Integer.parseInt(psSplit[1]) > 0;
101 					if (!isPresent)
102 						continue;
103 				} else if (checkLine.startsWith("POWER_SUPPLY_NAME")) {
104 					// Name
105 					String[] psSplit = checkLine.split("=");
106 					if (psSplit.length > 1)
107 						name = psSplit[1];
108 				} else if (checkLine.startsWith("POWER_SUPPLY_ENERGY_NOW")
109 						|| checkLine.startsWith("POWER_SUPPLY_CHARGE_NOW")) {
110 					// Remaining Capacity = energyNow / energyFull
111 					String[] psSplit = checkLine.split("=");
112 					if (psSplit.length > 1)
113 						energyNow = Integer.parseInt(psSplit[1]);
114 				} else if (checkLine.startsWith("POWER_SUPPLY_ENERGY_FULL")
115 						|| checkLine.startsWith("POWER_SUPPLY_CHARGE_FULL")) {
116 					String[] psSplit = checkLine.split("=");
117 					if (psSplit.length > 1)
118 						energyFull = Integer.parseInt(psSplit[1]);
119 				} else if (checkLine.startsWith("POWER_SUPPLY_STATUS")) {
120 					// Check if charging
121 					String[] psSplit = checkLine.split("=");
122 					if (psSplit.length > 1 && psSplit[1].equals("Charging"))
123 						isCharging = true;
124 				} else if (checkLine.startsWith("POWER_SUPPLY_POWER_NOW")
125 						|| checkLine.startsWith("POWER_SUPPLY_CURRENT_NOW")) {
126 					// Time Remaining = energyNow / powerNow (hours)
127 					String[] psSplit = checkLine.split("=");
128 					if (psSplit.length > 1)
129 						powerNow = Integer.parseInt(psSplit[1]);
130 					if (powerNow <= 0)
131 						isCharging = true;
132 				}
133 			}
134 			psList.add(new LinuxPowerSource(name, (double) energyNow
135 					/ energyFull, isCharging ? -2d : 3600d * energyNow
136 					/ powerNow));
137 		}
138 
139 		return psList.toArray(new LinuxPowerSource[psList.size()]);
140 	}
141 }