diff options
author | Sean E. Russell <ser@ser1.net> | 2020-02-27 18:51:28 -0600 |
---|---|---|
committer | Sean E. Russell <ser@ser1.net> | 2020-02-28 07:06:51 -0600 |
commit | 7a89225d729d4c54c5bc95b21979f48f9cd046b1 (patch) | |
tree | 10bf143324cf553765d7002d0eb82abc21c72bb1 /widgets | |
parent | 4fce1654c5c263797205997e7635c7d06c393a85 (diff) |
Abstracts CPU & mem devices.
Finishes device refactoring: temps
Refactoring to allow updating maps. Simpler, and optimizable.
Diffstat (limited to 'widgets')
-rw-r--r-- | widgets/cpu.go | 110 | ||||
-rw-r--r-- | widgets/include/smc.c | 700 | ||||
-rw-r--r-- | widgets/include/smc.h | 254 | ||||
-rw-r--r-- | widgets/mem.go | 105 | ||||
-rw-r--r-- | widgets/mem_freebsd.go | 67 | ||||
-rw-r--r-- | widgets/mem_other.go | 25 | ||||
-rw-r--r-- | widgets/temp.go | 13 | ||||
-rw-r--r-- | widgets/temp_darwin.go | 74 | ||||
-rw-r--r-- | widgets/temp_freebsd.go | 124 | ||||
-rw-r--r-- | widgets/temp_linux.go | 32 | ||||
-rw-r--r-- | widgets/temp_openbsd.go | 74 | ||||
-rw-r--r-- | widgets/temp_windows.go | 29 |
12 files changed, 96 insertions, 1511 deletions
diff --git a/widgets/cpu.go b/widgets/cpu.go index c0f25bc..e56cd3d 100644 --- a/widgets/cpu.go +++ b/widgets/cpu.go @@ -1,14 +1,12 @@ package widgets import ( - "context" "fmt" "log" "sync" "time" "github.com/prometheus/client_golang/prometheus" - psCpu "github.com/shirou/gopsutil/cpu" "github.com/xxxserxxx/gotop/devices" ui "github.com/xxxserxxx/gotop/termui" @@ -20,27 +18,19 @@ type CpuWidget struct { ShowAverageLoad bool ShowPerCpuLoad bool updateInterval time.Duration - formatString string updateLock sync.Mutex - metric []prometheus.Gauge + metric map[string]prometheus.Gauge } +var cpuLabels []string + func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverageLoad bool, showPerCpuLoad bool) *CpuWidget { - cpuCount, err := devices.Counts(false) - if err != nil { - log.Printf("failed to get CPU count: %v", err) - } - formatString := "CPU%1d" - if cpuCount > 10 { - formatString = "CPU%02d" - } self := &CpuWidget{ LineGraph: ui.NewLineGraph(), - CpuCount: cpuCount, + CpuCount: len(cpuLabels), updateInterval: updateInterval, ShowAverageLoad: showAverageLoad, ShowPerCpuLoad: showPerCpuLoad, - formatString: formatString, } self.Title = " CPU Usage " self.HorizontalScale = horizontalScale @@ -58,9 +48,10 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage } if self.ShowPerCpuLoad { - for i := 0; i < int(self.CpuCount); i++ { - key := fmt.Sprintf(formatString, i) - self.Data[key] = []float64{0} + cpus := make(map[string]float64) + devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad) + for k, v := range cpus { + self.Data[k] = []float64{v} } } @@ -77,29 +68,24 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage func (self *CpuWidget) EnableMetric() { if self.ShowAverageLoad { - self.metric = make([]prometheus.Gauge, 1) - self.metric[0] = prometheus.NewGauge(prometheus.GaugeOpts{ + self.metric = make(map[string]prometheus.Gauge) + self.metric["AVRG"] = prometheus.NewGauge(prometheus.GaugeOpts{ Subsystem: "cpu", Name: "avg", }) } else { - ctx, ccl := context.WithTimeout(context.Background(), time.Second*5) - defer ccl() - percents, err := psCpu.PercentWithContext(ctx, self.updateInterval, true) - if err != nil { - log.Printf("error setting up metrics: %v", err) - return - } - self.metric = make([]prometheus.Gauge, self.CpuCount) - for i, perc := range percents { + cpus := make(map[string]float64) + devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad) + self.metric = make(map[string]prometheus.Gauge) + for key, perc := range cpus { gauge := prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "gotop", Subsystem: "cpu", - Name: fmt.Sprintf("%d", i), + Name: key, }) gauge.Set(perc) prometheus.MustRegister(gauge) - self.metric[i] = gauge + self.metric[key] = gauge } } } @@ -111,47 +97,41 @@ func (b *CpuWidget) Scale(i int) { func (self *CpuWidget) update() { if self.ShowAverageLoad { go func() { - percent, err := devices.Percent(self.updateInterval, false) - if err != nil { - log.Printf("failed to get average CPU usage percent: %v. self.updateInterval: %v. percpu: %v", err, self.updateInterval, false) - } else { - self.Lock() - defer self.Unlock() - self.updateLock.Lock() - defer self.updateLock.Unlock() - self.Data["AVRG"] = append(self.Data["AVRG"], percent[0]) - self.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", percent[0]) - if self.metric != nil { - self.metric[0].Set(percent[0]) - } + cpus := make(map[string]float64) + devices.UpdateCPU(cpus, self.updateInterval, false) + self.Lock() + defer self.Unlock() + self.updateLock.Lock() + defer self.updateLock.Unlock() + var val float64 + for _, v := range cpus { + val = v + break + } + self.Data["AVRG"] = append(self.Data["AVRG"], val) + self.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", val) + if self.metric != nil { + self.metric["AVRG"].Set(val) } }() } if self.ShowPerCpuLoad { go func() { - percents, err := devices.Percent(self.updateInterval, true) - if err != nil { - log.Printf("failed to get CPU usage percents: %v. self.updateInterval: %v. percpu: %v", err, self.updateInterval, true) - } else { - if len(percents) != int(self.CpuCount) { - log.Printf("error: number of CPU usage percents doesn't match CPU count. percents: %v. self.Count: %v", percents, self.CpuCount) - } else { - self.Lock() - defer self.Unlock() - self.updateLock.Lock() - defer self.updateLock.Unlock() - for i, percent := range percents { - key := fmt.Sprintf(self.formatString, i) - self.Data[key] = append(self.Data[key], percent) - self.Labels[key] = fmt.Sprintf("%3.0f%%", percent) - if self.metric != nil { - if self.metric[i] == nil { - log.Printf("ERROR: not enough metrics %d", i) - } else { - self.metric[i].Set(percent) - } - } + cpus := make(map[string]float64) + devices.UpdateCPU(cpus, self.updateInterval, true) + self.Lock() + defer self.Unlock() + self.updateLock.Lock() + defer self.updateLock.Unlock() + for key, percent := range cpus { + self.Data[key] = append(self.Data[key], percent) + self.Labels[key] = fmt.Sprintf("%3.0f%%", percent) + if self.metric != nil { + if self.metric[key] == nil { + log.Printf("no metrics for %s", key) + } else { + self.metric[key].Set(percent) } } } diff --git a/widgets/include/smc.c b/widgets/include/smc.c deleted file mode 100644 index 0c200d6..0000000 --- a/widgets/include/smc.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * Apple System Management Controller (SMC) API from user space for Intel based - * Macs. Works by talking to the AppleSMC.kext (kernel extension), the driver - * for the SMC. - * - * smc.c - * libsmc - * - * Copyright (C) 2014 beltex <https://github.com/beltex> - * - * Based off of fork from: - * osx-cpu-temp <https://github.com/lavoiesl/osx-cpu-temp> - * - * With credits to: - * - * Copyright (C) 2006 devnull - * Apple System Management Control (SMC) Tool - * - * Copyright (C) 2006 Hendrik Holtmann - * smcFanControl <https://github.com/hholtmann/smcFanControl> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <string.h> -#include "smc.h" - - -//------------------------------------------------------------------------------ -// MARK: MACROS -//------------------------------------------------------------------------------ - - -/** -Name of the SMC IOService as seen in the IORegistry. You can view it either via -command line with ioreg or through the IORegistryExplorer app (found on Apple's -developer site - Hardware IO Tools for Xcode) -*/ -#define IOSERVICE_SMC "AppleSMC" - - -/** -IOService for getting machine model name -*/ -#define IOSERVICE_MODEL "IOPlatformExpertDevice" - - -/** -SMC data types - 4 byte multi-character constants - -Sources: See TMP SMC keys in smc.h - -http://stackoverflow.com/questions/22160746/fpe2-and-sp78-data-types -*/ -#define DATA_TYPE_UINT8 "ui8 " -#define DATA_TYPE_UINT16 "ui16" -#define DATA_TYPE_UINT32 "ui32" -#define DATA_TYPE_FLAG "flag" -#define DATA_TYPE_FPE2 "fpe2" -#define DATA_TYPE_SFDS "{fds" -#define DATA_TYPE_SP78 "sp78" - - -//------------------------------------------------------------------------------ -// MARK: GLOBAL VARS -//------------------------------------------------------------------------------ - - -/** -Our connection to the SMC -*/ -static io_connect_t conn; - - -/** -Number of characters in an SMC key -*/ -static const int SMC_KEY_SIZE = 4; - - -/** -Number of characters in a data type "key" returned from the SMC. See data type -macros. -*/ -static const int DATA_TYPE_SIZE = 4; - - -//------------------------------------------------------------------------------ -// MARK: ENUMS -//------------------------------------------------------------------------------ - - -/** -Defined by AppleSMC.kext. See SMCParamStruct. - -These are SMC specific return codes -*/ -typedef enum { - kSMCSuccess = 0, - kSMCError = 1, - kSMCKeyNotFound = 0x84 -} kSMC_t; - - -/** -Defined by AppleSMC.kext. See SMCParamStruct. - -Function selectors. Used to tell the SMC which function inside it to call. -*/ -typedef enum { - kSMCUserClientOpen = 0, - kSMCUserClientClose = 1, - kSMCHandleYPCEvent = 2, - kSMCReadKey = 5, - kSMCWriteKey = 6, - kSMCGetKeyCount = 7, - kSMCGetKeyFromIndex = 8, - kSMCGetKeyInfo = 9 -} selector_t; - - -//------------------------------------------------------------------------------ -// MARK: STRUCTS -//------------------------------------------------------------------------------ - - -/** -Defined by AppleSMC.kext. See SMCParamStruct. -*/ -typedef struct { - unsigned char major; - unsigned char minor; - unsigned char build; - unsigned char reserved; - unsigned short release; -} SMCVersion; - - -/** -Defined by AppleSMC.kext. See SMCParamStruct. -*/ -typedef struct { - uint16_t version; - uint16_t length; - uint32_t cpuPLimit; - uint32_t gpuPLimit; - uint32_t memPLimit; -} SMCPLimitData; - - -/** -Defined by AppleSMC.kext. See SMCParamStruct. - -- dataSize : How many values written to SMCParamStruct.bytes -- dataType : Type of data written to SMCParamStruct.bytes. This lets us know how - to interpret it (translate it to human readable) -*/ -typedef struct { - IOByteCount dataSize; - uint32_t dataType; - uint8_t dataColors; -} SMCKeyInfoData; - - -/** -Defined by AppleSMC.kext. - -This is the predefined struct that must be passed to communicate with the -AppleSMC driver. While the driver is closed source, the definition of this -struct happened to appear in the Apple PowerManagement project at around -version 211, and soon after disappeared. It can be seen in the PrivateLib.c -file under pmconfigd. - -https://www.opensource.apple.com/source/PowerManagement/PowerManagement-211/ -*/ -typedef struct { - uint32_t key; - SMCVersion vers; - SMCPLimitData pLimitData; - SMCKeyInfoData keyInfo; - uint8_t result; - uint8_t status; - uint8_t data8; - uint32_t data32; - uint8_t bytes[32]; -} SMCParamStruct; - - -/** -Used for returning data from the SMC. -*/ -typedef struct { - uint8_t data[32]; - uint32_t dataType; - uint32_t dataSize; - kSMC_t kSMC; -} smc_return_t; - - -//------------------------------------------------------------------------------ -// MARK: HELPERS - TYPE CONVERSION -//------------------------------------------------------------------------------ - - -/** -Convert data from SMC of fpe2 type to human readable. - -:param: data Data from the SMC to be converted. Assumed data size of 2. -:returns: Converted data -*/ -static unsigned int from_fpe2(uint8_t data[32]) -{ - unsigned int ans = 0; - - // Data type for fan calls - fpe2 - // This is assumend to mean floating point, with 2 exponent bits - // http://stackoverflow.com/questions/22160746/fpe2-and-sp78-data-types - ans += data[0] << 6; - ans += data[1] << 2; - - return ans; -} - - -/** -Convert to fpe2 data type to be passed to SMC. - -:param: val Value to convert -:param: data Pointer to data array to place result -*/ -static void to_fpe2(unsigned int val, uint8_t *data) -{ - data[0] = val >> 6; - data[1] = (val << 2) ^ (data[0] << 8); -} - - -/** -Convert SMC key to uint32_t. This must be done to pass it to the SMC. - -:param: key The SMC key to convert -:returns: uint32_t translation. - Returns zero if key is not 4 characters in length. -*/ -static uint32_t to_uint32_t(char *key) -{ - uint32_t ans = 0; - uint32_t shift = 24; - - // SMC key is expected to be 4 bytes - thus 4 chars - if (strlen(key) != SMC_KEY_SIZE) { - return 0; - } - - for (int i = 0; i < SMC_KEY_SIZE; i++) { - ans += key[i] << shift; - shift -= 8; - } - - return ans; -} - - -/** -For converting the dataType return from the SMC to human readable 4 byte -multi-character constant. -*/ -static void to_string(uint32_t val, char *dataType) -{ - int shift = 24; - - for (int i = 0; i < DATA_TYPE_SIZE; i++) { - // To get each char, we shift it into the lower 8 bits, and then & by - // 255 to insolate it - dataType[i] = (val >> shift) & 0xff; - shift -= 8; - } -} - - -//------------------------------------------------------------------------------ -// MARK: HELPERS - TMP CONVERSION -//------------------------------------------------------------------------------ - - -/** -Celsius to Fahrenheit -*/ -static double to_fahrenheit(double tmp) -{ - // http://en.wikipedia.org/wiki/Fahrenheit#Definition_and_conversions - return (tmp * 1.8) + 32; -} - - -/** -Celsius to Kelvin -*/ -static double to_kelvin(double tmp) -{ - // http://en.wikipedia.org/wiki/Kelvin - return tmp + 273.15; -} - - -//------------------------------------------------------------------------------ -// MARK: "PRIVATE" FUNCTIONS -//------------------------------------------------------------------------------ - - -/** -Make a call to the SMC - -:param: inputStruct Struct that holds data telling the SMC what you want -:param: outputStruct Struct holding the SMC's response -:returns: I/O Kit return code -*/ -static kern_return_t call_smc(SMCParamStruct *inputStruct, - SMCParamStruct *outputStruct) -{ - kern_return_t result; - size_t inputStructCnt = sizeof(SMCParamStruct); - size_t outputStructCnt = sizeof(SMCParamStruct); - - result = IOConnectCallStructMethod(conn, kSMCHandleYPCEvent, - inputStruct, - inputStructCnt, - outputStruct, - &outputStructCnt); - - if (result != kIOReturnSuccess) { - // IOReturn error code lookup. See "Accessing Hardware From Applications - // -> Handling Errors" Apple doc - result = err_get_code(result); - } - - return result; -} - - -/** -Read data from the SMC - -:param: key The SMC key -*/ -static kern_return_t read_smc(char *key, smc_return_t *result_smc) -{ - kern_return_t result; - SMCParamStruct inputStruct; - SMCParamStruct outputStruct; - - memset(&inputStruct, 0, sizeof(SMCParamStruct)); - memset(&outputStruct, 0, sizeof(SMCParamStruct)); - memset(result_smc, 0, sizeof(smc_return_t)); - - // First call to AppleSMC - get key info - inputStruct.key = to_uint32_t(key); - inputStruct.data8 = kSMCGetKeyInfo; - - result = call_smc(&inputStruct, &outputStruct); - result_smc->kSMC = outputStruct.result; - - if (result != kIOReturnSuccess || outputStruct.result != kSMCSuccess) { - return result; - } - - // Store data for return - result_smc->dataSize = outputStruct.keyInfo.dataSize; - result_smc->dataType = outputStruct.keyInfo.dataType; - - - // Second call to AppleSMC - now we can get the data - inputStruct.keyInfo.dataSize = outputStruct.keyInfo.dataSize; - inputStruct.data8 = kSMCReadKey; - - result = call_smc(&inputStruct, &outputStruct); - result_smc->kSMC = outputStruct.result; - - if (result != kIOReturnSuccess || outputStruct.result != kSMCSuccess) { - return result; - } - - memcpy(result_smc->data, outputStruct.bytes, sizeof(outputStruct.bytes)); - - return result; -} - - -/** -Write data to the SMC. - -:returns: IOReturn IOKit return code -*/ -static kern_return_t write_smc(char *key, smc_return_t *result_smc) -{ - kern_return_t result; - SMCParamStruct inputStruct; - SMCParamStruct outputStruct; - - memset(&inputStruct, 0, sizeof(SMCParamStruct)); - memset(&outputStruct, 0, sizeof(SMCParamStruct)); - - // First call to AppleSMC - get key info - inputStruct.key = to_uint32_t(key); - inputStruct.data8 = kSMCGetKeyInfo; - - result = call_smc(&inputStruct, &outputStruct); - result_smc->kSMC = outputStruct.result; - - if (result != kIOReturnSuccess || outputStruct.result != kSMCSuccess) { - return result; - } - - // Check data is correct - if (result_smc->dataSize != outputStruct.keyInfo.dataSize || - result_smc->dataType != outputStruct.keyInfo.dataType) { - return kIOReturnBadArgument; - } - - // Second call to AppleSMC - now we can write the data - inputStruct.data8 = kSMCWriteKey; - inputStruct.keyInfo.dataSize = outputStruct.keyInfo.dataSize; - - // Set data to write - memcpy(inputStruct.bytes, result_smc->data, sizeof(result_smc->data)); - - result = call_smc(&inputStruct, &outputStruct); - result_smc->kSMC = outputStruct.result; - - return result; -} - - -/** -Get the model name of the machine. -*/ -static kern_return_t get_machine_model(io_name_t model) -{ - io_service_t service; - kern_return_t result; - - service = IOServiceGetMatchingService(kIOMasterPortDefault, - IOServiceMatching(IOSERVICE_MODEL)); - - if (service == 0) { - printf("ERROR: %s NOT FOUND\n", IOSERVICE_MODEL); - return kIOReturnError; - } - - // Get the model name - result = IORegistryEntryGetName(service, model); - IOObjectRelease(service); - - return result; -} - - -//------------------------------------------------------------------------------ -// MARK: "PUBLIC" FUNCTIONS -//------------------------------------------------------------------------------ - - -kern_return_t open_smc(void) -{ - kern_return_t result; - io_service_t service; - - service = IOServiceGetMatchingService(kIOMasterPortDefault, - IOServiceMatching(IOSERVICE_SMC)); - - if (service == 0) { - // NOTE: IOServiceMatching documents 0 on failure - printf("ERROR: %s NOT FOUND\n", IOSERVICE_SMC); - return kIOReturnError; - } - - result = IOServiceOpen(service, mach_task_self(), 0, &conn); - IOObjectRelease(service); - - return result; -} - - -kern_return_t close_smc(void) -{ - return IOServiceClose(conn); -} - - -bool is_key_valid(char *key) -{ - bool ans = false; - kern_return_t result; - smc_return_t result_smc; - - if (strlen(key) != SMC_KEY_SIZE) { - printf("ERROR: Invalid key size - must be 4 chars\n"); - return ans; - } - - // Try a read and see if it succeeds - result = read_smc(key, &result_smc); - - if (result == kIOReturnSuccess && result_smc.kSMC == kSMCSuccess) { - ans = true; - } - - return ans; -} - - -double get_tmp(char *key, tmp_unit_t unit) -{ - kern_return_t result; - smc_return_t result_smc; - - result = read_smc(key, &result_smc); - - if (!(result == kIOReturnSuccess && - result_smc.dataSize == 2 && - result_smc.dataType == to_uint32_t(DATA_TYPE_SP78))) { - // Error - return 0.0; - } - - // TODO: Create from_sp78() convert function - double tmp = result_smc.data[0]; - - switch (unit) { - case CELSIUS: - break; - case FAHRENHEIT: - tmp = to_fahrenheit(tmp); - break; - case KELVIN: - tmp = to_kelvin(tmp); - break; - } - - return tmp; -} - - -bool is_battery_powered(void) -{ - kern_return_t result; - smc_return_t result_smc; - - result = read_smc(BATT_PWR, &result_smc); - - if (!(result == kIOReturnSuccess && - result_smc.dataSize == 1 && - result_smc.dataType == to_uint32_t(DATA_TYPE_FLAG))) { - // Error - return false; - } - - return result_smc.data[0]; -} - - -bool is_optical_disk_drive_full(void) -{ - kern_return_t result; - smc_return_t result_smc; - - result = read_smc(ODD_FULL, &result_smc); - - if (!(result == kIOReturnSuccess && - result_smc.dataSize == 1 && - result_smc.dataType == to_uint32_t(DATA_TYPE_FLAG))) { - // Error - return false; - } - - return result_smc.data[0]; -} - - -//------------------------------------------------------------------------------ -// MARK: FAN FUNCTIONS -//------------------------------------------------------------------------------ - - -bool get_fan_name(unsigned int fan_num, fan_name_t name) -{ - char key[5]; - kern_return_t result; - smc_return_t result_smc; - - sprintf(key, "F%dID", fan_num); - result = read_smc(key, &result_smc); - - if (!(result == kIOReturnSuccess && - result_smc.dataSize == 16 && - result_smc.dataType == to_uint32_t(DATA_TYPE_SFDS))) { - return false; - } - - - /* - We know the data size is 16 bytes and the type is "{fds", a custom - struct defined by the AppleSMC.kext. See TMP enum sources for the - struct. - - The last 12 bytes contain the name of the fan, an array of chars, hence - the loop range. - */ - int index = 0; - for (int i = 4; i < 16; i++) { - // Check if at the end (name may not be full 12 bytes) - // Could check for 0 (null), but instead we check for 32 (space). This - // is a hack to remove whitespace. :) - if (result_smc.data[i] == 32) { - break; - } - - name[index] = result_smc.data[i]; - index++; - } - - return true; -} - - -int get_num_fans(void) -{ - kern_return_t result; - smc_return_t result_smc; - - result = read_smc(NUM_FANS, &result_smc); - - if (!(result == kIOReturnSuccess && - result_smc.dataSize == 1 && - result_smc.dataType == to_uint32_t(DATA_TYPE_UINT8))) { - // Error - return -1; - } - - return result_smc.data[0]; -} - - -unsigned int get_fan_rpm(unsigned int fan_num) -{ - char key[5]; - kern_return_t result; - smc_return_t result_smc; - - sprintf(key, "F%dAc", fan_num); - result = read_smc(key, &result_smc); - - if (!(result == kIOReturnSuccess && - result_smc.dataSize == 2 && - result_smc.dataType == to_uint32_t(DATA_TYPE_FPE2))) { - // Error - return 0; - } - - return from_fpe2(result_smc.data); -} - - -bool set_fan_min_rpm(unsigned int fan_num, unsigned int rpm, bool auth) -{ - // TODO: Add rpm val safety check - char key[5]; - bool ans = false; - kern_return_t result; - smc_return_t result_smc; - - memset(&result_smc, 0, sizeof(smc_return_t)); - - // TODO: Don't use magic number - result_smc.dataSize = 2; - result_smc.dataType = to_uint32_t(DATA_TYPE_FPE2); - to_fpe2(rpm, result_smc.data); - - sprintf(key, "F%dMn", fan_num); - result = write_smc(key, &result_smc); - - if (result == kIOReturnSuccess && result_smc.kSMC == kSMCSuccess) { - ans = true; - } - - return ans; -} diff --git a/widgets/include/smc.h b/widgets/include/smc.h deleted file mode 100644 index d837e11..0000000 --- a/widgets/include/smc.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Apple System Management Controller (SMC) API from user space for Intel based - * Macs. Works by talking to the AppleSMC.kext (kernel extension), the driver - * for the SMC. - * - * smc.h - * libsmc - * - * Copyright (C) 2014 beltex <https://github.com/beltex> - * - * Based off of fork from: - * osx-cpu-temp <https://github.com/lavoiesl/osx-cpu-temp> - * - * With credits to: - * - * Copyright (C) 2006 devnull - * Apple System Management Control (SMC) Tool - * - * Copyright (C) 2006 Hendrik Holtmann - * smcFanControl <https://github.com/hholtmann/smcFanControl> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <IOKit/IOKitLib.h> - - -//------------------------------------------------------------------------------ -// MARK: MACROS -//------------------------------------------------------------------------------ - - -/** -SMC keys for temperature sensors - 4 byte multi-character constants - -Not applicable to all Mac's of course. In adition, the definition of the codes -may not be 100% accurate necessarily. Finally, list is incomplete. - -Presumed letter translations: - -- T = Temperature (if first char) -- C = CPU -- G = GPU -- P = Proximity -- D = Diode -- H = Heatsink - -Sources: - -- https://www.apple.com/downloads/dashboard/status/istatpro.html -- https://github.com/hholtmann/smcFanControl -- https://github.com/jedda/OSX-Monitoring-Tools -- http://www.parhelia.ch/blog/statics/k3_keys.html -*/ -#define AMBIENT_AIR_0 "TA0P" -#define AMBIENT_AIR_1 "TA1P" -#define CPU_0_DIODE "TC0D" -#define CPU_0_HEATSINK "TC0H" -#define CPU_0_PROXIMITY "TC0P" -#define ENCLOSURE_BASE_0 "TB0T" -#define ENCLOSURE_BASE_1 "TB1T" -#define ENCLOSURE_BASE_2 "TB2T" -#define ENCLOSURE_BASE_3 "TB3T" -#define GPU_0_DIODE "TG0D" -#define GPU_0_HEATSINK "TG0H" -#define GPU_0_PROXIMITY "TG0P" -#define HARD_DRIVE_BAY "TH0P" -#define MEMORY_SLOT_0 "TM0S" -#define MEMORY_SLOTS_PROXIMITY "TM0P" -#define NORTHBRIDGE "TN0H" -#define NORTHBRIDGE_DIODE "TN0D" -#define NORTHBRIDGE_PROXIMITY "TN0P" -#define THUNDERBOLT_0 "TI0P" -#define THUNDERBOLT_1 "TI1P" -#define WIRELESS_MODULE "TW0P" - - -/** -SMC keys for fans - 4 byte multi-character constants - -Number of fans on Macs vary of course, thus not all keys will be applicable. - -Presumed letter translations: - -- F = Fan -- Ac = Acutal -- Mn = Min -- Mx = Max -- Sf = Safe -- Tg = Target - -Sources: See TMP SMC keys -*/ -#define FAN_0 "F0Ac" -#define FAN_0_MIN_RPM "F0Mn" -#define FAN_0_MAX_RPM "F0Mx" -#define FAN_0_SAFE_RPM "F0Sf" -#define FAN_0_TARGET_RPM "F0Tg" -#define FAN_1 "F1Ac" -#define FAN_1_MIN_RPM "F1Mn" -#define FAN_1_MAX_RPM "F1Mx" -#define FAN_1_SAFE_RPM "F1Sf" -#define FAN_1_TARGET_RPM "F1Tg" -#define FAN_2 "F2Ac" -#define FAN_2_MIN_RPM "F2Mn" -#define FAN_2_MAX_RPM "F2Mx" -#define FAN_2_SAFE_RPM "F2Sf" -#define FAN_2_TARGET_RPM "F2Tg" -#define NUM_FANS "FNum" -#define FORCE_BITS "FS! " - - -/** -Misc SMC keys - 4 byte multi-character constants - -Sources: See TMP SMC keys -*/ -#define BATT_PWR "BATP" -#define NUM_KEYS "#KEY" -#define ODD_FULL "MSDI" - - -//------------------------------------------------------------------------------ -// MARK: TYPES -//------------------------------------------------------------------------------ - - -typedef char fan_name_t[13]; - - -//------------------------------------------------------------------------------ -// MARK: ENUMS -//------------------------------------------------------------------------------ - - -typedef enum { - CELSIUS, - FAHRENHEIT, - KELVIN -} tmp_unit_t; - - -//------------------------------------------------------------------------------ -// MARK: PROTOTYPES -//------------------------------------------------------------------------------ - - -/** -Open a connection to the SMC - -:returns: kIOReturnSuccess on successful connection to the SMC. -*/ -kern_return_t open_smc(void); - - -/** -Close connection to the SMC - -:returns: kIOReturnSuccess on successful close of connection to the SMC. -*/ -kern_return_t close_smc(void); - - -/** -Check if an SMC key is valid. Useful for determining if a certain machine has -particular sensor or fan for example. - -:param: key The SMC key to check. 4 byte multi-character constant. Must be 4 - characters in length. -:returns: True if the key is found, false otherwise -*/ -bool is_key_valid(char *key); - - -/** -Get the current temperature from a sensor - -:param: key The temperature sensor to read |