#!/usr/bin/env bash cache_dir=~/.cache/tmux cache_file=$cache_dir/system-info # Make sure the output directory exists. if [ ! -d $cache_dir ]; then mkdir -p $cache_dir fi if [ ! -f $cache_dir/cpu-temp ]; then clang -x objective-c -Wall -O2 -g -c -o $cache_dir/cpu-temp.o - << EOF #import #import #include #define IOHIDEventFieldBase(type) (type << 16) #define kIOHIDEventTypeTemperature 15 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); int main(int argc, char *argv[]) { NSDictionary *thermalSensors = @{ @"PrimaryUsagePage" : [NSNumber numberWithInt:0xFF00], @"PrimaryUsage" : [NSNumber numberWithInt:5], }; IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault); IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)thermalSensors); NSArray *serviceClients = (__bridge NSArray *)IOHIDEventSystemClientCopyServices(system); long count = [serviceClients count]; for (NSUInteger i = 0; i < count; i++) { IOHIDServiceClientRef serviceClient = (IOHIDServiceClientRef)serviceClients[i]; NSString *name = (NSString *)IOHIDServiceClientCopyProperty( serviceClient, (__bridge CFStringRef) @"Product"); if ([name isEqualToString:[NSString stringWithUTF8String:argv[1]]]) { IOHIDEventRef event = IOHIDServiceClientCopyEvent( serviceClient, kIOHIDEventTypeTemperature, 0, 0); NSNumber *value; double temp = 0.0; if (event != 0) { temp = IOHIDEventGetFloatValue( event, IOHIDEventFieldBase(kIOHIDEventTypeTemperature)); } value = [NSNumber numberWithDouble:temp]; printf("%.1lf°C\n", [value doubleValue]); break; } } return 0; } EOF clang -o $cache_dir/cpu-temp $cache_dir/cpu-temp.o -framework Foundation -framework IOKit rm $cache_dir/cpu-temp.o fi # Cleanup cache file when interrupted. trap '[ -f $cache_file ] && rm $cache_file; exit' INT trap '[ -f $cache_file ] && rm $cache_file; exit' TERM # Check if a battery is installed. ioreg -w0 -l | grep BatteryInstalled &> /dev/null && \ has_battery=true || has_battery=false while true; do # Get the current CPU temperature. cpu_temp="`$cache_dir/cpu-temp 'PMU tdie0'` " cpu_load=$(sudo powermetrics --format text \ --sample-rate 1200 --sample-count 1 --samplers cpu_power | grep --color=never -E 'CPU \d idle residency:' | grep --color=never -Eo '\d+\.\d+' | gawk '$idle ~ /[-.0-9]*/ { printf "%s", substr("█▇▆▅▄▃▂▁ ", int($idle / 10), 1) }' ) # Parse the current battery charge percentage. if $has_battery; then raw_battery="$(pmset -g batt | \ grep --color=never 'InternalBattery' | \ grep --color=never -Eo '\d+%' | \ grep --color=never -Eo '\d+')" battery="$(echo $raw_battery | gawk '$battery ~ /.*/ { printf " %d%% %s\n", $battery, substr("󰂎󰁺󰁻󰁼󰁽󰁾󰁿󰂀󰂁󰂂󰁹", int($battery / 9), 1) }')" fi # Write to the cache file. echo "$cpu_temp$cpu_load$battery" > $cache_file done