github.com/wtfutil/wtf@v0.43.0/modules/power/managed_devices.go (about) 1 package power 2 3 import ( 4 "bufio" 5 "fmt" 6 "os/exec" 7 "strconv" 8 "strings" 9 10 "github.com/wtfutil/wtf/utils" 11 ) 12 13 // ManageDevices are ... 14 type ManagedDevices struct { 15 Devices []*ManagedDevice 16 17 args []string 18 cmd string 19 } 20 21 func NewManagedDevices() *ManagedDevices { 22 manDevices := &ManagedDevices{ 23 Devices: []*ManagedDevice{}, 24 25 // This command queries for all managed devices 26 args: []string{"-c", "AppleDeviceManagementHIDEventService", "-r", "-l"}, 27 cmd: "ioreg", 28 } 29 30 return manDevices 31 } 32 33 func (manDevices *ManagedDevices) Refresh() { 34 cmd := exec.Command(manDevices.cmd, manDevices.args...) 35 data := utils.ExecuteCommand(cmd) 36 37 manDevices.Devices = manDevices.parse(data) 38 } 39 40 /* -------------------- Unexported Functions -------------------- */ 41 42 // parse takes the output of the command and turns it into ManagedDevice instances 43 func (manDevices *ManagedDevices) parse(data string) []*ManagedDevice { 44 devices := []*ManagedDevice{} 45 46 chunks := utils.FindBetween(data, "{\n", "}\n") 47 48 for _, chunk := range chunks { 49 manDev := NewManagedDevice() 50 manDev.Add(chunk) 51 52 devices = append(devices, manDev) 53 } 54 55 return devices 56 } 57 58 /* -------------------- And Another Thing -------------------- */ 59 60 // ManagedDevice represents an entry in the output returned by ioreg when 61 // passed AppleDeviceManagementHIDEventService 62 type ManagedDevice struct { 63 Attributes map[string]string 64 } 65 66 func NewManagedDevice() *ManagedDevice { 67 manDev := &ManagedDevice{ 68 Attributes: map[string]string{}, 69 } 70 71 return manDev 72 } 73 74 /* -------------------- Exported Functions -------------------- */ 75 76 // Add takes a chunk of raw text and attempts to parse it as managed device data 77 // and create an attribute map from it. 78 /* 79 A typical chunk will look like: 80 81 "LowBatteryNotificationPercentage" = 2 82 "BatteryFaultNotificationType" = "TPBatteryFault" 83 ... 84 "VersionNumber" = 0 85 86 which should become: 87 88 { 89 "LowBatteryNotificationPercentage": 2, 90 "BatteryFaultNotificationType": "TPBatteryFault", 91 "VersionNumber": 0, 92 } 93 */ 94 func (manDev *ManagedDevice) Add(chunk string) { 95 scanner := bufio.NewScanner(strings.NewReader(chunk)) 96 97 for scanner.Scan() { 98 line := strings.ReplaceAll(scanner.Text(), "\"", "") 99 100 pieces := strings.Split(line, "=") 101 if len(pieces) == 2 { 102 left := strings.TrimSpace(pieces[0]) 103 right := strings.TrimSpace(pieces[1]) 104 105 manDev.Attributes[left] = right 106 } 107 } 108 } 109 110 // Dump writes out all the device attributes as a single string 111 func (manDev *ManagedDevice) Dump() string { 112 out := "" 113 114 for attribute, value := range manDev.Attributes { 115 out += fmt.Sprintf("%s %s\n", attribute, value) 116 } 117 118 return out 119 } 120 121 /* -------------------- Attributes -------------------- */ 122 123 // BatteryPercent returns the percent of the device battery 124 func (manDev *ManagedDevice) BatteryPercent() int64 { 125 percent, err := strconv.ParseInt(manDev.Attributes["BatteryPercent"], 10, 64) 126 if err != nil { 127 return -1 128 } 129 130 return percent 131 } 132 133 // BluetoothDevice returns whether or not the device supports bluetooth 134 func (manDev *ManagedDevice) BluetoothDevice() bool { 135 return manDev.Attributes["BluetoothDevice"] == "Yes" 136 } 137 138 // BuiltIn returns whether or not the device is built into the computer 139 func (manDev *ManagedDevice) BuiltIn() bool { 140 return manDev.Attributes["BuiltIn"] == "Yes" 141 } 142 143 // HasBattery returns whether or not the device has a battery 144 func (manDev *ManagedDevice) HasBattery() bool { 145 return manDev.Attributes["HasBattery"] == "Yes" 146 } 147 148 // Product returns the name of the device 149 func (manDev *ManagedDevice) Product() string { 150 return manDev.Attributes["Product"] 151 }