├── BatteryStatusShow.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── slee.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings ├── xcshareddata │ ├── xcbaselines │ │ └── 614C00841EC23FA8001543D9.xcbaseline │ │ │ ├── A867FA62-9552-4CAC-B3B0-A0335CC4E9DE.plist │ │ │ └── Info.plist │ └── xcschemes │ │ └── smcutil.xcscheme └── xcuserdata │ └── slee.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── BatteryStatusShow.xcscheme │ └── xcschememanagement.plist ├── BatteryStatusShow ├── .DS_Store ├── AppDelegate.swift ├── Assets.xcassets │ ├── .DS_Store │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── app1024.png │ │ ├── app128.png │ │ ├── app16.png │ │ ├── app256-1.png │ │ ├── app256.png │ │ ├── app32-1.png │ │ ├── app32.png │ │ ├── app512-1.png │ │ ├── app512.png │ │ └── app64.png │ ├── Contents.json │ ├── Graph.imageset │ │ ├── .DS_Store │ │ ├── Contents.json │ │ ├── graph32.png │ │ └── graph64.png │ ├── Iphone.imageset │ │ ├── Contents.json │ │ ├── com.apple.iphone-7-plus-1_32.png │ │ └── com.apple.iphone-7-plus-1_64.png │ ├── Log.imageset │ │ ├── Contents.json │ │ ├── log32.png │ │ └── log64.png │ └── Mouse.imageset │ │ ├── Contents.json │ │ ├── Mouse32.png │ │ └── Mouse64.png ├── Base.lproj │ └── Main.storyboard ├── BaseChartView.swift ├── BatteryStatusItem.swift ├── BatteryStatusShow.entitlements ├── BatteryStatusShow_loc │ ├── .DS_Store │ └── zh_tw.xliff ├── BatteryViewController.swift ├── Bridging-Header.h ├── ChartViewController.swift ├── DataController.swift ├── DetailViewController.swift ├── HistoryMO.swift ├── HistoryViewController.swift ├── IOBattery.swift ├── IOHID.swift ├── IOSModelDict.swift ├── Info.plist ├── LogView.swift ├── LogViewController.swift ├── PeripheralViewControl.swift ├── PowerViewController.swift ├── SmcHelper.h ├── SmcHelper.m ├── StatusBaseChartView.swift ├── TabViewController.swift ├── TwoAxisBaseChartView.swift ├── WindowsController.swift ├── battery.csv ├── change.sh ├── changealldylib.sh ├── data.xcdatamodeld │ ├── .xccurrentversion │ ├── data.xcdatamodel │ │ └── contents │ └── v2.xcdatamodel │ │ └── contents ├── iOSDetailViewController.swift ├── include │ ├── .DS_Store │ ├── libimobiledevice │ │ ├── .DS_Store │ │ ├── diagnostics_relay.h │ │ ├── libimobiledevice.h │ │ └── lockdown.h │ └── plist │ │ └── plist.h ├── iosbattery.csv ├── lib4758cca.dylib ├── libaep.dylib ├── libatalla.dylib ├── libcapi.dylib ├── libchil.dylib ├── libcrypto.1.0.0.dylib ├── libcrypto.a ├── libcrypto.dylib ├── libcswift.dylib ├── libgmp.dylib ├── libgost.dylib ├── libimobiledevice.6.dylib ├── libimobiledevice.a ├── libimobiledevice.dylib ├── libimobiledevice.la ├── libltdl.7.dylib ├── libltdl.a ├── libltdl.dylib ├── libltdl.la ├── libnuron.dylib ├── libpadlock.dylib ├── libplist++.3.dylib ├── libplist++.a ├── libplist++.dylib ├── libplist++.la ├── libplist.3.dylib ├── libplist.a ├── libplist.dylib ├── libplist.la ├── libssl.1.0.0.dylib ├── libssl.a ├── libssl.dylib ├── libsureware.dylib ├── libubsec.dylib ├── libusb-1.0.0.dylib ├── libusb-1.0.a ├── libusb-1.0.dylib ├── libusb-1.0.la ├── libusbmuxd.4.dylib ├── libusbmuxd.a ├── libusbmuxd.dylib ├── libusbmuxd.la ├── libxml2.2.dylib ├── libxml2.a ├── libxml2.dylib ├── libxml2.la ├── mapping .xcmappingmodel │ └── xcmapping.xml ├── mappingtoold.xcmappingmodel │ └── xcmapping.xml ├── program_inside_script.sh ├── smc.c ├── smc.h ├── smcutil └── smcutil-Prefix.pch ├── BatteryStatusShowTests ├── BatteryStatusShowTests.swift └── Info.plist ├── BatteryStatusShowUITests ├── BatteryStatusShowUITests.swift └── Info.plist ├── CycleEntityMigrationPolicy.swift ├── IOSHistoryViewController.swift ├── LICENSE ├── README.md ├── README ├── readme_pic1.png └── readme_pic2.png ├── release ├── BatteryStatusShow_1.5.1.zip ├── BatteryStatusShow_1.5.2.zip ├── BatteryStatusShow_1.5.3.zip ├── BatteryStatusShow_1.5.41.zip └── BatteryStatusShow_1.5.5.zip └── smcutil └── main.m /BatteryStatusShow.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/project.xcworkspace/xcuserdata/slee.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow.xcodeproj/project.xcworkspace/xcuserdata/slee.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/project.xcworkspace/xcuserdata/slee.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | EnabledFullIndexStoreVisibility 12 | 13 | IssueFilterStyle 14 | ShowActiveSchemeOnly 15 | LiveSourceIssuesEnabled 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/xcshareddata/xcbaselines/614C00841EC23FA8001543D9.xcbaseline/A867FA62-9552-4CAC-B3B0-A0335CC4E9DE.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | classNames 6 | 7 | BatteryStatusShowTests 8 | 9 | testPerformanceDatabase() 10 | 11 | com.apple.XCTPerformanceMetric_WallClockTime 12 | 13 | baselineAverage 14 | 4.39 15 | baselineIntegrationDisplayName 16 | 2017年6月24日 下午6:31:45 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/xcshareddata/xcbaselines/614C00841EC23FA8001543D9.xcbaseline/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | runDestinationsByUUID 6 | 7 | A867FA62-9552-4CAC-B3B0-A0335CC4E9DE 8 | 9 | localComputer 10 | 11 | busSpeedInMHz 12 | 100 13 | cpuCount 14 | 1 15 | cpuKind 16 | Intel Core M 17 | cpuSpeedInMHz 18 | 1100 19 | logicalCPUCoresPerPackage 20 | 4 21 | modelCode 22 | MacBook8,1 23 | physicalCPUCoresPerPackage 24 | 2 25 | platformIdentifier 26 | com.apple.platform.macosx 27 | 28 | targetArchitecture 29 | x86_64 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/xcshareddata/xcschemes/smcutil.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/xcuserdata/slee.xcuserdatad/xcschemes/BatteryStatusShow.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 52 | 58 | 59 | 60 | 61 | 62 | 72 | 74 | 80 | 81 | 82 | 83 | 89 | 91 | 97 | 98 | 99 | 100 | 102 | 103 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /BatteryStatusShow.xcodeproj/xcuserdata/slee.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BatteryStatusShow.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | smcutil.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 614C00731EC23FA8001543D9 21 | 22 | primary 23 | 24 | 25 | 614C00841EC23FA8001543D9 26 | 27 | primary 28 | 29 | 30 | 614C008F1EC23FA8001543D9 31 | 32 | primary 33 | 34 | 35 | 6193277224708379000EA703 36 | 37 | primary 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /BatteryStatusShow/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/.DS_Store -------------------------------------------------------------------------------- /BatteryStatusShow/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/10. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | 13 | 14 | 15 | @NSApplicationMain 16 | class AppDelegate: NSObject, NSApplicationDelegate { 17 | 18 | static let programprefix = "sicreativelee.batterystatusshow" 19 | 20 | static let user_default_alwayontop_key = "alwayontop" 21 | static let alwayontop_notify = AppDelegate.programprefix + ".alwayontopnotify" 22 | 23 | @IBAction func linkHomePage(_ sender: Any) { 24 | if let url = URL(string: "https://github.com/sicreative/BatteryStatusShow"), NSWorkspace.shared.open(url) { 25 | 26 | } 27 | } 28 | 29 | @IBOutlet weak var alwaysOnTopMenu: NSMenuItem! 30 | 31 | 32 | 33 | var batterystatus = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength) 34 | var windowscontroller : NSWindowController! 35 | var iobattery : IOBattery! 36 | var datacontroller : DataController! 37 | var ioHID : IOHID! 38 | var batterystatusitem : BatteryStatusItem! 39 | 40 | @IBAction func alwaysOnTopMenuAction(_ sender: NSMenuItem) { 41 | 42 | sender.state = NSControl.StateValue(rawValue: sender.state.rawValue == 0 ? 1 : 0) 43 | 44 | UserDefaults.standard.set(sender.state, forKey: AppDelegate.user_default_alwayontop_key) 45 | 46 | NotificationCenter.default.post(name:Notification.Name(rawValue:AppDelegate.alwayontop_notify),object: nil,userInfo:nil) 47 | 48 | 49 | 50 | } 51 | 52 | func applicationDidFinishLaunching(_ aNotification: Notification) { 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | startApplication() 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | } 72 | 73 | func startApplication(){ 74 | 75 | datacontroller = DataController(completionClosure: self.datacontrollerfinished); 76 | } 77 | 78 | 79 | 80 | 81 | func datacontrollerfinished(){ 82 | 83 | if #available(OSX 10.12.2, *) { 84 | NSApplication.shared.isAutomaticCustomizeTouchBarMenuItemEnabled = true 85 | } 86 | 87 | 88 | 89 | batterystatusitem = BatteryStatusItem() 90 | 91 | updatestatusbutton(chargestatus:.nobattery, batterylevel: 3) 92 | 93 | if let button = batterystatus.button { 94 | 95 | 96 | 97 | // button.image = NSImage(named: "Status") 98 | button.action = #selector(openmainwindows(sender:)) 99 | 100 | } 101 | 102 | iobattery = IOBattery() 103 | 104 | let storyboard = NSStoryboard.init(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil) 105 | windowscontroller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "mainwindowcontroller")) as? NSWindowController 106 | 107 | 108 | 109 | NSApplication.shared.activate(ignoringOtherApps: true) 110 | 111 | openmainwindows(sender: self) 112 | 113 | 114 | 115 | 116 | 117 | 118 | iobattery.startTimer() 119 | 120 | ioHID = IOHID() 121 | 122 | ioHID.startTimer() 123 | 124 | 125 | 126 | 127 | alwaysOnTopMenu.state = NSControl.StateValue(rawValue: UserDefaults.standard.integer(forKey: AppDelegate.user_default_alwayontop_key)) 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | /* 136 | 137 | (storyboard.instantiateController(withIdentifier: "detailviewcontroller") as! DetailViewController).setIOBattery(iobattery) 138 | 139 | (storyboard.instantiateController(withIdentifier: "iosdetailviewcontroller") as! IOSDetailViewController).setIOBattery(iobattery) 140 | 141 | 142 | 143 | 144 | 145 | (storyboard.instantiateController(withIdentifier: "peripheralviewcontroller") as! PeripheralViewController).ioHID = ioHID 146 | */ 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | } 155 | 156 | func applicationWillFinishLaunching(_ notification: Notification) { 157 | UserDefaults.standard.set(false, forKey: "NSFullScreenMenuItemEverywhere") 158 | 159 | } 160 | 161 | func applicationWillTerminate(_ aNotification: Notification) { 162 | // Insert code here to tear down your application 163 | 164 | iobattery.stopTimer() 165 | ioHID.stopTimer() 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | } 175 | 176 | @objc func openmainwindows(sender: AnyObject){ 177 | 178 | 179 | 180 | if (windowscontroller == nil){ 181 | let storyboard = NSStoryboard.init(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil) 182 | windowscontroller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "mainwindowcontroller")) as? NSWindowController 183 | } 184 | 185 | 186 | 187 | windowscontroller.showWindow(sender) 188 | 189 | 190 | 191 | 192 | 193 | } 194 | 195 | 196 | 197 | 198 | func getBattery()->IOBattery{ 199 | if (iobattery==nil){ 200 | iobattery = IOBattery() 201 | } 202 | return iobattery 203 | } 204 | 205 | func getDataController()->DataController{ 206 | return datacontroller 207 | } 208 | 209 | func updatestatusbutton(chargestatus:BatteryStatusItem.ChangeStatus,batterylevel:Int){ 210 | if let button = batterystatus.button { 211 | if( batterystatusitem.updatelogo(chargestatus: chargestatus, batterylevel: batterylevel)){ 212 | button.image = batterystatusitem.image 213 | } 214 | } 215 | 216 | } 217 | 218 | 219 | func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) ->Bool{ 220 | //datacontrollerfinished() 221 | 222 | if (datacontroller==nil){ 223 | startApplication() 224 | return true 225 | } 226 | 227 | if (iobattery==nil){ 228 | startApplication() 229 | return true 230 | } 231 | 232 | iobattery.startTimer() 233 | ioHID.startTimer() 234 | 235 | openmainwindows(sender: self) 236 | 237 | return true; 238 | } 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | } 249 | 250 | 251 | -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app32-1.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app256-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app512-1.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app1024.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app128.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app16.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app256-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app256-1.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app256.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app32-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app32-1.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app32.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app512-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app512-1.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app512.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/AppIcon.appiconset/app64.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Graph.imageset/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Graph.imageset/.DS_Store -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Graph.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "graph32.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "graph64.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Graph.imageset/graph32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Graph.imageset/graph32.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Graph.imageset/graph64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Graph.imageset/graph64.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Iphone.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "com.apple.iphone-7-plus-1_32.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "com.apple.iphone-7-plus-1_64.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Iphone.imageset/com.apple.iphone-7-plus-1_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Iphone.imageset/com.apple.iphone-7-plus-1_32.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Iphone.imageset/com.apple.iphone-7-plus-1_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Iphone.imageset/com.apple.iphone-7-plus-1_64.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Log.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "log32.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "log64.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Log.imageset/log32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Log.imageset/log32.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Log.imageset/log64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Log.imageset/log64.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Mouse.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Mouse32.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Mouse64.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Mouse.imageset/Mouse32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Mouse.imageset/Mouse32.png -------------------------------------------------------------------------------- /BatteryStatusShow/Assets.xcassets/Mouse.imageset/Mouse64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/Assets.xcassets/Mouse.imageset/Mouse64.png -------------------------------------------------------------------------------- /BatteryStatusShow/BatteryStatusItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatteryStatusItem.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/6/3. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class BatteryStatusItem { 12 | 13 | 14 | var image : NSImage! 15 | private var changestatus :ChangeStatus! 16 | private var batterylevel :Int! 17 | 18 | public enum ChangeStatus { 19 | case nochange 20 | case change_fast 21 | case change_slow 22 | case dischange_fast 23 | case dischange_slow 24 | case dischange_verylight 25 | case nobattery 26 | } 27 | 28 | func updatelogo(chargestatus:ChangeStatus,batterylevel:Int)->Bool{ 29 | 30 | if (self.changestatus != nil && self.batterylevel != nil){ 31 | if (self.changestatus == chargestatus && self.batterylevel == batterylevel){ 32 | if (image != nil){ 33 | return false 34 | } 35 | } 36 | 37 | 38 | 39 | } 40 | 41 | self.changestatus = chargestatus 42 | self.batterylevel = batterylevel 43 | 44 | let size = 36 45 | 46 | 47 | let bitmapdata = calloc(size*4*size,MemoryLayout.size) 48 | 49 | 50 | 51 | 52 | let context = CGContext(data: bitmapdata, width: size, height: size, bitsPerComponent: 8, bytesPerRow: size*4, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) 53 | 54 | 55 | 56 | 57 | 58 | context?.setShouldAntialias(true) 59 | 60 | 61 | context?.setStrokeColor(CGColor.black) 62 | context?.setFillColor(CGColor.black) 63 | 64 | context?.beginPath() 65 | var x = 0; 66 | 67 | context?.addPath(CGPath(roundedRect: CGRect(x: x, y: 6, width: 2, height: 24), cornerWidth: 1, cornerHeight: 1, transform: nil)) 68 | 69 | x += 4 70 | 71 | if (batterylevel>0){ 72 | 73 | for _ in 1...batterylevel { 74 | context?.addPath(CGPath(roundedRect: CGRect(x: x, y: 6, width: 6, height: 24), cornerWidth: 2, cornerHeight: 2, transform: nil)) 75 | x += 6 76 | } 77 | } 78 | 79 | context?.addPath(CGPath(roundedRect: CGRect(x: x, y: 14, width: 4, height: 8), cornerWidth: 1, cornerHeight: 1, transform: nil)) 80 | 81 | 82 | context?.clip() 83 | 84 | 85 | 86 | var gradient_color : [CGFloat] 87 | switch chargestatus { 88 | case .nochange: 89 | gradient_color = [0.3,0.3,0.3,1.0,0.1,0.1,0.1,0.0] 90 | case .change_fast: 91 | gradient_color = [0.5,0.1,0.9,1.0,0.3,0.1,0.6,0.5] 92 | case .change_slow: 93 | gradient_color = [0.4,0.3,0.7,0.5,0.2,0.3,0.5,0.2] 94 | case .dischange_fast: 95 | if (batterylevel>=2){ 96 | gradient_color = [0.1,0.9,0.1,1.0,0.1,0.75,0.1,0.7] 97 | }else if (batterylevel==1){ 98 | gradient_color = [0.9,0.9,0.1,1.0,0.75,0.75,0.1,0.7] 99 | }else{ 100 | gradient_color = [0.9,0.1,0.1,1.0,0.75,0,0.1,0.7] 101 | } 102 | case .dischange_slow: 103 | if (batterylevel>=2){ 104 | gradient_color = [0.2,0.8,0.2,0.9,0.2,0.6,0.2,0.5]} 105 | else if (batterylevel==1){ 106 | gradient_color = [0.8,0.8,0.2,0.9,0.6,0.6,0.2,0.5] 107 | }else{ 108 | gradient_color = [0.9,0.1,0.1,1.0,0.75,0,0.1,0.7] 109 | } 110 | case .dischange_verylight: 111 | if (batterylevel>=2){ 112 | gradient_color = [0.3,0.7,0.3,0.8,0.3,0.5,0.3,0.4]} 113 | else if (batterylevel==1){ 114 | gradient_color = [0.7,0.7,0.3,0.8,0.5,0.5,0.3,0.4] 115 | }else{ 116 | gradient_color = [0.9,0.1,0.1,1.0,0.75,0,0.1,0.7] 117 | } 118 | default: 119 | gradient_color = [0.9,0.9,0.9,1.0,0.5,0.5,0.5,0.0] 120 | 121 | } 122 | 123 | 124 | let gradient_location :[CGFloat] = [0.0,1.0] 125 | 126 | 127 | let gradient = CGGradient(colorSpace: CGColorSpaceCreateDeviceRGB(), colorComponents: gradient_color, locations: gradient_location, count: gradient_location.count) 128 | 129 | 130 | context?.drawRadialGradient(gradient!, startCenter: CGPoint(x:CGFloat(16),y:CGFloat(16)), startRadius: 0, endCenter: CGPoint(x:CGFloat(16),y:CGFloat(16)), endRadius: 28, options: CGGradientDrawingOptions.drawsBeforeStartLocation) 131 | 132 | 133 | 134 | 135 | // context?.fillPath() 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | // CGImage(maskWidth: size, height: size, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: size/8, provider: CGDataProvider(dataInfo:nil,data:bitmapdata!,size:size*4*36*8,releaseData: CGDataProviderReleaseDataCallback()), decode: nil, shouldInterpolate: false) 147 | 148 | image = NSImage(cgImage: context!.makeImage()!, size: NSSize(width: size/2, height: size/2)) 149 | 150 | free (bitmapdata) 151 | 152 | 153 | 154 | return true 155 | 156 | 157 | 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /BatteryStatusShow/BatteryStatusShow.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.disable-library-validation 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BatteryStatusShow/BatteryStatusShow_loc/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/BatteryStatusShow_loc/.DS_Store -------------------------------------------------------------------------------- /BatteryStatusShow/BatteryViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatteryViewController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/11. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class BatteryViewController: NSViewController { 12 | 13 | 14 | 15 | var iobattery:IOBattery! 16 | var datacontroller:DataController! 17 | 18 | 19 | 20 | var lastupdate:NSNumber = 0 21 | 22 | 23 | 24 | 25 | 26 | var timer: DispatchSourceTimer? 27 | 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | NotificationCenter.default.addObserver(self, selector:#selector(BatteryViewController.update), name: NSNotification.Name(rawValue:IOBattery.updatenotify), object: nil) 31 | 32 | self.view.window?.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.floatingWindow))) 33 | 34 | // Do any additional setup after loading the view. 35 | } 36 | 37 | override func viewDidAppear() { 38 | 39 | super.viewDidAppear() 40 | datacontroller = (NSApplication.shared.delegate as! AppDelegate).getDataController() 41 | 42 | update() 43 | updatebatterydesc() 44 | 45 | 46 | 47 | 48 | } 49 | 50 | override func viewWillDisappear() { 51 | // NotificationCenter.default.removeObserver(self) 52 | super.viewWillDisappear() 53 | 54 | } 55 | 56 | 57 | 58 | 59 | /* 60 | 61 | public func startTimer() { 62 | let labelid = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String 63 | let queue = DispatchQueue(label: (labelid! + "." + String(describing: type(of: self))), attributes: .concurrent) 64 | 65 | timer?.cancel() // cancel previous timer if any 66 | 67 | timer = DispatchSource.makeTimerSource(queue: queue) 68 | 69 | timer?.scheduleRepeating(deadline: .now(), interval: .seconds(interval), leeway: .seconds(1)) 70 | 71 | timer?.setEventHandler { // `[weak self]` only needed if you reference `self` in this closure and you want to prevent strong reference cycle 72 | 73 | 74 | self.update() 75 | 76 | 77 | } 78 | 79 | timer?.resume() 80 | } 81 | 82 | public func stopTimer() { 83 | timer?.cancel() 84 | timer = nil 85 | } 86 | */ 87 | 88 | @objc func update(){ 89 | 90 | 91 | 92 | if (iobattery==nil){ 93 | 94 | 95 | DispatchQueue.main.async{ 96 | self.iobattery = (NSApplication.shared.delegate as! AppDelegate).getBattery() 97 | self.updatebatterydesc() 98 | } 99 | 100 | } 101 | DispatchQueue.main.async{ 102 | if (Int(truncating: self.iobattery.lastupdatetime) > Int(truncating: self.lastupdate) ){ 103 | 104 | 105 | 106 | self.updatebatteryinfo() 107 | 108 | 109 | 110 | self.lastupdate = self.iobattery.lastupdatetime 111 | 112 | 113 | } 114 | 115 | 116 | } 117 | 118 | DispatchQueue.main.async{ 119 | self.updateview() 120 | } 121 | 122 | } 123 | 124 | func updateview(){ 125 | 126 | } 127 | 128 | func updatebatteryinfo(){ 129 | 130 | 131 | } 132 | 133 | func updatebatterydesc(){ 134 | 135 | 136 | 137 | 138 | } 139 | 140 | 141 | 142 | 143 | override var representedObject: Any? { 144 | didSet { 145 | 146 | // Update the view, if already loaded. 147 | 148 | 149 | 150 | } 151 | } 152 | 153 | 154 | 155 | func setIOBattery(_ iobattery:IOBattery){ 156 | self.iobattery = iobattery 157 | 158 | // self.iobattery = (NSApplication.shared.delegate as! AppDelegate).getBattery(); 159 | 160 | 161 | 162 | 163 | } 164 | 165 | 166 | } 167 | 168 | -------------------------------------------------------------------------------- /BatteryStatusShow/Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Bridging-Heading.h 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/27. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | #ifndef Bridging_Heading_h 10 | #define Bridging_Heading_h 11 | 12 | 13 | 14 | #include "include/libimobiledevice/libimobiledevice.h" 15 | #include "include/libimobiledevice/diagnostics_relay.h" 16 | #include "include/libimobiledevice/lockdown.h" 17 | 18 | 19 | 20 | #endif /* Bridging_Heading_h */ 21 | -------------------------------------------------------------------------------- /BatteryStatusShow/ChartViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatViewController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/16. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | import Cocoa 9 | 10 | class ChartViewController: BatteryViewController { 11 | 12 | 13 | 14 | override func updatebatteryinfo() { 15 | 16 | } 17 | 18 | override func updatebatterydesc() { 19 | 20 | } 21 | 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /BatteryStatusShow/DataController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/17. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | class DataController : NSObject { 13 | 14 | 15 | var managedObjectContext: NSManagedObjectContext 16 | 17 | 18 | init(completionClosure: @escaping () -> ()) { 19 | //This resource is the same name as your xcdatamodeld contained in your project 20 | guard let modelURL = Bundle.main.url(forResource: "data", withExtension:"momd") else { 21 | fatalError("Error loading model from bundle") 22 | } 23 | // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. 24 | guard let mom = NSManagedObjectModel(contentsOf: modelURL) else { 25 | fatalError("Error initializing mom from: \(modelURL)") 26 | } 27 | 28 | let psc = NSPersistentStoreCoordinator(managedObjectModel: mom) 29 | 30 | managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType) 31 | managedObjectContext.persistentStoreCoordinator = psc 32 | 33 | let queue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background) 34 | queue.async { 35 | guard var docURL = FileManager.default.urls(for: .applicationSupportDirectory , in: .userDomainMask).last else { 36 | fatalError("Unable to resolve document directory") 37 | } 38 | 39 | docURL.appendPathComponent((Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String)!) 40 | 41 | let isDir = UnsafeMutablePointer.allocate(capacity: 1) 42 | isDir.initialize(to: ObjCBool(true)) 43 | 44 | if (!FileManager.default.fileExists(atPath: docURL.path, isDirectory: isDir)){ 45 | 46 | do { 47 | 48 | try FileManager.default.createDirectory(at:docURL, withIntermediateDirectories: false, attributes: nil) 49 | } catch let error as NSError { 50 | print(error.localizedDescription); 51 | } 52 | } 53 | 54 | isDir.deinitialize(count: 0) 55 | 56 | let storeURL = docURL.appendingPathComponent("data.sqlite") 57 | do { 58 | try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption:true]) 59 | //The callback block is expected to complete the User Interface and therefore should be presented back on the main queue so that the user interface does not need to be concerned with which queue this call is coming from. 60 | DispatchQueue.main.sync(execute: completionClosure) 61 | } catch { 62 | 63 | // fatalError("Error migrating store: \(error)") 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /BatteryStatusShow/HistoryMO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HistoryMO.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/17. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | 13 | class HistoryMO: NSManagedObject { 14 | @NSManaged var capacity: NSNumber? 15 | @NSManaged var cycle: NSNumber? 16 | @NSManaged var time: Date? 17 | @NSManaged var temperature: NSNumber? 18 | @NSManaged var serialno: NSString? 19 | 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /BatteryStatusShow/HistoryViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HistoryViewController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/16. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class HistoryViewController: BatteryViewController { 12 | 13 | var history: [HistoryMO]! 14 | 15 | 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | (view as! BaseChartView).title.stringValue = "Battery Health" 21 | (view as! BaseChartView).title.sizeToFit() 22 | 23 | (view as! BaseChartView).ytitle.stringValue = "capacity" 24 | (view as! BaseChartView).ytitle.sizeToFit() 25 | 26 | (view as! BaseChartView).xtitle.stringValue = "months" 27 | (view as! BaseChartView).xtitle.sizeToFit() 28 | 29 | 30 | 31 | (view as! BaseChartView).showbelowcolor = true 32 | (view as! BaseChartView).showmaxmin = true 33 | 34 | 35 | 36 | 37 | // Do any additional setup after loading the view. 38 | } 39 | 40 | 41 | 42 | 43 | 44 | override func updatebatterydesc() { 45 | 46 | (view as! BaseChartView).linechart.removeAll() 47 | 48 | (view as! BaseChartView).rowstep = iobattery.design_capacity / 4 49 | (view as! BaseChartView).rowinit = iobattery.design_capacity / 4 50 | 51 | 52 | 53 | 54 | 55 | 56 | let historyFetch :NSFetchRequest = NSFetchRequest(entityName: "History") 57 | historyFetch.sortDescriptors = [NSSortDescriptor(key: "time", ascending: true)] 58 | 59 | historyFetch.predicate = NSPredicate(format:"( serialno = %@ )",iobattery.battery_serialno) 60 | 61 | do { 62 | if (datacontroller==nil){ 63 | return 64 | } 65 | history = try datacontroller.managedObjectContext.fetch(historyFetch) as? [HistoryMO] 66 | 67 | var maxduration : Int = 12; 68 | let now = Date() 69 | 70 | 71 | 72 | let dateformatter = DateFormatter() 73 | dateformatter.timeZone = NSTimeZone.local 74 | dateformatter.dateStyle = .medium 75 | dateformatter.timeStyle = .medium 76 | 77 | if (history.count>0){ 78 | 79 | 80 | var interval = history[0].time?.timeIntervalSince(now) 81 | let months = interval! / (-86400 * 30.4375) 82 | let calender = Calendar.current 83 | if (Int(months) > maxduration){ 84 | maxduration = Int(months) 85 | }else{ 86 | 87 | 88 | interval = calender.date(byAdding: .year, value: -1, to: now)?.timeIntervalSince(now) 89 | } 90 | 91 | (view as! BaseChartView).columnstep = -maxduration / 4 92 | (view as! BaseChartView).columninit = maxduration / 4 * 3 93 | 94 | 95 | var nextpointday = 1; 96 | 97 | 98 | let showcount :Int = months>12 ? 24:(Int(months)+1)*2 99 | 100 | if (history.count / showcount > 0){ 101 | nextpointday = history.count / showcount + 1 102 | } 103 | 104 | 105 | 106 | var dayfollowing = calender.startOfDay(for: history[0].time! ) 107 | 108 | var min = history[0].capacity as! Int 109 | var max = history[0].capacity as! Int 110 | var numskip = 0 111 | var totalcap = 0 112 | 113 | for item in history { 114 | 115 | let capacity = item.capacity as! Int 116 | 117 | if (capacity > max){ 118 | max = capacity 119 | } 120 | if (capacity < min){ 121 | min = capacity 122 | } 123 | 124 | 125 | 126 | totalcap += capacity 127 | 128 | 129 | if ((dayfollowing.timeIntervalSince(calender.startOfDay(for: item.time!))) > TimeInterval(0) ){ 130 | numskip += 1 131 | 132 | 133 | 134 | 135 | continue; 136 | } 137 | 138 | dayfollowing = dayfollowing.addingTimeInterval(Double(nextpointday) * 86400.0 ) 139 | 140 | 141 | 142 | let iteminterval = item.time?.timeIntervalSince(now) 143 | 144 | 145 | let xvalue = iteminterval! / interval! 146 | 147 | 148 | totalcap /= (numskip + 1) 149 | 150 | (view as! BaseChartView).linechart.append(CGPoint(x:1-xvalue, 151 | y: Double(totalcap ) / Double(iobattery.design_capacity))) 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | // print (String(format: "history: %d, %@", totalcap,showdate )) 163 | 164 | totalcap = 0 165 | numskip = 0 166 | 167 | } 168 | 169 | if ((view as! BaseChartView).linechart.count>0){ 170 | 171 | (view as! BaseChartView).linechart.append(CGPoint(x:1, 172 | y: (view as! BaseChartView).linechart[(view as! BaseChartView).linechart.count-1].y)) 173 | } 174 | 175 | 176 | 177 | (view as! BaseChartView).custommin = CGFloat(min) 178 | (view as! BaseChartView).custommax = CGFloat(max) 179 | 180 | 181 | if (history.count>30){ 182 | 183 | let reg = DetailViewController.calcatedline(history) 184 | let date = Date().timeIntervalSince1970 185 | 186 | let nowcap = DetailViewController.calcatepredict(x: date, slope: reg.slope, intersection: reg.intersect) 187 | 188 | let firstcap = DetailViewController.calcatepredict(x: (history[0].time?.timeIntervalSince1970)!, slope: reg.slope, intersection: reg.intersect) 189 | 190 | (view as! BaseChartView).reglineBegin = CGPoint(x:1-(history[0].time?.timeIntervalSinceNow)!/interval!,y:firstcap/Double(iobattery.design_capacity)) 191 | 192 | (view as! BaseChartView).reglineEnd = CGPoint(x:1,y:nowcap/Double(iobattery.design_capacity)) 193 | 194 | 195 | } 196 | 197 | 198 | 199 | 200 | 201 | 202 | } 203 | }catch { 204 | // fatalError("Failed to fetch history: \(error)") 205 | } 206 | 207 | 208 | 209 | 210 | 211 | 212 | view.layer?.setNeedsDisplay() 213 | view.layer?.displayIfNeeded() 214 | 215 | 216 | } 217 | 218 | 219 | 220 | 221 | 222 | } 223 | 224 | -------------------------------------------------------------------------------- /BatteryStatusShow/IOHID.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IOHID.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/23. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class IOHID{ 12 | 13 | static let updatenotify = AppDelegate.programprefix + ".iohidnotifyupdate" 14 | 15 | 16 | 17 | 18 | var timer: DispatchSourceTimer? 19 | var interval:Int = 20 20 | 21 | var batteryMatchDictionary:NSDictionary! 22 | var iterator:io_iterator_t = io_iterator_t() 23 | var iomasterport:mach_port_t = mach_port_t() 24 | 25 | var devices_name:[String] = [String]() 26 | var batterylevel:[Int] = [Int]() 27 | var devices_serialno:[String] = [String]() 28 | var status_flag:[Int]=[Int]() 29 | var updating:Bool = false 30 | 31 | 32 | 33 | 34 | 35 | var nodevices:Bool = false 36 | 37 | 38 | 39 | 40 | 41 | 42 | init(){ 43 | // updatebattery() 44 | // commandlineshowinfo() 45 | 46 | update() 47 | 48 | } 49 | 50 | func updateHID(){ 51 | 52 | 53 | 54 | batteryMatchDictionary = IOServiceNameMatching("AppleDeviceManagementHIDEventService") 55 | // batteryMatchDictionary = IOServiceGetMatchingServices("AppleSmartBattery"); 56 | IOMasterPort(mach_port_t(MACH_PORT_NULL), &iomasterport) 57 | var waittime = mach_timespec_t(tv_sec: 1,tv_nsec: 0); 58 | 59 | IOServiceWaitQuiet(iomasterport, &waittime) 60 | 61 | if (IOServiceGetMatchingServices(iomasterport,batteryMatchDictionary,&iterator)==kIOReturnSuccess){ 62 | 63 | 64 | ioregHID() 65 | } 66 | 67 | return ; 68 | } 69 | 70 | func ioregHID(){ 71 | 72 | // CFDictionaryGetValue 73 | 74 | IOIteratorReset(iterator); 75 | 76 | 77 | 78 | devices_name.removeAll() 79 | batterylevel.removeAll() 80 | devices_serialno.removeAll() 81 | status_flag.removeAll() 82 | 83 | 84 | repeat{ 85 | 86 | let io :io_service_t = IOIteratorNext(iterator); 87 | 88 | 89 | 90 | 91 | 92 | 93 | if (io==0){ 94 | break; 95 | } 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | let devName = UnsafeMutablePointer.allocate(capacity: 1); 104 | 105 | 106 | // let devrawName = UnsafeMutableRawPointer(devName).bindMemory(to: io_name_t.self, capacity: 1) 107 | 108 | let int8Pointer = UnsafeMutableRawPointer(devName).bindMemory(to: Int8.self,capacity: 1) 109 | 110 | 111 | let pathName = UnsafeMutablePointer.allocate(capacity: 1); 112 | 113 | let int8NamePointer = UnsafeMutableRawPointer(pathName).bindMemory(to: Int8.self,capacity: 1) 114 | 115 | 116 | IORegistryEntryGetName(io, int8Pointer); 117 | 118 | IORegistryEntryGetPath(io, kIOServicePlane, int8NamePointer); 119 | #if DEBUG 120 | // print(String(format:"AppleDeviceManagementHIDEventService Devices: %s found. path in IOService plane = %s\n",devName, pathName)); 121 | #endif 122 | int8Pointer.deinitialize() 123 | int8NamePointer.deinitialize() 124 | devName.deinitialize() 125 | pathName.deinitialize() 126 | 127 | 128 | 129 | 130 | 131 | 132 | // IORegistryEntryGetPath(io, kIOUSBPlane, pathName); 133 | // printf("Device's path in IOUSB plane = %s\n", pathName); 134 | 135 | var child:Unmanaged? 136 | 137 | IORegistryEntryCreateCFProperties(io, &child, kCFAllocatorDefault, 0) 138 | // IORegistryEntryGetChildIterator(io,kIOServicePlane,&child) 139 | 140 | let childdict = NSDictionary(dictionary:(child?.takeUnretainedValue())!) 141 | 142 | if let batterypercentage = childdict["BatteryPercent"] { 143 | batterylevel.append(Int(truncating: batterypercentage as! NSNumber)) 144 | }else{ 145 | continue 146 | } 147 | 148 | devices_name.append(childdict["Product"] as! String) 149 | 150 | if let serialno = childdict["SerialNumber"] { 151 | devices_serialno.append(serialno as! String) 152 | }else{ 153 | devices_serialno.append("") 154 | } 155 | 156 | if let flags = childdict["BatteryStatusFlags"] { 157 | status_flag.append(Int(truncating: flags as! NSNumber)) 158 | }else{ 159 | status_flag.append(0) 160 | } 161 | 162 | 163 | child?.release() 164 | 165 | IOObjectRelease(io) 166 | 167 | 168 | 169 | 170 | }while(IOIteratorIsValid(iterator)==boolean_t(truncating: true)) 171 | 172 | 173 | NotificationCenter.default.post(name:Notification.Name(rawValue:IOHID.updatenotify),object:nil) 174 | 175 | 176 | 177 | 178 | } 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | func startTimer() { 188 | let labelid = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String 189 | let queue = DispatchQueue(label: (labelid! + "." + String(describing: type(of: self))), attributes: .concurrent) 190 | 191 | timer?.cancel() // cancel previous timer if any 192 | 193 | timer = DispatchSource.makeTimerSource(queue: queue) 194 | 195 | timer?.schedule(deadline: .now(), repeating: .seconds(interval), leeway: .seconds(1)) 196 | 197 | timer?.setEventHandler { // `[weak self]` only needed if you reference `self` in this closure and you want to prevent strong reference cycle 198 | 199 | 200 | self.update() 201 | 202 | 203 | } 204 | 205 | timer?.resume() 206 | } 207 | 208 | func stopTimer() { 209 | timer?.cancel() 210 | timer = nil 211 | } 212 | 213 | private func update(){ 214 | 215 | updating = true 216 | 217 | updateHID() 218 | 219 | updating = false 220 | 221 | 222 | } 223 | 224 | 225 | 226 | } 227 | -------------------------------------------------------------------------------- /BatteryStatusShow/IOSModelDict.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IOSModelDict.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/6/3. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class IOSModelDict{ 12 | 13 | static func ProductTypeToName(producttype:String)->String{ 14 | 15 | let dict:[String:String] = [ 16 | "iPhone1,1":"iPhone", 17 | "iPhone2,1":"iPhone 3GS", 18 | "iPhone3,1":"iPhone 4 (GSM)", 19 | "iPhone3,3":"iPhone 4 (CDMA)", 20 | "iPhone4,1":"iPhone 4S", 21 | "iPhone5,1":"iPhone 5 (A1428)", 22 | "iPhone5,2":"iPhone 5 (A1429)", 23 | "iPhone5,3":"iPhone 5c (A1456/A1532)", 24 | "iPhone5,4":"iPhone 5c (A1507/A1516/A1529)", 25 | "iPhone6,1":"iPhone 5s (A1433/A1453)", 26 | "iPhone6,2":"iPhone 5s (A1457/A1518/A1530)", 27 | "iPhone7,1":"iPhone 6 Plus", 28 | "iPhone7,2":"iPhone 6", 29 | "iPhone8,1":"iPhone 6s", 30 | "iPhone8,2":"iPhone 6s Plus", 31 | "iPhone8,4":"iPhone SE", 32 | "iPhone9,1":"iPhone 7 (A1660/A1779/A1780)", 33 | "iPhone9,2":"iPhone 7 Plus (A1661/A1785/A1786)", 34 | "iPhone9,3":"iPhone 7 (A1778)", 35 | "iPhone9,4":"iPhone 7 Plus (A1784)", 36 | "iPhone10,1":"iPhone 8 (CDMA+GSM/LTE)", 37 | "iPhone10,2":"iPhone 8 Plus (CDMA+GSM/LTE)", 38 | "iPhone10,3":"iPhone X (CDMA+GSM/LTE)", 39 | "iPhone10,4":"iPhone 8 (GSM/LTE)", 40 | "iPhone10,5":"iPhone 8 Plus (GSM/LTE)", 41 | "iPhone10,6":"iPhone X (GSM/LTE)", 42 | "iPhone11,2" : "iPhone XS", 43 | "iPhone11,4" : "iPhone XS Max", 44 | "iPhone11,6" : "iPhone XS Max Global", 45 | "iPhone11,8" : "iPhone XR", 46 | "iPhone12,1" : "iPhone 11", 47 | "iPhone12,3" : "iPhone 11 Pro", 48 | "iPhone12,5" : "iPhone 11 Pro Max", 49 | "iPhone12,8" : "iPhone SE 2nd Gen", 50 | "iPad1,1":"iPad", 51 | "iPad2,1":"iPad 2 (Wi-Fi)", 52 | "iPad2,2":"iPad 2 (GSM)", 53 | "iPad2,3":"iPad 2 (CDMA)", 54 | "iPad2,4":"iPad 2 (Wi-Fi, revised)", 55 | "iPad2,5":"iPad mini (Wi-Fi)", 56 | "iPad2,6":"iPad mini (A1454)", 57 | "iPad2,7":"iPad mini (A1455)", 58 | "iPad3,1":"iPad (3rd gen, Wi-Fi)", 59 | "iPad3,2":"iPad (3rd gen, Wi-Fi+LTE Verizon)", 60 | "iPad3,3":"iPad (3rd gen, Wi-Fi+LTE AT&T)", 61 | "iPad3,4":"iPad (4th gen, Wi-Fi)", 62 | "iPad3,5":"iPad (4th gen, A1459)", 63 | "iPad3,6":"iPad (4th gen, A1460)", 64 | "iPad4,1":"iPad Air (Wi-Fi)", 65 | "iPad4,2":"iPad Air (Wi-Fi+LTE)", 66 | "iPad4,3":"iPad Air (Rev)", 67 | "iPad4,4":"iPad mini 2 (Wi-Fi)", 68 | "iPad4,5":"iPad mini 2 (Wi-Fi+LTE)", 69 | "iPad4,6":"iPad mini 2 (Rev)", 70 | "iPad4,7":"iPad mini 3 (Wi-Fi)", 71 | "iPad4,8":"iPad mini 3 (A1600)", 72 | "iPad4,9":"iPad mini 3 (A1601)", 73 | "iPad5,1":"iPad mini 4 (Wi-Fi)", 74 | "iPad5,2":"iPad mini 4 (Wi-Fi+LTE)", 75 | "iPad5,3":"iPad Air 2 (Wi-Fi)", 76 | "iPad5,4":"iPad Air 2 (Wi-Fi+LTE)", 77 | "iPad6,3":"iPad Pro (9.7 inch) (Wi-Fi)", 78 | "iPad6,4":"iPad Pro (9.7 inch) (Wi-Fi+LTE)", 79 | "iPad6,7":"iPad Pro (12.9 inch, Wi-Fi)", 80 | "iPad6,8":"iPad Pro (12.9 inch, Wi-Fi+LTE)", 81 | "iPad6,11":"iPad 9.7-Inch 5th Gen (Wi-Fi Only)", 82 | "iPad6,12":"iPad 9.7-Inch 5th Gen (Wi-Fi/Cellular)", 83 | "iPad7,1":"iPad Pro 12.9-inch 2nd Gen (Wi-Fi Only)", 84 | "iPad7,2":"iPad Pro 12.9-inch 2nd Gen (Wi-Fi/Cellular)", 85 | "iPad7,3":"Apple iPad Pro 10.5-Inch (Wi-Fi Only)", 86 | "iPad7,4":"Apple iPad Pro 10.5-Inch (Wi-Fi/Cellular)", 87 | "iPad7,5" : "iPad 6th Gen (WiFi)", 88 | "iPad7,6" : "iPad 6th Gen (WiFi+Cellular)", 89 | "iPad7,11" : "iPad 7th Gen 10.2-inch (WiFi)", 90 | "iPad7,12" : "iPad 7th Gen 10.2-inch (WiFi+Cellular)", 91 | "iPad8,1" : "iPad Pro 11 inch (WiFi)", 92 | "iPad8,2" : "iPad Pro 11 inch (1TB, WiFi)", 93 | "iPad8,3" : "iPad Pro 11 inch (WiFi+Cellular)", 94 | "iPad8,4" : "iPad Pro 11 inch (1TB, WiFi+Cellular)", 95 | "iPad8,5" : "iPad Pro 12.9 inch 3rd Gen (WiFi)", 96 | "iPad8,6" : "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi)", 97 | "iPad8,7" : "iPad Pro 12.9 inch 3rd Gen (WiFi+Cellular)", 98 | "iPad8,8" : "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi+Cellular)", 99 | "iPad8,9" : "iPad Pro 11 inch 2nd Gen (WiFi)", 100 | "iPad8,10" : "iPad Pro 11 inch 2nd Gen (WiFi+Cellular)", 101 | "iPad8,11" : "iPad Pro 12.9 inch 4th Gen (WiFi)", 102 | "iPad8,12" : "iPad Pro 12.9 inch 4th Gen (WiFi+Cellular)", 103 | "iPad11,1" : "iPad mini 5th Gen (WiFi)", 104 | "iPad11,2" : "iPad mini 5th Gen", 105 | "iPad11,3" : "iPad Air 3rd Gen (WiFi)", 106 | "iPad11,4" : "iPad Air 3rd Gen", 107 | 108 | "iPod1,1":"iPod touch", 109 | "iPod2,1":"iPod touch (2nd gen)", 110 | "iPod3,1":"iPod touch (3rd gen)", 111 | "iPod4,1":"iPod touch (4th gen)", 112 | "iPod5,1":"iPod touch (5th gen)", 113 | "iPod7,1":"iPod touch (6th gen)"] 114 | 115 | if let name = dict[producttype]{ 116 | return name 117 | }else{ 118 | return "" 119 | } 120 | 121 | 122 | 123 | 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /BatteryStatusShow/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSApplicationCategoryType 24 | public.app-category.utilities 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2020 sicreativelee. All rights reserved. 29 | This APP uses the library of libimobiledevice under LGPL 2.1 30 | http://www.libimobiledevice.org 31 | NSMainStoryboardFile 32 | Main 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /BatteryStatusShow/LogView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LogView.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/30. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class LogView:StatusBaseChartView { 12 | 13 | 14 | 15 | 16 | override func setdefault() { 17 | super.setdefault() 18 | 19 | 20 | 21 | 22 | 23 | } 24 | 25 | override func magnify(with event:NSEvent){ 26 | 27 | 28 | if (event.magnification == 0){ 29 | return 30 | } 31 | 32 | // Swift.print (String(format:"magnify: %f",event.magnification)) 33 | 34 | let settedinterval = event.magnification * 10000 35 | 36 | NotificationCenter.default.post(name:Notification.Name(LogViewController.magnifynotifykey), object: nil, userInfo: ["magnification":settedinterval]) 37 | 38 | 39 | } 40 | 41 | 42 | override func swipe(with event: NSEvent){ 43 | 44 | // Swift.print (String(format:"swipe: %f",event.deltaX)) 45 | 46 | 47 | } 48 | 49 | override func scrollWheel(with event: NSEvent){ 50 | 51 | // Swift.print (String(format:"scroll: %f",event.deltaX)) 52 | 53 | if (event.scrollingDeltaX != CGFloat(0)){ 54 | 55 | // Swift.print (String(format:"scrollY: %f",event.scrollingDeltaY)) 56 | 57 | NotificationCenter.default.post(name:Notification.Name(LogViewController.movenotifykey), object: nil, userInfo: ["moving":event.scrollingDeltaX ]) 58 | 59 | return; 60 | } 61 | 62 | 63 | if (event.scrollingDeltaY != CGFloat(0)){ 64 | 65 | 66 | 67 | 68 | let settedinterval = event.scrollingDeltaY * 100 69 | // Swift.print (String(format:"scrollY: %f",event.scrollingDeltaY)) 70 | 71 | NotificationCenter.default.post(name:Notification.Name(LogViewController.magnifynotifykey), object: nil, userInfo: ["magnification":settedinterval]) 72 | } 73 | 74 | 75 | 76 | 77 | 78 | } 79 | 80 | 81 | 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /BatteryStatusShow/PeripheralViewControl.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PeripheralViewControl.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/28. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | class PeripheralViewController: NSViewController { 13 | 14 | 15 | var ioHID:IOHID! 16 | 17 | 18 | 19 | 20 | 21 | var lastupdate:NSNumber = 0 22 | 23 | var timer: DispatchSourceTimer? 24 | 25 | var nameTextFields:[NSTextField] = [NSTextField]() 26 | var batterylevelTextFields:[NSTextField] = [NSTextField]() 27 | var hozlines:[NSBox]=[NSBox]() 28 | var updating = false; 29 | 30 | 31 | 32 | 33 | override func viewDidAppear() { 34 | 35 | super.viewDidAppear() 36 | NotificationCenter.default.addObserver(self, selector:#selector(BatteryViewController.update), name: NSNotification.Name(rawValue:IOHID.updatenotify), object: nil) 37 | 38 | 39 | update() 40 | /* 41 | 42 | NotificationCenter.default.addObserver(self, selector:#selector(BatteryViewController.update), name: NSNotification.Name(rawValue:IOBattery.updatenotify), object: nil) 43 | 44 | */ 45 | 46 | 47 | 48 | } 49 | 50 | override func viewWillDisappear() { 51 | NotificationCenter.default.removeObserver(self) 52 | 53 | 54 | super.viewWillDisappear() 55 | 56 | 57 | } 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | @objc func update(){ 66 | if (!updating){ 67 | self.updating = true; 68 | DispatchQueue.main.asyncAfter(deadline: .now()+0.2) { 69 | 70 | self.updateperipheral() 71 | self.updating = false; 72 | 73 | 74 | } 75 | 76 | } 77 | 78 | // DispatchQueue.main.async 79 | } 80 | 81 | 82 | func updateperipheral(){ 83 | 84 | 85 | 86 | 87 | if (ioHID==nil){ 88 | if ((NSApplication.shared.delegate as! AppDelegate).ioHID != nil){ 89 | ioHID = (NSApplication.shared.delegate as! AppDelegate).ioHID 90 | }else{ 91 | (NSApplication.shared.delegate as! AppDelegate).ioHID = IOHID(); 92 | if ((NSApplication.shared.delegate as! AppDelegate).ioHID != nil){ 93 | ioHID = (NSApplication.shared.delegate as! AppDelegate).ioHID 94 | }else{ 95 | return; 96 | } 97 | } 98 | 99 | } 100 | 101 | if (ioHID.updating){ 102 | return 103 | } 104 | 105 | 106 | // let viewwidth = view.bounds.width 107 | let viewheight = view.bounds.height 108 | 109 | if (ioHID.batterylevel.count < hozlines.count){ 110 | for i in ioHID.batterylevel.count.. batterylevelTextFields.count-1){ 133 | 134 | let hozline = NSBox() 135 | hozline.frame = NSMakeRect(20, CGFloat(viewheight-56.0-CGFloat(i)*25.0), 420, 5) 136 | hozline.title = "" 137 | view.addSubview(hozline) 138 | hozlines.append(hozline) 139 | 140 | 141 | 142 | let batterynameTextField = NSTextField(); 143 | 144 | batterynameTextField.stringValue = ioHID.batterylevel[i].description + " %" + status 145 | batterynameTextField.frame = NSMakeRect(25, CGFloat(viewheight-52.0-CGFloat(i)*25.0), 100,100) 146 | 147 | 148 | 149 | 150 | batterynameTextField.backgroundColor = NSColor.controlColor 151 | batterynameTextField.textColor = NSColor.labelColor 152 | batterynameTextField.isBordered = false 153 | batterynameTextField.isEditable = false 154 | batterynameTextField.isBezeled = false 155 | batterynameTextField.alignment = NSTextAlignment.center 156 | batterynameTextField.font = NSFont(name:"Helvetica Neue Medium", size:12) 157 | view.addSubview(batterynameTextField) 158 | nameTextFields.append(batterynameTextField) 159 | 160 | 161 | 162 | 163 | 164 | let batterylevelTextField = NSTextField(); 165 | 166 | 167 | 168 | 169 | batterylevelTextField.stringValue = ioHID.batterylevel[i].description + " %" + status 170 | batterylevelTextField.frame = NSMakeRect(320, CGFloat(viewheight-50.0-CGFloat(i)*25.0), 100,100) 171 | 172 | 173 | 174 | 175 | batterylevelTextField.backgroundColor = NSColor.controlColor 176 | batterylevelTextField.textColor = NSColor.labelColor 177 | batterylevelTextField.isBordered = false 178 | batterylevelTextField.isEditable = false 179 | batterylevelTextField.isBezeled = false 180 | batterylevelTextField.alignment = NSTextAlignment.center 181 | batterylevelTextField.font = NSFont(name:"Helvetica Neue Medium", size:12) 182 | 183 | view.addSubview(batterylevelTextField) 184 | batterylevelTextFields.append(batterylevelTextField) 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | } 193 | batterylevelTextFields[i].isHidden = false 194 | batterylevelTextFields[i].stringValue = ioHID.batterylevel[i].description + " %" + status 195 | batterylevelTextFields[i].sizeToFit() 196 | nameTextFields[i].isHidden = false 197 | nameTextFields[i].stringValue = ioHID.devices_name[i] + " (" + ioHID.devices_serialno[i] + ")" 198 | 199 | nameTextFields[i].sizeToFit() 200 | hozlines[i].isHidden = false 201 | 202 | } 203 | 204 | 205 | } 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | } 214 | -------------------------------------------------------------------------------- /BatteryStatusShow/PowerViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PowerViewController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/17. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class PowerViewController: BatteryViewController { 12 | 13 | var totalshowmins = 20 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | (view as! BaseChartView).title.stringValue = "Power" 19 | (view as! BaseChartView).title.sizeToFit() 20 | 21 | (view as! BaseChartView).ytitle.stringValue = "Watt" 22 | (view as! BaseChartView).ytitle.sizeToFit() 23 | 24 | (view as! BaseChartView).xtitle.stringValue = "mins" 25 | (view as! BaseChartView).xtitle.sizeToFit() 26 | 27 | (view as! TwoAxisBaseChartView).righttitle.stringValue = "voltage" 28 | (view as! TwoAxisBaseChartView).righttitle.sizeToFit() 29 | 30 | 31 | 32 | 33 | (view as! BaseChartView).maxmindecimal = 2 34 | (view as! BaseChartView).showmaxmin = true 35 | 36 | (view as! TwoAxisBaseChartView).rightmaxmindecimal = 2 37 | 38 | 39 | 40 | 41 | // Do any additional setup after loading the view. 42 | } 43 | 44 | 45 | 46 | 47 | 48 | 49 | override func updateview() { 50 | 51 | let nowtime = Date() 52 | let firstshowtime = (Calendar.current).date(byAdding: .minute, value: -totalshowmins, to: nowtime) 53 | 54 | //skill out of time item 55 | 56 | 57 | 58 | 59 | let sorted = iobattery.batteryrecord.sorted(by: {a,b in a.key > b.key}) 60 | var records:Array = Array() 61 | 62 | for item in sorted{ 63 | 64 | 65 | if (iobattery.ischarge && item.value.current < 0){ 66 | 67 | break 68 | } 69 | 70 | if (!iobattery.ischarge && item.value.current > 0){ 71 | break 72 | } 73 | 74 | records.append(item.value) 75 | 76 | 77 | 78 | if (item.key <= Int(firstshowtime!.timeIntervalSince1970)){ 79 | break 80 | } 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | } 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | if (iobattery.ischarge){ 104 | 105 | (view as! BaseChartView).chartlinecolor = 106 | CGColor(red:0.8,green:0.2,blue:0.2,alpha:0.95) 107 | (view as! BaseChartView).title.stringValue = "Power (Charge)" 108 | 109 | 110 | }else if (iobattery.withcharger){ 111 | (view as! BaseChartView).chartlinecolor = 112 | CGColor(red:0.1,green:0.1,blue:0.8,alpha:0.95) 113 | (view as! BaseChartView).title.stringValue = "Power (With Charger)" 114 | 115 | }else{ 116 | (view as! BaseChartView).chartlinecolor = 117 | CGColor(red:0.1,green:0.1,blue:0.8,alpha:0.95) 118 | (view as! BaseChartView).title.stringValue = "Power (DisCharge)" 119 | 120 | } 121 | (view as! BaseChartView).title.sizeToFit() 122 | 123 | if (records.count == 0){ 124 | return 125 | } 126 | 127 | //var watt = iobattery.voltage * Float(iobattery.amperage)/1000 128 | let maxitem = records.max(by: {a,b in (Float(abs(a.current)) * a.voltage) < (Float(abs(b.current)) * b.voltage) }) 129 | 130 | var watt = maxitem!.voltage * Float(abs(maxitem!.current)) / 1000 131 | 132 | 133 | if (watt < 8){ 134 | watt = 8 135 | }else{ 136 | let remainder = watt.truncatingRemainder(dividingBy: 4) 137 | watt -= remainder 138 | watt += 4 139 | 140 | } 141 | 142 | (view as! BaseChartView).rowstep = Int (watt) / 4 143 | (view as! BaseChartView).rowinit = Int (watt) / 4 144 | 145 | 146 | let maxvoltageitem = records.max(by: {a,b in a.voltage < b.voltage }) 147 | 148 | // Macbook Pro with Voltage heighter that 10 149 | 150 | let voltageremainer = maxvoltageitem!.voltage.truncatingRemainder(dividingBy: 2) 151 | 152 | (view as! TwoAxisBaseChartView).rightrowinit = Int (maxvoltageitem!.voltage - voltageremainer - Float(2)) 153 | 154 | 155 | 156 | (view as! TwoAxisBaseChartView).rightrowstep = 2 157 | 158 | 159 | 160 | 161 | 162 | 163 | (view as! BaseChartView).linechart.removeAll() 164 | (view as! TwoAxisBaseChartView).rightlinechart.removeAll() 165 | 166 | 167 | let rightvoltagemin:Float = Float ((view as! TwoAxisBaseChartView).rightrowinit - (view as! TwoAxisBaseChartView).rightrowstep) 168 | 169 | 170 | 171 | 172 | for item in records{ 173 | 174 | 175 | 176 | // print(String(format:"key = %d, %d firshowtime",item.timestamp,Int(firstshowtime!.timeIntervalSince1970))) 177 | 178 | let x = CGFloat( (Double(item.timestamp)-firstshowtime!.timeIntervalSince1970)/(nowtime.timeIntervalSince1970 - firstshowtime!.timeIntervalSince1970)) 179 | 180 | let y = CGFloat((item.voltage * Float(abs(item.current))) / (watt*1000)) 181 | 182 | (view as! BaseChartView).linechart.append(CGPoint(x:x,y:y)) 183 | 184 | let right = Float((item.voltage - rightvoltagemin) / Float((view as! TwoAxisBaseChartView).rightrowstep * 4 )) 185 | 186 | (view as! TwoAxisBaseChartView).rightlinechart.append(CGPoint(x:x,y:CGFloat(right))) 187 | 188 | } 189 | 190 | //Alighment of right edge 191 | if ((view as! BaseChartView).linechart.count >= 1){ 192 | (view as! BaseChartView).linechart[0].x = 1; 193 | 194 | 195 | 196 | 197 | 198 | //Alighment of left edge 199 | 200 | 201 | 202 | if ((view as! BaseChartView).linechart[(view as! BaseChartView).linechart.count-1].x<0){ 203 | 204 | let a = (view as! BaseChartView).linechart[(view as! BaseChartView).linechart.count-1] 205 | let b = (view as! BaseChartView).linechart[(view as! BaseChartView).linechart.count-2] 206 | let slope = (a.y - b.y) / (a.x - b.x) 207 | 208 | // y = mx + b 209 | (view as! BaseChartView).linechart[(view as! BaseChartView).linechart.count-1].y = b.y - slope * b.x 210 | 211 | 212 | 213 | (view as! BaseChartView).linechart[(view as! BaseChartView).linechart.count-1].x = 0 214 | 215 | 216 | } 217 | 218 | } 219 | 220 | if ((view as! TwoAxisBaseChartView).rightlinechart.count>=2){ 221 | (view as! TwoAxisBaseChartView).rightlinechart[0].x = 1; 222 | } 223 | 224 | if ((view as! TwoAxisBaseChartView).rightlinechart.count>=1 && 225 | (view as! TwoAxisBaseChartView).rightlinechart[(view as! BaseChartView).linechart.count-1].x<0){ 226 | 227 | if (view as! TwoAxisBaseChartView).rightlinechart.count>1{ 228 | 229 | 230 | 231 | 232 | 233 | let a = (view as! TwoAxisBaseChartView).rightlinechart[(view as! BaseChartView).linechart.count-1] 234 | let b = (view as! TwoAxisBaseChartView).rightlinechart[(view as! BaseChartView).linechart.count-2] 235 | let slope = (a.y - b.y) / (a.x - b.x) 236 | 237 | // y = mx + b 238 | (view as! TwoAxisBaseChartView).rightlinechart[ (view as! TwoAxisBaseChartView).rightlinechart.count-1].y = b.y - slope * b.x 239 | 240 | 241 | } 242 | (view as! TwoAxisBaseChartView).rightlinechart[(view as! TwoAxisBaseChartView).rightlinechart.count-1].x = 0 243 | 244 | 245 | 246 | 247 | } 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | view.layer?.setNeedsDisplay() 258 | view.layer?.displayIfNeeded() 259 | 260 | 261 | 262 | 263 | 264 | 265 | } 266 | 267 | override func updatebatterydesc() { 268 | (view as! BaseChartView).columnstep = -totalshowmins / 4 269 | (view as! BaseChartView).columninit = totalshowmins * 3 / 4 270 | 271 | } 272 | 273 | 274 | 275 | } 276 | 277 | 278 | -------------------------------------------------------------------------------- /BatteryStatusShow/SmcHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // SmcHelper.h 3 | // HWMonitor 4 | // 5 | // Created by Kozlek on 28/11/13. 6 | // Copyright (c) 2013 kozlek. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "smc.h" 11 | 12 | #define bit_get(p,m) ((p) & (m)) 13 | #define bit_set(p,m) ((p) |= (m)) 14 | #define bit_clear(p,m) ((p) &= ~(m)) 15 | #define bit_flip(p,m) ((p) ^= (m)) 16 | #define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m)) 17 | #define BIT(x) (0x01 << (x)) 18 | #define LONGBIT(x) ((unsigned long)0x00000001 << (x)) 19 | 20 | //#define ABS(x) ((x) >= 0 ? (x) : -(x)) 21 | #define SGN(x) ((x) > 0 ? 1.0 : -1.0) 22 | #define ROUND(x) ((x) + 0.5 > int(x) + 1 ? int(x) + 1 : int(x)) 23 | #define ROUND50(x) (((int)((x) + 25) / 50) * 50) 24 | 25 | @interface SmcHelper : NSObject 26 | 27 | + (int)getIndexFromHexChar:(char)c; 28 | + (BOOL)isValidIntegerSmcType:(NSString *)type; 29 | + (BOOL)isValidFloatingSmcType:(NSString *)type; 30 | + (NSNumber*)decodeNumericValueFromBuffer:(void*)data length:(NSUInteger)length type:(const char *)type; 31 | + (BOOL)encodeNumericValue:(NSNumber*)value length:(NSUInteger)length type:(const char *)type outBuffer:(void*)outBuffer; 32 | 33 | + (NSNumber*)readNumericKey:(NSString*)key connection:(io_connect_t)connection; 34 | + (BOOL)writeNumericKey:(NSString*)key value:(NSNumber*)value connection:(io_connect_t)connection; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /BatteryStatusShow/SmcHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // SmcHelper.m 3 | // HWMonitor 4 | // 5 | // Created by Kozlek on 28/11/13. 6 | // Copyright (c) 2013 kozlek. All rights reserved. 7 | // 8 | // Modifyed by SC Lee for BatteryStatusShow 9 | // Copyright (c) 2020 10 | // 11 | 12 | #import "SmcHelper.h" 13 | 14 | 15 | 16 | @implementation SmcHelper 17 | 18 | + (int)getIndexFromHexChar:(char)c 19 | { 20 | return c > 96 && c < 103 ? c - 87 : c > 47 && c < 58 ? c - 48 : -1; 21 | } 22 | 23 | + (BOOL)isValidIntegerSmcType:(NSString *)type 24 | { 25 | if (type && [type length] >= 3) { 26 | if (([type characterAtIndex:0] == 'u' || [type characterAtIndex:0] == 's') && [type characterAtIndex:1] == 'i') { 27 | 28 | switch ([type characterAtIndex:2]) { 29 | case '8': 30 | return type.length < 4 || [type characterAtIndex:3] == ' '; 31 | case '1': 32 | return [type characterAtIndex:3] == '6' ? TRUE : FALSE; 33 | case '3': 34 | return [type characterAtIndex:3] == '2' ? TRUE : FALSE; 35 | } 36 | } 37 | } 38 | 39 | return FALSE; 40 | } 41 | 42 | + (BOOL)isValidFloatingSmcType:(NSString *)type 43 | { 44 | if (type && [type length] >= 3) { 45 | 46 | if ([type characterAtIndex:0] == 'f' && [type characterAtIndex:1] == 'l'&& [type characterAtIndex:2] == 't' ) 47 | return TRUE; 48 | 49 | 50 | if (([type characterAtIndex:0] == 'f' || [type characterAtIndex:0] == 's') && [type characterAtIndex:1] == 'p') { 51 | UInt8 i = [SmcHelper getIndexFromHexChar:[type characterAtIndex:2]]; 52 | UInt8 f = [SmcHelper getIndexFromHexChar:[type characterAtIndex:3]]; 53 | 54 | if (i + f != ([type characterAtIndex:0] == 's' ? 15 : 16)) 55 | return FALSE; 56 | 57 | return TRUE; 58 | } 59 | } 60 | 61 | return FALSE; 62 | } 63 | 64 | + (NSNumber*)decodeNumericValueFromBuffer:(void *)data length:(NSUInteger)length type:(const char *)type 65 | { 66 | if (type && data) { 67 | 68 | size_t typeLength = strnlen(type, 4); 69 | 70 | if (typeLength >= 3) { 71 | if ((type[0] == 'u' || type[0] == 's') && type[1] == 'i') { 72 | 73 | BOOL signd = type[0] == 's'; 74 | 75 | switch (type[2]) { 76 | case '8': 77 | if (length == 1) { 78 | UInt8 encoded = 0; 79 | 80 | bcopy(data, &encoded, 1); 81 | 82 | if (signd && bit_get(encoded, BIT(7))) { 83 | bit_clear(encoded, BIT(7)); 84 | return [NSNumber numberWithInteger:-encoded]; 85 | } 86 | 87 | return [NSNumber numberWithUnsignedInteger:encoded]; 88 | } 89 | break; 90 | 91 | case '1': 92 | if (type[3] == '6' && length == 2) { 93 | UInt16 encoded = 0; 94 | 95 | bcopy(data, &encoded, 2); 96 | 97 | encoded = OSSwapBigToHostInt16(encoded); 98 | 99 | if (signd && bit_get(encoded, BIT(15))) { 100 | bit_clear(encoded, BIT(15)); 101 | return [NSNumber numberWithInteger:-encoded]; 102 | } 103 | 104 | return [NSNumber numberWithUnsignedInteger:encoded]; 105 | } 106 | break; 107 | 108 | case '3': 109 | if (type[3] == '2' && length == 4) { 110 | UInt32 encoded = 0; 111 | 112 | bcopy(data, &encoded, 4); 113 | 114 | encoded = OSSwapBigToHostInt32(encoded); 115 | 116 | if (signd && bit_get(encoded, BIT(31))) { 117 | bit_clear(encoded, BIT(31)); 118 | return [NSNumber numberWithInteger:-encoded]; 119 | } 120 | 121 | return [NSNumber numberWithUnsignedInteger:encoded]; 122 | } 123 | break; 124 | } 125 | } 126 | else if ((type[0] == 'f' || type[0] == 's') && type[1] == 'p' && length == 2) { 127 | UInt16 encoded = 0; 128 | 129 | bcopy(data, &encoded, 2); 130 | 131 | UInt8 i = [SmcHelper getIndexFromHexChar:type[2]]; 132 | UInt8 f = [SmcHelper getIndexFromHexChar:type[3]]; 133 | 134 | if (i + f != (type[0] == 's' ? 15 : 16) ) 135 | return nil; 136 | 137 | UInt16 swapped = OSSwapBigToHostInt16(encoded); 138 | 139 | BOOL signd = type[0] == 's'; 140 | BOOL minus = bit_get(swapped, BIT(15)); 141 | 142 | if (signd && minus) bit_clear(swapped, BIT(15)); 143 | 144 | return [NSNumber numberWithFloat:((float)swapped / (float)BIT(f)) * (signd && minus ? -1 : 1)]; 145 | }else if (type[0] == 'f' && type[1] == 'l' && type[2] == 't' && length == 4){ 146 | 147 | float encoded = 0; 148 | 149 | bcopy(data, &encoded, 4); 150 | 151 | 152 | 153 | 154 | return [NSNumber numberWithFloat:(encoded )]; 155 | } 156 | } 157 | } 158 | 159 | return nil; 160 | } 161 | 162 | + (BOOL)encodeNumericValue:(NSNumber*)value length:(NSUInteger)length type:(const char *)type outBuffer:(void*)outBuffer 163 | { 164 | if (type && outBuffer) { 165 | 166 | size_t typeLength = strnlen(type, 4); 167 | 168 | if (typeLength >= 3) { 169 | if ((type[0] == 'u' || type[0] == 's') && type[1] == 'i') { 170 | 171 | int intValue = [value intValue]; 172 | 173 | bool minus = intValue < 0; 174 | bool signd = type[0] == 's'; 175 | 176 | if (minus) intValue = -intValue; 177 | 178 | switch (type[2]) { 179 | case '8': 180 | if (type[3] == '\0' && length == 1) { 181 | UInt8 encoded = (UInt8)intValue; 182 | if (signd) bit_write(signd && minus, encoded, BIT(7)); 183 | bcopy(&encoded, outBuffer, 1); 184 | return TRUE; 185 | } 186 | break; 187 | 188 | case '1': 189 | if (type[3] == '6' && length == 2) { 190 | UInt16 encoded = (UInt16)intValue; 191 | if (signd) bit_write(signd && minus, encoded, BIT(15)); 192 | OSWriteBigInt16(outBuffer, 0, encoded); 193 | return TRUE; 194 | } 195 | break; 196 | 197 | case '3': 198 | if (type[3] == '2' && length == 4) { 199 | UInt32 encoded = (UInt32)intValue; 200 | if (signd) bit_write(signd && minus, encoded, BIT(31)); 201 | OSWriteBigInt32(outBuffer, 0, encoded); 202 | return TRUE; 203 | } 204 | break; 205 | } 206 | } 207 | else if ((type[0] == 'f' || type[0] == 's') && type[1] == 'p') { 208 | float floatValue = [value floatValue]; 209 | bool minus = floatValue < 0; 210 | bool signd = type[0] == 's'; 211 | UInt8 i = [SmcHelper getIndexFromHexChar:type[2]]; 212 | UInt8 f = [SmcHelper getIndexFromHexChar:type[3]]; 213 | 214 | if (i + f == (signd ? 15 : 16)) { 215 | if (minus) floatValue = -floatValue; 216 | UInt16 encoded = floatValue * (float)BIT(f); 217 | if (signd) bit_write(minus, encoded, BIT(15)); 218 | OSWriteBigInt16(outBuffer, 0, encoded); 219 | return TRUE; 220 | } 221 | } 222 | } 223 | } 224 | 225 | return FALSE; 226 | } 227 | 228 | + (NSNumber*)readNumericKey:(NSString*)key connection:(io_connect_t)connection 229 | { 230 | SMCVal_t info; 231 | 232 | NSNumber *value; 233 | 234 | if (kIOReturnSuccess == SMCReadKey(connection, key.UTF8String, &info)) { 235 | value = [SmcHelper decodeNumericValueFromBuffer:info.bytes length:info.dataSize type:info.dataType]; 236 | } 237 | 238 | return value; 239 | } 240 | 241 | + (BOOL)writeNumericKey:(NSString*)key value:(NSNumber*)value connection:(io_connect_t)connection 242 | { 243 | SMCVal_t info; 244 | 245 | if (kIOReturnSuccess == SMCReadKey(connection, [key cStringUsingEncoding:NSASCIIStringEncoding], &info)) { 246 | if ([SmcHelper encodeNumericValue:value length:info.dataSize type:info.dataType outBuffer:info.bytes]) { 247 | return kIOReturnSuccess == SMCWriteKeyUnsafe(connection, &info) ? TRUE : FALSE; 248 | } 249 | } 250 | 251 | return FALSE; 252 | } 253 | 254 | @end 255 | -------------------------------------------------------------------------------- /BatteryStatusShow/TabViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabViewController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/28. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class TabViewController : NSTabViewController { 12 | 13 | static let tabselectnotify = AppDelegate.programprefix + ".tabselectnotify" 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | let storyboard = NSStoryboard.init(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil) 18 | let iostabviewitem = NSTabViewItem() 19 | iostabviewitem.label = "IOS" 20 | iostabviewitem.image = NSImage(named:NSImage.Name(rawValue: "Iphone")) 21 | 22 | iostabviewitem.viewController = (storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "iosdetailviewcontroller")) as! IOSDetailViewController) 23 | self.addTabViewItem(iostabviewitem) 24 | 25 | let peripheraltabviewitem = NSTabViewItem() 26 | peripheraltabviewitem.label = "Peripheral" 27 | peripheraltabviewitem.image = NSImage(named:NSImage.Name(rawValue: "Mouse")) 28 | peripheraltabviewitem.viewController = (storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "peripheralviewcontroller")) as! PeripheralViewController) 29 | self.addTabViewItem(peripheraltabviewitem) 30 | 31 | 32 | let logviewitem = NSTabViewItem() 33 | logviewitem.label = "Log" 34 | logviewitem.image = NSImage(named:NSImage.Name(rawValue: "Log")) 35 | logviewitem.viewController = (storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "logviewcontroller")) as! LogViewController) 36 | self.addTabViewItem(logviewitem) 37 | 38 | 39 | addObserver(self, forKeyPath: "selectedTabViewItemIndex", options: [.new,.initial], context: nil) 40 | 41 | NotificationCenter.default.addObserver(self, selector: #selector(TabViewController.touchbarchange), name: NSNotification.Name(rawValue: WindowController.touchbarchangednotify), object: nil) 42 | 43 | NotificationCenter.default.addObserver(self, selector: #selector(TabViewController.alwayontopchange), name: NSNotification.Name(rawValue: AppDelegate.alwayontop_notify), object: nil) 44 | 45 | 46 | 47 | self.addObserver(self, forKeyPath: "view.window", options: [.new, .initial], context: nil) 48 | 49 | alwayontopchange() 50 | 51 | 52 | 53 | } 54 | 55 | @objc func touchbarchange(_ aNotification:Notification){ 56 | DispatchQueue.main.async { 57 | self.selectedTabViewItemIndex = aNotification.userInfo?["touchbarselected"] as! Int 58 | } 59 | } 60 | 61 | 62 | 63 | @objc func alwayontopchange(){ 64 | DispatchQueue.main.async{ 65 | if let window = self.view.window { 66 | if (UserDefaults.standard.integer(forKey: AppDelegate.user_default_alwayontop_key)==1){ 67 | window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(CGWindowLevelKey.floatingWindow))) 68 | }else{ 69 | window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(CGWindowLevelKey.normalWindow))) 70 | // window.level = Int(CGWindowLevelForKey(CGWindowLevelKey.floatingWindow)) 71 | } 72 | } 73 | } 74 | } 75 | 76 | 77 | 78 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 79 | //print("CHANGE OBSERVED: \(String(describing: change))") 80 | if (keyPath == "selectedTabViewItemIndex"){ 81 | 82 | NotificationCenter.default.post(name:Notification.Name(rawValue:TabViewController.tabselectnotify),object: nil,userInfo:["tabselected":change?[NSKeyValueChangeKey.newKey] as Any]) 83 | 84 | } else if (keyPath == "view.window"){ 85 | if let window = self.view.window { 86 | 87 | window.tabbingMode = .disallowed 88 | 89 | 90 | // custom window here 91 | if (UserDefaults.standard.integer(forKey: AppDelegate.user_default_alwayontop_key)==1){ 92 | window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(CGWindowLevelKey.floatingWindow))) 93 | }else{ 94 | window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(CGWindowLevelKey.normalWindow))) 95 | // window.level = Int(CGWindowLevelForKey(CGWindowLevelKey.floatingWindow)) 96 | } 97 | } 98 | } 99 | } 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | } 109 | -------------------------------------------------------------------------------- /BatteryStatusShow/TwoAxisBaseChartView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TwoEdgeBaseChartView.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/21. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | class TwoAxisBaseChartView:BaseChartView{ 13 | 14 | 15 | var rightaxiscolor:CGColor! 16 | 17 | var rightrowlabel:[NSTextField]! 18 | var righttitle:NSTextField! 19 | 20 | 21 | 22 | var rightminnum:NSTextField! 23 | var rightmaxnum:NSTextField! 24 | 25 | 26 | var rightrowstep:Int! 27 | 28 | var rightrowinit:Int! 29 | 30 | var rightlinechart:[CGPoint]! 31 | 32 | var rightlinechartcolor:CGColor! 33 | var rightmaxdashlinecolor:CGColor! 34 | var rightmindashlinecolor:CGColor! 35 | 36 | 37 | 38 | var rightmaxmindecimal:Int! 39 | var customrightmax:CGFloat! 40 | var customrightmin:CGFloat! 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | func rightmaxminlabelinit()->Bool{ 49 | 50 | 51 | if (showmaxmin){ 52 | 53 | 54 | if (rightminnum == nil || rightmaxnum == nil){ 55 | rightminnum = NSTextField(string: "test") 56 | rightmaxnum = NSTextField(string: "test") 57 | rightminnum.backgroundColor = NSColor.controlColor 58 | rightminnum.textColor = NSColor.labelColor 59 | rightminnum.isBordered = false 60 | rightminnum.isEditable = false 61 | rightminnum.isBezeled = false 62 | rightminnum.alignment = NSTextAlignment.center 63 | rightminnum.font = NSFont(name:"Helvetica Neue Medium", size:8) 64 | 65 | rightmaxnum.backgroundColor = NSColor.controlColor 66 | rightmaxnum.textColor = NSColor.labelColor 67 | rightmaxnum.isBordered = false 68 | rightmaxnum.isEditable = false 69 | rightmaxnum.isBezeled = false 70 | rightmaxnum.alignment = NSTextAlignment.center 71 | rightmaxnum.font = NSFont(name:"Helvetica Neue Medium", size:8) 72 | 73 | self.addSubview(rightminnum) 74 | self.addSubview(rightmaxnum) 75 | } 76 | 77 | return true 78 | 79 | } 80 | if (rightminnum != nil){ 81 | rightminnum.removeFromSuperview() 82 | rightminnum = nil 83 | } 84 | 85 | if (rightmaxnum != nil){ 86 | rightmaxnum.removeFromSuperview() 87 | rightmaxnum = nil 88 | } 89 | 90 | 91 | return false 92 | } 93 | 94 | override func setdefault(){ 95 | 96 | super.setdefault() 97 | 98 | rightaxiscolor = CGColor(red:0.8,green:0.8,blue:0.1,alpha:0.8) 99 | 100 | rightlinechartcolor = CGColor(red:0.8,green:0.8,blue:0.1,alpha:0.8) 101 | 102 | rightmaxdashlinecolor = CGColor(red:0.1,green:0.8,blue:0.1,alpha:0.8) 103 | rightmindashlinecolor = CGColor(red:0.8,green:0.1,blue:0.1,alpha:0.8) 104 | 105 | 106 | 107 | righttitle = NSTextField(string:"righttitle") 108 | 109 | 110 | righttitle.backgroundColor = NSColor.controlColor 111 | righttitle.textColor = NSColor.labelColor 112 | righttitle.isBordered = false 113 | righttitle.isEditable = false 114 | righttitle.isBezeled = false 115 | righttitle.alignment = NSTextAlignment.center 116 | righttitle.font = NSFont(name:"Helvetica Neue Medium", size:10) 117 | self.addSubview(righttitle) 118 | 119 | 120 | 121 | 122 | 123 | 124 | rightrowlabel = [NSTextField]() 125 | 126 | for i in 0...3 { 127 | 128 | let row = NSTextField(string: String(i)) 129 | row.backgroundColor = NSColor.controlColor 130 | row.textColor = NSColor.labelColor 131 | row.isBordered = false 132 | row.isEditable = false 133 | row.isBezeled = false 134 | row.autoresizesSubviews = true 135 | row.autoresizingMask = NSView.AutoresizingMask.width 136 | 137 | self.addSubview(row) 138 | 139 | rightrowlabel.append(row) 140 | 141 | rightrowstep = 0 142 | 143 | rightrowinit = 0 144 | 145 | 146 | rightmaxmindecimal = 0 147 | 148 | 149 | 150 | } 151 | 152 | 153 | rightlinechart = [CGPoint]() 154 | 155 | 156 | 157 | 158 | 159 | 160 | } 161 | 162 | 163 | 164 | 165 | override func buildchat(_ context:CGContext,_ dirtyRect: NSRect){ 166 | 167 | super.buildchat(context, dirtyRect) 168 | 169 | 170 | 171 | context.setStrokeColor(rightaxiscolor); 172 | // Reset to solid line 173 | context.setLineDash(phase: 0, lengths: []) 174 | 175 | 176 | var linewidth:CGFloat = dirtyRect.width/100 177 | if (linewidth < 3){ 178 | linewidth = 3 179 | } 180 | 181 | let xoffset : CGFloat = lineoffset.x / 100 * dirtyRect.width; 182 | let yoffset : CGFloat = lineoffset.y / 100 * dirtyRect.height; 183 | 184 | 185 | for i in 0...3 { 186 | 187 | rightrowlabel[i].stringValue = String(rightrowinit + i * rightrowstep) 188 | rightrowlabel[i].sizeToFit() 189 | 190 | 191 | let rightrowinterval = NSPoint(x: dirtyRect.width - xoffset + rightrowlabel[i].fittingSize.width/2, 192 | y:(dirtyRect.height-yoffset*2)/4 * CGFloat(i+1)+yoffset - rightrowlabel[i].fittingSize.height / 2 ) 193 | 194 | 195 | rightrowlabel[i].setFrameOrigin(rightrowinterval) 196 | 197 | 198 | 199 | 200 | 201 | 202 | } 203 | 204 | 205 | context.setLineWidth(linewidth) 206 | 207 | 208 | context.move(to:CGPoint(x:dirtyRect.width - linewidth/2 - xoffset, y: yoffset)) 209 | context.addLine(to: CGPoint(x :dirtyRect.width - linewidth/2 - xoffset, y: dirtyRect.height - linewidth/2 - yoffset)) 210 | 211 | 212 | context.strokePath() 213 | 214 | 215 | 216 | righttitle.setFrameOrigin(NSPoint(x:dirtyRect.width - xoffset/8 - righttitle.fittingSize.width, y: dirtyRect.height-yoffset * 0.75 )) 217 | 218 | 219 | 220 | if (rightlinechart.count > 0){ 221 | 222 | if ( rightlinechart.count==1){ 223 | rightlinechart.append(CGPoint(x:1.0,y: rightlinechart[rightlinechart.count-1].y)) 224 | } 225 | 226 | let lines = lineChartToPoints(dirtyRect, linewidth, rightlinechart) 227 | 228 | 229 | 230 | if (showbelowcolor){ 231 | context.setStrokeColor(CGColor.clear) 232 | context.setFillColor(chartfillcolor) 233 | context.addLines(between: lines) 234 | context.addLine(to: CGPoint(x:context.currentPointOfPath.x ,y:yoffset+linewidth)) 235 | context.addLine(to: CGPoint(x:lines[0].x,y:context.currentPointOfPath.y)) 236 | context.closePath() 237 | context.fillPath() 238 | 239 | } 240 | 241 | context.setStrokeColor(rightlinechartcolor) 242 | 243 | //context.setLineWidth(2) 244 | 245 | 246 | 247 | 248 | 249 | context.addLines(between: lines) 250 | 251 | 252 | context.strokePath() 253 | 254 | 255 | 256 | 257 | if ( rightmaxminlabelinit()){ 258 | 259 | 260 | 261 | context.setLineWidth(2) 262 | context.setLineDash(phase: 0, lengths: [2,3]) 263 | let max = lines.max(by: { a,b in 264 | a.y < b.y 265 | }) 266 | 267 | let min = lines.min (by: { a,b in 268 | a.y < b.y 269 | }) 270 | 271 | rightmaxnum.textColor = NSColor(cgColor:rightmaxdashlinecolor) 272 | 273 | 274 | if (customrightmax == nil){ 275 | let maxrelative = rightlinechart.max(by: { a,b in 276 | a.y < b.y 277 | }) 278 | 279 | rightmaxnum.stringValue = numtolabelstring(maxrelative!.y * CGFloat( 4 * rightrowstep ) + CGFloat(rightrowinit - rightrowstep)) 280 | }else{ 281 | rightmaxnum.stringValue = numtolabelstring(customrightmax) 282 | } 283 | 284 | 285 | rightminnum.textColor = NSColor(cgColor:rightmindashlinecolor) 286 | 287 | if (customrightmin == nil){ 288 | 289 | let minrelative = rightlinechart.min (by: { a,b in 290 | a.y < b.y 291 | }) 292 | 293 | rightminnum.stringValue = numtolabelstring(minrelative!.y * CGFloat( 4 * rightrowstep ) + CGFloat(rightrowinit - rightrowstep)) 294 | 295 | }else{ 296 | rightminnum.stringValue = numtolabelstring(customrightmin) 297 | 298 | } 299 | 300 | rightminnum.sizeToFit() 301 | rightmaxnum.sizeToFit() 302 | 303 | rightminnum.setFrameOrigin(CGPoint(x:dirtyRect.width - xoffset - linewidth - rightminnum.fittingSize.width,y:min!.y-minnum.fittingSize.height*0.8)) 304 | 305 | rightmaxnum.setFrameOrigin(CGPoint(x:dirtyRect.width - xoffset - linewidth - rightmaxnum.fittingSize.width, y:max!.y)) 306 | 307 | context.setStrokeColor(rightmaxdashlinecolor) 308 | context.move (to: CGPoint(x:xoffset+linewidth,y:max!.y)) 309 | 310 | 311 | context.addLine(to: CGPoint(x:dirtyRect.width-xoffset-linewidth, y:max!.y)) 312 | context.strokePath() 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | context.setStrokeColor(rightmindashlinecolor) 321 | context.move (to: CGPoint(x:xoffset+linewidth,y:min!.y)) 322 | 323 | context.addLine(to: CGPoint(x:dirtyRect.width-xoffset-linewidth, y:min!.y)) 324 | context.strokePath() 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | } 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | } 347 | 348 | 349 | 350 | 351 | // title.draw(NSRect(x:dirtyRect.width/2, y: dirtyRect.height - linewidth/2 - lineoffset.y, width:title.fittingSize.width, height:title.fittingSize.height)) 352 | 353 | 354 | 355 | 356 | 357 | } 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | } 370 | -------------------------------------------------------------------------------- /BatteryStatusShow/WindowsController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindowsController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/6/5. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @available(OSX 10.12.2, *) 12 | fileprivate extension NSTouchBar.CustomizationIdentifier { 13 | 14 | static let touchBar = NSTouchBar.CustomizationIdentifier( AppDelegate.programprefix + ".touchBar") 15 | } 16 | 17 | @available(OSX 10.12.2, *) 18 | fileprivate extension NSTouchBarItem.Identifier { 19 | 20 | @available(OSX 10.12.2, *) 21 | static let tab = NSTouchBarItem.Identifier( AppDelegate.programprefix + ".tab") 22 | 23 | } 24 | 25 | 26 | @available(OSX 10.12.2, *) 27 | fileprivate extension NSTouchBarItem.Identifier { 28 | 29 | 30 | } 31 | 32 | extension WindowController: NSTouchBarDelegate { 33 | 34 | 35 | 36 | 37 | @available(OSX 10.12.2, *) 38 | func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? { 39 | 40 | switch identifier { 41 | 42 | case NSTouchBarItem.Identifier.tab: 43 | 44 | 45 | 46 | 47 | 48 | let tabStyleItem = NSCustomTouchBarItem(identifier: identifier) 49 | 50 | 51 | 52 | tabStyleItem.customizationLabel = "Tab Selector" 53 | 54 | 55 | tabStyleItem.view = gettabStyleSegment() 56 | 57 | 58 | 59 | 60 | return tabStyleItem; 61 | 62 | 63 | 64 | default: return nil 65 | } 66 | } 67 | } 68 | 69 | 70 | 71 | 72 | class WindowController: NSWindowController { 73 | 74 | var iobattery:IOBattery! 75 | var iohid:IOHID! 76 | 77 | 78 | static let touchbarchangednotify = AppDelegate.programprefix + ".touchbarchangednotify" 79 | 80 | 81 | 82 | @available(OSX 10.12.2, *) 83 | override func makeTouchBar() -> NSTouchBar? { 84 | 85 | let touchBar = NSTouchBar() 86 | touchBar.delegate = self 87 | touchBar.customizationIdentifier = .touchBar 88 | touchBar.defaultItemIdentifiers = [.tab] 89 | touchBar.customizationAllowedItemIdentifiers = [.tab] 90 | 91 | return touchBar 92 | } 93 | 94 | @objc func changetab(_ sender: NSSegmentedControl) { 95 | 96 | let selected = sender.selectedSegment 97 | 98 | NotificationCenter.default.post(name:Notification.Name(rawValue:WindowController.touchbarchangednotify),object: nil,userInfo:["touchbarselected":selected]) 99 | 100 | 101 | // let style = sender.selectedSegment 102 | // self.setTextViewFont(index: style) 103 | } 104 | 105 | @objc func tabchanged(_ aNotification: Notification) { 106 | 107 | if #available(OSX 10.12.2, *) { 108 | 109 | 110 | (touchBar?.item(forIdentifier: .tab)?.view as! NSSegmentedControl).setSelected(true, forSegment: aNotification.userInfo?["tabselected"] as! Int) 111 | 112 | } 113 | 114 | } 115 | 116 | override func windowWillLoad() { 117 | 118 | guard #available(OSX 10.12.2, *) else { 119 | 120 | return; 121 | 122 | } 123 | 124 | 125 | NotificationCenter.default.addObserver(self, selector: #selector(WindowController.tabchanged), name: NSNotification.Name(rawValue: TabViewController.tabselectnotify), object: nil) 126 | 127 | NotificationCenter.default.addObserver(self, selector:#selector(WindowController.update), name: NSNotification.Name(rawValue:IOBattery.updatenotify), object: nil) 128 | 129 | NotificationCenter.default.addObserver(self, selector:#selector(WindowController.update), name: NSNotification.Name(rawValue:IOHID.updatenotify), object: nil) 130 | } 131 | 132 | @objc func update(){ 133 | 134 | 135 | 136 | if #available(OSX 10.12.2, *) { 137 | DispatchQueue.main.async { 138 | self.touchBar = nil 139 | } 140 | 141 | 142 | 143 | } 144 | } 145 | 146 | 147 | 148 | @available(OSX 10.12.2, *) 149 | func settabtext()->NSSegmentedControl{ 150 | if (self.iobattery==nil){ 151 | 152 | self.iobattery = (NSApplication.shared.delegate as! AppDelegate).getBattery() 153 | 154 | } 155 | 156 | 157 | 158 | 159 | 160 | var mactext = "💻" 161 | var iostext = "📱" 162 | 163 | if (self.iobattery != nil ){ 164 | if (!self.iobattery.nobattery){ 165 | mactext += " " + self.iobattery.capacity.description + "/" + self.iobattery.max_capacity.description 166 | } 167 | if (self.iobattery.withIOSDevice){ 168 | iostext += " " + self.iobattery.iosCurrentCapacity.description + "/" + self.iobattery.iosMaxCapacity.description 169 | } 170 | } 171 | 172 | 173 | var peripheraltext = "🖱" 174 | 175 | if (self.iohid==nil){ 176 | 177 | self.iohid = (NSApplication.shared.delegate as! AppDelegate).ioHID 178 | 179 | 180 | } 181 | 182 | if (self.iohid != nil && self.iohid.batterylevel.count>0){ 183 | 184 | 185 | 186 | for item in self.iohid.devices_name { 187 | if (item.range(of:"Mouse") != nil){ 188 | 189 | if let index = self.iohid.devices_name.index(of: item){ 190 | 191 | peripheraltext += " " + String( self.iohid.batterylevel[index]) + "%" 192 | break; 193 | } 194 | } 195 | } 196 | } 197 | 198 | let graphtext = "📈" 199 | let lottext = "🖌" 200 | 201 | 202 | 203 | 204 | return NSSegmentedControl(labels: [mactext,graphtext,iostext,peripheraltext,lottext], trackingMode: .momentary, target: self, action: #selector(changetab)) 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | } 216 | 217 | @available(OSX 10.12.2, *) 218 | func gettabStyleSegment()->NSSegmentedControl{ 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | let tabStyleSegment = settabtext() 227 | 228 | tabStyleSegment.setSelected(true, forSegment: 1) 229 | 230 | tabStyleSegment.segmentStyle = NSSegmentedControl.Style.rounded 231 | 232 | tabStyleSegment.trackingMode = .selectOne 233 | 234 | return tabStyleSegment 235 | 236 | } 237 | 238 | 239 | } 240 | -------------------------------------------------------------------------------- /BatteryStatusShow/battery.csv: -------------------------------------------------------------------------------- 1 | 2016-06-30,5332,2,38 2 | 2016-07-22,5295,8,38 3 | 2016-07-27,5232,10,33 4 | 2016-08-01,5262,13,35 5 | 2016-08-03,5260,14,40 6 | 2016-08-05,5110,15,31 7 | 2016-08-09,5088,18,36 8 | 2016-08-18,5107,26,35 9 | 2016-08-26,4996,29,36 10 | 2016-09-04,4934,31,28 11 | 2016-09-06,4968,32,32 12 | 2016-09-10,5006,32,30 13 | 2016-10-01,4838,38,31 14 | 2016-10-03,4823,39,31 15 | 2016-10-06,4893,40,31 16 | 2016-10-24,4768,48,31 17 | 2016-10-31,4831,52,35 18 | 2016-11-01,4855,54,35 19 | 2016-11-12,4712,58,35 20 | 2016-11-14,4845,60,38 21 | 2016-11-18,4773,61,23 22 | 2016-12-02,4661,64,25 23 | 2016-12-03,4542,65,27 24 | 2016-12-08,4639,66,30 25 | 2016-12-09,4557,67,38 26 | 2016-12-15,4527,70,40 27 | 2016-12-20,4658,71,38 28 | 2016-12-29,4465,74,36 29 | 2017-01-04,4626,77,41 30 | 2017-01-12,4474,82,38 31 | 2017-01-16,4508,84,38 32 | 2017-01-29,4503,89,38 33 | 2017-02-06,4300,94,38 34 | 2017-02-11,4361,96,38 35 | 2017-03-17,4366,106,32 36 | 2017-03-26,4333,109,35 37 | 2017-04-06,4259,111,35 38 | -------------------------------------------------------------------------------- /BatteryStatusShow/change.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | excfile=$(ls -la | grep -E ^-.{2}x\|^-.{5}x\|^-.{8}x |grep -v .sh | grep -oE '[^ ]+$') 3 | result=$(otool -L $excfile) 4 | array=($result) 5 | i=0 6 | for item in ${array[@]}; 7 | do 8 | if echo "${item}" | grep -q '^/usr/local/opt/'; then 9 | changenamearray[i]=$(echo "${item}" | grep -oE '[^/]+$') 10 | changeorg[i++]=$(echo "${item}") 11 | fi 12 | 13 | done 14 | 15 | i=0 16 | for item in ${changenamearray[@]}; 17 | do 18 | install_name_tool -id "@rpath/${item}" ../Frameworks/${item} 19 | install_name_tool -change "${changeorg[i++]}" "@rpath/${item}" "./${excfile}" 20 | done 21 | #echo ${array[1]} 22 | -------------------------------------------------------------------------------- /BatteryStatusShow/changealldylib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | excfiles=$(ls -la | grep -E '.dylib$' | grep -oE '[^ ]+$') 3 | 4 | for excfile in ${excfiles[@]}; 5 | do 6 | result=$(otool -L $excfile) 7 | array=($result) 8 | i=0 9 | for item in ${array[@]}; 10 | do 11 | if echo "${item}" | grep -q '^/usr/local/'; then 12 | changenamearray[i]=$(echo "${item}" | grep -oE '[^/]+$') 13 | changeorg[i++]=$(echo "${item}") 14 | fi 15 | 16 | done 17 | 18 | i=0 19 | for item in ${changenamearray[@]}; 20 | do 21 | install_name_tool -id "@rpath/${item}" ${item} 22 | install_name_tool -change "${changeorg[i++]}" "@rpath/${item}" "./${excfile}" 23 | done 24 | done 25 | #echo ${array[1]} 26 | 27 | 28 | -------------------------------------------------------------------------------- /BatteryStatusShow/data.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | v2.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /BatteryStatusShow/data.xcdatamodeld/data.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /BatteryStatusShow/data.xcdatamodeld/v2.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /BatteryStatusShow/iOSDetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // iOSDetailViewController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/28. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | 10 | import Cocoa 11 | 12 | class IOSDetailViewController: BatteryViewController { 13 | 14 | @IBOutlet weak var iOSSerialno: NSTextField! 15 | @IBOutlet weak var iOSName: NSTextField! 16 | @IBOutlet var detailviewoutlet: NSView! 17 | @IBOutlet weak var status: NSTextField! 18 | @IBOutlet weak var iOSColor: NSTextFieldCell! 19 | @IBOutlet weak var iOSDesc: NSTextField! 20 | @IBOutlet weak var estimatedText: NSTextField! 21 | 22 | @IBOutlet weak var manufdateText: NSTextField! 23 | 24 | @IBOutlet weak var voltageText: NSTextField! 25 | 26 | @IBOutlet weak var adaptorView: NSView! 27 | 28 | 29 | @IBOutlet weak var adaptorNameText: NSTextField! 30 | @IBOutlet weak var adaptorVoltageText: NSTextField! 31 | @IBOutlet weak var adaptorAmperageText: NSTextField! 32 | @IBOutlet weak var adaptorWattText: NSTextField! 33 | 34 | @IBOutlet weak var batteryPercentIndicator: NSLevelIndicator! 35 | @IBOutlet weak var batterypercentText: NSTextField! 36 | @IBOutlet weak var capacityFullText: NSTextField! 37 | @IBOutlet weak var powerText: NSTextField! 38 | @IBOutlet weak var serialText: NSTextField! 39 | @IBOutlet weak var cycleText: NSTextField! 40 | @IBOutlet weak var avgpowerText: NSTextField! 41 | @IBOutlet weak var temperatureText: NSTextField! 42 | @IBOutlet weak var manfText: NSTextField! 43 | @IBOutlet weak var currentText: NSTextField! 44 | @IBOutlet weak var capacityText: NSTextField! 45 | @IBOutlet weak var modelText: NSTextField! 46 | 47 | 48 | 49 | 50 | 51 | 52 | var count = 0; 53 | 54 | var updatedesc = true; 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | override func updatebatteryinfo(){ 64 | 65 | //iobattery = (NSApplication.shared().delegate as! AppDelegate).iobattery 66 | 67 | 68 | 69 | 70 | 71 | if (iobattery != nil ){ 72 | // iobattery.updatebattery() 73 | 74 | 75 | 76 | // detailviewoutlet.isHidden = false; 77 | 78 | //voltage = iobattery.voltage.description 79 | voltageText.stringValue = iobattery.iosVoltage.description + " v" 80 | 81 | currentText.stringValue = (iobattery.iosAmperage > 0 ? "⬆︎ ": iobattery.iosAmperage < 0 ? "⬇︎ ":" ") + abs(iobattery.iosAmperage).description + " ma" 82 | 83 | 84 | capacityText.stringValue = iobattery.iosCurrentCapacity.description + " mah" 85 | capacityFullText.stringValue = String(format:"%@ / %@ (%.1f %%)",iobattery.iosMaxCapacity.description,iobattery.iosDesignCapacity.description,iobattery.iosbatteryhealthpercent()) 86 | 87 | cycleText.stringValue = String(format:"%@ ",iobattery.iosCycle.description) 88 | 89 | temperatureText.stringValue = iobattery.iosBatteryTemp.description + " °C" 90 | 91 | let power = iobattery.iospower() 92 | 93 | powerText.stringValue = (power > 0 ? "⬆︎ ": power < 0 ? "⬇︎ ":" ") + String(format:"%.2f w",abs(power)) 94 | 95 | batterypercentText.stringValue = String(format:"%.1f %%",iobattery.iosbatterypercentage()) 96 | 97 | if (count==0){ 98 | avgpowerText.stringValue = (power > 0 ? "⬆︎ ": power < 0 ? "⬇︎ ":" ") + String(format:"%.2f w",abs(power)) 99 | 100 | }else{ 101 | let avgvalue = Float(avgpowerText.stringValue)! / Float(count) * Float(count-1) + 102 | power / Float(count) 103 | 104 | avgpowerText.stringValue = (avgvalue > 0 ? "⬆︎ ": avgvalue < 0 ? "⬇︎ ":" ") + String(format:"%.2f w",abs(avgvalue)) 105 | 106 | } 107 | 108 | 109 | 110 | 111 | batteryPercentIndicator.intValue = Int32(iobattery.iosbatterypercentage()) 112 | 113 | 114 | 115 | if (iobattery.iosIsCharging){ 116 | status.textColor = NSColor(red: 0.45,green: 0.32,blue: 0.70,alpha: 1.0) 117 | status.stringValue = "Charging" 118 | 119 | 120 | /* 121 | if (iobattery.iosTimeRemaining != 0 ){ 122 | 123 | 124 | 125 | let hour = Int(iobattery.iosTimeRemaining / 60) 126 | 127 | let min = Int(iobattery.iosTimeRemaining % 60) 128 | 129 | 130 | 131 | estimatedText.stringValue = String(format:"%d:%02d",hour,min) 132 | }else{ 133 | estimatedText.stringValue = "" 134 | }*/ 135 | 136 | 137 | 138 | }else { 139 | status.textColor = NSColor(red: 0.5,green: 0.5,blue: 0.5,alpha: 1.0) 140 | status.stringValue = "use Power" 141 | // estimatedText.stringValue = "" 142 | } 143 | 144 | 145 | 146 | 147 | 148 | 149 | // voltageText.stringValue = iobattery.voltage.description 150 | } 151 | 152 | } 153 | 154 | override func updatebatterydesc(){ 155 | // iobattery = (NSApplication.shared().delegate as! AppDelegate).iobattery 156 | 157 | 158 | 159 | 160 | 161 | if (iobattery.withIOSDevice){ 162 | 163 | 164 | modelText.stringValue = iobattery.iosModel 165 | serialText.stringValue = iobattery.iosBatterySerialNumber 166 | manfText.stringValue = iobattery.iosManufacturer 167 | 168 | 169 | 170 | 171 | iOSColor.backgroundColor = iobattery.iosdevicecolor 172 | iOSName.stringValue = iobattery.iosproductname 173 | iOSName.sizeToFit() 174 | iOSDesc.stringValue = iobattery.iosproductversion + " ("+iobattery.iosproducttype+")" 175 | iOSDesc.sizeToFit() 176 | 177 | iOSSerialno.stringValue = "("+iobattery.iosserialno+")" 178 | iOSSerialno.sizeToFit() 179 | 180 | manufdateText.stringValue = iobattery.iosmanufdate 181 | manufdateText.sizeToFit() 182 | 183 | 184 | iOSSerialno.stringValue = "("+iobattery.iosserialno+")" 185 | iOSSerialno.sizeToFit() 186 | 187 | 188 | 189 | 190 | 191 | 192 | adaptorView.isHidden = false 193 | adaptorNameText.stringValue = iobattery.iosAdapterDesc 194 | adaptorVoltageText.stringValue = String(format:"%f v",iobattery.iosAdapterVoltage) 195 | adaptorAmperageText.stringValue = iobattery.iosAdapterAmperage.description + "ma" 196 | adaptorWattText.stringValue = iobattery.iosAdapterWatts.description 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | //predictedlife() 206 | 207 | 208 | 209 | updatedesc = false 210 | 211 | } 212 | 213 | 214 | } 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | override func update(){ 231 | 232 | if (detailviewoutlet==nil){ 233 | return 234 | } 235 | 236 | if (iobattery==nil){ 237 | DispatchQueue.main.async{ 238 | self.iobattery = (NSApplication.shared.delegate as! AppDelegate).getBattery() 239 | } 240 | } 241 | 242 | if (iobattery != nil && !iobattery.withIOSDevice){ 243 | DispatchQueue.main.async { 244 | self.view.isHidden = true; 245 | self.updatedesc = true 246 | } 247 | 248 | // detailviewoutlet.isHidden = false; 249 | 250 | 251 | 252 | }else{ 253 | 254 | 255 | if (iobattery != nil && Int(iobattery.iosUpdateTime) > Int(truncating: lastupdate) ){ 256 | self.lastupdate = NSNumber(integerLiteral: self.iobattery.iosUpdateTime) 257 | DispatchQueue.main.async { 258 | self.view.isHidden = false; 259 | self.updatebatteryinfo() 260 | 261 | if (self.updatedesc){ 262 | self.updatebatterydesc() 263 | 264 | } 265 | 266 | 267 | } 268 | } 269 | 270 | DispatchQueue.main.async { 271 | self.updateview() 272 | } 273 | } 274 | 275 | 276 | } 277 | } 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /BatteryStatusShow/include/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/include/.DS_Store -------------------------------------------------------------------------------- /BatteryStatusShow/include/libimobiledevice/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/include/libimobiledevice/.DS_Store -------------------------------------------------------------------------------- /BatteryStatusShow/include/libimobiledevice/diagnostics_relay.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file libimobiledevice/diagnostics_relay.h 3 | * @brief Request iOS diagnostic information from device. 4 | * \internal 5 | * 6 | * Copyright (c) 2012-2014 Martin Szulecki, All Rights Reserved. 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #ifndef IDIAGNOSTICS_RELAY_H 24 | #define IDIAGNOSTICS_RELAY_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include 31 | #include 32 | 33 | #define DIAGNOSTICS_RELAY_SERVICE_NAME "com.apple.mobile.diagnostics_relay" 34 | 35 | /** Error Codes */ 36 | typedef enum { 37 | DIAGNOSTICS_RELAY_E_SUCCESS = 0, 38 | DIAGNOSTICS_RELAY_E_INVALID_ARG = -1, 39 | DIAGNOSTICS_RELAY_E_PLIST_ERROR = -2, 40 | DIAGNOSTICS_RELAY_E_MUX_ERROR = -3, 41 | DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST = -4, 42 | DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR = -256 43 | } diagnostics_relay_error_t; 44 | 45 | #define DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT (1 << 1) 46 | #define DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS (1 << 2) 47 | #define DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL (1 << 3) 48 | 49 | #define DIAGNOSTICS_RELAY_REQUEST_TYPE_ALL "All" 50 | #define DIAGNOSTICS_RELAY_REQUEST_TYPE_WIFI "WiFi" 51 | #define DIAGNOSTICS_RELAY_REQUEST_TYPE_GAS_GAUGE "GasGauge" 52 | #define DIAGNOSTICS_RELAY_REQUEST_TYPE_NAND "NAND" 53 | 54 | typedef struct diagnostics_relay_client_private diagnostics_relay_client_private; 55 | typedef diagnostics_relay_client_private *diagnostics_relay_client_t; /**< The client handle. */ 56 | 57 | /** 58 | * Connects to the diagnostics_relay service on the specified device. 59 | * 60 | * @param device The device to connect to. 61 | * @param service The service descriptor returned by lockdownd_start_service. 62 | * @param client Reference that will point to a newly allocated 63 | * diagnostics_relay_client_t upon successful return. 64 | * 65 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, 66 | * DIAGNOSTICS_RELAY_E_INVALID_ARG when one of the parameters is invalid, 67 | * or DIAGNOSTICS_RELAY_E_MUX_ERROR when the connection failed. 68 | */ 69 | diagnostics_relay_error_t diagnostics_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, diagnostics_relay_client_t *client); 70 | 71 | /** 72 | * Starts a new diagnostics_relay service on the specified device and connects to it. 73 | * 74 | * @param device The device to connect to. 75 | * @param client Pointer that will point to a newly allocated 76 | * diagnostics_relay_client_t upon successful return. Must be freed using 77 | * diagnostics_relay_client_free() after use. 78 | * @param label The label to use for communication. Usually the program name. 79 | * Pass NULL to disable sending the label in requests to lockdownd. 80 | * 81 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, or an DIAGNOSTICS_RELAY_E_* error 82 | * code otherwise. 83 | */ 84 | diagnostics_relay_error_t diagnostics_relay_client_start_service(idevice_t device, diagnostics_relay_client_t* client, const char* label); 85 | 86 | /** 87 | * Disconnects a diagnostics_relay client from the device and frees up the 88 | * diagnostics_relay client data. 89 | * 90 | * @param client The diagnostics_relay client to disconnect and free. 91 | * 92 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, 93 | * DIAGNOSTICS_RELAY_E_INVALID_ARG when one of client or client->parent 94 | * is invalid, or DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR when the was an 95 | * error freeing the parent property_list_service client. 96 | */ 97 | diagnostics_relay_error_t diagnostics_relay_client_free(diagnostics_relay_client_t client); 98 | 99 | 100 | /** 101 | * Sends the Goodbye request signaling the end of communication. 102 | * 103 | * @param client The diagnostics_relay client 104 | * 105 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, 106 | * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, 107 | * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the 108 | * request 109 | */ 110 | diagnostics_relay_error_t diagnostics_relay_goodbye(diagnostics_relay_client_t client); 111 | 112 | /** 113 | * Puts the device into deep sleep mode and disconnects from host. 114 | * 115 | * @param client The diagnostics_relay client 116 | * 117 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, 118 | * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, 119 | * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the 120 | * request 121 | */ 122 | diagnostics_relay_error_t diagnostics_relay_sleep(diagnostics_relay_client_t client); 123 | 124 | /** 125 | * Restart the device and optionally show a user notification. 126 | * 127 | * @param client The diagnostics_relay client 128 | * @param flags A binary flag combination of 129 | * DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT to wait until 130 | * diagnostics_relay_client_free() disconnects before execution and 131 | * DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL to show a "FAIL" dialog 132 | * or DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS to show an "OK" dialog 133 | * 134 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, 135 | * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, 136 | * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the 137 | * request 138 | */ 139 | diagnostics_relay_error_t diagnostics_relay_restart(diagnostics_relay_client_t client, int flags); 140 | 141 | /** 142 | * Shutdown of the device and optionally show a user notification. 143 | * 144 | * @param client The diagnostics_relay client 145 | * @param flags A binary flag combination of 146 | * DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT to wait until 147 | * diagnostics_relay_client_free() disconnects before execution and 148 | * DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL to show a "FAIL" dialog 149 | * or DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS to show an "OK" dialog 150 | * 151 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, 152 | * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, 153 | * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the 154 | * request 155 | */ 156 | diagnostics_relay_error_t diagnostics_relay_shutdown(diagnostics_relay_client_t client, int flags); 157 | 158 | /** 159 | * Shutdown of the device and optionally show a user notification. 160 | * 161 | * @param client The diagnostics_relay client 162 | * @param flags A binary flag combination of 163 | * DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT to wait until 164 | * diagnostics_relay_client_free() disconnects before execution and 165 | * DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL to show a "FAIL" dialog 166 | * or DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS to show an "OK" dialog 167 | * 168 | * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, 169 | * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, 170 | * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the 171 | * request 172 | */ 173 | diagnostics_relay_error_t diagnostics_relay_request_diagnostics(diagnostics_relay_client_t client, const char* type, plist_t* diagnostics); 174 | 175 | diagnostics_relay_error_t diagnostics_relay_query_mobilegestalt(diagnostics_relay_client_t client, plist_t keys, plist_t* result); 176 | 177 | diagnostics_relay_error_t diagnostics_relay_query_ioregistry_entry(diagnostics_relay_client_t client, const char* name, const char* class, plist_t* result); 178 | 179 | diagnostics_relay_error_t diagnostics_relay_query_ioregistry_plane(diagnostics_relay_client_t client, const char* plane, plist_t* result); 180 | 181 | #ifdef __cplusplus 182 | } 183 | #endif 184 | 185 | #endif 186 | -------------------------------------------------------------------------------- /BatteryStatusShow/include/libimobiledevice/libimobiledevice.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file libimobiledevice/libimobiledevice.h 3 | * @brief Device/Connection handling and communication 4 | * \internal 5 | * 6 | * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. 7 | * Copyright (c) 2014 Christophe Fergeau All Rights Reserved. 8 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public 21 | * License along with this library; if not, write to the Free Software 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | */ 24 | 25 | #ifndef IMOBILEDEVICE_H 26 | #define IMOBILEDEVICE_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | /** Error Codes */ 38 | typedef enum { 39 | IDEVICE_E_SUCCESS = 0, 40 | IDEVICE_E_INVALID_ARG = -1, 41 | IDEVICE_E_UNKNOWN_ERROR = -2, 42 | IDEVICE_E_NO_DEVICE = -3, 43 | IDEVICE_E_NOT_ENOUGH_DATA = -4, 44 | IDEVICE_E_BAD_HEADER = -5, 45 | IDEVICE_E_SSL_ERROR = -6 46 | } idevice_error_t; 47 | 48 | typedef struct idevice_private idevice_private; 49 | typedef idevice_private *idevice_t; /**< The device handle. */ 50 | 51 | typedef struct idevice_connection_private idevice_connection_private; 52 | typedef idevice_connection_private *idevice_connection_t; /**< The connection handle. */ 53 | 54 | /* discovery (events/asynchronous) */ 55 | /** The event type for device add or removal */ 56 | enum idevice_event_type { 57 | IDEVICE_DEVICE_ADD = 1, 58 | IDEVICE_DEVICE_REMOVE 59 | }; 60 | 61 | /* event data structure */ 62 | /** Provides information about the occured event. */ 63 | typedef struct { 64 | enum idevice_event_type event; /**< The event type. */ 65 | const char *udid; /**< The device unique id. */ 66 | int conn_type; /**< The connection type. Currently only 1 for usbmuxd. */ 67 | } idevice_event_t; 68 | 69 | /* event callback function prototype */ 70 | /** Callback to notifiy if a device was added or removed. */ 71 | typedef void (*idevice_event_cb_t) (const idevice_event_t *event, void *user_data); 72 | 73 | /* functions */ 74 | 75 | /** 76 | * Set the level of debugging. 77 | * 78 | * @param level Set to 0 for no debug output or 1 to enable debug output. 79 | */ 80 | void idevice_set_debug_level(int level); 81 | 82 | /** 83 | * Register a callback function that will be called when device add/remove 84 | * events occur. 85 | * 86 | * @param callback Callback function to call. 87 | * @param user_data Application-specific data passed as parameter 88 | * to the registered callback function. 89 | * 90 | * @return IDEVICE_E_SUCCESS on success or an error value when an error occured. 91 | */ 92 | idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data); 93 | 94 | /** 95 | * Release the event callback function that has been registered with 96 | * idevice_event_subscribe(). 97 | * 98 | * @return IDEVICE_E_SUCCESS on success or an error value when an error occured. 99 | */ 100 | idevice_error_t idevice_event_unsubscribe(void); 101 | 102 | /* discovery (synchronous) */ 103 | 104 | /** 105 | * Get a list of currently available devices. 106 | * 107 | * @param devices List of udids of devices that are currently available. 108 | * This list is terminated by a NULL pointer. 109 | * @param count Number of devices found. 110 | * 111 | * @return IDEVICE_E_SUCCESS on success or an error value when an error occured. 112 | */ 113 | idevice_error_t idevice_get_device_list(char ***devices, int *count); 114 | 115 | /** 116 | * Free a list of device udids. 117 | * 118 | * @param devices List of udids to free. 119 | * 120 | * @return Always returnes IDEVICE_E_SUCCESS. 121 | */ 122 | idevice_error_t idevice_device_list_free(char **devices); 123 | 124 | /* device structure creation and destruction */ 125 | 126 | /** 127 | * Creates an idevice_t structure for the device specified by udid, 128 | * if the device is available. 129 | * 130 | * @note The resulting idevice_t structure has to be freed with 131 | * idevice_free() if it is no longer used. 132 | * 133 | * @param device Upon calling this function, a pointer to a location of type 134 | * idevice_t. On successful return, this location will be populated. 135 | * @param udid The UDID to match. 136 | * 137 | * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. 138 | */ 139 | idevice_error_t idevice_new(idevice_t *device, const char *udid); 140 | 141 | /** 142 | * Cleans up an idevice structure, then frees the structure itself. 143 | * This is a library-level function; deals directly with the device to tear 144 | * down relations, but otherwise is mostly internal. 145 | * 146 | * @param device idevice_t to free. 147 | */ 148 | idevice_error_t idevice_free(idevice_t device); 149 | 150 | /* connection/disconnection */ 151 | 152 | /** 153 | * Set up a connection to the given device. 154 | * 155 | * @param device The device to connect to. 156 | * @param port The destination port to connect to. 157 | * @param connection Pointer to an idevice_connection_t that will be filled 158 | * with the necessary data of the connection. 159 | * 160 | * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. 161 | */ 162 | idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection); 163 | 164 | /** 165 | * Disconnect from the device and clean up the connection structure. 166 | * 167 | * @param connection The connection to close. 168 | * 169 | * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. 170 | */ 171 | idevice_error_t idevice_disconnect(idevice_connection_t connection); 172 | 173 | /* communication */ 174 | 175 | /** 176 | * Send data to a device via the given connection. 177 | * 178 | * @param connection The connection to send data over. 179 | * @param data Buffer with data to send. 180 | * @param len Size of the buffer to send. 181 | * @param sent_bytes Pointer to an uint32_t that will be filled 182 | * with the number of bytes actually sent. 183 | * 184 | * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. 185 | */ 186 | idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes); 187 | 188 | /** 189 | * Receive data from a device via the given connection. 190 | * This function will return after the given timeout even if no data has been 191 | * received. 192 | * 193 | * @param connection The connection to receive data from. 194 | * @param data Buffer that will be filled with the received data. 195 | * This buffer has to be large enough to hold len bytes. 196 | * @param len Buffer size or number of bytes to receive. 197 | * @param recv_bytes Number of bytes actually received. 198 | * @param timeout Timeout in milliseconds after which this function should 199 | * return even if no data has been received. 200 | * 201 | * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. 202 | */ 203 | idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout); 204 | 205 | /** 206 | * Receive data from a device via the given connection. 207 | * This function is like idevice_connection_receive_timeout, but with a 208 | * predefined reasonable timeout. 209 | * 210 | * @param connection The connection to receive data from. 211 | * @param data Buffer that will be filled with the received data. 212 | * This buffer has to be large enough to hold len bytes. 213 | * @param len Buffer size or number of bytes to receive. 214 | * @param recv_bytes Number of bytes actually received. 215 | * 216 | * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. 217 | */ 218 | idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes); 219 | 220 | /** 221 | * Enables SSL for the given connection. 222 | * 223 | * @param connection The connection to enable SSL for. 224 | * 225 | * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection 226 | * is NULL or connection->ssl_data is non-NULL, or IDEVICE_E_SSL_ERROR when 227 | * SSL initialization, setup, or handshake fails. 228 | */ 229 | idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection); 230 | 231 | /** 232 | * Disable SSL for the given connection. 233 | * 234 | * @param connection The connection to disable SSL for. 235 | * 236 | * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection 237 | * is NULL. This function also returns IDEVICE_E_SUCCESS when SSL is not 238 | * enabled and does no further error checking on cleanup. 239 | */ 240 | idevice_error_t idevice_connection_disable_ssl(idevice_connection_t connection); 241 | 242 | /* misc */ 243 | 244 | /** 245 | * Gets the handle of the device. Depends on the connection type. 246 | */ 247 | idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle); 248 | 249 | /** 250 | * Gets the unique id for the device. 251 | */ 252 | idevice_error_t idevice_get_udid(idevice_t device, char **udid); 253 | 254 | #ifdef __cplusplus 255 | } 256 | #endif 257 | 258 | #endif 259 | 260 | -------------------------------------------------------------------------------- /BatteryStatusShow/iosbattery.csv: -------------------------------------------------------------------------------- 1 | 2016-06-30,1580,2,38 2 | 2016-07-22,1532,8,38 3 | 2016-07-27,1562,10,33 4 | 2016-08-01,1543,13,35 5 | 2016-08-03,1542,14,40 6 | 2016-08-05,1532,15,31 7 | 2016-08-09,1550,18,36 8 | 2016-08-18,1532,26,35 9 | 2016-08-26,1512,29,36 10 | 2016-09-04,1600,31,28 11 | 2016-09-06,1550,32,32 12 | 2016-09-10,1632,32,30 13 | 2016-10-01,1620,38,31 14 | 2016-10-03,1580,39,31 15 | 2016-10-06,1580,40,31 16 | 2016-10-24,1580,48,31 17 | 2016-10-31,1580,52,35 18 | 2016-11-01,1520,54,35 19 | 2016-11-12,1580,58,35 20 | 2016-11-14,1540,60,38 21 | 2016-11-18,1520,61,23 22 | 2016-12-02,1550,64,25 23 | 2016-12-03,1600,65,27 24 | 2016-12-08,1540,66,30 25 | 2016-12-09,1600,67,38 26 | 2016-12-15,1600,70,40 27 | 2016-12-20,1574,41,38 28 | 2016-12-29,1600,43,36 29 | 2017-01-04,1580,47,41 30 | 2017-01-12,1580,48,38 31 | 2017-01-16,1580,50,38 32 | 2017-01-29,1560,52,38 33 | 2017-02-06,1550,58,38 34 | 2017-02-11,1550,60,38 35 | 2017-03-17,1532,65,32 36 | 2017-03-26,1489,70,35 37 | 2017-04-06,1530,72,35 38 | -------------------------------------------------------------------------------- /BatteryStatusShow/lib4758cca.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/lib4758cca.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libaep.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libaep.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libatalla.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libatalla.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libcapi.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libcapi.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libchil.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libchil.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libcrypto.1.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libcrypto.1.0.0.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libcrypto.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libcrypto.a -------------------------------------------------------------------------------- /BatteryStatusShow/libcrypto.dylib: -------------------------------------------------------------------------------- 1 | libcrypto.1.0.0.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libcswift.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libcswift.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libgmp.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libgmp.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libgost.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libgost.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libimobiledevice.6.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libimobiledevice.6.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libimobiledevice.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libimobiledevice.a -------------------------------------------------------------------------------- /BatteryStatusShow/libimobiledevice.dylib: -------------------------------------------------------------------------------- 1 | libimobiledevice.6.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libimobiledevice.la: -------------------------------------------------------------------------------- 1 | # libimobiledevice.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4.6 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='libimobiledevice.6.dylib' 9 | 10 | # Names of this library. 11 | library_names='libimobiledevice.6.dylib libimobiledevice.dylib' 12 | 13 | # The name of the static archive. 14 | old_library='libimobiledevice.a' 15 | 16 | # Linker flags that cannot go in dependency_libs. 17 | inherited_linker_flags=' ' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs=' -L/Users/slee/Documents/Development/libmobile/installroot/lib -lssl -lcrypto /Users/slee/Documents/Development/libmobile/installroot/lib/libusbmuxd.la -lpthread /Users/slee/Documents/Development/libmobile/installroot/lib/libplist.la' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libimobiledevice. 26 | current=6 27 | age=0 28 | revision=0 29 | 30 | # Is this an already installed library? 31 | installed=yes 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/Users/slee/Documents/Development/libmobile/installroot/lib' 42 | -------------------------------------------------------------------------------- /BatteryStatusShow/libltdl.7.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libltdl.7.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libltdl.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libltdl.a -------------------------------------------------------------------------------- /BatteryStatusShow/libltdl.dylib: -------------------------------------------------------------------------------- 1 | libltdl.7.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libltdl.la: -------------------------------------------------------------------------------- 1 | # libltdl.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4.6 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='libltdl.7.dylib' 9 | 10 | # Names of this library. 11 | library_names='libltdl.7.dylib libltdl.dylib' 12 | 13 | # The name of the static archive. 14 | old_library='libltdl.a' 15 | 16 | # Linker flags that cannot go in dependency_libs. 17 | inherited_linker_flags=' ' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs='' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libltdl. 26 | current=10 27 | age=3 28 | revision=1 29 | 30 | # Is this an already installed library? 31 | installed=yes 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/Users/slee/Documents/Development/libmobile/installroot/lib' 42 | -------------------------------------------------------------------------------- /BatteryStatusShow/libnuron.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libnuron.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libpadlock.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libpadlock.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libplist++.3.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libplist++.3.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libplist++.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libplist++.a -------------------------------------------------------------------------------- /BatteryStatusShow/libplist++.dylib: -------------------------------------------------------------------------------- 1 | libplist++.3.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libplist++.la: -------------------------------------------------------------------------------- 1 | # libplist++.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4.6 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='libplist++.3.dylib' 9 | 10 | # Names of this library. 11 | library_names='libplist++.3.dylib libplist++.dylib' 12 | 13 | # The name of the static archive. 14 | old_library='libplist++.a' 15 | 16 | # Linker flags that cannot go in dependency_libs. 17 | inherited_linker_flags=' ' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs=' /Users/slee/Documents/Development/libmobile/installroot/lib/libplist.la' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libplist++. 26 | current=4 27 | age=1 28 | revision=0 29 | 30 | # Is this an already installed library? 31 | installed=yes 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/Users/slee/Documents/Development/libmobile/installroot/lib' 42 | -------------------------------------------------------------------------------- /BatteryStatusShow/libplist.3.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libplist.3.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libplist.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libplist.a -------------------------------------------------------------------------------- /BatteryStatusShow/libplist.dylib: -------------------------------------------------------------------------------- 1 | libplist.3.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libplist.la: -------------------------------------------------------------------------------- 1 | # libplist.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4.6 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='libplist.3.dylib' 9 | 10 | # Names of this library. 11 | library_names='libplist.3.dylib libplist.dylib' 12 | 13 | # The name of the static archive. 14 | old_library='libplist.a' 15 | 16 | # Linker flags that cannot go in dependency_libs. 17 | inherited_linker_flags=' ' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs='' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libplist. 26 | current=4 27 | age=1 28 | revision=0 29 | 30 | # Is this an already installed library? 31 | installed=yes 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/Users/slee/Documents/Development/libmobile/installroot/lib' 42 | -------------------------------------------------------------------------------- /BatteryStatusShow/libssl.1.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libssl.1.0.0.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libssl.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libssl.a -------------------------------------------------------------------------------- /BatteryStatusShow/libssl.dylib: -------------------------------------------------------------------------------- 1 | libssl.1.0.0.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libsureware.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libsureware.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libubsec.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libubsec.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libusb-1.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libusb-1.0.0.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libusb-1.0.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libusb-1.0.a -------------------------------------------------------------------------------- /BatteryStatusShow/libusb-1.0.dylib: -------------------------------------------------------------------------------- 1 | libusb-1.0.0.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libusb-1.0.la: -------------------------------------------------------------------------------- 1 | # libusb-1.0.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4.2 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='libusb-1.0.0.dylib' 9 | 10 | # Names of this library. 11 | library_names='libusb-1.0.0.dylib libusb-1.0.dylib' 12 | 13 | # The name of the static archive. 14 | old_library='libusb-1.0.a' 15 | 16 | # Linker flags that can not go in dependency_libs. 17 | inherited_linker_flags=' ' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs=' -lobjc' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libusb-1.0. 26 | current=1 27 | age=1 28 | revision=0 29 | 30 | # Is this an already installed library? 31 | installed=yes 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/Users/slee/Documents/Development/libmobile/installroot/lib' 42 | -------------------------------------------------------------------------------- /BatteryStatusShow/libusbmuxd.4.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libusbmuxd.4.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libusbmuxd.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libusbmuxd.a -------------------------------------------------------------------------------- /BatteryStatusShow/libusbmuxd.dylib: -------------------------------------------------------------------------------- 1 | libusbmuxd.4.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libusbmuxd.la: -------------------------------------------------------------------------------- 1 | # libusbmuxd.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4.2 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='libusbmuxd.4.dylib' 9 | 10 | # Names of this library. 11 | library_names='libusbmuxd.4.dylib libusbmuxd.dylib' 12 | 13 | # The name of the static archive. 14 | old_library='libusbmuxd.a' 15 | 16 | # Linker flags that can not go in dependency_libs. 17 | inherited_linker_flags=' ' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs=' -L/Users/slee/Documents/Development/libmobile/installroot/lib /Users/slee/Documents/Development/libmobile/installroot/lib/libplist.la /Users/slee/Documents/Development/libmobile/installroot/lib/libxml2.la -lpthread -lz -liconv -lm' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libusbmuxd. 26 | current=4 27 | age=0 28 | revision=0 29 | 30 | # Is this an already installed library? 31 | installed=yes 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/Users/slee/Documents/Development/libmobile/installroot/lib' 42 | -------------------------------------------------------------------------------- /BatteryStatusShow/libxml2.2.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libxml2.2.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libxml2.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/libxml2.a -------------------------------------------------------------------------------- /BatteryStatusShow/libxml2.dylib: -------------------------------------------------------------------------------- 1 | libxml2.2.dylib -------------------------------------------------------------------------------- /BatteryStatusShow/libxml2.la: -------------------------------------------------------------------------------- 1 | # libxml2.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='libxml2.2.dylib' 9 | 10 | # Names of this library. 11 | library_names='libxml2.2.dylib libxml2.dylib' 12 | 13 | # The name of the static archive. 14 | old_library='libxml2.a' 15 | 16 | # Linker flags that can not go in dependency_libs. 17 | inherited_linker_flags=' ' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs=' -lpthread -lz -liconv -lm' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libxml2. 26 | current=10 27 | age=8 28 | revision=0 29 | 30 | # Is this an already installed library? 31 | installed=yes 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/Users/slee/Documents/Development/libmobile/installroot/lib' 42 | -------------------------------------------------------------------------------- /BatteryStatusShow/program_inside_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # program_inside_script.sh 4 | # 5 | # 6 | # Created by slee on 2017/5/27. 7 | # 8 | 9 | dir="${BUILT_PRODUCTS_DIR}/${TARGET_NAME}.app/Contents/MacOS/" 10 | excname="${dir}${TARGET_NAME}" 11 | result=$(otool -L ${excname}) 12 | array=($result) 13 | i=0 14 | for item in ${array[@]}; 15 | do 16 | if echo "${item}" | grep -q '^/usr/local/opt/'; then 17 | changenamearray[i]=$(echo "${item}" | grep -oE '[^/]+$') 18 | changeorg[i++]=$(echo "${item}") 19 | fi 20 | 21 | done 22 | 23 | i=0 24 | for item in ${changenamearray[@]}; 25 | do 26 | install_name_tool -id "@rpath/${item}" ${dir}../Frameworks/${item} 27 | 28 | 29 | 30 | install_name_tool -change "${changeorg[i++]}" "@rpath/${item}" "${excname}" 31 | done 32 | #echo ${array[1]} 33 | exit 0 34 | -------------------------------------------------------------------------------- /BatteryStatusShow/smc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Apple System Management Control (SMC) Tool 3 | * Copyright (C) 2006 devnull 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | /* 20 | cc ./smc.c -o smcutil -framework IOKit -framework CoreFoundation -Wno-four-char-constants -Wall -g -arch i386 21 | */ 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | 34 | #include "smc.h" 35 | 36 | // Cache the keyInfo to lower the energy impact of SMCReadKey() 37 | #define KEY_INFO_CACHE_SIZE 100 38 | struct { 39 | UInt32 key; 40 | SMCKeyData_keyInfo_t keyInfo; 41 | } g_keyInfoCache[KEY_INFO_CACHE_SIZE]; 42 | 43 | int g_keyInfoCacheCount = 0; 44 | 45 | 46 | UInt32 _strtoul(const char *str, int size, int base) 47 | { 48 | UInt32 total = 0; 49 | int i; 50 | 51 | for (i = 0; i < size; i++) 52 | { 53 | if (base == 16) 54 | total += str[i] << (size - 1 - i) * 8; 55 | else 56 | total += (unsigned char) (str[i] << (size - 1 - i) * 8); 57 | } 58 | return total; 59 | } 60 | 61 | void _ultostr(char *str, UInt32 val) 62 | { 63 | str[4] = '\0'; 64 | snprintf(str, 5, "%c%c%c%c", 65 | (unsigned int) val >> 24, 66 | (unsigned int) val >> 16, 67 | (unsigned int) val >> 8, 68 | (unsigned int) val); 69 | } 70 | 71 | 72 | 73 | kern_return_t SMCOpen(const char *serviceName, io_connect_t *conn) 74 | { 75 | kern_return_t result; 76 | mach_port_t masterPort; 77 | io_iterator_t iterator; 78 | io_object_t device; 79 | 80 | 81 | 82 | 83 | if (__builtin_available(macOS 12.0, *)) { 84 | IOMainPort(MACH_PORT_NULL, &masterPort); 85 | } else { 86 | IOMasterPort(MACH_PORT_NULL, &masterPort); 87 | } 88 | 89 | 90 | 91 | CFMutableDictionaryRef matchingDictionary = IOServiceMatching(serviceName); 92 | result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator); 93 | if (result != kIOReturnSuccess) 94 | { 95 | //printf("Error: IOServiceGetMatchingServices() = %08x\n", result); 96 | return 1; 97 | } 98 | 99 | device = IOIteratorNext(iterator); 100 | IOObjectRelease((io_object_t)iterator); 101 | if (device == 0) 102 | { 103 | //printf("Error: no SMC found\n"); 104 | return 1; 105 | } 106 | 107 | result = IOServiceOpen(device, mach_task_self(), 0, conn); 108 | IOObjectRelease(device); 109 | if (result != kIOReturnSuccess) 110 | { 111 | //printf("Error: IOServiceOpen() = %08x\n", result); 112 | return 1; 113 | } 114 | 115 | return kIOReturnSuccess; 116 | } 117 | 118 | kern_return_t SMCClose(io_connect_t conn) 119 | { 120 | return IOServiceClose(conn); 121 | } 122 | 123 | kern_return_t SMCCall(io_connect_t conn, int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure) 124 | { 125 | size_t structureInputSize; 126 | size_t structureOutputSize; 127 | 128 | structureInputSize = sizeof(SMCKeyData_t); 129 | structureOutputSize = sizeof(SMCKeyData_t); 130 | 131 | return IOConnectCallStructMethod( 132 | conn, 133 | index, 134 | inputStructure, 135 | structureInputSize, 136 | outputStructure, 137 | &structureOutputSize 138 | ); 139 | } 140 | 141 | // Provides key info, using a cache to dramatically improve the energy impact of smcFanControl 142 | kern_return_t SMCGetKeyInfo(io_connect_t conn, UInt32 key, SMCKeyData_keyInfo_t* keyInfo) 143 | { 144 | SMCKeyData_t inputStructure; 145 | SMCKeyData_t outputStructure; 146 | kern_return_t result = kIOReturnSuccess; 147 | int i = 0; 148 | 149 | // OSSpinLock g_keyInfoSpinLock = 0; 150 | //OSSpinLockLock(&g_keyInfoSpinLock); 151 | 152 | os_unfair_lock lock; 153 | if (__builtin_available(macOS 12.0, *)) { 154 | lock = OS_UNFAIR_LOCK_INIT; 155 | } 156 | os_unfair_lock_lock(&lock); 157 | 158 | 159 | for (; i < g_keyInfoCacheCount; ++i) 160 | { 161 | if (key == g_keyInfoCache[i].key) 162 | { 163 | *keyInfo = g_keyInfoCache[i].keyInfo; 164 | break; 165 | } 166 | } 167 | 168 | if (i == g_keyInfoCacheCount) 169 | { 170 | // Not in cache, must look it up. 171 | memset(&inputStructure, 0, sizeof(inputStructure)); 172 | memset(&outputStructure, 0, sizeof(outputStructure)); 173 | 174 | inputStructure.key = key; 175 | inputStructure.data8 = SMC_CMD_READ_KEYINFO; 176 | 177 | result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); 178 | if (result == kIOReturnSuccess) 179 | { 180 | *keyInfo = outputStructure.keyInfo; 181 | if (g_keyInfoCacheCount < KEY_INFO_CACHE_SIZE) 182 | { 183 | g_keyInfoCache[g_keyInfoCacheCount].key = key; 184 | g_keyInfoCache[g_keyInfoCacheCount].keyInfo = outputStructure.keyInfo; 185 | ++g_keyInfoCacheCount; 186 | } 187 | } 188 | } 189 | 190 | 191 | os_unfair_lock_unlock(&lock); 192 | 193 | //OSSpinLockUnlock(&g_keyInfoSpinLock); 194 | 195 | return result; 196 | } 197 | 198 | kern_return_t SMCReadKey(io_connect_t conn, const UInt32Char_t key, SMCVal_t *val) 199 | { 200 | kern_return_t result; 201 | SMCKeyData_t inputStructure; 202 | SMCKeyData_t outputStructure; 203 | 204 | memset(&inputStructure, 0, sizeof(SMCKeyData_t)); 205 | memset(&outputStructure, 0, sizeof(SMCKeyData_t)); 206 | memset(val, 0, sizeof(SMCVal_t)); 207 | 208 | inputStructure.key = _strtoul(key, 4, 16); 209 | //REVEIW_REHABMAN: mempcy used to avoid deprecated strcpy... 210 | //strcpy(val->key, key); 211 | memcpy(val->key, key, sizeof(val->key)); 212 | 213 | result = SMCGetKeyInfo(conn, inputStructure.key, &outputStructure.keyInfo); 214 | if (result != kIOReturnSuccess) 215 | return result; 216 | 217 | val->dataSize = outputStructure.keyInfo.dataSize; 218 | _ultostr(val->dataType, outputStructure.keyInfo.dataType); 219 | inputStructure.keyInfo.dataSize = val->dataSize; 220 | inputStructure.data8 = SMC_CMD_READ_BYTES; 221 | 222 | result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); 223 | if (result != kIOReturnSuccess) 224 | return result; 225 | 226 | memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); 227 | 228 | return kIOReturnSuccess; 229 | } 230 | 231 | kern_return_t SMCWriteKey(io_connect_t conn, const SMCVal_t *val) 232 | { 233 | SMCVal_t readVal; 234 | 235 | printf(""); 236 | IOReturn result = SMCReadKey(conn, val->key, &readVal); 237 | if (result != kIOReturnSuccess) 238 | return result; 239 | 240 | 241 | 242 | 243 | if (readVal.dataSize != val->dataSize) 244 | return kIOReturnError; 245 | 246 | 247 | 248 | return SMCWriteKeyUnsafe(conn, val); 249 | } 250 | 251 | kern_return_t SMCWriteKeyUnsafe(io_connect_t conn, const SMCVal_t *val) 252 | { 253 | kern_return_t result; 254 | SMCKeyData_t inputStructure; 255 | SMCKeyData_t outputStructure; 256 | 257 | memset(&inputStructure, 0, sizeof(SMCKeyData_t)); 258 | memset(&outputStructure, 0, sizeof(SMCKeyData_t)); 259 | 260 | inputStructure.key = _strtoul(val->key, 4, 16); 261 | inputStructure.data8 = SMC_CMD_WRITE_BYTES; 262 | inputStructure.keyInfo.dataSize = val->dataSize; 263 | memcpy(inputStructure.bytes, val->bytes, sizeof(val->bytes)); 264 | 265 | result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); 266 | if (result != kIOReturnSuccess) 267 | return result; 268 | 269 | return kIOReturnSuccess; 270 | } 271 | -------------------------------------------------------------------------------- /BatteryStatusShow/smc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Apple System Management Control (SMC) Tool 3 | * Copyright (C) 2006 devnull 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef __SMC_H__ 21 | #define __SMC_H__ 22 | 23 | 24 | 25 | 26 | #define VERSION "1.0" 27 | 28 | #define OP_NONE 0 29 | #define OP_LIST 1 30 | #define OP_READ 2 31 | #define OP_READ_FAN 3 32 | #define OP_WRITE 4 33 | #define OP_BRUTEFORCE 5 34 | 35 | #define KERNEL_INDEX_SMC 2 36 | 37 | #define SMC_CMD_READ_BYTES 5 38 | #define SMC_CMD_WRITE_BYTES 6 39 | #define SMC_CMD_READ_INDEX 8 40 | #define SMC_CMD_READ_KEYINFO 9 41 | #define SMC_CMD_READ_PLIMIT 11 42 | #define SMC_CMD_READ_VERS 12 43 | 44 | #define SMC_TYPE_FPE2 "fpe2" 45 | #define SMC_TYPE_FP2E "fp2e" 46 | #define SMC_TYPE_FP4C "fp4c" 47 | #define SMC_TYPE_CH8 "ch8*" 48 | #define SMC_TYPE_SP78 "sp78" 49 | #define SMC_TYPE_SP4B "sp4b" 50 | #define SMC_TYPE_FP5B "fp5b" 51 | #define SMC_TYPE_FP88 "fp88" 52 | #define SMC_TYPE_UI8 "ui8" 53 | #define SMC_TYPE_UI16 "ui16" 54 | #define SMC_TYPE_UI32 "ui32" 55 | #define SMC_TYPE_SI8 "si8" 56 | #define SMC_TYPE_SI16 "si16" 57 | #define SMC_TYPE_SI32 "si32" 58 | #define SMC_TYPE_FLAG "flag" 59 | #define SMC_TYPE_FDS "{fds" 60 | #define SMC_TYPE_FLT "flt " 61 | 62 | #define SMC_TYPE_FPXX_SIZE 2 63 | #define SMC_TYPE_SPXX_SIZE 2 64 | #define SMC_TYPE_UI8_SIZE 1 65 | #define SMC_TYPE_UI16_SIZE 2 66 | #define SMC_TYPE_UI32_SIZE 4 67 | #define SMC_TYPE_SI8_SIZE 1 68 | #define SMC_TYPE_SI16_SIZE 2 69 | #define SMC_TYPE_SI32_SIZE 4 70 | #define SMC_TYPE_FLAG_SIZE 1 71 | 72 | 73 | 74 | typedef struct { 75 | UInt8 major; 76 | UInt8 minor; 77 | UInt8 build; 78 | UInt8 reserved[1]; 79 | UInt16 release; 80 | } SMCKeyData_vers_t; 81 | 82 | typedef struct { 83 | UInt16 version; 84 | UInt16 length; 85 | UInt32 cpuPLimit; 86 | UInt32 gpuPLimit; 87 | UInt32 memPLimit; 88 | } SMCKeyData_pLimitData_t; 89 | 90 | typedef struct { 91 | UInt32 dataSize; 92 | UInt32 dataType; 93 | UInt8 dataAttributes; 94 | } SMCKeyData_keyInfo_t; 95 | 96 | typedef UInt8 SMCBytes_t[32]; 97 | 98 | typedef struct { 99 | UInt32 key; 100 | SMCKeyData_vers_t vers; 101 | SMCKeyData_pLimitData_t pLimitData; 102 | SMCKeyData_keyInfo_t keyInfo; 103 | UInt8 result; 104 | UInt8 status; 105 | UInt8 data8; 106 | UInt32 data32; 107 | SMCBytes_t bytes; 108 | } SMCKeyData_t; 109 | 110 | typedef char UInt32Char_t[5]; 111 | 112 | typedef struct { 113 | UInt32Char_t key; 114 | UInt32 dataSize; 115 | UInt32Char_t dataType; 116 | SMCBytes_t bytes; 117 | } SMCVal_t; 118 | 119 | UInt32 _strtoul(const char *str, int size, int base); 120 | void _ultostr(char *str, UInt32 val); 121 | 122 | kern_return_t SMCOpen(const char *serviceName, io_connect_t *conn); 123 | kern_return_t SMCClose(io_connect_t conn); 124 | kern_return_t SMCCall(io_connect_t conn, int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure); 125 | kern_return_t SMCReadKey(io_connect_t conn, const UInt32Char_t key, SMCVal_t *val); 126 | kern_return_t SMCWriteKey(io_connect_t conn, const SMCVal_t *val); 127 | kern_return_t SMCWriteKeyUnsafe(io_connect_t conn, const SMCVal_t *val); 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /BatteryStatusShow/smcutil: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/BatteryStatusShow/smcutil -------------------------------------------------------------------------------- /BatteryStatusShow/smcutil-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'smcutil' target in the 'smcutil' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /BatteryStatusShowTests/BatteryStatusShowTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatteryStatusShowTests.swift 3 | // BatteryStatusShowTests 4 | // 5 | // Created by slee on 2017/5/10. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import BatteryStatusShow 11 | 12 | class BatteryStatusShowTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceDatabase() { 30 | 31 | let iobattery = (NSApplication.shared.delegate as! AppDelegate).getBattery() 32 | 33 | let testbattery_serialno = "TEST" 34 | // This is an example of a performance test case. 35 | self.measure { 36 | 37 | 38 | //Run Loop for insert 39 | for _ in 1...10000{ 40 | 41 | iobattery.rundatabase ("History", iobattery.max_capacity as NSNumber, Date(timeIntervalSince1970: iobattery.lastupdatetime as! TimeInterval), iobattery.cycle_count as NSNumber, iobattery.tempKtoC() as NSNumber, testbattery_serialno as NSString) 42 | 43 | iobattery.save = true; 44 | 45 | iobattery.databasesave() 46 | } 47 | 48 | 49 | } 50 | 51 | 52 | let historyFetch :NSFetchRequest = NSFetchRequest(entityName: "History") 53 | historyFetch.sortDescriptors = [NSSortDescriptor(key: "time", ascending: true)] 54 | 55 | historyFetch.predicate = NSPredicate(format:"( serialno = %@ )",testbattery_serialno) 56 | 57 | 58 | 59 | //Remove all test inserts 60 | do { 61 | 62 | 63 | let batchdelete = NSBatchDeleteRequest(fetchRequest: historyFetch); 64 | 65 | try iobattery.datacontroller.managedObjectContext.execute(batchdelete); 66 | 67 | iobattery.databasesave() 68 | }catch { 69 | 70 | } 71 | 72 | 73 | 74 | // Put the code you want to measure the time of here. 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /BatteryStatusShowTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /BatteryStatusShowUITests/BatteryStatusShowUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatteryStatusShowUITests.swift 3 | // BatteryStatusShowUITests 4 | // 5 | // Created by slee on 2017/5/10. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class BatteryStatusShowUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testUI() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | 35 | let app = XCUIApplication() 36 | let batteryStatusShowWindow = app.windows["Battery Status Show"] 37 | let toolbarsQuery = batteryStatusShowWindow.toolbars 38 | toolbarsQuery.buttons["IOS"].click() 39 | 40 | let peripheralButton = toolbarsQuery.buttons["Peripheral"] 41 | peripheralButton.click() 42 | toolbarsQuery.buttons["Log"].click() 43 | 44 | let startButton = batteryStatusShowWindow.buttons["Start"] 45 | startButton.click() 46 | batteryStatusShowWindow.buttons["Stop"].click() 47 | startButton.click() 48 | batteryStatusShowWindow.checkBoxes["Label"].doubleClick() 49 | peripheralButton.click() 50 | toolbarsQuery.buttons["Graph"].click() 51 | toolbarsQuery.buttons["macOS"].click() 52 | app.menuBars.menuBarItems["Window"].click() 53 | batteryStatusShowWindow.toolbars.containing(.button, identifier:"macOS").element.click() 54 | 55 | 56 | let query2 = app.radioButtons.matching(NSPredicate(format: "title LIKE '*🖱*'")) 57 | //(identifier: "💻").radioButtons.allElementsBoundByIndex 58 | 59 | 60 | 61 | if query2.count > 0 { 62 | query2.element(boundBy: 0).tap() 63 | } 64 | 65 | app.radioButtons["📈"].tap() 66 | app.radioButtons["📱"].tap() 67 | // app.radioButtons["🖱 41%"].tap() 68 | app.radioButtons["🖌"].tap() 69 | 70 | let query = app.radioButtons.containing(NSPredicate(format: "title LIKE %@","*💻*")) 71 | 72 | 73 | 74 | 75 | if query.count > 0 { 76 | query.element(boundBy: 0).tap() 77 | } 78 | 79 | 80 | // app.radioButtons["💻"].tap() 81 | 82 | 83 | batteryStatusShowWindow.typeKey(XCUIKeyboardKey.escape, modifierFlags:[]) 84 | batteryStatusShowWindow.buttons[XCUIIdentifierCloseWindow].click() 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /BatteryStatusShowUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /CycleEntityMigrationPolicy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CycleEntityMigrationPolicy.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/22. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | 13 | class CycleEntityMigrationPolicy : NSEntityMigrationPolicy { 14 | 15 | // public let NSMigrationEntityPolicyKey = "CycleEntityMigrationPolicy" 16 | 17 | 18 | 19 | 20 | 21 | override func createRelationships(forDestination dInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws { 22 | 23 | try super.createRelationships(forDestination: dInstance,in: mapping,manager: manager) 24 | 25 | let count = (NSApplication.shared.delegate as! AppDelegate).getBattery().cycle_count 26 | let temp = (NSApplication.shared.delegate as! AppDelegate).getBattery().tempKtoC() 27 | dInstance.setValue(count, forKey: "cycle") 28 | dInstance.setValue(temp, forKey: "temperature") 29 | 30 | 31 | 32 | 33 | 34 | // let destinattion = dInstance as! HistoryMO 35 | // destinattion.cycle = 0 36 | } 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /IOSHistoryViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IOSHistoryViewController.swift 3 | // BatteryStatusShow 4 | // 5 | // Created by slee on 2017/5/31. 6 | // Copyright © 2017年 sicreativelee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class IOSHistoryViewController: BatteryViewController { 12 | 13 | var history: [HistoryMO]! 14 | 15 | 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | (view as! BaseChartView).title.stringValue = "" 21 | (view as! BaseChartView).title.sizeToFit() 22 | 23 | (view as! BaseChartView).ytitle.stringValue = "capacity" 24 | (view as! BaseChartView).ytitle.sizeToFit() 25 | 26 | (view as! BaseChartView).xtitle.stringValue = "months" 27 | (view as! BaseChartView).xtitle.sizeToFit() 28 | 29 | 30 | 31 | (view as! BaseChartView).showbelowcolor = true 32 | (view as! BaseChartView).showmaxmin = true 33 | 34 | (view as! BaseChartView).offsety = -10 35 | 36 | 37 | 38 | 39 | 40 | // Do any additional setup after loading the view. 41 | } 42 | 43 | 44 | 45 | 46 | 47 | override func updatebatterydesc() { 48 | 49 | (view as! BaseChartView).linechart.removeAll() 50 | 51 | 52 | (view as! BaseChartView).rowstep = iobattery.iosDesignCapacity / 4 53 | (view as! BaseChartView).rowinit = iobattery.iosDesignCapacity / 4 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | let historyFetch :NSFetchRequest = NSFetchRequest(entityName: "IOSHistory") 63 | historyFetch.sortDescriptors = [NSSortDescriptor(key: "time", ascending: true)] 64 | 65 | historyFetch.predicate = NSPredicate(format:"( serialno = %@ )",iobattery.iosBatterySerialNumber) 66 | 67 | do { 68 | history = try datacontroller.managedObjectContext.fetch(historyFetch) as? [HistoryMO] 69 | 70 | var maxduration : Int = 12; 71 | let now = Date() 72 | 73 | 74 | 75 | let dateformatter = DateFormatter() 76 | dateformatter.timeZone = NSTimeZone.local 77 | dateformatter.dateStyle = .medium 78 | dateformatter.timeStyle = .medium 79 | 80 | if (history.count>0){ 81 | 82 | 83 | var interval = history[0].time?.timeIntervalSince(now) 84 | let months = interval! / (-86400 * 30.4375) 85 | let calender = Calendar.current 86 | if (Int(months) > maxduration){ 87 | maxduration = Int(months) 88 | }else{ 89 | 90 | 91 | interval = calender.date(byAdding: .year, value: -1, to: now)?.timeIntervalSince(now) 92 | } 93 | 94 | (view as! BaseChartView).columnstep = -maxduration / 4 95 | (view as! BaseChartView).columninit = maxduration / 4 * 3 96 | 97 | 98 | var nextpointday = 1; 99 | 100 | 101 | let showcount :Int = months>12 ? 24:(Int(months)+1)*2 102 | 103 | if (history.count / showcount > 0){ 104 | nextpointday = history.count / showcount + 1 105 | } 106 | 107 | 108 | 109 | var dayfollowing = calender.startOfDay(for: history[0].time! ) 110 | 111 | var min = history[0].capacity as! Int 112 | var max = history[0].capacity as! Int 113 | var numskip = 0 114 | var totalcap = 0 115 | 116 | for item in history { 117 | 118 | let capacity = item.capacity as! Int 119 | 120 | if (capacity > max){ 121 | max = capacity 122 | } 123 | if (capacity < min){ 124 | min = capacity 125 | } 126 | 127 | 128 | 129 | totalcap += capacity 130 | 131 | 132 | if ((dayfollowing.timeIntervalSince(calender.startOfDay(for: item.time!))) > TimeInterval(0) ){ 133 | numskip += 1 134 | 135 | 136 | 137 | 138 | continue; 139 | } 140 | 141 | dayfollowing = dayfollowing.addingTimeInterval(Double(nextpointday) * 86400.0 ) 142 | 143 | 144 | 145 | 146 | let iteminterval = item.time?.timeIntervalSince(now) 147 | 148 | 149 | let xvalue = iteminterval! / interval! 150 | 151 | 152 | totalcap /= (numskip + 1) 153 | 154 | (view as! BaseChartView).linechart.append(CGPoint(x:1-xvalue, 155 | y: Double ( totalcap ) / Double(iobattery.iosDesignCapacity))) 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | // print (String(format: "ios history: %d, %@", totalcap,showdate )) 167 | 168 | totalcap = 0 169 | numskip = 0 170 | 171 | } 172 | 173 | 174 | 175 | if ((view as! BaseChartView).linechart.count>0){ 176 | 177 | (view as! BaseChartView).linechart.append(CGPoint(x:1, 178 | y: (view as! BaseChartView).linechart[(view as! BaseChartView).linechart.count-1].y)) 179 | } 180 | 181 | 182 | 183 | 184 | (view as! BaseChartView).custommin = CGFloat(min) 185 | (view as! BaseChartView).custommax = CGFloat(max) 186 | 187 | 188 | 189 | 190 | if (history.count>30){ 191 | 192 | let reg = DetailViewController.calcatedline(history) 193 | let date = Date().timeIntervalSince1970 194 | 195 | let nowcap = DetailViewController.calcatepredict(x: date, slope: reg.slope, intersection: reg.intersect) 196 | 197 | let firstcap = DetailViewController.calcatepredict(x: (history[0].time?.timeIntervalSince1970)!, slope: reg.slope, intersection: reg.intersect) 198 | 199 | (view as! BaseChartView).reglineBegin = CGPoint(x:1-(history[0].time?.timeIntervalSinceNow)!/interval!,y:firstcap/Double(iobattery.iosDesignCapacity)) 200 | 201 | (view as! BaseChartView).reglineEnd = CGPoint(x:1,y:nowcap/Double(iobattery.iosDesignCapacity)) 202 | 203 | 204 | } 205 | 206 | /* 207 | 208 | if ((view as! BaseChartView).minnum != nil && (view as! BaseChartView).maxnum != nil && (view as! BaseChartView).minnum.stringValue == (view as! BaseChartView).maxnum.stringValue){ 209 | 210 | (view as! BaseChartView).showmaxmin = false; 211 | 212 | } 213 | */ 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | } 222 | }catch { 223 | // fatalError("Failed to fetch IOS history: \(error)") 224 | } 225 | 226 | 227 | 228 | 229 | 230 | 231 | view.layer?.setNeedsDisplay() 232 | view.layer?.displayIfNeeded() 233 | 234 | 235 | } 236 | 237 | 238 | 239 | 240 | 241 | } 242 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BatteryStatusShow 2 | ### View detail battery information on OSX for IOS and MAC devices 3 | 4 | ![ pic1](/README/readme_pic1.png) 5 | ![ pic2](/README/readme_pic2.png) 6 | 7 | #### Version 1.5.5 8 | Support Monterey 9 | #### Version 1.5.41 10 | Solve 1.5.4 unable change level 11 | #### Version 1.5.4 12 | Support Big Sur and Xcode 12 (only support Intel Platform, not for Apple Silicon) 13 | #### Version 1.5.3 14 | fixed crash and show information of latest IOS devices (suppot IOS 13) 15 | #### Version 1.5.2 16 | fixed crash for not found device description (Macbook 16) and stable improvement 17 | #### Version 1.5.1 18 | fixed crash by library dependencies issue 19 | #### Version 1.5 20 | 21 | 22 | 23 | ##### 1. Updated view and change of Battery Change Limit Level (By modifiy of SMC, USE AS YOUR RISK!) 24 | 25 | 26 | ``` 27 | To change of Changing Limit, such 70% to stop change, 28 | start BatteryStatusShow > macOS > click change button next Charge Level 29 | A dialog with a slider to adjust the changing level, default is 100% 30 | Click OK,input your sudo password on next dialog 31 | Finish! 32 | May need up to above one minutes to update the status. 33 | 34 | Resume default value simple set to 100% or reset SMC 35 | Tested under 10.15.4 Macbook Pro 2018, may or may not work on your model. 36 | ``` 37 | ##### 2. Update macOS device detail 38 | ##### 3. Update IOS device detail 39 | 40 | 41 | ## Download complied APP 42 | 43 | [BatteryStatusShow_1.5.5.zip](/release/BatteryStatusShow_1.5.5.zip) 44 | 45 | ### Complie 46 | 1. clone this git 47 | 2. complie smcutil scheme 48 | 3. complie BatteryStatusShow scheme 49 | 50 | Copyright (c) 2020 SC Lee. All rights reserved. 51 | 52 | Libmobiledevice http://www.libimobiledevice.org 53 | smcutil modify from https://github.com/RehabMan/OS-X-FakeSMC-kozlek 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /README/readme_pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/README/readme_pic1.png -------------------------------------------------------------------------------- /README/readme_pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/README/readme_pic2.png -------------------------------------------------------------------------------- /release/BatteryStatusShow_1.5.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/release/BatteryStatusShow_1.5.1.zip -------------------------------------------------------------------------------- /release/BatteryStatusShow_1.5.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/release/BatteryStatusShow_1.5.2.zip -------------------------------------------------------------------------------- /release/BatteryStatusShow_1.5.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/release/BatteryStatusShow_1.5.3.zip -------------------------------------------------------------------------------- /release/BatteryStatusShow_1.5.41.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/release/BatteryStatusShow_1.5.41.zip -------------------------------------------------------------------------------- /release/BatteryStatusShow_1.5.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sicreative/BatteryStatusShow/cf127e12ea56de14e2cb574be53e7eb4cd7da5fe/release/BatteryStatusShow_1.5.5.zip -------------------------------------------------------------------------------- /smcutil/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // smcutil 4 | // 5 | // Created by kozlek on 31.03.13. 6 | // Copyright (c) 2013 kozlek. All rights reserved. 7 | // 8 | 9 | /* 10 | * Apple System Management Control (SMC) Tool 11 | * Copyright (C) 2006 devnull 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | */ 27 | 28 | #import 29 | #import 30 | 31 | #import "SmcHelper.h" 32 | 33 | #define NSStr(x) [NSString stringWithCString:(x) encoding:NSASCIIStringEncoding] 34 | 35 | #define OPTION_NONE 0 36 | #define OPTION_LIST 1 37 | #define OPTION_READ 2 38 | #define OPTION_WRITE 3 39 | #define OPTION_HELP 4 40 | 41 | void usage(const char* prog) 42 | { 43 | printf("smcutil v%s\n", VERSION); 44 | printf("Usage:\n"); 45 | printf("%s [options]\n", prog); 46 | printf(" -l : list of all keys\n"); 47 | printf(" -r : show key value\n"); 48 | printf(" -h : help\n"); 49 | printf("\n"); 50 | } 51 | 52 | UInt32 SMCReadIndexCount(io_connect_t connection) 53 | { 54 | return [[SmcHelper readNumericKey:@"#KEY" connection:connection] intValue]; 55 | } 56 | 57 | bool printKeyValue(SMCVal_t val) 58 | { 59 | if (val.dataSize > 0) 60 | { 61 | if (!strncasecmp(val.dataType, "ch8*", 4)) { 62 | for (int i = 0; i < val.dataSize; i++) 63 | printf("%c", (char)val.bytes[i]); 64 | } 65 | else if (!strncasecmp(val.dataType, "flag", 4)) { 66 | printf(val.bytes[0] ? "TRUE" : "FALSE"); 67 | } 68 | else if ([SmcHelper isValidIntegerSmcType:NSStr(val.dataType)]) { 69 | printf("%d", [SmcHelper decodeNumericValueFromBuffer:val.bytes length:val.dataSize type:val.dataType].unsignedIntValue); 70 | } 71 | else if ([SmcHelper isValidFloatingSmcType:NSStr(val.dataType)]) { 72 | printf("%.2f", [SmcHelper decodeNumericValueFromBuffer:val.bytes length:val.dataSize type:val.dataType].floatValue); 73 | } 74 | else return false; 75 | 76 | return true; 77 | } 78 | else 79 | { 80 | printf("no data"); 81 | } 82 | 83 | return false; 84 | } 85 | 86 | void printValueBytes(SMCVal_t val) 87 | { 88 | printf("(bytes"); 89 | if (val.dataSize > 0) 90 | { 91 | for (int i = 0; i < val.dataSize; i++) 92 | printf(" %02x", (unsigned char) val.bytes[i]); 93 | } 94 | else { 95 | printf(" -"); 96 | } 97 | printf(")"); 98 | } 99 | 100 | int main(int argc, const char * argv[]) 101 | { 102 | @autoreleasepool { 103 | int c, option; 104 | char key[5]; 105 | SMCVal_t val; 106 | 107 | option = OPTION_HELP; 108 | 109 | while ((c = getopt(argc, argv, "lrw")) != -1) 110 | { 111 | switch(c) 112 | { 113 | case 'l': 114 | option = OPTION_LIST; 115 | break; 116 | case 'r': 117 | option = OPTION_READ; 118 | break; 119 | case 'w': 120 | option = OPTION_WRITE; 121 | break; 122 | case 'h': 123 | case '?': 124 | default: 125 | usage(argv[0]); 126 | return 1; 127 | } 128 | } 129 | 130 | io_connect_t connection; 131 | 132 | if (kIOReturnSuccess == SMCOpen("AppleSMC", &connection)) { 133 | 134 | switch (option) { 135 | case OPTION_LIST: { 136 | 137 | UInt32 count = SMCReadIndexCount(connection); 138 | 139 | for (UInt32 index = 0; index < count; index++) { 140 | SMCKeyData_t inputStructure; 141 | SMCKeyData_t outputStructure; 142 | 143 | memset(&inputStructure, 0, sizeof(SMCKeyData_t)); 144 | memset(&outputStructure, 0, sizeof(SMCKeyData_t)); 145 | memset(&val, 0, sizeof(SMCVal_t)); 146 | 147 | inputStructure.data8 = SMC_CMD_READ_INDEX; 148 | inputStructure.data32 = index; 149 | 150 | if (kIOReturnSuccess == SMCCall(connection, KERNEL_INDEX_SMC, &inputStructure, &outputStructure)) { 151 | _ultostr(key, outputStructure.key); 152 | 153 | if (kIOReturnSuccess == SMCReadKey(connection, key, &val)) { 154 | printf(" %-4s [%-4s] ", val.key, val.dataType); 155 | if (printKeyValue(val)) 156 | printf(" "); 157 | printValueBytes(val); 158 | printf("\n"); 159 | } 160 | } 161 | } 162 | 163 | break; 164 | } 165 | 166 | case OPTION_READ: 167 | snprintf(key, 5, "%s", argv[2]); 168 | if (kIOReturnSuccess == SMCReadKey(connection, key, &val)) { 169 | printKeyValue(val); 170 | } 171 | break; 172 | 173 | case OPTION_WRITE: { 174 | const char *args = argv[3]; 175 | 176 | snprintf(key, 5, "%s", argv[2]); 177 | 178 | // bcopy(val.key, key, 4); 179 | 180 | memcpy(val.key, key, sizeof(val.key)); 181 | 182 | 183 | 184 | int i; 185 | char chr[3]; 186 | for (i = 0; i < strlen(args); i++) 187 | { 188 | sprintf(chr, "%c%c", args[i * 2], args[(i * 2) + 1]); 189 | val.bytes[i] = (int) strtol(chr, NULL, 16); 190 | } 191 | val.dataSize = i / 2; 192 | if ((val.dataSize * 2) != strlen(args)) 193 | { 194 | printf("Error: value is not valid\n"); 195 | return 1; 196 | } 197 | 198 | kern_return_t result = SMCWriteKey(connection, &val); 199 | 200 | if (kIOReturnSuccess == result ) { 201 | // printKeyValue(val); 202 | }else if (kIOReturnError == result ){ 203 | printf("Error: write error\n"); 204 | return 1; 205 | }else if (kIOReturnLockedWrite == result){ 206 | printf("Locked\n"); 207 | }else{ 208 | printf("Error %04x\n",result); 209 | } 210 | break; 211 | } 212 | 213 | case OPTION_HELP: 214 | usage(argv[0]); 215 | break; 216 | } 217 | 218 | SMCClose(connection); 219 | } 220 | else { 221 | printf("failed to connect to SMC!\n"); 222 | } 223 | 224 | } 225 | return 0; 226 | } 227 | 228 | --------------------------------------------------------------------------------