1// Copyright 2018 The Prometheus Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14// +build !windows 15 16package sysfs 17 18import ( 19 "fmt" 20 "io/ioutil" 21 "path/filepath" 22 23 "github.com/prometheus/procfs/internal/util" 24) 25 26// PowerSupply contains info from files in /sys/class/power_supply for a 27// single power supply. 28type PowerSupply struct { 29 Name string // Power Supply Name 30 Authentic *int64 // /sys/class/power_supply/<Name>/authentic 31 Calibrate *int64 // /sys/class/power_supply/<Name>/calibrate 32 Capacity *int64 // /sys/class/power_supply/<Name>/capacity 33 CapacityAlertMax *int64 // /sys/class/power_supply/<Name>/capacity_alert_max 34 CapacityAlertMin *int64 // /sys/class/power_supply/<Name>/capacity_alert_min 35 CapacityLevel string // /sys/class/power_supply/<Name>/capacity_level 36 ChargeAvg *int64 // /sys/class/power_supply/<Name>/charge_avg 37 ChargeControlLimit *int64 // /sys/class/power_supply/<Name>/charge_control_limit 38 ChargeControlLimitMax *int64 // /sys/class/power_supply/<Name>/charge_control_limit_max 39 ChargeCounter *int64 // /sys/class/power_supply/<Name>/charge_counter 40 ChargeEmpty *int64 // /sys/class/power_supply/<Name>/charge_empty 41 ChargeEmptyDesign *int64 // /sys/class/power_supply/<Name>/charge_empty_design 42 ChargeFull *int64 // /sys/class/power_supply/<Name>/charge_full 43 ChargeFullDesign *int64 // /sys/class/power_supply/<Name>/charge_full_design 44 ChargeNow *int64 // /sys/class/power_supply/<Name>/charge_now 45 ChargeTermCurrent *int64 // /sys/class/power_supply/<Name>/charge_term_current 46 ChargeType string // /sys/class/power_supply/<Name>/charge_type 47 ConstantChargeCurrent *int64 // /sys/class/power_supply/<Name>/constant_charge_current 48 ConstantChargeCurrentMax *int64 // /sys/class/power_supply/<Name>/constant_charge_current_max 49 ConstantChargeVoltage *int64 // /sys/class/power_supply/<Name>/constant_charge_voltage 50 ConstantChargeVoltageMax *int64 // /sys/class/power_supply/<Name>/constant_charge_voltage_max 51 CurrentAvg *int64 // /sys/class/power_supply/<Name>/current_avg 52 CurrentBoot *int64 // /sys/class/power_supply/<Name>/current_boot 53 CurrentMax *int64 // /sys/class/power_supply/<Name>/current_max 54 CurrentNow *int64 // /sys/class/power_supply/<Name>/current_now 55 CycleCount *int64 // /sys/class/power_supply/<Name>/cycle_count 56 EnergyAvg *int64 // /sys/class/power_supply/<Name>/energy_avg 57 EnergyEmpty *int64 // /sys/class/power_supply/<Name>/energy_empty 58 EnergyEmptyDesign *int64 // /sys/class/power_supply/<Name>/energy_empty_design 59 EnergyFull *int64 // /sys/class/power_supply/<Name>/energy_full 60 EnergyFullDesign *int64 // /sys/class/power_supply/<Name>/energy_full_design 61 EnergyNow *int64 // /sys/class/power_supply/<Name>/energy_now 62 Health string // /sys/class/power_supply/<Name>/health 63 InputCurrentLimit *int64 // /sys/class/power_supply/<Name>/input_current_limit 64 Manufacturer string // /sys/class/power_supply/<Name>/manufacturer 65 ModelName string // /sys/class/power_supply/<Name>/model_name 66 Online *int64 // /sys/class/power_supply/<Name>/online 67 PowerAvg *int64 // /sys/class/power_supply/<Name>/power_avg 68 PowerNow *int64 // /sys/class/power_supply/<Name>/power_now 69 PrechargeCurrent *int64 // /sys/class/power_supply/<Name>/precharge_current 70 Present *int64 // /sys/class/power_supply/<Name>/present 71 Scope string // /sys/class/power_supply/<Name>/scope 72 SerialNumber string // /sys/class/power_supply/<Name>/serial_number 73 Status string // /sys/class/power_supply/<Name>/status 74 Technology string // /sys/class/power_supply/<Name>/technology 75 Temp *int64 // /sys/class/power_supply/<Name>/temp 76 TempAlertMax *int64 // /sys/class/power_supply/<Name>/temp_alert_max 77 TempAlertMin *int64 // /sys/class/power_supply/<Name>/temp_alert_min 78 TempAmbient *int64 // /sys/class/power_supply/<Name>/temp_ambient 79 TempAmbientMax *int64 // /sys/class/power_supply/<Name>/temp_ambient_max 80 TempAmbientMin *int64 // /sys/class/power_supply/<Name>/temp_ambient_min 81 TempMax *int64 // /sys/class/power_supply/<Name>/temp_max 82 TempMin *int64 // /sys/class/power_supply/<Name>/temp_min 83 TimeToEmptyAvg *int64 // /sys/class/power_supply/<Name>/time_to_empty_avg 84 TimeToEmptyNow *int64 // /sys/class/power_supply/<Name>/time_to_empty_now 85 TimeToFullAvg *int64 // /sys/class/power_supply/<Name>/time_to_full_avg 86 TimeToFullNow *int64 // /sys/class/power_supply/<Name>/time_to_full_now 87 Type string // /sys/class/power_supply/<Name>/type 88 UsbType string // /sys/class/power_supply/<Name>/usb_type 89 VoltageAvg *int64 // /sys/class/power_supply/<Name>/voltage_avg 90 VoltageBoot *int64 // /sys/class/power_supply/<Name>/voltage_boot 91 VoltageMax *int64 // /sys/class/power_supply/<Name>/voltage_max 92 VoltageMaxDesign *int64 // /sys/class/power_supply/<Name>/voltage_max_design 93 VoltageMin *int64 // /sys/class/power_supply/<Name>/voltage_min 94 VoltageMinDesign *int64 // /sys/class/power_supply/<Name>/voltage_min_design 95 VoltageNow *int64 // /sys/class/power_supply/<Name>/voltage_now 96 VoltageOCV *int64 // /sys/class/power_supply/<Name>/voltage_ocv 97} 98 99// PowerSupplyClass is a collection of every power supply in 100// /sys/class/power_supply. 101// 102// The map keys are the names of the power supplies. 103type PowerSupplyClass map[string]PowerSupply 104 105// PowerSupplyClass returns info for all power supplies read from 106// /sys/class/power_supply. 107func (fs FS) PowerSupplyClass() (PowerSupplyClass, error) { 108 path := fs.sys.Path("class/power_supply") 109 110 dirs, err := ioutil.ReadDir(path) 111 if err != nil { 112 return nil, fmt.Errorf("failed to list power supplies at %q: %v", path, err) 113 } 114 115 psc := make(PowerSupplyClass, len(dirs)) 116 for _, d := range dirs { 117 ps, err := parsePowerSupply(filepath.Join(path, d.Name())) 118 if err != nil { 119 return nil, err 120 } 121 122 ps.Name = d.Name() 123 psc[d.Name()] = *ps 124 } 125 126 return psc, nil 127} 128 129func parsePowerSupply(path string) (*PowerSupply, error) { 130 files, err := ioutil.ReadDir(path) 131 if err != nil { 132 return nil, err 133 } 134 135 var ps PowerSupply 136 for _, f := range files { 137 if f.IsDir() { 138 continue 139 } 140 141 name := filepath.Join(path, f.Name()) 142 value, err := util.SysReadFile(name) 143 if err != nil { 144 return nil, fmt.Errorf("failed to read file %q: %v", name, err) 145 } 146 147 vp := util.NewValueParser(value) 148 149 switch f.Name() { 150 case "authentic": 151 ps.Authentic = vp.PInt64() 152 case "calibrate": 153 ps.Calibrate = vp.PInt64() 154 case "capacity": 155 ps.Capacity = vp.PInt64() 156 case "capacity_alert_max": 157 ps.CapacityAlertMax = vp.PInt64() 158 case "capacity_alert_min": 159 ps.CapacityAlertMin = vp.PInt64() 160 case "capacity_level": 161 ps.CapacityLevel = value 162 case "charge_avg": 163 ps.ChargeAvg = vp.PInt64() 164 case "charge_control_limit": 165 ps.ChargeControlLimit = vp.PInt64() 166 case "charge_control_limit_max": 167 ps.ChargeControlLimitMax = vp.PInt64() 168 case "charge_counter": 169 ps.ChargeCounter = vp.PInt64() 170 case "charge_empty": 171 ps.ChargeEmpty = vp.PInt64() 172 case "charge_empty_design": 173 ps.ChargeEmptyDesign = vp.PInt64() 174 case "charge_full": 175 ps.ChargeFull = vp.PInt64() 176 case "charge_full_design": 177 ps.ChargeFullDesign = vp.PInt64() 178 case "charge_now": 179 ps.ChargeNow = vp.PInt64() 180 case "charge_term_current": 181 ps.ChargeTermCurrent = vp.PInt64() 182 case "charge_type": 183 ps.ChargeType = value 184 case "constant_charge_current": 185 ps.ConstantChargeCurrent = vp.PInt64() 186 case "constant_charge_current_max": 187 ps.ConstantChargeCurrentMax = vp.PInt64() 188 case "constant_charge_voltage": 189 ps.ConstantChargeVoltage = vp.PInt64() 190 case "constant_charge_voltage_max": 191 ps.ConstantChargeVoltageMax = vp.PInt64() 192 case "current_avg": 193 ps.CurrentAvg = vp.PInt64() 194 case "current_boot": 195 ps.CurrentBoot = vp.PInt64() 196 case "current_max": 197 ps.CurrentMax = vp.PInt64() 198 case "current_now": 199 ps.CurrentNow = vp.PInt64() 200 case "cycle_count": 201 ps.CycleCount = vp.PInt64() 202 case "energy_avg": 203 ps.EnergyAvg = vp.PInt64() 204 case "energy_empty": 205 ps.EnergyEmpty = vp.PInt64() 206 case "energy_empty_design": 207 ps.EnergyEmptyDesign = vp.PInt64() 208 case "energy_full": 209 ps.EnergyFull = vp.PInt64() 210 case "energy_full_design": 211 ps.EnergyFullDesign = vp.PInt64() 212 case "energy_now": 213 ps.EnergyNow = vp.PInt64() 214 case "health": 215 ps.Health = value 216 case "input_current_limit": 217 ps.InputCurrentLimit = vp.PInt64() 218 case "manufacturer": 219 ps.Manufacturer = value 220 case "model_name": 221 ps.ModelName = value 222 case "online": 223 ps.Online = vp.PInt64() 224 case "power_avg": 225 ps.PowerAvg = vp.PInt64() 226 case "power_now": 227 ps.PowerNow = vp.PInt64() 228 case "precharge_current": 229 ps.PrechargeCurrent = vp.PInt64() 230 case "present": 231 ps.Present = vp.PInt64() 232 case "scope": 233 ps.Scope = value 234 case "serial_number": 235 ps.SerialNumber = value 236 case "status": 237 ps.Status = value 238 case "technology": 239 ps.Technology = value 240 case "temp": 241 ps.Temp = vp.PInt64() 242 case "temp_alert_max": 243 ps.TempAlertMax = vp.PInt64() 244 case "temp_alert_min": 245 ps.TempAlertMin = vp.PInt64() 246 case "temp_ambient": 247 ps.TempAmbient = vp.PInt64() 248 case "temp_ambient_max": 249 ps.TempAmbientMax = vp.PInt64() 250 case "temp_ambient_min": 251 ps.TempAmbientMin = vp.PInt64() 252 case "temp_max": 253 ps.TempMax = vp.PInt64() 254 case "temp_min": 255 ps.TempMin = vp.PInt64() 256 case "time_to_empty_avg": 257 ps.TimeToEmptyAvg = vp.PInt64() 258 case "time_to_empty_now": 259 ps.TimeToEmptyNow = vp.PInt64() 260 case "time_to_full_avg": 261 ps.TimeToFullAvg = vp.PInt64() 262 case "time_to_full_now": 263 ps.TimeToFullNow = vp.PInt64() 264 case "type": 265 ps.Type = value 266 case "usb_type": 267 ps.UsbType = value 268 case "voltage_avg": 269 ps.VoltageAvg = vp.PInt64() 270 case "voltage_boot": 271 ps.VoltageBoot = vp.PInt64() 272 case "voltage_max": 273 ps.VoltageMax = vp.PInt64() 274 case "voltage_max_design": 275 ps.VoltageMaxDesign = vp.PInt64() 276 case "voltage_min": 277 ps.VoltageMin = vp.PInt64() 278 case "voltage_min_design": 279 ps.VoltageMinDesign = vp.PInt64() 280 case "voltage_now": 281 ps.VoltageNow = vp.PInt64() 282 case "voltage_ocv": 283 ps.VoltageOCV = vp.PInt64() 284 } 285 286 if err := vp.Err(); err != nil { 287 return nil, err 288 } 289 } 290 291 return &ps, nil 292} 293