liquidctlUtil: add support for sensors from liquidctl (#202)

Requires liquidctl v1.7.0 or later, or a current git snapshot.
This commit is contained in:
Jonas Malaco
2021-07-20 07:01:50 -03:00
committed by GitHub
parent a3eb96ff7c
commit 1730654c55
4 changed files with 129 additions and 1 deletions

View File

@@ -16,6 +16,7 @@ const AticonfigUtil = Me.imports.aticonfigUtil;
const NvidiaUtil = Me.imports.nvidiaUtil;
const HddtempUtil = Me.imports.hddtempUtil;
const SensorsUtil = Me.imports.sensorsUtil;
const liquidctlUtil = Me.imports.liquidctlUtil;
const smartctlUtil = Me.imports.smartctlUtil;
const nvmecliUtil = Me.imports.nvmecliUtil;
const BumblebeeNvidiaUtil = Me.imports.bumblebeeNvidiaUtil;
@@ -68,6 +69,7 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend
};
this._initDriveUtility();
this._initGpuUtility();
this._initLiquidctlUtility();
let temperatureIcon = Gio.icon_new_for_string(Me.path + '/icons/material-icons/material-temperature-symbolic.svg');
this._sensorIcons = {
@@ -106,6 +108,7 @@ 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('show-liquidctl', this._liquidctlUtilityChanged.bind(this));
this._addSettingChangedSignal('position-in-panel', this._positionInPanelChanged.bind(this));
this._addSettingChangedSignal('panel-box-index', this._positionInPanelChanged.bind(this));
this._addSettingChangedSignal('group-temperature', this._querySensors.bind(this))
@@ -247,6 +250,24 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend
this._querySensors();
}
_initLiquidctlUtility() {
if (this._settings.get_boolean('show-liquidctl'))
this._utils.liquidctl = new liquidctlUtil.LiquidctlUtil();
}
_destroyLiquidctlUtility() {
if (this._utils.liquidctl) {
this._utils.liquidctl.destroy();
delete this._utils.liquidctl;
}
}
_liquidctlUtilityChanged() {
this._destroyLiquidctlUtility();
this._initLiquidctlUtility();
this._querySensors();
}
_updateTimeChanged(){
Mainloop.source_remove(this._timeoutId);
this._addTimer();
@@ -267,6 +288,7 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend
_onButtonDestroy(){
this._destroyDriveUtility();
this._destroyGpuUtility();
this._destroyLiquidctlUtility();
Mainloop.source_remove(this._timeoutId);
Mainloop.source_remove(this._updateUITimeoutId);
@@ -341,6 +363,12 @@ const FreonMenuButton = GObject.registerClass(class Freon_FreonMenuButton extend
driveTempInfo = this._utils.disks.temp;
}
if (this._utils.liquidctl && this._utils.liquidctl.available) {
sensorsTempInfo = sensorsTempInfo.concat(this._utils.liquidctl.temp);
fanInfo = fanInfo.concat(this._utils.liquidctl.rpm);
voltageInfo = voltageInfo.concat(this._utils.liquidctl.volt);
}
sensorsTempInfo.sort(function(a,b) { return a.label.localeCompare(b.label) });
driveTempInfo.sort(function(a,b) { return a.label.localeCompare(b.label) });
fanInfo.sort(function(a,b) { return a.label.localeCompare(b.label) });

View File

@@ -0,0 +1,90 @@
// Provide sensor data from liquidctl.
const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const commandLineUtil = Me.imports.commandLineUtil;
var LiquidctlUtil = class extends commandLineUtil.CommandLineUtil {
constructor() {
super();
const path = GLib.find_program_in_path('liquidctl');
this._argv = path ? [path, 'status', '--json'] : null;
}
// Avoid processing the data more than once.
execute(callback) {
super.execute(() => {
try {
const output = this._output.join('');
if (output == '')
throw 'no data (liquidctl probably exited with an error)';
let temp = [];
let rpm = [];
let volt = [];
let dest = null;
let type = null;
for (const device of JSON.parse(output)) {
// use a shorter device name to reduce visual noise:
// - omit manufacturer name
// - omit details in parenthesis
const shortDevice = device.description.replace(/(^.+? )|( \(.+)/g, '');
for (const item of device.status) {
switch (item.unit) {
case '°C':
dest = temp;
type = 'temp';
break;
case 'rpm':
dest = rpm;
type = 'rpm';
break;
case 'V':
dest = volt;
type = 'volt';
break;
default:
continue;
}
// use a shorter sensor name to reduce visual noise:
// - omit temperature|speed|voltage suffix
const shortKey = item.key.replace(/ (temperature|speed|voltage)/, '');
const feature = {
label: shortDevice + ' ' + shortKey,
[type]: item.value,
};
dest.push(feature);
}
}
this._temp = temp;
this._rpm = rpm;
this._volt = volt;
callback();
} catch (e) {
this._temp = null;
this._rpm = null;
this._volt = null;
global.log('failed to process data from liquidctl: ' + e.toString());
}
});
}
get temp() {
return this._temp || [];
}
get rpm() {
return this._rpm || [];
}
get volt() {
return this._volt || [];
}
};

View File

@@ -84,9 +84,13 @@ var FreonPrefsWidget = new GObject.registerClass(class Freon_FreonPrefsWidget ex
'nvidia-settings' : _('NVIDIA'),
'aticonfig' : _('Catalyst'),
'bumblebee-nvidia-smi': _('Bumblebee + NVIDIA') },
key: 'gpu-utility', y : i, x : 3,
key: 'gpu-utility', y : i++, x : 3,
label: _('Video Card Temperature Utility')
});
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){

View File

@@ -63,6 +63,12 @@
<description>Utility for detect video card temperature ('none', 'nvidia-settings' or 'aticonfig')</description>
</key>
<key type="b" name="show-liquidctl">
<default>false</default>
<summary>Show liquidctl sensors</summary>
<description>Show data from liquidctl v1.7.0 or later</description>
</key>
<key type="s" name="position-in-panel">
<default>'right'</default>
<summary>Position in Panel</summary>