1
2
3
4
5 package oshi.hardware.platform.unix.freebsd;
6
7 import java.time.LocalDate;
8 import java.util.Arrays;
9 import java.util.HashMap;
10 import java.util.List;
11 import java.util.Locale;
12 import java.util.Map;
13
14 import oshi.annotation.concurrent.ThreadSafe;
15 import oshi.hardware.PowerSource;
16 import oshi.hardware.common.AbstractPowerSource;
17 import oshi.util.Constants;
18 import oshi.util.ExecutingCommand;
19 import oshi.util.ParseUtil;
20 import oshi.util.platform.unix.freebsd.BsdSysctlUtil;
21
22
23
24
25 @ThreadSafe
26 public final class FreeBsdPowerSource extends AbstractPowerSource {
27
28 public FreeBsdPowerSource(String psName, String psDeviceName, double psRemainingCapacityPercent,
29 double psTimeRemainingEstimated, double psTimeRemainingInstant, double psPowerUsageRate, double psVoltage,
30 double psAmperage, boolean psPowerOnLine, boolean psCharging, boolean psDischarging,
31 CapacityUnits psCapacityUnits, int psCurrentCapacity, int psMaxCapacity, int psDesignCapacity,
32 int psCycleCount, String psChemistry, LocalDate psManufactureDate, String psManufacturer,
33 String psSerialNumber, double psTemperature) {
34 super(psName, psDeviceName, psRemainingCapacityPercent, psTimeRemainingEstimated, psTimeRemainingInstant,
35 psPowerUsageRate, psVoltage, psAmperage, psPowerOnLine, psCharging, psDischarging, psCapacityUnits,
36 psCurrentCapacity, psMaxCapacity, psDesignCapacity, psCycleCount, psChemistry, psManufactureDate,
37 psManufacturer, psSerialNumber, psTemperature);
38 }
39
40
41
42
43
44
45 public static List<PowerSource> getPowerSources() {
46 return Arrays.asList(getPowerSource("BAT0"));
47 }
48
49 private static FreeBsdPowerSource getPowerSource(String name) {
50 String psName = name;
51 double psRemainingCapacityPercent = 1d;
52 double psTimeRemainingEstimated = -1d;
53 double psPowerUsageRate = 0d;
54 int psVoltage = -1;
55 double psAmperage = 0d;
56 boolean psPowerOnLine = false;
57 boolean psCharging = false;
58 boolean psDischarging = false;
59 CapacityUnits psCapacityUnits = CapacityUnits.RELATIVE;
60 int psCurrentCapacity = 0;
61 int psMaxCapacity = 1;
62 int psDesignCapacity = 1;
63 int psCycleCount = -1;
64 LocalDate psManufactureDate = null;
65
66 double psTemperature = 0d;
67
68
69 int state = BsdSysctlUtil.sysctl("hw.acpi.battery.state", 0);
70 if (state == 2) {
71 psCharging = true;
72 } else {
73 int time = BsdSysctlUtil.sysctl("hw.acpi.battery.time", -1);
74
75 psTimeRemainingEstimated = time < 0 ? -1d : 60d * time;
76 if (state == 1) {
77 psDischarging = true;
78 }
79 }
80
81 int life = BsdSysctlUtil.sysctl("hw.acpi.battery.life", -1);
82 if (life > 0) {
83 psRemainingCapacityPercent = life / 100d;
84 }
85 List<String> acpiconf = ExecutingCommand.runNative("acpiconf -i 0");
86 Map<String, String> psMap = new HashMap<>();
87 for (String line : acpiconf) {
88 String[] split = line.split(":", 2);
89 if (split.length > 1) {
90 String value = split[1].trim();
91 if (!value.isEmpty()) {
92 psMap.put(split[0], value);
93 }
94 }
95 }
96
97 String psDeviceName = psMap.getOrDefault("Model number", Constants.UNKNOWN);
98 String psSerialNumber = psMap.getOrDefault("Serial number", Constants.UNKNOWN);
99 String psChemistry = psMap.getOrDefault("Type", Constants.UNKNOWN);
100 String psManufacturer = psMap.getOrDefault("OEM info", Constants.UNKNOWN);
101 String cap = psMap.get("Design capacity");
102 if (cap != null) {
103 psDesignCapacity = ParseUtil.getFirstIntValue(cap);
104 if (cap.toLowerCase(Locale.ROOT).contains("mah")) {
105 psCapacityUnits = CapacityUnits.MAH;
106 } else if (cap.toLowerCase(Locale.ROOT).contains("mwh")) {
107 psCapacityUnits = CapacityUnits.MWH;
108 }
109 }
110 cap = psMap.get("Last full capacity");
111 if (cap != null) {
112 psMaxCapacity = ParseUtil.getFirstIntValue(cap);
113 } else {
114 psMaxCapacity = psDesignCapacity;
115 }
116 double psTimeRemainingInstant = psTimeRemainingEstimated;
117 String time = psMap.get("Remaining time");
118 if (time != null) {
119 String[] hhmm = time.split(":");
120 if (hhmm.length == 2) {
121 psTimeRemainingInstant = 3600d * ParseUtil.parseIntOrDefault(hhmm[0], 0)
122 + 60d * ParseUtil.parseIntOrDefault(hhmm[1], 0);
123 }
124 }
125 String rate = psMap.get("Present rate");
126 if (rate != null) {
127 psPowerUsageRate = ParseUtil.getFirstIntValue(rate);
128 }
129 String volts = psMap.get("Present voltage");
130 if (volts != null) {
131 psVoltage = ParseUtil.getFirstIntValue(volts);
132 if (psVoltage != 0) {
133 psAmperage = psPowerUsageRate / psVoltage;
134 }
135 }
136
137 return new FreeBsdPowerSource(psName, psDeviceName, psRemainingCapacityPercent, psTimeRemainingEstimated,
138 psTimeRemainingInstant, psPowerUsageRate, psVoltage, psAmperage, psPowerOnLine, psCharging,
139 psDischarging, psCapacityUnits, psCurrentCapacity, psMaxCapacity, psDesignCapacity, psCycleCount,
140 psChemistry, psManufactureDate, psManufacturer, psSerialNumber, psTemperature);
141 }
142 }