Skip to content

Commit

Permalink
Merge pull request #1672 from Girbons/fix/arm-temperature-sensors
Browse files Browse the repository at this point in the history
fix: read temperature sensors darwin arm
  • Loading branch information
shirou authored Jul 19, 2024
2 parents dab07a3 + ba82fef commit 0fc9a73
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 1 deletion.
110 changes: 110 additions & 0 deletions sensors/darwin_arm_sensors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-FileCopyrightText: Copyright (c) 2016-2018, "freedom" Koan-Sin Tan
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/freedomtan/sensors/blob/master/sensors/sensors.m
#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDEventSystemClient.h>
#include <unistd.h>

typedef struct __IOHIDEvent *IOHIDEventRef;
typedef struct __IOHIDServiceClient *IOHIDServiceClientRef;
typedef double IOHIDFloat;

IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator);

int IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef client, CFDictionaryRef match);

IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t, int32_t, int64_t);

CFStringRef IOHIDServiceClientCopyProperty(IOHIDServiceClientRef service, CFStringRef property);

IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef event, int32_t field);

NSDictionary *matching(int page, int usage) {
NSDictionary *dict = @{
@"PrimaryUsagePage" : [NSNumber numberWithInt:page],
@"PrimaryUsage" : [NSNumber numberWithInt:usage],
};

return dict;
}

NSArray *getProductNames(NSDictionary *sensors) {
IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault);

IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)sensors);
NSArray *matchingsrvs = (__bridge NSArray *)IOHIDEventSystemClientCopyServices(system);

long count = [matchingsrvs count];
NSMutableArray *array = [[NSMutableArray alloc] init];

for (int i = 0; i < count; i++) {
IOHIDServiceClientRef sc = (IOHIDServiceClientRef)matchingsrvs[i];
NSString *name = (NSString *)IOHIDServiceClientCopyProperty(sc, (__bridge CFStringRef)@"Product");

if (name) {
[array addObject:name];
} else {
[array addObject:@"noname"];
}
}

return array;
}

#define IOHIDEventFieldBase(type) (type << 16)
#define kIOHIDEventTypeTemperature 15
#define kIOHIDEventTypePower 25

NSArray *getThermalValues(NSDictionary *sensors) {
IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault);

IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)sensors);
NSArray *matchingsrvs = (__bridge NSArray *)IOHIDEventSystemClientCopyServices(system);

long count = [matchingsrvs count];
NSMutableArray *array = [[NSMutableArray alloc] init];

for (int i = 0; i < count; i++) {
IOHIDServiceClientRef sc = (IOHIDServiceClientRef)matchingsrvs[i];
IOHIDEventRef event = IOHIDServiceClientCopyEvent(sc, kIOHIDEventTypeTemperature, 0, 0);

NSNumber *value;
double temp = 0.0;

if (event != 0) {
temp = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kIOHIDEventTypeTemperature));
}

value = [NSNumber numberWithDouble:temp];
[array addObject:value];
}

return array;
}

NSString *dumpNamesValues(NSArray *kvsN, NSArray *kvsV) {
NSMutableString *valueString = [[NSMutableString alloc] init];
int count = [kvsN count];

for (int i = 0; i < count; i++) {
NSString *output = [NSString stringWithFormat:@"%s:%lf\n", [kvsN[i] UTF8String], [kvsV[i] doubleValue]];
[valueString appendString:output];
}

return valueString;
}

char *getThermals() {
NSDictionary *thermalSensors = matching(0xff00, 5);
NSArray *thermalNames = getProductNames(thermalSensors);
NSArray *thermalValues = getThermalValues(thermalSensors);
NSString *result = dumpNamesValues(thermalNames, thermalValues);
char *finalStr = strdup([result UTF8String]);

CFRelease(thermalSensors);
CFRelease(thermalNames);
CFRelease(thermalValues);
CFRelease(result);

return finalStr;
}
45 changes: 44 additions & 1 deletion sensors/sensors_darwin_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,57 @@

package sensors

// #cgo LDFLAGS: -framework IOKit
// #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework Foundation -framework IOKit
// #include "smc_darwin.h"
// #include "darwin_arm_sensors.h"
import "C"
import (
"bufio"
"context"
"math"
"runtime"
"strconv"
"strings"
"unsafe"
)

func ReadTemperaturesArm() []TemperatureStat {
cStr := C.getThermals()
defer C.free(unsafe.Pointer(cStr))

var stats []TemperatureStat
goStr := C.GoString(cStr)
scanner := bufio.NewScanner(strings.NewReader(goStr))
for scanner.Scan() {
split := strings.Split(scanner.Text(), ":")
if len(split) != 2 {
continue
}

val, err := strconv.ParseFloat(split[1], 32)
if err != nil {
continue
}

sensorKey := strings.Split(split[0], " ")[0]

val = math.Abs(val)

stats = append(stats, TemperatureStat{
SensorKey: sensorKey,
Temperature: float64(val),
})
}

return stats
}

func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
if runtime.GOARCH == "arm64" {
return ReadTemperaturesArm(), nil
}

temperatureKeys := []string{
C.AMBIENT_AIR_0,
C.AMBIENT_AIR_1,
Expand Down Expand Up @@ -48,5 +90,6 @@ func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
Temperature: float64(C.gopsutil_v4_get_temperature(ckey)),
})
}

return temperatures, nil
}

0 comments on commit 0fc9a73

Please sign in to comment.