diff --git a/freon@UshakovVasilii_Github.yahoo.com/extension.js b/freon@UshakovVasilii_Github.yahoo.com/extension.js index 7f8e347..8b52dd9 100644 --- a/freon@UshakovVasilii_Github.yahoo.com/extension.js +++ b/freon@UshakovVasilii_Github.yahoo.com/extension.js @@ -20,6 +20,7 @@ const liquidctlUtil = Me.imports.liquidctlUtil; const smartctlUtil = Me.imports.smartctlUtil; const nvmecliUtil = Me.imports.nvmecliUtil; const BumblebeeNvidiaUtil = Me.imports.bumblebeeNvidiaUtil; +const FreeipmiUtil = Me.imports.freeipmiUtil; const FreonItem = Me.imports.freonItem; const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); @@ -67,8 +68,10 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend this._utils = { sensors: new SensorsUtil.SensorsUtil() }; + this._initDriveUtility(); this._initGpuUtility(); + this._initIpmiUtility(); this._initLiquidctlUtility(); let temperatureIcon = Gio.icon_new_for_string(Me.path + '/icons/material-icons/material-temperature-symbolic.svg'); @@ -108,6 +111,8 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend this._addSettingChangedSignal('show-voltage', this._querySensors.bind(this)); this._addSettingChangedSignal('drive-utility', this._driveUtilityChanged.bind(this)); this._addSettingChangedSignal('gpu-utility', this._gpuUtilityChanged.bind(this)); + this._addSettingChangedSignal('ipmi-utility', this._ipmiUtilityChanged.bind(this)); + this._addSettingChangedSignal('method-ipmi-utility', this._ipmiUtilityChanged.bind(this)); this._addSettingChangedSignal('show-liquidctl', this._liquidctlUtilityChanged.bind(this)); this._addSettingChangedSignal('position-in-panel', this._positionInPanelChanged.bind(this)); this._addSettingChangedSignal('panel-box-index', this._positionInPanelChanged.bind(this)); @@ -250,6 +255,27 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend this._querySensors(); } + _initIpmiUtility(){ + switch(this._settings.get_string('ipmi-utility')){ + case 'freeipmi': + this._utils.ipmi = new FreeipmiUtil.FreeipmiUtil(); + break; + } + } + + _destroyIpmiUtility(){ + if(this._utils.ipmi){ + this._utils.ipmi.destroy(); + delete this._utils.ipmi; + } + } + + _ipmiUtilityChanged(){ + this._destroyIpmiUtility(); + this._initIpmiUtility(); + this._querySensors(); + } + _initLiquidctlUtility() { if (this._settings.get_boolean('show-liquidctl')) this._utils.liquidctl = new liquidctlUtil.LiquidctlUtil(); @@ -288,6 +314,7 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend _onButtonDestroy(){ this._destroyDriveUtility(); this._destroyGpuUtility(); + this._destroyIpmiUtility(); this._destroyLiquidctlUtility(); Mainloop.source_remove(this._timeoutId); Mainloop.source_remove(this._updateUITimeoutId); @@ -343,13 +370,12 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend } _updateDisplay(){ - let gpuTempInfo = this._utils.sensors.gpu; + let sensorsTempInfo = this._utils.sensors.temp; + let gpuTempInfo = this._utils.sensors.gpu; if (this._utils.gpu && this._utils.gpu.available) gpuTempInfo = gpuTempInfo.concat(this._utils.gpu.temp); - let sensorsTempInfo = this._utils.sensors.temp; - let fanInfo = []; if (this._settings.get_boolean('show-fan-rpm')) fanInfo = this._utils.sensors.rpm; @@ -363,6 +389,14 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend driveTempInfo = driveTempInfo.concat(this._utils.disks.temp); } + if (this._utils.ipmi && this._utils.ipmi.available) { + sensorsTempInfo = sensorsTempInfo.concat(this._utils.ipmi.temp); + if (this._settings.get_boolean('show-fan-rpm')) + fanInfo = fanInfo.concat(this._utils.ipmi.rpm); + if (this._settings.get_boolean('show-voltage')) + voltageInfo = voltageInfo.concat(this._utils.ipmi.volt); + } + if (this._utils.liquidctl && this._utils.liquidctl.available) { sensorsTempInfo = sensorsTempInfo.concat(this._utils.liquidctl.temp); if (this._settings.get_boolean('show-fan-rpm')) diff --git a/freon@UshakovVasilii_Github.yahoo.com/freeipmiUtil.js b/freon@UshakovVasilii_Github.yahoo.com/freeipmiUtil.js new file mode 100644 index 0000000..7b9c6f0 --- /dev/null +++ b/freon@UshakovVasilii_Github.yahoo.com/freeipmiUtil.js @@ -0,0 +1,100 @@ +const GLib = imports.gi.GLib; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const CommandLineUtil = Me.imports.commandLineUtil; + +var FreeipmiUtil = class extends CommandLineUtil.CommandLineUtil { + constructor() { + super(); + + const path = GLib.find_program_in_path('ipmi-sensors'); + // --comma-separated-output: pseudo csv output format, splitting on comma may be good enough for the values we read. + this._argv = path ? [path, '--comma-separated-output'] : null; + + if (this._argv) { + const ExtensionUtils = imports.misc.extensionUtils; + const Me = ExtensionUtils.getCurrentExtension(); + if (ExtensionUtils.getSettings().get_string('method-ipmi-utility') === 'sudo') + { + const sudo_path = GLib.find_program_in_path('sudo'); + // --non-interactive: do not ask for password, return if no permission. + this._argv = sudo_path ? [sudo_path, '--non-interactive'].concat(this._argv) : null; + } + } + } + + // Avoid parsing the data more than once. + execute(callback) { + super.execute(() => { + let data = []; + + for (const line of this._output) { + if (!line) + continue; + + const value_list = line.split(','); + + if (value_list.length <= 1) + break; + + const id = value_list[0]; + + if (id === 'ID') + continue; + + const name = value_list[1]; + const value = value_list[3]; + const unit = value_list[4]; + + if (value !== 'N/A' && unit !== 'N/A') { + data[name] = {}; + data[name]["value"] = value; + data[name]["unit"] = unit; + } + } + + this._data = data; + callback(); + }); + } + + get temp() { + return this._parseSensorsOutput(/^(C|C per minute)$/, 'temp'); + } + + get rpm() { + return this._parseSensorsOutput(/^RPM$/, 'rpm'); + } + + get volt() { + return this._parseSensorsOutput(/^V$/, 'volt'); + } + + _parseSensorsOutput(sensorFilter, sensorType) { + if(!this._data) + return []; + + const data = this._data; + + let sensors = []; + for (const name in data) { + if (!data.hasOwnProperty(name)) + continue; + + const value = data[name]["value"] + const unit = data[name]["unit"] + + if (!sensorFilter.test(unit)) + continue; + + const feature = { + label: name, + [sensorType]: parseFloat(value) + }; + + sensors.push(feature); + } + + return sensors; + } +}; diff --git a/freon@UshakovVasilii_Github.yahoo.com/prefs.js b/freon@UshakovVasilii_Github.yahoo.com/prefs.js index 8e63e0e..47b5aa3 100644 --- a/freon@UshakovVasilii_Github.yahoo.com/prefs.js +++ b/freon@UshakovVasilii_Github.yahoo.com/prefs.js @@ -88,9 +88,26 @@ var FreonPrefsWidget = new GObject.registerClass(class Freon_FreonPrefsWidget ex label: _('Video Card Temperature Utility') }); + this._addComboBox({ + items : { + 'none' : _('None'), + 'freeipmi' : _('FreeIPMI') }, + key: 'ipmi-utility', y : i, x : 0, + label: _('IPMI Sensors Utility') + }); + + this._addComboBox({ + items : { + 'direct' : 'Direct', + 'sudo' : 'sudo' }, + key: 'method-ipmi-utility', y : i, x : 1, + label: '' + }); + this._addSwitch({key : 'show-liquidctl', y : i++, x : 3, label : _('Show liquidctl Sensors'), help : _('Show data from liquidctl v1.7.0 or later')}); + } _addSwitch(params){ diff --git a/freon@UshakovVasilii_Github.yahoo.com/schemas/org.gnome.shell.extensions.sensors.gschema.xml b/freon@UshakovVasilii_Github.yahoo.com/schemas/org.gnome.shell.extensions.sensors.gschema.xml index 3b8d146..09bc886 100644 --- a/freon@UshakovVasilii_Github.yahoo.com/schemas/org.gnome.shell.extensions.sensors.gschema.xml +++ b/freon@UshakovVasilii_Github.yahoo.com/schemas/org.gnome.shell.extensions.sensors.gschema.xml @@ -63,6 +63,18 @@ Utility for detect video card temperature ('none', 'nvidia-settings' or 'aticonfig') + + 'none' + Utility for reading IPMI sensors + Utility reading IPMI sensors ('none', 'freeipmi') + + + + 'direct' + Method to run IPMI utility + Method to run IPMI utility + + false Show liquidctl sensors