iStats 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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