iStats 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e7b93789e36378ae3f5b7d25de279ae08e377f9f
4
- data.tar.gz: 1610e948db9a121dc1d140f52bddac0820e5e50d
3
+ metadata.gz: 0edfe640e0fa303d06ffedce02b71914494c16a4
4
+ data.tar.gz: fbc51f28120c27def40ad66e98f3a85eb2337c82
5
5
  SHA512:
6
- metadata.gz: 13b22c663000f88713f847afe6ad1171a0027a97c801d037596fc06f1bdd5841250d69e3e4225be8653ac21fe67fc65e711ac1c1640f901d2a0763f563655cb2
7
- data.tar.gz: 704090fef830d84c530c1b9fdcafa5091c0b9a351713e1e2bb842af6b3068cdb9541b45587849cd0d8224cf8b07d5abae417805f5a8b537ae0ae535345d803f4
6
+ metadata.gz: cbb1ef8e4ecedb0d02d7717295852364f4e45e29220d1dfb71cb103c4e20ef94a4900c6300a7a8481e674c8a32fd56fd9a28035f15f6233f7f5ff9a737147829
7
+ data.tar.gz: fedee41c1544357376465b55ade0a3abd9b8b91a890209700a83e40f72d96ba348af2bc0d20c1ace317ab0733bcbe9fc8b4734f8b3872ad742cee7141c7c5c07
data/README.md CHANGED
@@ -7,12 +7,9 @@ iStats is a command-line tool that allows you to easily grab the CPU temperature
7
7
 
8
8
  $ gem install iStats
9
9
 
10
- #### Warning
11
- **This is now fixed with the release of OS X 10.9.3**<br>
12
- A [bug in Ruby](https://bugs.ruby-lang.org/issues/9624) and Apple XCode 5.1 onwards (new CLANG version) might make it impossible to install this gem if you are using Ruby from the Xcode command-line tools package. If you see an error when the gem is building the native extension try to use this command to install iStats: <br>
13
- `sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future gem install iStats`<br>
14
- If you are using RVM or homebrew to manage your Ruby installation you should be fine.
15
-
10
+ ##### Note
11
+ If you are running an older version of OS X and the install fails you might want to try running this command instead:
12
+ `sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future gem install iStats`
16
13
 
17
14
  ## Screenshot
18
15
  #### All Stats
@@ -42,9 +39,23 @@ If you are using RVM or homebrew to manage your Ruby installation you should be
42
39
  istats battery [charge] Print battery charge
43
40
  istats battery [capacity] Print battery capacity info
44
41
 
42
+ istats scan Scans and print temperatures
43
+ istats scan [key] Print single SMC temperature key
44
+ istats enable [key | all] Enables key
45
+ istats disable [key | all] Disable key
46
+ istats list List available keys
47
+
45
48
  for more help see: https://github.com/Chris911/iStats
46
49
  ```
47
50
 
51
+ ## Advanced usage
52
+
53
+ iStats now supports extra sensors for advanced users. Here's how to enable that functionality:
54
+
55
+ 1. Run `istats scan` to scan your computer for SMC sensors
56
+ 2. Enable extra sensors by running `istats enable key` or `istats enable all`
57
+ 3. Run `istats` or `istats extra` to see the extra sensors information.
58
+
48
59
  ## Contributing
49
60
 
50
61
  1. Fork it
@@ -54,6 +65,10 @@ If you are using RVM or homebrew to manage your Ruby installation you should be
54
65
  5. Create new Pull Request
55
66
 
56
67
  #### Tested on
57
- MacBook Pro 2012<br>
58
- OS X 10.9.3<br>
59
- Ruby: 1.9.3, 2.0.0, 2.1.1<br>
68
+ MacBook Pro 2012
69
+ OS X: 10.9.3
70
+ Ruby: 1.9.3, 2.0.0, 2.1.1
71
+
72
+ MacBook Pro 2014
73
+ OS X: 10.10.3, 10.10.4
74
+ Ruby: 2.1.3
@@ -318,6 +318,7 @@ int getBatteryCharge() {
318
318
  /*
319
319
  RUBY MODULES
320
320
  */
321
+ VALUE SMC_INFO = Qnil;
321
322
  VALUE CPU_STATS = Qnil;
322
323
  VALUE FAN_STATS = Qnil;
323
324
  VALUE BATTERY_STATS = Qnil;
@@ -326,6 +327,10 @@ VALUE BATTERY_STATS = Qnil;
326
327
  * We never call this, Ruby does.
327
328
  */
328
329
  void Init_osx_stats() {
330
+
331
+ SMC_INFO = rb_define_module("SMC_INFO");
332
+ rb_define_method(SMC_INFO,"is_key_supported",method_SMCKeySupported,1);
333
+
329
334
  CPU_STATS = rb_define_module("CPU_STATS");
330
335
  rb_define_method(CPU_STATS, "get_cpu_temp", method_get_cpu_temp, 0);
331
336
 
@@ -342,6 +347,17 @@ void Init_osx_stats() {
342
347
  rb_define_method(BATTERY_STATS, "get_battery_charge", method_get_battery_charge, 0);
343
348
  }
344
349
 
350
+ VALUE method_SMCKeySupported(VALUE self, VALUE key)
351
+ {
352
+ char *keyString = RSTRING_PTR(key);
353
+ SMCOpen();
354
+ double temp = SMCGetTemperature(keyString);
355
+ SMCClose();
356
+
357
+ return rb_float_new(temp);
358
+ }
359
+
360
+
345
361
  VALUE method_get_cpu_temp(VALUE self) {
346
362
  SMCOpen();
347
363
  double temp = SMCGetTemperature(SMC_KEY_CPU_TEMP);
@@ -103,6 +103,7 @@ CFDictionaryRef IOPSGetPowerSourceDescription(CFTypeRef blob, CFTypeRef ps);
103
103
 
104
104
  // Ruby modules
105
105
  void Init_osx_stats();
106
+ VALUE method_SMCKeySupported(VALUE self, VALUE key);
106
107
  VALUE method_get_cpu_temp(VALUE self);
107
108
  VALUE method_get_fan_speed(VALUE self, VALUE num);
108
109
  VALUE method_get_fan_number(VALUE self);
@@ -26,6 +26,7 @@ spec = Gem::Specification.new do |s|
26
26
  s.required_ruby_version = ">= 1.9.3"
27
27
 
28
28
  s.add_dependency "sparkr", "~> 0.4"
29
+ s.add_dependency "parseconfig", "~> 1.0"
29
30
 
30
31
  s.add_development_dependency "bundler", "~> 1.3"
31
32
  s.add_development_dependency "rake", "~> 1.8"
@@ -14,6 +14,9 @@ require 'iStats/command'
14
14
  require 'iStats/cpu'
15
15
  require 'iStats/fan'
16
16
  require 'iStats/battery'
17
+ require 'iStats/extra'
18
+ require 'iStats/smc'
19
+ require 'iStats/settings'
17
20
 
18
21
  module IStats
19
22
  def self.options
@@ -13,6 +13,7 @@ module IStats
13
13
  category = args.empty? ? 'all' : args.shift
14
14
  stat = args.empty? ? 'all' : args.shift
15
15
 
16
+ Settings.load;
16
17
  parse_options
17
18
  delegate(category, stat)
18
19
  end
@@ -32,6 +33,16 @@ module IStats
32
33
  Fan.delegate stat
33
34
  when 'battery'
34
35
  Battery.delegate stat
36
+ when 'extra'
37
+ Extra.delegate stat
38
+ when 'scan'
39
+ SMC.delegate stat
40
+ when 'enable'
41
+ Settings.delegate ['enable',stat]
42
+ when 'disable'
43
+ Settings.delegate ['disable',stat]
44
+ when 'list'
45
+ Settings.list
35
46
  else
36
47
  help("Unknown category: #{category}")
37
48
  end
@@ -46,6 +57,14 @@ module IStats
46
57
  Fan.all
47
58
  puts "\n--- Battery Stats ---\n"
48
59
  Battery.all
60
+
61
+ sensors = $config.params
62
+ if sensors.keys.any? {|key| sensors[key]['enabled'] == "1"}
63
+ puts "\n--- Extra Stats ---\n"
64
+ Extra.all
65
+ else
66
+ puts "\nFor more stats run `istats extra` and follow the instructions."
67
+ end
49
68
  end
50
69
 
51
70
  # Public: Parse extra options
@@ -96,6 +115,12 @@ module IStats
96
115
  istats battery [temp | temperature] Print battery temperature
97
116
  istats battery [charge] Print battery charge
98
117
  istats battery [capacity] Print battery capacity info
118
+
119
+ istats scan Scans and print temperatures
120
+ istats scan [key] Print single SMC temperature key
121
+ istats enable [key | all] Enables key
122
+ istats disable [key | all] Disable key
123
+ istats list List available keys
99
124
 
100
125
  for more help see: https://github.com/Chris911/iStats
101
126
  ".gsub(/^ {8}/, '') # strip the first eight spaces of every line
@@ -0,0 +1,61 @@
1
+ # Extra Stats
2
+ # Displays any extra sensors enabled in config
3
+ #
4
+ module IStats
5
+ class Extra
6
+ extend SMC_INFO
7
+ class << self
8
+
9
+ # Delegate CLI command to function
10
+ #
11
+ def delegate(stat)
12
+ if stat == 'all'
13
+ all
14
+ else
15
+ sensor_temperature stat
16
+ end
17
+ end
18
+
19
+ # Prints temperature for all enabled keys
20
+ #
21
+ def all
22
+ sensors = $config.params
23
+ display = sensors['AltDisplay']
24
+ if sensors.keys.any? {|key| sensors[key]['enabled'] == "1"}
25
+ sensors.keys.each{ |key|
26
+ if (sensors[key]['enabled'] == "1")
27
+ extra_enabled = true
28
+ display_temp(key, sensors[key], display)
29
+ end
30
+ }
31
+ else
32
+ puts "Looks like you don't have any extra keys enabled. \nRun `istats scan` for the initial scan or `istats --help` for more info."
33
+ end
34
+ end
35
+
36
+ # Prints temperature for specific key
37
+ #
38
+ def sensor_temperature(key)
39
+ sensors = $config.params
40
+ display = sensors['AltDisplay']
41
+ sensor = sensors[key]
42
+ if sensor.nil?
43
+ Command.help "Unknown sensor: #{stat}"
44
+ else
45
+ display_temp(key, sensor, display)
46
+ end
47
+ end
48
+
49
+ # Pretty print sensor tempaerature
50
+ def display_temp(key, sensor, display)
51
+ t = SMC.is_key_supported(key).round(2);
52
+ thresholds = sensor['thresholds'][1..-2].split(/, /).map { |s| s.to_i }
53
+ if (display)
54
+ puts "#{key} #{t}#{Symbols.degree}C \t" + Printer.gen_sparkline(t, thresholds) + " #{sensor['name']}"
55
+ else
56
+ puts "#{key} #{sensor['name']} temp: #{t}#{Symbols.degree}C " + Printer.gen_sparkline(t, thresholds)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,102 @@
1
+ module IStats
2
+ class Settings
3
+ require 'parseconfig'
4
+ @configFile = "sensors.conf"
5
+ @configDir = File.expand_path("~/.iStats") + "/"
6
+
7
+ class << self
8
+
9
+ def delegate(stat)
10
+ case stat[0]
11
+ when 'enable'
12
+ if (stat[1] == 'all')
13
+ toggleAll("1")
14
+ else
15
+ set(stat[1], "1")
16
+ end
17
+ when 'disable'
18
+ if (stat[1] == 'all')
19
+ toggleAll("0")
20
+ else
21
+ set(stat[1], "0")
22
+ end
23
+ else
24
+ puts "Unknown command"
25
+ end
26
+ end
27
+
28
+ def load
29
+ if File.exists?(@configDir + @configFile)
30
+ $config = ParseConfig.new(@configDir + @configFile)
31
+ else
32
+ $config = ParseConfig.new
33
+ end
34
+ end
35
+
36
+ def configFileExists
37
+ if File.exists?(@configDir + @configFile)
38
+ $config = ParseConfig.new(@configDir + @configFile)
39
+ else
40
+ puts "No config file #{@configDir}#{@configFile} found .. Run scan"
41
+ if !File.exists?(@configDir)
42
+ Dir.mkdir( @configDir)
43
+ end
44
+ file=File.open(@configDir + @configFile,"w+")
45
+ file.close
46
+ end
47
+ end
48
+
49
+ def addSensor(key,sensors)
50
+ settings = ParseConfig.new(@configDir + @configFile)
51
+ settings.add(key,sensors)
52
+ file = File.open(@configDir + @configFile,'w')
53
+ settings.write(file)
54
+ file.close
55
+ end
56
+
57
+ def set(key,value)
58
+ configFileExists
59
+ settings = ParseConfig.new(@configDir + @configFile)
60
+ sensors =settings.params
61
+ if (sensors[key])
62
+ sensors[key]['enabled'] = value
63
+ else
64
+ puts "Not valid key"
65
+ end
66
+ file = File.open(@configDir + @configFile,'w')
67
+ settings.write(file)
68
+ file.close
69
+ end
70
+
71
+ def toggleAll(value)
72
+ if File.exists?(@configDir + @configFile)
73
+ settings = ParseConfig.new(@configDir + @configFile)
74
+ settings.params.keys.each{ |key|
75
+ if (settings.params[key]['enabled'])
76
+ settings.params[key]['enabled'] = value
77
+ end
78
+ }
79
+ file = File.open(@configDir + @configFile,'w')
80
+ settings.write(file)
81
+ file.close
82
+ else
83
+ puts "Run 'istats scan' first"
84
+ end
85
+ end
86
+
87
+ def list
88
+ if File.exists?(@configDir + @configFile)
89
+ settings = ParseConfig.new(@configDir + @configFile)
90
+ settings.params.keys.each{ |key|
91
+ if (settings[key]['enabled'])
92
+ puts key + " => " + SMC.name(key) + " Enabled = " + settings[key]['enabled']
93
+ end
94
+ }
95
+ else
96
+ puts "Run 'istats scan' first"
97
+ end
98
+ end
99
+
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,130 @@
1
+ # SMC
2
+ # Extend CPU_STATS C module (ext/osx_stats/smc.c)
3
+ #
4
+ module IStats
5
+ class SMC
6
+ extend SMC_INFO
7
+ class << self
8
+ # Delegate CLI command to function
9
+ #
10
+ def delegate(stat)
11
+ case stat
12
+ when 'all'
13
+ all
14
+ else
15
+ scan_supported_key(stat)
16
+ end
17
+ end
18
+
19
+ # Call all functions (stats)
20
+ #
21
+ def all
22
+ scan_supported_keys
23
+ end
24
+
25
+ def name(key)
26
+ sensors_name = {
27
+ 'TA0P' => 'Ambient temperature',
28
+ 'TA0p' => 'Ambient temperature',
29
+ 'TA1P' => 'Ambient temperature',
30
+ 'TA1p' => 'Ambient temperature',
31
+ 'TA0S' => 'PCI Slot 1 Pos 1',
32
+ 'TA1S' => 'PCI Slot 1 Pos 2',
33
+ 'TA2S' => 'PCI Slot 2 Pos 1',
34
+ 'TA3S' => 'PCI Slot 2 Pos 2',
35
+ 'Tb0P' => 'BLC Proximity',
36
+ 'TB0T' => 'Battery TS_MAX',
37
+ 'TB1T' => 'Battery 1',
38
+ 'TB2T' => 'Battery 2',
39
+ 'TB3T' => 'Battery 3',
40
+ 'TC0C' => 'CPU 0 Core',
41
+ 'TC0D' => 'CPU 0 Die',
42
+ 'TCXC' => 'PECI CPU',
43
+ 'TCXc' => 'PECI CPU',
44
+ 'TC0E' => 'CPU 0 ??',
45
+ 'TC0F' => 'CPU 0 ??',
46
+ 'TC0G' => 'CPU 0 ??',
47
+ 'TC0H' => 'CPU 0 Heatsink',
48
+ 'TC0J' => 'CPU 0 ??',
49
+ 'TC0P' => 'CPU 0 Proximity',
50
+ 'TC0c' => '',
51
+ 'TC0d' => '',
52
+ 'TC0p' => '',
53
+ 'TC1C' => 'Core 1',
54
+ 'TC1c' => '',
55
+ 'TC2C' => 'Core 2',
56
+ 'TC2c' => '',
57
+ 'TC3C' => 'Core 3',
58
+ 'TC3c' => '',
59
+ 'TC4C' => 'Core 4',
60
+ 'TC5C' => 'Core 5',
61
+ 'TC6C' => 'Core 6',
62
+ 'TC7C' => 'Core 7',
63
+ 'TC8C' => 'Core 8',
64
+ 'TCGC' => 'PECI GPU',
65
+ 'TCGc' => 'PECI GPU',
66
+ 'TCPG' => '',
67
+ 'TCSC' => 'PECI SA',
68
+ 'TCSc' => 'PECI SA',
69
+ 'TCSA' => 'PECI SA',
70
+ 'TG0H' => 'GPU 0 Heatsink',
71
+ 'TG0P' => 'GPU 0 Proximity',
72
+ 'TG0D' => 'GPU 0 Die',
73
+ 'TG1D' => 'GPU 1 Die',
74
+ 'TG1H' => 'GPU 1 Heatsink',
75
+ 'TH0P' => 'Harddisk 0 Proximity',
76
+ 'Th1H' => 'NB/CPU/GPU HeatPipe 1 Proximity',
77
+ 'TL0P' => 'LCD Proximity',
78
+ 'TM0P' => 'Memory Slot Proximity',
79
+ 'TM0S' => 'Memory Slot 1',
80
+ 'Tm0p' => 'Misc (clock chip) Proximity',
81
+ 'TO0P' => 'Optical Drive Proximity',
82
+ 'Tp0P' => 'PowerSupply Proximity',
83
+ 'TS0C' => 'Expansion slots',
84
+ 'Ts0P' => 'Palm rest L',
85
+ 'Ts0S' => 'Memory Bank Proximity',
86
+ 'Ts1p' => 'Palm rest R',
87
+ 'TW0P' => 'AirPort Proximity'
88
+ }
89
+
90
+ return sensors_name.fetch(key,"Unknown")
91
+
92
+ end
93
+ # Print temperature with sparkline
94
+ #
95
+ def scan_supported_keys
96
+ sensors = Hash.new
97
+ Settings.configFileExists
98
+
99
+ puts "Scanning keys...\n\n"
100
+
101
+ characters = [('a'..'z'), ('A'..'Z'),(0..9)].map { |i| i.to_a }.flatten
102
+ characters.each {|l1|
103
+ characters.each {|l2|
104
+ characters.each {|l3|
105
+ key = "T#{l1}#{l2}#{l3}"
106
+ t = is_key_supported(key);
107
+ if (t != 0.0)
108
+ sensors['thresholds'] = [50, 68, 80, 90]
109
+ sensors['name'] = name(key)
110
+ sensors['enabled'] = 0
111
+
112
+ Settings.addSensor(key, sensors)
113
+
114
+ puts "#{key} #{sensors['name']} #{t}#{Symbols.degree}C " + Printer.gen_sparkline(t, sensors['thresholds'])
115
+ end
116
+ }
117
+ }
118
+ }
119
+ puts "\nDone scanning keys.\n"
120
+ puts "All keys are disabled by default. Use `istats set [key]` to enable specific keys or `istats enable all`."
121
+ puts "The enabled sensors will show up when running `istats` or `istats extra`."
122
+ end
123
+
124
+ def scan_supported_key(key)
125
+ t = is_key_supported(key)
126
+ puts " Scanned #{key} result = #{t}";
127
+ end
128
+ end
129
+ end
130
+ end
@@ -1,3 +1,3 @@
1
1
  module IStats
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iStats
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris911
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-29 00:00:00.000000000 Z
11
+ date: 2015-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sparkr
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: parseconfig
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -91,8 +105,11 @@ files:
91
105
  - lib/iStats/color.rb
92
106
  - lib/iStats/command.rb
93
107
  - lib/iStats/cpu.rb
108
+ - lib/iStats/extra.rb
94
109
  - lib/iStats/fan.rb
95
110
  - lib/iStats/printer.rb
111
+ - lib/iStats/settings.rb
112
+ - lib/iStats/smc.rb
96
113
  - lib/iStats/symbols.rb
97
114
  - lib/iStats/version.rb
98
115
  homepage: https://github.com/Chris911/iStats