add utility for Bumblebee & NVIDIA, #5

This commit is contained in:
UshakovVasilii
2015-04-11 03:46:57 +03:00
parent d5777b70d8
commit 27ea44ed56
4 changed files with 132 additions and 10 deletions

View File

@@ -0,0 +1,95 @@
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const CommandLineUtil = Me.imports.commandLineUtil;
const BumblebeeNvidiaUtil = new Lang.Class({
Name: 'BumblebeeNvidiaUtil',
Extends: CommandLineUtil.CommandLineUtil,
_init: function() {
this.parent();
// optirun nvidia-smi -q -d TEMPERATURE
this._path = GLib.find_program_in_path('optirun');
this._argv = this._path ? [this._path, 'nvidia-smi', '-q', '-d', 'TEMPERATURE'] : null;
// original source here:
// https://github.com/meden/gse-bumblebee-indicator
// thank meden!
let virtualDisplay = ':8';
let configFile = Gio.File.new_for_path('/etc/bumblebee/bumblebee.conf');
let contents = configFile.load_contents(null);
if (contents[0]) {
let pattern = /^VirtualDisplay=.*$/m
let match = new String(pattern.exec(new String(contents)));
virtualDisplay = match.substr(16);
}
let lockFile = '/tmp/.X' + virtualDisplay + '-lock';
this._lockMonitor = Gio.File.new_for_path(
lockFile).monitor_file(Gio.FileMonitorFlags.NONE, null
);
this._lockMonitor.id = this._lockMonitor.connect(
'changed', Lang.bind(this, this._statusChanged)
);
},
_detectLabel: function() {
// optirun nvidia-smi -L
// GPU 0: GeForce GT 525M (UUID: GPU-...)
for each(let line in GLib.spawn_command_line_sync(this._path + " nvidia-smi -L")){
let match = /.*GPU [\d]:([\w\d\ ]+).*/.exec(line);
if(match){
this._label = match[1];
if(this._label)
this._label = this._label.trim();
break;
}
}
},
_statusChanged: function(monitor, a_file, other_file, event_type) {
if (event_type == Gio.FileMonitorEvent.CREATED) {
if(this._argv && !this._label)
this._detectLabel();
this._active = true;
} else if (event_type == Gio.FileMonitorEvent.DELETED) {
this._active = false;
}
},
execute: function(callback) {
if(this._active)
this.parent(callback);
else
this._output = [];
},
get temp() {
let key = 'bumblebee-nvidia'
let label = this._label ? this._label : _('Bumblebee + NVIDIA');
if(!this._active || !this._output)
return [{label: key, temp: null, displayName: label}];
// GPU Current Temp : 37 C
for each(let line in this._output) {
if(!line)
continue;
let r;
if(line.indexOf('GPU Current Temp') > 0)
return [{
label: key,
temp: (r = /[\s]*GPU Current Temp[\s]*:[\s]*(\d{1,3}).*/.exec(line)) ? parseFloat(r[1]) : null,
displayName: label
}];
}
return [];
},
destroy: function(){
this.parent();
this._lockMonitor.disconnect(this._lockMonitor.id);
}
});

View File

@@ -15,6 +15,7 @@ const AticonfigUtil = Me.imports.aticonfigUtil;
const NvidiaUtil = Me.imports.nvidiaUtil;
const HddtempUtil = Me.imports.hddtempUtil;
const SensorsUtil = Me.imports.sensorsUtil;
const BumblebeeNvidiaUtil = Me.imports.bumblebeeNvidiaUtil;
const FreonItem = Me.imports.freonItem;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
@@ -177,6 +178,9 @@ const FreonMenuButton = new Lang.Class({
case 'aticonfig':
this._utils.gpu = new AticonfigUtil.AticonfigUtil();
break;
case 'bumblebee-nvidia-smi':
this._utils.gpu = new BumblebeeNvidiaUtil.BumblebeeNvidiaUtil();
break;
}
},
@@ -212,6 +216,7 @@ const FreonMenuButton = new Lang.Class({
_onDestroy: function(){
this._destroyDriveUtility();
this._destroyGpuUtility();
Mainloop.source_remove(this._timeoutId);
for each (let signal in this._settingChangedSignals){
@@ -257,18 +262,26 @@ const FreonMenuButton = new Lang.Class({
let tempInfo = gpuTempInfo.concat(sensorsTempInfo).concat(driveTempInfo);
if (tempInfo.length > 0){
let total = 0;
let sum = 0;
let max = 0;
for each (let i in tempInfo){
sum += i.temp;
if (i.temp > max)
max = i.temp;
if(i.temp !== 'N/A'){
total++;
sum += i.temp;
if (i.temp > max)
max = i.temp;
}
}
let sensors = [];
for each (let i in gpuTempInfo){
sensors.push({type:'gpu-temperature', label: i.label, value:this._formatTemp(i.temp)});
sensors.push({
type: 'gpu-temperature',
label: i.label,
value: this._formatTemp(i.temp),
displayName: i.displayName});
}
for each (let i in sensorsTempInfo){
sensors.push({type:'temperature', label: i.label, value:this._formatTemp(i.temp)});
@@ -281,7 +294,7 @@ const FreonMenuButton = new Lang.Class({
sensors.push({type : 'separator'});
// Add average and maximum entries
sensors.push({type:'temperature-average', label:_("Average"), value:this._formatTemp(sum/tempInfo.length)});
sensors.push({type:'temperature-average', label:_("Average"), value:this._formatTemp(sum/total)});
sensors.push({type:'temperature-maximum', label:_("Maximum"), value:this._formatTemp(max)});
if(fanInfo.length > 0 || voltageInfo.length > 0)
@@ -330,8 +343,11 @@ const FreonMenuButton = new Lang.Class({
if(item) {
if(s.type == 'temperature-group')
item.status.text = s.value;
else
else {
item.value = s.value;
if(s.displayName)
item.display_name = s.displayName;
}
} else {
this._needRerender = true;
}
@@ -399,7 +415,7 @@ const FreonMenuButton = new Lang.Class({
this._sensorMenuItems['temperature-group'] = temperatureGroup;
}
} else {
let item = new FreonItem.FreonItem(this._sensorIcons[s.type], s.label, s.value);
let item = new FreonItem.FreonItem(this._sensorIcons[s.type], s.label, s.value, s.displayName);
item.connect('activate', Lang.bind(this, function (self) {
let l = this._hotLabels[self.label];
let hotSensors = this._settings.get_strv('hot-sensors');
@@ -489,6 +505,8 @@ const FreonMenuButton = new Lang.Class({
},
_formatTemp: function(value) {
if(value === null)
return 'N/A';
if (this._settings.get_string('unit')=='fahrenheit'){
value = this._toFahrenheit(value);
}

View File

@@ -6,14 +6,15 @@ const FreonItem = new Lang.Class({
Name: 'FreonItem',
Extends: PopupMenu.PopupBaseMenuItem,
_init: function(gIcon, label, value) {
_init: function(gIcon, label, value, displayName) {
this.parent();
this._main = false;
this._label = label;
this._gIcon = gIcon;
this._labelActor = new St.Label({text: displayName ? displayName : label});
this.actor.add(new St.Icon({ style_class: 'popup-menu-icon', gicon : gIcon}));
this.actor.add(new St.Label({text: label}), {x_fill: true, expand: true});
this.actor.add(this._labelActor, {x_fill: true, expand: true});
this._valueLabel = new St.Label({text: value});
this.actor.add(this._valueLabel);
},
@@ -34,6 +35,10 @@ const FreonItem = new Lang.Class({
return this._label;
},
set display_name(text) {
return this._labelActor.text = text;
},
get gicon() {
return this._gIcon;
},

View File

@@ -75,7 +75,11 @@ const FreonPrefsWidget = new GObject.Class({
});
this._addComboBox({
items : {none : 'None', 'nvidia-settings' : 'Nvidia', aticonfig : 'Catalyst'},
items : {
'none' : _('None'),
'nvidia-settings' : _('NVIDIA'),
'aticonfig' : _('Catalyst'),
'bumblebee-nvidia-smi': _('Bumblebee + NVIDIA') },
key: 'gpu-utility', y : i, x : 2,
label: _('Video Card Temperature Utility')
});