diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2a2355d..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "SMCKitTool/lib/CommandLine"] - path = SMCKitTool/lib/CommandLine - url = https://github.com/beltex/CommandLine.git diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..00a0fda --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,169 @@ +whitelist_rules: + - anyobject_protocol + - array_init + - attributes + - block_based_kvo + - class_delegate_protocol + - closing_brace + - closure_end_indentation + - closure_parameter_position + - closure_spacing + - collection_alignment + - colon + - comma + - compiler_protocol_init + - conditional_returns_on_newline + - contains_over_filter_count + - contains_over_filter_is_empty + - contains_over_first_not_nil + - contains_over_range_nil_comparison + - control_statement + - deployment_target + - discarded_notification_center_observer + - discouraged_direct_init + - discouraged_object_literal + - discouraged_optional_boolean + - discouraged_optional_collection + - duplicate_enum_cases + - duplicate_imports + - dynamic_inline + - empty_collection_literal + - empty_count + - empty_enum_arguments + - empty_parameters + - empty_parentheses_with_trailing_closure + - empty_string + - empty_xctest_method + - explicit_init + - fallthrough + - fatal_error_message + - first_where + - flatmap_over_map_reduce + - for_where + - generic_type_name + - identical_operands + - identifier_name + - implicit_getter + - implicit_return + - inert_defer + - is_disjoint + - joined_default_parameter + - last_where + - leading_whitespace + - legacy_cggeometry_functions + - legacy_constant + - legacy_constructor + - legacy_hashing + - legacy_multiple + - legacy_nsgeometry_functions + - legacy_random + - literal_expression_end_indentation + - lower_acl_than_parent + - mark + - modifier_order + - multiline_arguments + - multiline_function_chains + - multiline_literal_brackets + - multiline_parameters + - multiline_parameters_brackets + - nimble_operator + - no_extension_access_modifier + - no_fallthrough_only + - no_space_in_method_call + - notification_center_detachment + - nsobject_prefer_isequal + - number_separator + - object_literal + - opening_brace + - operator_usage_whitespace + - operator_whitespace + - overridden_super_call + - pattern_matching_keywords + - private_action + - private_outlet + - private_unit_test + - prohibited_super_call + - protocol_property_accessors_order + - reduce_boolean + - reduce_into + - redundant_discardable_let + - redundant_nil_coalescing + - redundant_objc_attribute + - redundant_optional_initialization + - redundant_set_access_control + - redundant_string_enum_value + - redundant_type_annotation + - redundant_void_return + - required_enum_case + - return_arrow_whitespace + - shorthand_operator + - sorted_first_last + - statement_position + - static_operator + - strong_iboutlet + - superfluous_disable_command + - switch_case_alignment + - switch_case_on_newline + - syntactic_sugar + - todo + - toggle_bool + - trailing_closure + - trailing_comma + - trailing_newline + - trailing_semicolon + - trailing_whitespace + - type_name + - unavailable_function + - unneeded_break_in_switch + - unneeded_parentheses_in_closure_argument + - unowned_variable_capture + - untyped_error_in_catch + - unused_capture_list + - unused_closure_parameter + - unused_control_flow_label + - unused_enumerated + - unused_optional_binding + - unused_setter_value + - valid_ibinspectable + - vertical_parameter_alignment + - vertical_parameter_alignment_on_call + - vertical_whitespace_closing_braces + - vertical_whitespace_opening_braces + - void_return + - weak_delegate + - xct_specific_matcher + - xctfail_message + - yoda_condition +analyzer_rules: + - unused_declaration + - unused_import +force_cast: warning +force_unwrapping: warning +number_separator: + minimum_length: 5 +object_literal: + image_literal: false +discouraged_object_literal: + color_literal: false +identifier_name: + max_length: + warning: 100 + error: 100 + min_length: + warning: 2 + error: 2 + validates_start_with_lowercase: false + allowed_symbols: + - '_' + excluded: + - 'x' + - 'y' + - 'a' + - 'b' + - 'x1' + - 'x2' + - 'y1' + - 'y2' +excluded: + - Pods + diff --git a/Makefile b/Makefile deleted file mode 100644 index bd6f245..0000000 --- a/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -INSTALL_DIR = /usr/local/bin -MANPAGE_DIR = /usr/local/share/man/man1 -XCODE_CONFIG = Release -XCODE_TARGET = SMCKitTool -XCODE_BUILD = xcodebuild -target ${XCODE_TARGET} - -.PHONY: install machine release debug build uninstall jazzy ronn clean distclean - -install: machine release - cp bin/smckit ${INSTALL_DIR} - cp docs/smckit.1 ${MANPAGE_DIR} - du -sh ${INSTALL_DIR}/smckit -machine: - @sysctl hw.model; \ - sw_vers; \ - uname -v; \ - ioreg -lbrc AppleSMC | grep smc-version | tr -d "|" | xargs; \ - xcodebuild -version; \ - swiftc -v -release: build - strip bin/smckit -debug: XCODE_CONFIG=Debug -debug: build -build: SMCKitTool/lib/CommandLine/README.md - ${XCODE_BUILD} -configuration ${XCODE_CONFIG} build - mkdir -p bin - cp build/${XCODE_CONFIG}/SMCKitTool bin/smckit -SMCKitTool/lib/CommandLine/README.md: - git submodule update --init -uninstall: - rm ${INSTALL_DIR}/smckit - rm ${MANPAGE_DIR}/smckit.1 -jazzy: - jazzy -a beltex -u http://beltex.github.io -m SMCKit \ - -g https://github.com/beltex/SMCKit -ronn: - ronn --style=toc docs/smckit.1.ronn - mv docs/smckit.1.html docs/index.html -clean: - ${XCODE_BUILD} -configuration Debug clean - ${XCODE_BUILD} -configuration Release clean -distclean: - rm -rf bin build diff --git a/SMCKit.xcodeproj/project.pbxproj b/SMCKit.xcodeproj/project.pbxproj index a058df4..395562c 100644 --- a/SMCKit.xcodeproj/project.pbxproj +++ b/SMCKit.xcodeproj/project.pbxproj @@ -7,20 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 4C982BE01A040CD500F4A639 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C982BDF1A040CD500F4A639 /* main.swift */; }; - 4C982BE41A040CE200F4A639 /* SMC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE566A71A00A49600787F6B /* SMC.swift */; }; 4CA091201F8C4FCC00623AEF /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 4CA0911F1F8C4FCC00623AEF /* README.md */; }; 4CA091231F8C517E00623AEF /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 4CA091211F8C517E00623AEF /* LICENSE */; }; - 4CA091241F8C517E00623AEF /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 4CA091221F8C517E00623AEF /* Makefile */; }; - 4CDDA6A01AEC0D010037CE7B /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDDA69F1AEC0D010037CE7B /* main.swift */; }; - 4CDDA6A41AEC0D580037CE7B /* SMC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE566A71A00A49600787F6B /* SMC.swift */; }; 4CE566911A00A48800787F6B /* SMCKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CE566901A00A48800787F6B /* SMCKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4CE566971A00A48800787F6B /* SMCKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CE5668B1A00A48800787F6B /* SMCKit.framework */; }; 4CE5669E1A00A48800787F6B /* SMCKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5669D1A00A48800787F6B /* SMCKitTests.swift */; }; 4CE566A81A00A49600787F6B /* SMC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE566A71A00A49600787F6B /* SMC.swift */; }; - 4CE5BC241B1F85880030FA55 /* CommandLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5BC211B1F85880030FA55 /* CommandLine.swift */; }; - 4CE5BC251B1F85880030FA55 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5BC221B1F85880030FA55 /* Option.swift */; }; - 4CE5BC261B1F85880030FA55 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5BC231B1F85880030FA55 /* StringExtensions.swift */; }; + 6DC4E3E5E449F2D2CE4260CB /* Pods_SMCKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CF83879972840EA99CB1E793 /* Pods_SMCKit.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -33,34 +26,9 @@ }; /* End PBXContainerItemProxy section */ -/* Begin PBXCopyFilesBuildPhase section */ - 4C982BDB1A040CD500F4A639 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; - 4CDDA69B1AEC0D010037CE7B /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ - 4C982BDD1A040CD500F4A639 /* SMCKitTool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SMCKitTool; sourceTree = BUILT_PRODUCTS_DIR; }; - 4C982BDF1A040CD500F4A639 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 4CA0911F1F8C4FCC00623AEF /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 4CA091211F8C517E00623AEF /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; - 4CA091221F8C517E00623AEF /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; - 4CDDA69D1AEC0D010037CE7B /* powermetricsTests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = powermetricsTests; sourceTree = BUILT_PRODUCTS_DIR; }; 4CDDA69F1AEC0D010037CE7B /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 4CE5668B1A00A48800787F6B /* SMCKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SMCKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4CE5668F1A00A48800787F6B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -69,30 +37,17 @@ 4CE5669C1A00A48800787F6B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4CE5669D1A00A48800787F6B /* SMCKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SMCKitTests.swift; sourceTree = ""; }; 4CE566A71A00A49600787F6B /* SMC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SMC.swift; sourceTree = ""; }; - 4CE5BC211B1F85880030FA55 /* CommandLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CommandLine.swift; path = lib/CommandLine/CommandLineKit/CommandLine.swift; sourceTree = ""; }; - 4CE5BC221B1F85880030FA55 /* Option.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Option.swift; path = lib/CommandLine/CommandLineKit/Option.swift; sourceTree = ""; }; - 4CE5BC231B1F85880030FA55 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StringExtensions.swift; path = lib/CommandLine/CommandLineKit/StringExtensions.swift; sourceTree = ""; }; + 6F3EB8A5F670E08F0632670B /* Pods-SMCKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SMCKit.release.xcconfig"; path = "Target Support Files/Pods-SMCKit/Pods-SMCKit.release.xcconfig"; sourceTree = ""; }; + 8957FB16B2DEE4FAA4E9635A /* Pods-SMCKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SMCKit.debug.xcconfig"; path = "Target Support Files/Pods-SMCKit/Pods-SMCKit.debug.xcconfig"; sourceTree = ""; }; + CF83879972840EA99CB1E793 /* Pods_SMCKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SMCKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 4C982BDA1A040CD500F4A639 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4CDDA69A1AEC0D010037CE7B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 4CE566871A00A48800787F6B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 6DC4E3E5E449F2D2CE4260CB /* Pods_SMCKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -107,15 +62,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 4C982BDE1A040CD500F4A639 /* SMCKitTool */ = { - isa = PBXGroup; - children = ( - 4CE5BC1F1B1F855C0030FA55 /* lib */, - 4C982BDF1A040CD500F4A639 /* main.swift */, - ); - path = SMCKitTool; - sourceTree = ""; - }; 4CDDA69E1AEC0D010037CE7B /* powermetricsTests */ = { isa = PBXGroup; children = ( @@ -128,13 +74,13 @@ isa = PBXGroup; children = ( 4CA0911F1F8C4FCC00623AEF /* README.md */, - 4CA091221F8C517E00623AEF /* Makefile */, 4CA091211F8C517E00623AEF /* LICENSE */, 4CE5668D1A00A48800787F6B /* SMCKit */, 4CE5669A1A00A48800787F6B /* SMCKitTests */, 4CDDA69E1AEC0D010037CE7B /* powermetricsTests */, - 4C982BDE1A040CD500F4A639 /* SMCKitTool */, 4CE5668C1A00A48800787F6B /* Products */, + FBA67ADA640B2753AA129E85 /* Pods */, + EB397E1ABF8C99C8B068DC6D /* Frameworks */, ); sourceTree = ""; }; @@ -143,8 +89,6 @@ children = ( 4CE5668B1A00A48800787F6B /* SMCKit.framework */, 4CE566961A00A48800787F6B /* SMCKitTests.xctest */, - 4C982BDD1A040CD500F4A639 /* SMCKitTool */, - 4CDDA69D1AEC0D010037CE7B /* powermetricsTests */, ); name = Products; sourceTree = ""; @@ -184,22 +128,22 @@ name = "Supporting Files"; sourceTree = ""; }; - 4CE5BC1F1B1F855C0030FA55 /* lib */ = { + EB397E1ABF8C99C8B068DC6D /* Frameworks */ = { isa = PBXGroup; children = ( - 4CE5BC201B1F856B0030FA55 /* CommandLine */, + CF83879972840EA99CB1E793 /* Pods_SMCKit.framework */, ); - name = lib; + name = Frameworks; sourceTree = ""; }; - 4CE5BC201B1F856B0030FA55 /* CommandLine */ = { + FBA67ADA640B2753AA129E85 /* Pods */ = { isa = PBXGroup; children = ( - 4CE5BC211B1F85880030FA55 /* CommandLine.swift */, - 4CE5BC221B1F85880030FA55 /* Option.swift */, - 4CE5BC231B1F85880030FA55 /* StringExtensions.swift */, + 8957FB16B2DEE4FAA4E9635A /* Pods-SMCKit.debug.xcconfig */, + 6F3EB8A5F670E08F0632670B /* Pods-SMCKit.release.xcconfig */, ); - name = CommandLine; + name = Pods; + path = ../../Pods; sourceTree = ""; }; /* End PBXGroup section */ @@ -216,44 +160,12 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 4C982BDC1A040CD500F4A639 /* SMCKitTool */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4C982BE31A040CD500F4A639 /* Build configuration list for PBXNativeTarget "SMCKitTool" */; - buildPhases = ( - 4C982BD91A040CD500F4A639 /* Sources */, - 4C982BDA1A040CD500F4A639 /* Frameworks */, - 4C982BDB1A040CD500F4A639 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = SMCKitTool; - productName = SMCKitTool; - productReference = 4C982BDD1A040CD500F4A639 /* SMCKitTool */; - productType = "com.apple.product-type.tool"; - }; - 4CDDA69C1AEC0D010037CE7B /* powermetricsTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4CDDA6A31AEC0D010037CE7B /* Build configuration list for PBXNativeTarget "powermetricsTests" */; - buildPhases = ( - 4CDDA6991AEC0D010037CE7B /* Sources */, - 4CDDA69A1AEC0D010037CE7B /* Frameworks */, - 4CDDA69B1AEC0D010037CE7B /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = powermetricsTests; - productName = powermetricsTests; - productReference = 4CDDA69D1AEC0D010037CE7B /* powermetricsTests */; - productType = "com.apple.product-type.tool"; - }; 4CE5668A1A00A48800787F6B /* SMCKit */ = { isa = PBXNativeTarget; buildConfigurationList = 4CE566A11A00A48800787F6B /* Build configuration list for PBXNativeTarget "SMCKit" */; buildPhases = ( + 750E0DC6F70B33CCCDCCF381 /* [CP] Check Pods Manifest.lock */, + B48F916523DF5EF1002842F9 /* ShellScript */, 4CE566861A00A48800787F6B /* Sources */, 4CE566871A00A48800787F6B /* Frameworks */, 4CE566881A00A48800787F6B /* Headers */, @@ -293,33 +205,30 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1130; ORGANIZATIONNAME = beltex; TargetAttributes = { - 4C982BDC1A040CD500F4A639 = { - CreatedOnToolsVersion = 6.1; - LastSwiftMigration = 0900; - }; - 4CDDA69C1AEC0D010037CE7B = { - CreatedOnToolsVersion = 6.3.1; - LastSwiftMigration = 0900; - }; 4CE5668A1A00A48800787F6B = { CreatedOnToolsVersion = 6.1; - LastSwiftMigration = 0900; + DevelopmentTeam = J6GXEPK4NG; + LastSwiftMigration = 1130; + ProvisioningStyle = Automatic; }; 4CE566951A00A48800787F6B = { CreatedOnToolsVersion = 6.1; + DevelopmentTeam = J6GXEPK4NG; LastSwiftMigration = 0900; + ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 4CE566851A00A48800787F6B /* Build configuration list for PBXProject "SMCKit" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 4CE566811A00A48800787F6B; productRefGroup = 4CE5668C1A00A48800787F6B /* Products */; @@ -328,8 +237,6 @@ targets = ( 4CE5668A1A00A48800787F6B /* SMCKit */, 4CE566951A00A48800787F6B /* SMCKitTests */, - 4CDDA69C1AEC0D010037CE7B /* powermetricsTests */, - 4C982BDC1A040CD500F4A639 /* SMCKitTool */, ); }; /* End PBXProject section */ @@ -353,33 +260,53 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXSourcesBuildPhase section */ - 4C982BD91A040CD500F4A639 /* Sources */ = { - isa = PBXSourcesBuildPhase; +/* Begin PBXShellScriptBuildPhase section */ + 750E0DC6F70B33CCCDCCF381 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - 4CE5BC251B1F85880030FA55 /* Option.swift in Sources */, - 4CE5BC241B1F85880030FA55 /* CommandLine.swift in Sources */, - 4CE5BC261B1F85880030FA55 /* StringExtensions.swift in Sources */, - 4C982BE41A040CE200F4A639 /* SMC.swift in Sources */, - 4C982BE01A040CD500F4A639 /* main.swift in Sources */, + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SMCKit-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 4CDDA6991AEC0D010037CE7B /* Sources */ = { - isa = PBXSourcesBuildPhase; + B48F916523DF5EF1002842F9 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - 4CDDA6A41AEC0D580037CE7B /* SMC.swift in Sources */, - 4CDDA6A01AEC0D010037CE7B /* main.swift in Sources */, + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nif test -f \"${PODS_ROOT}/SwiftLint/swiftlint\"; then\n \"${PODS_ROOT}/SwiftLint/swiftlint\" autocorrect\n \"${PODS_ROOT}/SwiftLint/swiftlint\"\nelse\n echo \"warning: SwiftLint not installed, please install the dependencies of this project using CocoaPods\"\nfi\n"; }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ 4CE566861A00A48800787F6B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4CA091241F8C517E00623AEF /* Makefile in Sources */, 4CE566A81A00A49600787F6B /* SMC.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -403,64 +330,11 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 4C982BE11A040CD500F4A639 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - OTHER_SWIFT_FLAGS = "-D DEBUG"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - }; - name = Debug; - }; - 4C982BE21A040CD500F4A639 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - OTHER_SWIFT_FLAGS = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - }; - name = Release; - }; - 4CDDA6A11AEC0D010037CE7B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - }; - name = Debug; - }; - 4CDDA6A21AEC0D010037CE7B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_NO_COMMON_BLOCKS = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - }; - name = Release; - }; 4CE5669F1A00A48800787F6B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -469,12 +343,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -515,6 +391,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -523,12 +400,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -560,10 +439,16 @@ }; 4CE566A21A00A48800787F6B /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 8957FB16B2DEE4FAA4E9635A /* Pods-SMCKit.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1.0; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = J6GXEPK4NG; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -571,22 +456,31 @@ INFOPLIST_FILE = SMCKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - OTHER_SWIFT_FLAGS = "-D DEBUG"; - PRODUCT_BUNDLE_IDENTIFIER = "beltex.$(PRODUCT_NAME:rfc1034identifier)"; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MARKETING_VERSION = 1.0; + OTHER_SWIFT_FLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = io.github.iglance.SMCKit; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; }; name = Debug; }; 4CE566A31A00A48800787F6B /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 6F3EB8A5F670E08F0632670B /* Pods-SMCKit.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1.0; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = J6GXEPK4NG; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -594,18 +488,26 @@ INFOPLIST_FILE = SMCKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "beltex.$(PRODUCT_NAME:rfc1034identifier)"; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MARKETING_VERSION = 1.0; + OTHER_SWIFT_FLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = io.github.iglance.SMCKit; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; }; name = Release; }; 4CE566A51A00A48800787F6B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = J6GXEPK4NG; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", "$(inherited)", @@ -618,7 +520,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "beltex.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Debug; @@ -626,7 +529,11 @@ 4CE566A61A00A48800787F6B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = J6GXEPK4NG; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", "$(inherited)", @@ -635,7 +542,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "beltex.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Release; @@ -643,24 +551,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 4C982BE31A040CD500F4A639 /* Build configuration list for PBXNativeTarget "SMCKitTool" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4C982BE11A040CD500F4A639 /* Debug */, - 4C982BE21A040CD500F4A639 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 4CDDA6A31AEC0D010037CE7B /* Build configuration list for PBXNativeTarget "powermetricsTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4CDDA6A11AEC0D010037CE7B /* Debug */, - 4CDDA6A21AEC0D010037CE7B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 4CE566851A00A48800787F6B /* Build configuration list for PBXProject "SMCKit" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SMCKit.xcodeproj/xcshareddata/xcschemes/powermetricsTests.xcscheme b/SMCKit.xcodeproj/xcshareddata/xcschemes/powermetricsTests.xcscheme index de17bde..79d00fa 100644 --- a/SMCKit.xcodeproj/xcshareddata/xcschemes/powermetricsTests.xcscheme +++ b/SMCKit.xcodeproj/xcshareddata/xcschemes/powermetricsTests.xcscheme @@ -1,6 +1,6 @@ - - - - + + - - CFBundlePackageType FMWK CFBundleShortVersionString - 0.2.0-dev + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion diff --git a/SMCKit/SMC.swift b/SMCKit/SMC.swift index 9b14889..b2d1dff 100644 --- a/SMCKit/SMC.swift +++ b/SMCKit/SMC.swift @@ -36,6 +36,9 @@ import Foundation /// Floating point, unsigned, 14 bits exponent, 2 bits fraction public typealias FPE2 = (UInt8, UInt8) +/// Floating point data type for the 2018 Macbooks using the T2 chip +public typealias FLT = (UInt8, UInt8, UInt8, UInt8) + /// Floating point, signed, 7 bits exponent, 8 bits fraction public typealias SP78 = (UInt8, UInt8) @@ -49,8 +52,9 @@ public typealias SMCBytes = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, // MARK: Standard Library Extensions //------------------------------------------------------------------------------ -extension UInt32 { - +// this extension has to be public in order to be usable when importing the framework +// swiftlint:disable:next no_extension_access_modifier +public extension UInt32 { init(fromBytes bytes: (UInt8, UInt8, UInt8, UInt8)) { // TODO: Broken up due to "Expression was too complex" error as of // Swift 4. @@ -64,26 +68,37 @@ extension UInt32 { } } -extension Bool { - +// this extension has to be public in order to be usable when importing the framework +// swiftlint:disable:next no_extension_access_modifier +public extension Bool { init(fromByte byte: UInt8) { self = byte == 1 ? true : false } } +// this extension has to be public in order to be usable when importing the framework +// swiftlint:disable:next no_extension_access_modifier public extension Int { - init(fromFPE2 bytes: FPE2) { self = (Int(bytes.0) << 6) + (Int(bytes.1) >> 2) } + init(fromFLT bytes: FLT) { + // convert the SMCBytes to a float value + let byteArray: [UInt8] = [bytes.0, bytes.1, bytes.2, bytes.3] + var resultValue: Float = 0.0 + memcpy(&resultValue, byteArray, 4) + self = Int(resultValue) + } + func toFPE2() -> FPE2 { - return (UInt8(self >> 6), UInt8((self << 2) ^ ((self >> 6) << 8))) + (UInt8(self >> 6), UInt8((self << 2) ^ ((self >> 6) << 8))) } } -extension Double { - +// this extension has to be public in order to be usable when importing the framework +// swiftlint:disable:next no_extension_access_modifier +public extension Double { init(fromSP78 bytes: SP78) { // FIXME: Handle second byte let sign = bytes.0 & 0x80 == 0 ? 1.0 : -1.0 @@ -93,13 +108,14 @@ extension Double { // Thanks to Airspeed Velocity for the great idea! // http://airspeedvelocity.net/2015/05/22/my-talk-at-swift-summit/ +// this extension has to be public in order to be usable when importing the framework +// swiftlint:disable:next no_extension_access_modifier public extension FourCharCode { - init(fromString str: String) { - precondition(str.characters.count == 4) + precondition(str.count == 4) self = str.utf8.reduce(0) { sum, character in - return sum << 8 | UInt32(character) + sum << 8 | UInt32(character) } } @@ -120,10 +136,10 @@ public extension FourCharCode { } func toString() -> String { - return String(describing: UnicodeScalar(self >> 24 & 0xff)!) + + String(describing: UnicodeScalar(self >> 24 & 0xff)!) + String(describing: UnicodeScalar(self >> 16 & 0xff)!) + - String(describing: UnicodeScalar(self >> 8 & 0xff)!) + - String(describing: UnicodeScalar(self & 0xff)!) + String(describing: UnicodeScalar(self >> 8 & 0xff)!) + + String(describing: UnicodeScalar(self & 0xff)!) } } @@ -148,20 +164,19 @@ public extension FourCharCode { /// /// http://www.opensource.apple.com/source/PowerManagement/PowerManagement-211/ public struct SMCParamStruct { - /// I/O Kit function selector public enum Selector: UInt8 { - case kSMCHandleYPCEvent = 2 - case kSMCReadKey = 5 - case kSMCWriteKey = 6 + case kSMCHandleYPCEvent = 2 + case kSMCReadKey = 5 + case kSMCWriteKey = 6 case kSMCGetKeyFromIndex = 8 - case kSMCGetKeyInfo = 9 + case kSMCGetKeyInfo = 9 } /// Return codes for SMCParamStruct.result property public enum Result: UInt8 { - case kSMCSuccess = 0 - case kSMCError = 1 + case kSMCSuccess = 0 + case kSMCError = 1 case kSMCKeyNotFound = 132 } @@ -229,7 +244,6 @@ public struct SMCParamStruct { /// SMC data type information public struct DataTypes { - /// Fan information struct public static let FDS = DataType(type: FourCharCode(fromStaticString: "{fds"), size: 16) @@ -238,6 +252,8 @@ public struct DataTypes { /// See type aliases public static let FPE2 = DataType(type: FourCharCode(fromStaticString: "fpe2"), size: 2) + public static let FLT = + DataType(type: FourCharCode(fromStaticString: "flt "), size: 4) /// See type aliases public static let SP78 = DataType(type: FourCharCode(fromStaticString: "sp78"), size: 2) @@ -258,16 +274,14 @@ public struct DataType: Equatable { } public func ==(lhs: DataType, rhs: DataType) -> Bool { - return lhs.type == rhs.type && lhs.size == rhs.size + lhs.type == rhs.type && lhs.size == rhs.size } /// Apple System Management Controller (SMC) user-space client for Intel-based /// Macs. Works by talking to the AppleSMC.kext (kernel extension), the closed /// source driver for the SMC. public struct SMCKit { - public enum SMCError: Error { - /// AppleSMC driver not found case driverNotFound @@ -293,8 +307,13 @@ public struct SMCKit { /// Connection to the SMC driver fileprivate static var connection: io_connect_t = 0 - /// Open connection to the SMC driver. This must be done first before any - /// other calls + /** + * Open connection to the SMC driver. This must be done first before any other calls. + * + * - Throws: + * - `SMCError.driverNotFound` if the SMC driver was not found + * - `SMCError.failedToOpen` if opening the connection to the SMC failed + */ public static func open() throws { let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleSMC")) @@ -402,14 +421,13 @@ public struct SMCKit { //------------------------------------------------------------------------------ extension SMCKit { - /// Get all valid SMC keys for this machine public static func allKeys() throws -> [SMCKey] { let count = try keyCount() var keys = [SMCKey]() - for i in 0 ..< count { - let key = try keyInformationAtIndex(i) + for keyIndex in 0 ..< count { + let key = try keyInformationAtIndex(keyIndex) let info = try keyInformation(key) keys.append(SMCKey(code: key, info: info)) } @@ -452,7 +470,6 @@ extension SMCKit { /// * http://www.opensource.apple.com/source/net_snmp/ /// * http://www.parhelia.ch/blog/statics/k3_keys.html public struct TemperatureSensors { - public static let AMBIENT_AIR_0 = TemperatureSensor(name: "AMBIENT_AIR_0", code: FourCharCode(fromStaticString: "TA0P")) public static let AMBIENT_AIR_1 = TemperatureSensor(name: "AMBIENT_AIR_1", @@ -523,35 +540,35 @@ public struct TemperatureSensors { public static let THUNDERBOLT_1 = TemperatureSensor(name: "THUNDERBOLT_1", code: FourCharCode(fromStaticString: "TI1P")) - public static let all = [AMBIENT_AIR_0.code : AMBIENT_AIR_0, - AMBIENT_AIR_1.code : AMBIENT_AIR_1, - CPU_0_DIE.code : CPU_0_DIE, - CPU_0_DIODE.code : CPU_0_DIODE, - CPU_0_HEATSINK.code : CPU_0_HEATSINK, - CPU_0_PROXIMITY.code : CPU_0_PROXIMITY, - ENCLOSURE_BASE_0.code : ENCLOSURE_BASE_0, - ENCLOSURE_BASE_1.code : ENCLOSURE_BASE_1, - ENCLOSURE_BASE_2.code : ENCLOSURE_BASE_2, - ENCLOSURE_BASE_3.code : ENCLOSURE_BASE_3, - GPU_0_DIODE.code : GPU_0_DIODE, - GPU_0_HEATSINK.code : GPU_0_HEATSINK, - GPU_0_PROXIMITY.code : GPU_0_PROXIMITY, - HDD_PROXIMITY.code : HDD_PROXIMITY, - HEATSINK_0.code : HEATSINK_0, - HEATSINK_1.code : HEATSINK_1, - HEATSINK_2.code : HEATSINK_2, - MEM_SLOT_0.code : MEM_SLOT_0, + public static let all = [AMBIENT_AIR_0.code: AMBIENT_AIR_0, + AMBIENT_AIR_1.code: AMBIENT_AIR_1, + CPU_0_DIE.code: CPU_0_DIE, + CPU_0_DIODE.code: CPU_0_DIODE, + CPU_0_HEATSINK.code: CPU_0_HEATSINK, + CPU_0_PROXIMITY.code: CPU_0_PROXIMITY, + ENCLOSURE_BASE_0.code: ENCLOSURE_BASE_0, + ENCLOSURE_BASE_1.code: ENCLOSURE_BASE_1, + ENCLOSURE_BASE_2.code: ENCLOSURE_BASE_2, + ENCLOSURE_BASE_3.code: ENCLOSURE_BASE_3, + GPU_0_DIODE.code: GPU_0_DIODE, + GPU_0_HEATSINK.code: GPU_0_HEATSINK, + GPU_0_PROXIMITY.code: GPU_0_PROXIMITY, + HDD_PROXIMITY.code: HDD_PROXIMITY, + HEATSINK_0.code: HEATSINK_0, + HEATSINK_1.code: HEATSINK_1, + HEATSINK_2.code: HEATSINK_2, + MEM_SLOT_0.code: MEM_SLOT_0, MEM_SLOTS_PROXIMITY.code: MEM_SLOTS_PROXIMITY, - PALM_REST.code : PALM_REST, - LCD_PROXIMITY.code : LCD_PROXIMITY, - MISC_PROXIMITY.code : MISC_PROXIMITY, - NORTHBRIDGE.code : NORTHBRIDGE, - NORTHBRIDGE_DIODE.code : NORTHBRIDGE_DIODE, - NORTHBRIDGE_PROXIMITY.code : NORTHBRIDGE_PROXIMITY, - ODD_PROXIMITY.code : ODD_PROXIMITY, - PWR_SUPPLY_PROXIMITY.code : PWR_SUPPLY_PROXIMITY, - THUNDERBOLT_0.code : THUNDERBOLT_0, - THUNDERBOLT_1.code : THUNDERBOLT_1] + PALM_REST.code: PALM_REST, + LCD_PROXIMITY.code: LCD_PROXIMITY, + MISC_PROXIMITY.code: MISC_PROXIMITY, + NORTHBRIDGE.code: NORTHBRIDGE, + NORTHBRIDGE_DIODE.code: NORTHBRIDGE_DIODE, + NORTHBRIDGE_PROXIMITY.code: NORTHBRIDGE_PROXIMITY, + ODD_PROXIMITY.code: ODD_PROXIMITY, + PWR_SUPPLY_PROXIMITY.code: PWR_SUPPLY_PROXIMITY, + THUNDERBOLT_0.code: THUNDERBOLT_0, + THUNDERBOLT_1.code: THUNDERBOLT_1] } public struct TemperatureSensor { @@ -576,7 +593,6 @@ public enum TemperatureUnit { } extension SMCKit { - public static func allKnownTemperatureSensors() throws -> [TemperatureSensor] { var sensors = [TemperatureSensor]() @@ -593,7 +609,8 @@ extension SMCKit { return keys.filter { $0.code.toString().hasPrefix("T") && $0.info == DataTypes.SP78 && - TemperatureSensors.all[$0.code] == nil } + TemperatureSensors.all[$0.code] == nil + } .map { TemperatureSensor(name: "Unknown", code: $0.code) } } @@ -628,13 +645,12 @@ public struct Fan { } extension SMCKit { - public static func allFans() throws -> [Fan] { let count = try fanCount() var fans = [Fan]() - for i in 0 ..< count { - fans.append(try SMCKit.fan(i)) + for fanIndex in 0 ..< count { + fans.append(try SMCKit.fan(fanIndex)) } return fans @@ -664,15 +680,15 @@ extension SMCKit { // The last 12 bytes of '{fds' data type, a custom struct defined by the // AppleSMC.kext that is 16 bytes, contains the fan name - let c1 = String(UnicodeScalar(data.4)) - let c2 = String(UnicodeScalar(data.5)) - let c3 = String(UnicodeScalar(data.6)) - let c4 = String(UnicodeScalar(data.7)) - let c5 = String(UnicodeScalar(data.8)) - let c6 = String(UnicodeScalar(data.9)) - let c7 = String(UnicodeScalar(data.10)) - let c8 = String(UnicodeScalar(data.11)) - let c9 = String(UnicodeScalar(data.12)) + let c1 = String(UnicodeScalar(data.4)) + let c2 = String(UnicodeScalar(data.5)) + let c3 = String(UnicodeScalar(data.6)) + let c4 = String(UnicodeScalar(data.7)) + let c5 = String(UnicodeScalar(data.8)) + let c6 = String(UnicodeScalar(data.9)) + let c7 = String(UnicodeScalar(data.10)) + let c8 = String(UnicodeScalar(data.11)) + let c9 = String(UnicodeScalar(data.12)) let c10 = String(UnicodeScalar(data.13)) let c11 = String(UnicodeScalar(data.14)) let c12 = String(UnicodeScalar(data.15)) @@ -684,27 +700,57 @@ extension SMCKit { } public static func fanCurrentSpeed(_ id: Int) throws -> Int { - let key = SMCKey(code: FourCharCode(fromString: "F\(id)Ac"), - info: DataTypes.FPE2) + var data: SMCBytes - let data = try readData(key) - return Int(fromFPE2: (data.0, data.1)) + do { + // try getting the fan speed using the fpe2 type + let key = SMCKey(code: FourCharCode(fromString: "F\(id)Ac"), + info: DataTypes.FPE2) + data = try readData(key) + return Int(fromFPE2: (data.0, data.1)) + } catch SMCError.unknown(kIOReturn: 0, SMCResult: 135) { + // if that fails with an unknown error, try using the flt type + let key = SMCKey(code: FourCharCode(fromString: "F\(id)Ac"), info: DataTypes.FLT) + data = try readData(key) + return Int(fromFLT: (data.0, data.1, data.2, data.3)) + } } public static func fanMinSpeed(_ id: Int) throws -> Int { - let key = SMCKey(code: FourCharCode(fromString: "F\(id)Mn"), - info: DataTypes.FPE2) - - let data = try readData(key) - return Int(fromFPE2: (data.0, data.1)) + var data: SMCBytes + do { + // try getting the minimum fan speed usinng the fpe2 type + let key = SMCKey(code: FourCharCode(fromString: "F\(id)Mn"), + info: DataTypes.FPE2) + + data = try readData(key) + return Int(fromFPE2: (data.0, data.1)) + } catch SMCError.unknown(kIOReturn: 0, SMCResult: 135) { + // if that fails with an unknown error, try using the flt type + let key = SMCKey(code: FourCharCode(fromString: "F\(id)Mn"), + info: DataTypes.FLT) + + data = try readData(key) + return Int(fromFLT: (data.0, data.1, data.2, data.3)) + } } public static func fanMaxSpeed(_ id: Int) throws -> Int { - let key = SMCKey(code: FourCharCode(fromString: "F\(id)Mx"), + var data: SMCBytes + + do { + let key = SMCKey(code: FourCharCode(fromString: "F\(id)Mx"), info: DataTypes.FPE2) - let data = try readData(key) - return Int(fromFPE2: (data.0, data.1)) + data = try readData(key) + return Int(fromFPE2: (data.0, data.1)) + } catch SMCError.unknown(kIOReturn: 0, SMCResult: 135) { + let key = SMCKey(code: FourCharCode(fromString: "F\(id)Mx"), + info: DataTypes.FLT) + + data = try readData(key) + return Int(fromFLT: (data.0, data.1, data.2, data.3)) + } } /// Requires root privileges. By minimum we mean that OS X can interject and @@ -736,7 +782,7 @@ extension SMCKit { // MARK: Miscellaneous //------------------------------------------------------------------------------ -public struct batteryInfo { +public struct BatteryInfo { public let batteryCount: Int public let isACPresent: Bool public let isBatteryPowered: Bool @@ -745,7 +791,6 @@ public struct batteryInfo { } extension SMCKit { - public static func isOpticalDiskDriveFull() throws -> Bool { // TODO: Should we catch key not found? That just means the machine // doesn't have an ODD. Returning false though is not fully correct. @@ -757,7 +802,7 @@ extension SMCKit { return Bool(fromByte: data.0) } - public static func batteryInformation() throws -> batteryInfo { + public static func batteryInformation() throws -> BatteryInfo { let batteryCountKey = SMCKey(code: FourCharCode(fromStaticString: "BNum"), info: DataTypes.UInt8) @@ -779,7 +824,7 @@ extension SMCKit { let isACPresent = (batteryInfoData.0 >> 1) & 1 == 1 ? true : false let isBatteryOk = (batteryInfoData.0 >> 6) & 1 == 1 ? true : false - return batteryInfo(batteryCount: batteryCount, isACPresent: isACPresent, + return BatteryInfo(batteryCount: batteryCount, isACPresent: isACPresent, isBatteryPowered: isBatteryPowered, isBatteryOk: isBatteryOk, isCharging: isCharging) diff --git a/SMCKitTests/SMCKitTests.swift b/SMCKitTests/SMCKitTests.swift index a43c5bf..7ca1e2d 100644 --- a/SMCKitTests/SMCKitTests.swift +++ b/SMCKitTests/SMCKitTests.swift @@ -50,10 +50,9 @@ TODO works on second generation Intel Core 2 Duo chips and on. */ class SMCKitTests: XCTestCase { - /// List of internal ODD devices var internalODD = [DRDevice]() - + // TODO: Setup once? override func setUp() { // Put setup code here. This method is called before the invocation of @@ -75,7 +74,7 @@ class SMCKitTests: XCTestCase { super.tearDown() } - + // func testOpenConnectionTwice() { // XCTAssertNotEqual(smc.open(), kIOReturnSuccess) // } @@ -89,13 +88,13 @@ class SMCKitTests: XCTestCase { // XCTAssertGreaterThanOrEqual(smc.getNumFans().numFans, UInt(1)) // XCTAssertEqual(smc.close(), kIOReturnSuccess) // } - + func testTemperatureValues() { let temperatureSensors = try! SMCKit.allKnownTemperatureSensors() - + for sensor in temperatureSensors { let temperature = try! SMCKit.temperature(sensor.code) - + XCTAssertGreaterThan(temperature, -128.0) XCTAssertLessThan(temperature, 128.0) } @@ -118,7 +117,7 @@ class SMCKitTests: XCTestCase { // but we'll give it some slack incase XCTAssertLessThanOrEqual(fanCount, 4) } - + func testisKeyFound() { XCTAssertFalse(try! SMCKit.isKeyFound(FourCharCode(fromString: "CERN"))) XCTAssertFalse(try! SMCKit.isKeyFound(FourCharCode(fromString: "NASA"))) @@ -147,8 +146,7 @@ class SMCKitTests: XCTestCase { fatalError() } - - if DRDevice.devices().count == 0 { + if DRDevice.devices()?.isEmpty { // TODO: This means that there are no ODD that have burn capability? // Should be fine, as all Apple drives should have it print("No ODD devices") @@ -156,7 +154,6 @@ class SMCKitTests: XCTestCase { return } - // To get the ODD object, need to reg for notification and wait. Since, // were looking for an internel device, should be instant. // See deviceAppeared() helper. @@ -166,15 +163,14 @@ class SMCKitTests: XCTestCase { name: NSNotification.Name.DRDeviceAppeared.rawValue, object: nil ) - + // TODO: sleep here just incase for notification to be sent? - // TODO: Ignoring the Mac Pro case for now, with 2 drives if internalODD.count == 1 { let ODDStatus = internalODD[0].status()[DRDeviceMediaStateKey] as! String - + switch ODDStatus { case DRDeviceMediaStateMediaPresent: XCTAssertTrue(ODDStatusSMC) @@ -189,19 +185,19 @@ class SMCKitTests: XCTestCase { break } } - + DRNotificationCenter.currentRunLoop().removeObserver( self, name: NSNotification.Name.DRDeviceAppeared.rawValue, object: nil ) } - + func testBatteryPowerMethods() { - var isLaptop = false + var isLaptop = false var ASPCharging = false - var ASPCharged = false - + var ASPCharged = false + // Check if machine is a laptop - if it is, we use the service to cross // check our values // TODO: Simplify I/O Kit calls here - can do it in a single call @@ -210,38 +206,37 @@ class SMCKitTests: XCTestCase { IOServiceNameMatching("AppleSmartBattery")) if service != 0 { isLaptop = true - + // Getting these values to cross ref var prop = IORegistryEntryCreateCFProperty( service, "IsCharging" as CFString!, kCFAllocatorDefault, 0 ) - + ASPCharging = prop?.takeUnretainedValue() as! Bool - + prop = IORegistryEntryCreateCFProperty( service, "FullyCharged" as CFString!, kCFAllocatorDefault, 0 ) - + ASPCharged = prop?.takeUnretainedValue() as! Bool } - - let info = try! SMCKit.batteryInformation() + let info = try! SMCKit.batteryInformation() let batteryPowered = info.isBatteryPowered - let batteryOk = info.isBatteryOk - let ACPresent = info.isACPresent - let charging = info.isCharging - let numBatteries = info.batteryCount + let batteryOk = info.isBatteryOk + let ACPresent = info.isACPresent + let charging = info.isCharging + let numBatteries = info.batteryCount if isLaptop { // TODO: Is there any Mac that supports more then 1? XCTAssertEqual(numBatteries, 1) - + /* Yeah, truth tables!... :) @@ -261,29 +256,27 @@ class SMCKitTests: XCTestCase { http://www.wolframalpha.com */ - let A = batteryPowered - let B = ACPresent - let C = charging && ASPCharging - let D = ASPCharged + let battPow = batteryPowered + let ac = ACPresent + let charging = charging && ASPCharging + let charged = ASPCharged - XCTAssertTrue((!A || !B) && (A || B) && (B || !C) && (!C || !D)) - } - else { + XCTAssertTrue((!battPow || !ac) && (battPow || ac) && (ac || !charging) && (!charging || !charged)) + } else { XCTAssertFalse(batteryOk) XCTAssertFalse(batteryPowered) XCTAssertFalse(charging) XCTAssertTrue(ACPresent) XCTAssertEqual(numBatteries, 0) } - - + // TODO: Make sure this is called, even if tests above fail IOObjectRelease(service) } func testFourCharCodeExtension() { - let data: [(FourCharCode, String)] = [(1177567587, "F0Ac"), - (1413689414, "TC0F")] + let data: [(FourCharCode, String)] = [(1_177_567_587, "F0Ac"), + (1_413_689_414, "TC0F")] for (encoded, decoded) in data { XCTAssertEqual(encoded, FourCharCode(fromString: decoded)) @@ -292,7 +285,7 @@ class SMCKitTests: XCTestCase { } func testIntExtension() { - let data: [(FPE2, Int)] = [((31, 64), 2000), ((56, 244), 3645), + let data: [(FPE2, Int)] = [((31, 64), 2000), ((56, 244), 3645), ((96, 220), 6199)] for (encoded, decoded) in data { @@ -303,7 +296,6 @@ class SMCKitTests: XCTestCase { } } - //-------------------------------------------------------------------------- // MARK: Helpers //-------------------------------------------------------------------------- @@ -312,13 +304,13 @@ class SMCKitTests: XCTestCase { /// /// NOTE: Must not be private ACL, otherwise selector can't be reached func deviceAppeared(_ aNotification: Notification) { - let newDevice = aNotification.object as! DRDevice + let newDevice = aNotification.object as! DRDevice let deviceInfo = newDevice.info() - + let supportLevel = deviceInfo?[DRDeviceSupportLevelKey] as! String let interconnect = deviceInfo?[DRDevicePhysicalInterconnectLocationKey] as! String - + if interconnect == DRDevicePhysicalInterconnectLocationInternal && supportLevel == DRDeviceSupportLevelAppleShipping { // The supposition here is that the SMC will only know about @@ -328,7 +320,6 @@ class SMCKitTests: XCTestCase { } } - /// Get the model name of this machine. Same as "sysctl hw.model". Via /// SystemKit func modelName() -> String { @@ -339,7 +330,7 @@ class SMCKitTests: XCTestCase { // via I/O Kit which can also get the model name var size = MemoryLayout.size - let ptr = UnsafeMutablePointer.allocate(capacity: 1) + let ptr = UnsafeMutablePointer.allocate(capacity: 1) let result = sysctl(&mib, u_int(mib.count), ptr, &size, nil, 0) if result == 0 { diff --git a/SMCKitTool/lib/CommandLine b/SMCKitTool/lib/CommandLine deleted file mode 160000 index 2b3ef29..0000000 --- a/SMCKitTool/lib/CommandLine +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2b3ef29c23b19a366df8ad448f8791f5f9bffadf diff --git a/SMCKitTool/main.swift b/SMCKitTool/main.swift deleted file mode 100644 index d651c17..0000000 --- a/SMCKitTool/main.swift +++ /dev/null @@ -1,347 +0,0 @@ -// -// OS X Apple System Management Controller (SMC) Tool -// -// SMCKitTool/main.swift -// SMCKit -// -// The MIT License -// -// Copyright (C) 2015-2017 beltex -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import Darwin - -// Not using the following as frameworks, but as source files. See README.md for -// more -//import CommandLine -//import SMCKit - -//------------------------------------------------------------------------------ -// MARK: Globals -//------------------------------------------------------------------------------ - -let SMCKitToolVersion = "0.2.0-dev" -let maxTemperatureCelsius = 128.0 - -//------------------------------------------------------------------------------ -// MARK: Enums -//------------------------------------------------------------------------------ - -enum ANSIColor: String { - case Off = "\u{001B}[0;0m" - case Red = "\u{001B}[0;31m" - case Green = "\u{001B}[0;32m" - case Yellow = "\u{001B}[0;33m" - case Blue = "\u{001B}[0;34m" -} - -//------------------------------------------------------------------------------ -// MARK: CLI -//------------------------------------------------------------------------------ - -let CLIColorOption = BoolOption(shortFlag: "c", longFlag: "color", - helpMessage: "Colorize output where applicable") -let CLIDisplayKeysOption = BoolOption(shortFlag: "d", longFlag: "display-keys", - helpMessage: "Show SMC keys (FourCC) when printing temperature sensors") -let CLIFanOption = BoolOption(shortFlag: "f", longFlag: "fan", - helpMessage: "Show fan speeds (RPM)") -let CLIHelpOption = BoolOption(shortFlag: "h", longFlag: "help", - helpMessage: "Show the list of options") -let CLICheckKeyOption = StringOption(shortFlag: "k", longFlag: "check-key", - helpMessage: "Check if a FourCC is a valid SMC key on this machine") -let CLIMiscOption = BoolOption(shortFlag: "m", longFlag: "misc", - helpMessage: "Show misc information") -let CLIFanIdOption = IntOption(shortFlag: "n", longFlag: "fan-id", - helpMessage: "The id (number - starts from 0) of the fan whose speed to set") -let CLIPowerOption = BoolOption(shortFlag: "p", longFlag: "power", - helpMessage: "Show power related information") -let CLIFanSpeedOption = IntOption(shortFlag: "s", longFlag: "fan-speed", - helpMessage: "The min speed (RPM) of the fan to set") -let CLITemperatureOption = BoolOption(shortFlag: "t", longFlag: "temperature", - helpMessage: "Show temperature sensors whose hardware mapping is known") -let CLIUnknownTemperatureOption = BoolOption(shortFlag: "u", - longFlag: "unknown-temperature-sensors", - helpMessage: "Show temperature sensors whose hardware mapping is unknown") -let CLIVersionOption = BoolOption(shortFlag: "v", longFlag: "version", - helpMessage: "Show SMCKitTool version") -let CLIWarnOption = BoolOption(shortFlag: "w", longFlag: "warn", - helpMessage: "Show warning levels for temperature sensors and fan speeds") - -// Keep this list sorted by short flag. This will be the order that it is -// printed when printUsage() ('--help') is called -let CLIOptions = [CLIColorOption, - CLIDisplayKeysOption, - CLIFanOption, - CLIHelpOption, - CLICheckKeyOption, - CLIMiscOption, - CLIFanIdOption, - CLIFanSpeedOption, - CLIPowerOption, - CLITemperatureOption, - CLIUnknownTemperatureOption, - CLIVersionOption, - CLIWarnOption] - -let CLI = CommandLine() -CLI.addOptions(CLIOptions) - -do { - try CLI.parse() -} catch { - CLI.printUsage(error) - exit(EX_USAGE) -} - -// Give precedence to help flag -if CLIHelpOption.wasSet { - CLI.printUsage() - exit(EX_OK) -} else if CLIVersionOption.wasSet { - print(SMCKitToolVersion) - exit(EX_OK) -} - -//------------------------------------------------------------------------------ -// MARK: Functions -//------------------------------------------------------------------------------ - -func warningLevel(value: Double, maxValue: Double) -> (name: String, - color: ANSIColor) { - let percentage = value / maxValue - - switch percentage { - // TODO: Is this safe? Rather, is this the best way to go about this? - case -Double.infinity...0: return ("Cool", ANSIColor.Blue) - case 0...0.45: return ("Nominal", ANSIColor.Green) - case 0.45...0.75: return ("Danger", ANSIColor.Yellow) - default: return ("Crisis", ANSIColor.Red) - } -} - -func colorBoolOutput(value: Bool) -> String { - let color: ANSIColor - if CLIColorOption.wasSet { color = value ? ANSIColor.Green : ANSIColor.Red } - else { color = ANSIColor.Off } - - return "\(color.rawValue)\(value)\(ANSIColor.Off.rawValue)" -} - -func printTemperatureInformation(known: Bool = true) { - print("-- Temperature --") - - let sensors: [TemperatureSensor] - do { - if known { - sensors = try SMCKit.allKnownTemperatureSensors().sorted - { $0.name < $1.name } - } else { - sensors = try SMCKit.allUnknownTemperatureSensors() - } - - } catch { - print(error) - return - } - - - let sensorWithLongestName = sensors.max { $0.name.characters.count < - $1.name.characters.count } - - guard let longestSensorNameCount = sensorWithLongestName?.name.characters.count else { - print("No temperature sensors found") - return - } - - - for sensor in sensors { - let padding = String(repeating: " ", - count: longestSensorNameCount - sensor.name.characters.count) - - let smcKey = CLIDisplayKeysOption.wasSet ? "(\(sensor.code.toString()))" : "" - print("\(sensor.name + padding) \(smcKey) ", terminator: "") - - - guard let temperature = try? SMCKit.temperature(sensor.code) else { - print("NA") - return - } - - let warning = warningLevel(value: temperature, maxValue: maxTemperatureCelsius) - let level = CLIWarnOption.wasSet ? "(\(warning.name))" : "" - let color = CLIColorOption.wasSet ? warning.color : ANSIColor.Off - - print("\(color.rawValue)\(temperature)°C \(level)" + - "\(ANSIColor.Off.rawValue)") - } -} - -func printFanInformation() { - print("-- Fan --") - - let allFans: [Fan] - do { - allFans = try SMCKit.allFans() - } catch { - print(error) - return - } - - if allFans.count == 0 { print("No fans found") } - - for fan in allFans { - print("[id \(fan.id)] \(fan.name)") - print("\tMin: \(fan.minSpeed) RPM") - print("\tMax: \(fan.maxSpeed) RPM") - - guard let currentSpeed = try? SMCKit.fanCurrentSpeed(fan.id) else { - print("\tCurrent: NA") - return - } - - let warning = warningLevel(value: Double(currentSpeed), - maxValue: Double(fan.maxSpeed)) - let level = CLIWarnOption.wasSet ? "(\(warning.name))" : "" - let color = CLIColorOption.wasSet ? warning.color : ANSIColor.Off - print("\tCurrent: \(color.rawValue)\(currentSpeed) RPM \(level)" + - "\(ANSIColor.Off.rawValue)") - } -} - -func printPowerInformation() { - let information: batteryInfo - do { - information = try SMCKit.batteryInformation() - } catch { - print(error) - return - } - - print("-- Power --") - print("AC Present: \(colorBoolOutput(value: information.isACPresent))") - print("Battery Powered: \(colorBoolOutput(value: information.isBatteryPowered))") - print("Charging: \(colorBoolOutput(value: information.isCharging))") - print("Battery Ok: \(colorBoolOutput(value: information.isBatteryOk))") - print("Battery Count: \(information.batteryCount)") -} - -func printMiscInformation() { - print("-- Misc --") - - let ODDStatus: Bool - do { - ODDStatus = try SMCKit.isOpticalDiskDriveFull() - } catch SMCKit.SMCError.keyNotFound { ODDStatus = false } - catch { - print(error) - return - } - - print("Disc in ODD: \(colorBoolOutput(value: ODDStatus))") -} - -func printAll() { - printTemperatureInformation() - printFanInformation() - printPowerInformation() - printMiscInformation() -} - -func checkKey(key: String) { - if key.characters.count != 4 { - print("Must be a FourCC (four-character code)") - return - } - - do { - let isValid = try SMCKit.isKeyFound(FourCharCode(fromString: key)) - let answer = isValid ? "valid" : "invalid" - - print("\(key) is a \(answer) SMC key on this machine") - } catch { print(error) } -} - -func setMinFanSpeed(fanId: Int, fanSpeed: Int) { - do { - let fan = try SMCKit.fan(fanId) - let currentSpeed = try SMCKit.fanCurrentSpeed(fanId) - - try SMCKit.fanSetMinSpeed(fanId, speed: fanSpeed) - - print("Min fan speed set successfully") - print("[id \(fan.id)] \(fan.name)") - print("\tMin (Previous): \(fan.minSpeed) RPM") - print("\tMin (Target): \(fanSpeed) RPM") - print("\tCurrent: \(currentSpeed) RPM") - } catch SMCKit.SMCError.keyNotFound { - print("This machine has no fan with id \(fanId)") - } catch SMCKit.SMCError.notPrivileged { - print("This operation must be invoked as the superuser") - } catch SMCKit.SMCError.unsafeFanSpeed { - print("Invalid fan speed. Must be <= max fan speed") - } catch { - print(error) - } -} - -//------------------------------------------------------------------------------ -// MARK: MAIN -//------------------------------------------------------------------------------ - -do { - try SMCKit.open() -} catch { - print("Failed to open a connection to the SMC") - exit(EX_UNAVAILABLE) -} - -let wasSetOptions = CLIOptions.filter { $0.wasSet } - -// Want to check that only a combination of the following flags is passed for -// printAll to occur -let printAllOptionsCount = wasSetOptions.filter { - guard let shortFlag = $0.shortFlag else { return false } - - switch shortFlag { - case "c", "d", "w": return true - default : return false - } -}.count - -if printAllOptionsCount == wasSetOptions.count { printAll() } - - -if let fanId = CLIFanIdOption.value, let fanSpeed = CLIFanSpeedOption.value { - setMinFanSpeed(fanId: fanId, fanSpeed: fanSpeed) -} -else if CLIFanIdOption.wasSet != CLIFanSpeedOption.wasSet { - print("Usage: Must set fan number (-n) AND fan speed (-s)") -} - - -if let key = CLICheckKeyOption.value { checkKey(key: key) } - -if CLITemperatureOption.wasSet { printTemperatureInformation() } -if CLIUnknownTemperatureOption.wasSet { printTemperatureInformation(known: false) } -if CLIFanOption.wasSet { printFanInformation() } -if CLIPowerOption.wasSet { printPowerInformation() } -if CLIMiscOption.wasSet { printMiscInformation() } - -SMCKit.close() diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 654c349..0000000 --- a/docs/index.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - - - smckit(1) - macOS SMC tool - - - - - -
- - - -
    -
  1. smckit(1)
  2. -
  3. -
  4. smckit(1)
  5. -
- -

NAME

-

- smckit - macOS SMC tool -

- -

SYNOPSIS

- -

smckit [-cdfmptuw]
-       [-h]
-       [-k check-key]
-       [-n fan-id] [-s fan-speed]
-       [-v]

- -

DESCRIPTION

- -

A macOS command line tool for interfacing with the Apple System Management -Controller (SMC) in Swift on Intel based Macs.

- -

OPTIONS

- -

List of supported command line options (flags/switches). Providing no options -prints temperature (-t), fan (-f), power (-p), and misc (-m) -information.

- -
-
-c, --color

Colorize output where applicable.

-
-d, --show-keys

Show SMC keys (FourCC) when printing temperature sensors.

-
-f, --fan

Show the machines fan speeds (RPM).

-
-h, --help

Show the list of options.

-
-k, --check-key value

Check if a FourCC is a valid SMC key on this machine.

-
-m, --misc

Show misc information about this machine.

-
-n, --fan-id value

The id (number - starts from 0) of the fan whose speed to set. The list of -id's can be seen via the --fan option. Must be used in combination ---fan-speed.

-
-p, --power

Show power related information about this machine.

-
-s, --fan-speed value

The minimum speed (RPM - revolutions per minute) of the fan to set. By -minimum we mean that macOS can interject and raise the fan speed if needed, -however it will not go below this. Must be used with --fan-id. Requires -root privileges.

- -

WARNING: You are playing with hardware here, BE CAREFUL.

-
-t, --temperature

Show the list of known temperature sensors on this machine.

-
-u, --unknown-temperature-sensors

Show the list of temperature sensors whose hardware mapping is unknown.

-
-v, --version

Show SMCKitTool version.

-
-w, --warn

Show warning levels for temperature sensors and fan speeds.

-
- - -

DETAIL

- -
-
Fan

All Intel based Macs to this point have at least one fan, with the exception -of the newly added fanless MacBook (8,1).

-
Temperature

The list of known temperature sensors (-t) in combination with the unknown -ones (-u) is exhaustive. However, the names of the known sensors may not -be mapped to the correct hardware component. In addition, the maximum -temperature of each individual sensor is not known. Thus, a global max of -128 degrees Celsius is used. This is all due to the fact that the SMC has a -closed source driver, and thus information about it's inner workings is -limited.

- -

If a sensor has a value that is very high, constant, and completely -disproportionate to the rest, then there is a chance that it is faulty. This -could be due to bad or damaged hardware (liquid on the logic board). Run the - Apple Diagnostics (Apple Hardware Test for older machines) diagnostics -suite in such a case to confirm.

- -

Some sensors however report very low values, below zero. The current theory -on this is that at lower temperatures the sensors have inaccurate readings. -It maybe that they are located close to an internal fan, and the airflow is -causing it to be skewed.

-
- - -

ENVIRONMENT

- -

Due to Swift, smckit requires macOS 10.9 (Mavericks) and above. This implies an -Intel based 64-bit machine.

- -

REPOSITORY

- -

https://github.com/beltex/SMCKit

- -

All project related matters, including source code, can be found at the GitHub -repository listed above. In particular, the issue tracker, which can be used to -report feedback, feature requests and bugs.

- - - -

This project is under the MIT License.

- -

AUTHOR

- -

beltex https://beltex.github.io

- -

SEE ALSO

- -

dshb(1), powermetrics(1)

- - -
    -
  1. -
  2. October 2017
  3. -
  4. smckit(1)
  5. -
- -
- - diff --git a/docs/smckit.1 b/docs/smckit.1 deleted file mode 100644 index 26135d8..0000000 --- a/docs/smckit.1 +++ /dev/null @@ -1,119 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "SMCKIT" "1" "October 2017" "" "" -. -.SH "NAME" -\fBsmckit\fR \- macOS SMC tool -. -.SH "SYNOPSIS" -\fBsmckit\fR [\fB\-cdfmptuw\fR] -. -.br -\~\~\~\~\~\~\~[\fB\-h\fR] -. -.br -\~\~\~\~\~\~\~[\fB\-k\fR \fIcheck\-key\fR] -. -.br -\~\~\~\~\~\~\~[\fB\-n\fR \fIfan\-id\fR] [\fB\-s\fR \fIfan\-speed\fR] -. -.br -\~\~\~\~\~\~\~[\fB\-v\fR] -. -.br -. -.SH "DESCRIPTION" -A macOS command line tool for interfacing with the Apple System Management Controller (SMC) in Swift on Intel based Macs\. -. -.SH "OPTIONS" -List of supported command line options (flags/switches)\. Providing no options prints temperature (\fB\-t\fR), fan (\fB\-f\fR), power (\fB\-p\fR), and misc (\fB\-m\fR) information\. -. -.TP -\fB\-c\fR, \fB\-\-color\fR -Colorize output where applicable\. -. -.TP -\fB\-d\fR, \fB\-\-show\-keys\fR -Show SMC keys (FourCC) when printing temperature sensors\. -. -.TP -\fB\-f\fR, \fB\-\-fan\fR -Show the machines fan speeds (RPM)\. -. -.TP -\fB\-h\fR, \fB\-\-help\fR -Show the list of options\. -. -.TP -\fB\-k\fR, \fB\-\-check\-key\fR \fIvalue\fR -Check if a FourCC is a valid SMC key on this machine\. -. -.TP -\fB\-m\fR, \fB\-\-misc\fR -Show misc information about this machine\. -. -.TP -\fB\-n\fR, \fB\-\-fan\-id\fR \fIvalue\fR -The id (number \- starts from 0) of the fan whose speed to set\. The list of id\'s can be seen via the \fB\-\-fan\fR option\. Must be used in combination \fB\-\-fan\-speed\fR\. -. -.TP -\fB\-p\fR, \fB\-\-power\fR -Show power related information about this machine\. -. -.TP -\fB\-s\fR, \fB\-\-fan\-speed\fR \fIvalue\fR -The minimum speed (RPM \- revolutions per minute) of the fan to set\. By minimum we mean that macOS can interject and raise the fan speed if needed, however it will not go below this\. Must be used with \fB\-\-fan\-id\fR\. Requires root privileges\. -. -.IP -\fBWARNING\fR: You are playing with hardware here, \fBBE CAREFUL\fR\. -. -.TP -\fB\-t\fR, \fB\-\-temperature\fR -Show the list of known temperature sensors on this machine\. -. -.TP -\fB\-u\fR, \fB\-\-unknown\-temperature\-sensors\fR -Show the list of temperature sensors whose hardware mapping is unknown\. -. -.TP -\fB\-v\fR, \fB\-\-version\fR -Show SMCKitTool version\. -. -.TP -\fB\-w\fR, \fB\-\-warn\fR -Show warning levels for temperature sensors and fan speeds\. -. -.SH "DETAIL" -. -.TP -\fBFan\fR -All Intel based Macs to this point have at least one fan, with the exception of the newly added fanless MacBook (8,1)\. -. -.TP -\fBTemperature\fR -The list of known temperature sensors (\fB\-t\fR) in combination with the unknown ones (\fB\-u\fR) is exhaustive\. However, the names of the known sensors may not be mapped to the correct hardware component\. In addition, the maximum temperature of each individual sensor is not known\. Thus, a global max of 128 degrees Celsius is used\. This is all due to the fact that the SMC has a closed source driver, and thus information about it\'s inner workings is limited\. -. -.IP -If a sensor has a value that is very high, constant, and completely disproportionate to the rest, then there is a chance that it is faulty\. This could be due to bad or damaged hardware (liquid on the logic board)\. Run the \fIApple Diagnostics\fR (\fIApple Hardware Test\fR for older machines) diagnostics suite in such a case to confirm\. -. -.IP -Some sensors however report very low values, below zero\. The current theory on this is that at lower temperatures the sensors have inaccurate readings\. It maybe that they are located close to an internal fan, and the airflow is causing it to be skewed\. -. -.SH "ENVIRONMENT" -Due to Swift, \fBsmckit\fR requires macOS 10\.9 (Mavericks) and above\. This implies an Intel based 64\-bit machine\. -. -.SH "REPOSITORY" -\fIhttps://github\.com/beltex/SMCKit\fR -. -.P -All project related matters, including source code, can be found at the GitHub repository listed above\. In particular, the issue tracker, which can be used to report feedback, feature requests and bugs\. -. -.SH "COPYRIGHT" -This project is under the \fIMIT License\fR\. -. -.SH "AUTHOR" -beltex \fIhttps://beltex\.github\.io\fR -. -.SH "SEE ALSO" -dshb(1), powermetrics(1) diff --git a/docs/smckit.1.ronn b/docs/smckit.1.ronn deleted file mode 100644 index c643be8..0000000 --- a/docs/smckit.1.ronn +++ /dev/null @@ -1,118 +0,0 @@ -smckit(1) -- macOS SMC tool -=========================== - -## SYNOPSIS - -`smckit` [`-cdfmptuw`]
-       [`-h`]
-       [`-k` ]
-       [`-n` ] [`-s` ]
-       [`-v`]
- -## DESCRIPTION - -A macOS command line tool for interfacing with the Apple System Management -Controller (SMC) in Swift on Intel based Macs. - -## OPTIONS - -List of supported command line options (flags/switches). Providing no options -prints temperature (`-t`), fan (`-f`), power (`-p`), and misc (`-m`) -information. - - * `-c`, `--color`: - Colorize output where applicable. - - * `-d`, `--show-keys`: - Show SMC keys (FourCC) when printing temperature sensors. - - * `-f`, `--fan`: - Show the machines fan speeds (RPM). - - * `-h`, `--help`: - Show the list of options. - - * `-k`, `--check-key` : - Check if a FourCC is a valid SMC key on this machine. - - * `-m`, `--misc`: - Show misc information about this machine. - - * `-n`, `--fan-id` : - The id (number - starts from 0) of the fan whose speed to set. The list of - id's can be seen via the `--fan` option. Must be used in combination - `--fan-speed`. - - * `-p`, `--power`: - Show power related information about this machine. - - * `-s`, `--fan-speed` : - The minimum speed (RPM - revolutions per minute) of the fan to set. By - minimum we mean that macOS can interject and raise the fan speed if needed, - however it will not go below this. Must be used with `--fan-id`. Requires - root privileges. - - **WARNING**: You are playing with hardware here, **BE CAREFUL**. - - * `-t`, `--temperature`: - Show the list of known temperature sensors on this machine. - - * `-u`, `--unknown-temperature-sensors`: - Show the list of temperature sensors whose hardware mapping is unknown. - - * `-v`, `--version`: - Show SMCKitTool version. - - * `-w`, `--warn`: - Show warning levels for temperature sensors and fan speeds. - -## DETAIL - - * `Fan`: - All Intel based Macs to this point have at least one fan, with the exception - of the newly added fanless MacBook (8,1). - - * `Temperature`: - The list of known temperature sensors (`-t`) in combination with the unknown - ones (`-u`) is exhaustive. However, the names of the known sensors may not - be mapped to the correct hardware component. In addition, the maximum - temperature of each individual sensor is not known. Thus, a global max of - 128 degrees Celsius is used. This is all due to the fact that the SMC has a - closed source driver, and thus information about it's inner workings is - limited. - - If a sensor has a value that is very high, constant, and completely - disproportionate to the rest, then there is a chance that it is faulty. This - could be due to bad or damaged hardware (liquid on the logic board). Run the - _Apple Diagnostics_ (_Apple Hardware Test_ for older machines) diagnostics - suite in such a case to confirm. - - Some sensors however report very low values, below zero. The current theory - on this is that at lower temperatures the sensors have inaccurate readings. - It maybe that they are located close to an internal fan, and the airflow is - causing it to be skewed. - -## ENVIRONMENT - -Due to Swift, `smckit` requires macOS 10.9 (Mavericks) and above. This implies an -Intel based 64-bit machine. - -## REPOSITORY - - - -All project related matters, including source code, can be found at the GitHub -repository listed above. In particular, the issue tracker, which can be used to -report feedback, feature requests and bugs. - -## COPYRIGHT - -This project is under the _MIT License_. - -## AUTHOR - -beltex - -## SEE ALSO - -dshb(1), powermetrics(1) diff --git a/powermetricsTests/main.swift b/powermetricsTests/main.swift deleted file mode 100644 index fb992c6..0000000 --- a/powermetricsTests/main.swift +++ /dev/null @@ -1,124 +0,0 @@ -// -// Test SMCKit by cross-referencing with Apple's powermetrics(1) tool. This is -// not a pretty test by any means, were running a command line tool and parsing -// it's output. However, at this point in time, powermetrics is the only -// publicly available tool that displays SMC data from Apple, so it's our only -// "official" reference. Requires root privileges due to powermetrics. -// -// References: -// -// http://practicalswift.com/2014/06/25/how-to-execute-shell-commands-from-swift/ -// -// powermetricsTests/main.swift -// SMCKit -// -// The MIT License -// -// Copyright (C) 2015-2017 beltex -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import Foundation - - -// powermetrics added the SMC sampler in 10.10 -let processInfo = ProcessInfo() -let Yosemite = OperatingSystemVersion(majorVersion: 10, - minorVersion: 0, - patchVersion: 0) - -if !processInfo.isOperatingSystemAtLeast(Yosemite) { - print("ERROR: powermetrics requires OS X 10.10 (Yosemite) or greater") - exit(EX_USAGE) -} - - -// Setup SMC -do { - try SMCKit.open() -} catch { - print(error) - exit(EX_UNAVAILABLE) -} - - -// Setup command to run powermetrics -let powermetrics = Process() -powermetrics.launchPath = "/usr/bin/powermetrics" - -/* -TODO: Taking only 1 sample right now. In the future, could change this to take - many, and average it out to compare with SMCKit. However, would need to in - parallel run the SMCKit samples (need a serial GCD queue that fires at 1 - second intervals) -*/ -powermetrics.arguments = ["-s", "smc", "-n", "1"] - -let pipe = Pipe() -powermetrics.standardOutput = pipe -powermetrics.launch() -let data = pipe.fileHandleForReading.readDataToEndOfFile() - - -// Get SMC data right after powermetrics has run. This is because it first -// prints out some general information about the machine, and then seems to -// sleep for 1 second to "line up" its sampling window -let smcFanCount = try! SMCKit.fanCount() -let smcRPM = try! SMCKit.fanCurrentSpeed(0) - -// The key used by powermetrics was determined via DTrace script below -// https://gist.github.com/beltex/acbbeef815a7be938abf -let smcCPUDieTemperature = - try! SMCKit.temperature(TemperatureSensors.CPU_0_DIE.code) - - -// Parse the output from powermetrics -// TODO: Unknown format of various cases - multiple fans, no fans, 2 CPUs -// (Mac Pro) -if let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) { - // Break it down into lines - let lines = output.components(separatedBy: "\n") - - for line in lines { - let tokens = line.components(separatedBy: " ") - - if line.hasPrefix("Fan:") && line.hasSuffix("rpm") { - let powermetricsRPM = Int(tokens[1])! - let diff = abs(Int(smcRPM) - powermetricsRPM) - - print("SMCKit fan 0 RPM: \(smcRPM)") - print("powermetrics fan RPM: \(powermetricsRPM)") - assert(diff >= 0 && diff <= 5, "RPM differs by more than +/- 5") - - } else if line.hasPrefix("CPU die temperature:") && - line.hasSuffix("C") { - let powermetricsCPUDieTemperature = - (tokens[3] as NSString).doubleValue - let diff = abs(smcCPUDieTemperature - powermetricsCPUDieTemperature) - - print("SMCKit CPU_0_DIE: \(smcCPUDieTemperature)") - print("powermetrics CPU die temperature: " + - "\(powermetricsCPUDieTemperature)") - assert(diff >= 0 && diff <= 1, - "Temperature differs by more than +/- 1") - } - } -} - -SMCKit.close()