1
2
3
4
5 package oshi.hardware.platform.unix.solaris;
6
7 import java.time.LocalDate;
8 import java.util.Arrays;
9 import java.util.List;
10
11 import com.sun.jna.platform.unix.solaris.LibKstat.Kstat;
12
13 import oshi.annotation.concurrent.ThreadSafe;
14 import oshi.hardware.PowerSource;
15 import oshi.hardware.common.AbstractPowerSource;
16 import oshi.util.Constants;
17 import oshi.util.platform.unix.solaris.KstatUtil;
18 import oshi.util.platform.unix.solaris.KstatUtil.KstatChain;
19
20
21
22
23 @ThreadSafe
24 public final class SolarisPowerSource extends AbstractPowerSource {
25
26
27 private static final String[] KSTAT_BATT_MOD = { null, "battery", "acpi_drv" };
28
29 private static final int KSTAT_BATT_IDX;
30
31 static {
32 try (KstatChain kc = KstatUtil.openChain()) {
33 if (kc.lookup(KSTAT_BATT_MOD[1], 0, null) != null) {
34 KSTAT_BATT_IDX = 1;
35 } else if (kc.lookup(KSTAT_BATT_MOD[2], 0, null) != null) {
36 KSTAT_BATT_IDX = 2;
37 } else {
38 KSTAT_BATT_IDX = 0;
39 }
40 }
41 }
42
43 public SolarisPowerSource(String psName, String psDeviceName, double psRemainingCapacityPercent,
44 double psTimeRemainingEstimated, double psTimeRemainingInstant, double psPowerUsageRate, double psVoltage,
45 double psAmperage, boolean psPowerOnLine, boolean psCharging, boolean psDischarging,
46 CapacityUnits psCapacityUnits, int psCurrentCapacity, int psMaxCapacity, int psDesignCapacity,
47 int psCycleCount, String psChemistry, LocalDate psManufactureDate, String psManufacturer,
48 String psSerialNumber, double psTemperature) {
49 super(psName, psDeviceName, psRemainingCapacityPercent, psTimeRemainingEstimated, psTimeRemainingInstant,
50 psPowerUsageRate, psVoltage, psAmperage, psPowerOnLine, psCharging, psDischarging, psCapacityUnits,
51 psCurrentCapacity, psMaxCapacity, psDesignCapacity, psCycleCount, psChemistry, psManufactureDate,
52 psManufacturer, psSerialNumber, psTemperature);
53 }
54
55
56
57
58
59
60 public static List<PowerSource> getPowerSources() {
61 return Arrays.asList(getPowerSource("BAT0"));
62 }
63
64 private static SolarisPowerSource getPowerSource(String name) {
65 String psName = name;
66 String psDeviceName = Constants.UNKNOWN;
67 double psRemainingCapacityPercent = 1d;
68 double psTimeRemainingEstimated = -1d;
69 double psTimeRemainingInstant = 0d;
70 double psPowerUsageRate = 0d;
71 double psVoltage = -1d;
72 double psAmperage = 0d;
73 boolean psPowerOnLine = false;
74 boolean psCharging = false;
75 boolean psDischarging = false;
76 CapacityUnits psCapacityUnits = CapacityUnits.RELATIVE;
77 int psCurrentCapacity = 0;
78 int psMaxCapacity = 1;
79 int psDesignCapacity = 1;
80 int psCycleCount = -1;
81 String psChemistry = Constants.UNKNOWN;
82 LocalDate psManufactureDate = null;
83 String psManufacturer = Constants.UNKNOWN;
84 String psSerialNumber = Constants.UNKNOWN;
85 double psTemperature = 0d;
86
87
88 if (KSTAT_BATT_IDX > 0) {
89
90 try (KstatChain kc = KstatUtil.openChain()) {
91 Kstat ksp = kc.lookup(KSTAT_BATT_MOD[KSTAT_BATT_IDX], 0, "battery BIF0");
92 if (ksp != null && kc.read(ksp)) {
93
94 long energyFull = KstatUtil.dataLookupLong(ksp, "bif_last_cap");
95 if (energyFull == 0xffffffff || energyFull <= 0) {
96 energyFull = KstatUtil.dataLookupLong(ksp, "bif_design_cap");
97 }
98 if (energyFull != 0xffffffff && energyFull > 0) {
99 psMaxCapacity = (int) energyFull;
100 }
101 long unit = KstatUtil.dataLookupLong(ksp, "bif_unit");
102 if (unit == 0) {
103 psCapacityUnits = CapacityUnits.MWH;
104 } else if (unit == 1) {
105 psCapacityUnits = CapacityUnits.MAH;
106 }
107 psDeviceName = KstatUtil.dataLookupString(ksp, "bif_model");
108 psSerialNumber = KstatUtil.dataLookupString(ksp, "bif_serial");
109 psChemistry = KstatUtil.dataLookupString(ksp, "bif_type");
110 psManufacturer = KstatUtil.dataLookupString(ksp, "bif_oem_info");
111 }
112
113
114 ksp = kc.lookup(KSTAT_BATT_MOD[KSTAT_BATT_IDX], 0, "battery BST0");
115 if (ksp != null && kc.read(ksp)) {
116
117 long energyNow = KstatUtil.dataLookupLong(ksp, "bst_rem_cap");
118 if (energyNow >= 0) {
119 psCurrentCapacity = (int) energyNow;
120 }
121
122 long powerNow = KstatUtil.dataLookupLong(ksp, "bst_rate");
123 if (powerNow == 0xFFFFFFFF) {
124 powerNow = 0L;
125 }
126
127
128
129
130 boolean isCharging = (KstatUtil.dataLookupLong(ksp, "bst_state") & 0x10) > 0;
131
132 if (!isCharging) {
133 psTimeRemainingEstimated = powerNow > 0 ? 3600d * energyNow / powerNow : -1d;
134 }
135
136 long voltageNow = KstatUtil.dataLookupLong(ksp, "bst_voltage");
137 if (voltageNow > 0) {
138 psVoltage = voltageNow / 1000d;
139 psAmperage = psPowerUsageRate * 1000d / voltageNow;
140 }
141 }
142 }
143 }
144
145 return new SolarisPowerSource(psName, psDeviceName, psRemainingCapacityPercent, psTimeRemainingEstimated,
146 psTimeRemainingInstant, psPowerUsageRate, psVoltage, psAmperage, psPowerOnLine, psCharging,
147 psDischarging, psCapacityUnits, psCurrentCapacity, psMaxCapacity, psDesignCapacity, psCycleCount,
148 psChemistry, psManufactureDate, psManufacturer, psSerialNumber, psTemperature);
149 }
150 }