Warning, file /plasma/libksysguard/systemstats/SensorsFeatureSensor.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * SPDX-FileCopyrightText: 2021 David Redondo <kde@david-redondo.de>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #include "SensorsFeatureSensor.h"
0008 
0009 #include "SensorObject.h"
0010 
0011 #include <KLocalizedString>
0012 
0013 #include <QRegularExpression>
0014 
0015 #include <sensors/sensors.h>
0016 
0017 static QString prettyName(const sensors_chip_name *const chipName, const sensors_feature *const feature)
0018 {
0019     std::unique_ptr<char, decltype(&free)> label(sensors_get_label(chipName, feature), &free);
0020     const QString labelString = QString::fromUtf8(label.get());
0021     switch (feature->type) {
0022     case SENSORS_FEATURE_IN: {
0023         static QRegularExpression inRegex(QStringLiteral("in(\\d+)"));
0024         auto inMatch = inRegex.match(labelString);
0025         if (inMatch.hasMatch()) {
0026             return i18nc("@title %1 is a number", "Voltage %1", inMatch.captured(1));
0027         }
0028         break;
0029     }
0030     case SENSORS_FEATURE_FAN: {
0031         static QRegularExpression fanRegex(QStringLiteral("fan(\\d+)"));
0032         auto fanMatch = fanRegex.match(labelString);
0033         if (fanMatch.hasMatch()) {
0034             return i18nc("@title %1 is a number", "Fan %1", fanMatch.captured(1));
0035         }
0036         break;
0037     }
0038     case SENSORS_FEATURE_TEMP: {
0039         static QRegularExpression tempRegex(QStringLiteral("temp(\\d+)"));
0040         auto tempMatch = tempRegex.match(labelString);
0041         if (tempMatch.hasMatch()) {
0042             return i18nc("@title %1 is a number", "Temperature %1", tempMatch.captured(1));
0043         }
0044         break;
0045     }
0046     default:
0047         break;
0048     }
0049     return labelString;
0050 }
0051 
0052 namespace KSysGuard
0053 {
0054 SensorsFeatureSensor *
0055 makeSensorsFeatureSensor(const QString &id, const sensors_chip_name *const chipName, const sensors_feature *const feature, SensorObject *parent)
0056 {
0057     if (parent->sensor(id)) {
0058         return nullptr;
0059     }
0060 
0061     const sensors_subfeature *valueFeature = nullptr;
0062     double minimum = 0;
0063     double maximum = 0;
0064     Unit unit;
0065 
0066     auto getValueOfFirstExisting = [chipName, feature](std::initializer_list<sensors_subfeature_type> subfeatureTypes) {
0067         double value;
0068         for (auto subfeatureType : subfeatureTypes) {
0069             const sensors_subfeature *const subfeature = sensors_get_subfeature(chipName, feature, subfeatureType);
0070             if (subfeature && sensors_get_value(chipName, subfeature->number, &value) == 0) {
0071                 return value;
0072             }
0073         }
0074         return 0.0;
0075     };
0076 
0077     switch (feature->type) {
0078     case SENSORS_FEATURE_IN:
0079         valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_IN_INPUT);
0080         unit = UnitVolt;
0081         minimum = getValueOfFirstExisting({SENSORS_SUBFEATURE_IN_LCRIT, SENSORS_SUBFEATURE_IN_MIN});
0082         maximum = getValueOfFirstExisting({SENSORS_SUBFEATURE_IN_CRIT, SENSORS_SUBFEATURE_IN_MAX});
0083         break;
0084     case SENSORS_FEATURE_FAN:
0085         valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_FAN_INPUT);
0086         unit = UnitRpm;
0087         minimum = getValueOfFirstExisting({SENSORS_SUBFEATURE_FAN_MIN});
0088         maximum = getValueOfFirstExisting({SENSORS_SUBFEATURE_FAN_MAX});
0089         break;
0090     case SENSORS_FEATURE_TEMP:
0091         valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
0092         unit = UnitCelsius;
0093         minimum = getValueOfFirstExisting({SENSORS_SUBFEATURE_TEMP_LCRIT, SENSORS_SUBFEATURE_TEMP_MIN});
0094         maximum = getValueOfFirstExisting({SENSORS_SUBFEATURE_TEMP_EMERGENCY, SENSORS_SUBFEATURE_TEMP_CRIT, SENSORS_SUBFEATURE_TEMP_MAX});
0095         break;
0096     case SENSORS_FEATURE_POWER:
0097         valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_POWER_INPUT);
0098         if (!valueFeature) {
0099             valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_POWER_AVERAGE);
0100         }
0101         unit = UnitWatt;
0102         maximum = getValueOfFirstExisting({SENSORS_SUBFEATURE_POWER_CRIT, SENSORS_SUBFEATURE_POWER_MAX});
0103         break;
0104     case SENSORS_FEATURE_ENERGY:
0105         valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_ENERGY_INPUT);
0106         unit = UnitWattHour;
0107         break;
0108     case SENSORS_FEATURE_CURR:
0109         valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_CURR_INPUT);
0110         unit = UnitAmpere;
0111         minimum = getValueOfFirstExisting({SENSORS_SUBFEATURE_CURR_LCRIT, SENSORS_SUBFEATURE_CURR_MIN});
0112         maximum = getValueOfFirstExisting({SENSORS_SUBFEATURE_CURR_CRIT, SENSORS_SUBFEATURE_CURR_MAX});
0113         break;
0114     case SENSORS_FEATURE_HUMIDITY:
0115         valueFeature = sensors_get_subfeature(chipName, feature, SENSORS_SUBFEATURE_HUMIDITY_INPUT);
0116         unit = UnitPercent;
0117         break;
0118     default:
0119         return nullptr;
0120     }
0121 
0122     if (!valueFeature) {
0123         return nullptr;
0124     }
0125 
0126     auto sensor = new SensorsFeatureSensor(id, chipName, valueFeature, parent);
0127     sensor->setName(prettyName(chipName, feature));
0128     sensor->setUnit(unit);
0129     sensor->setMax(maximum);
0130     sensor->setMin(minimum);
0131 
0132     return sensor;
0133 }
0134 
0135 SensorsFeatureSensor::SensorsFeatureSensor(const QString &id,
0136                                            const sensors_chip_name *const chipName,
0137                                            const sensors_subfeature *const valueFeature,
0138                                            SensorObject *parent)
0139     : SensorProperty(id, id, 0, parent)
0140     , m_chipName(chipName)
0141     , m_valueFeature(valueFeature)
0142 {
0143 }
0144 
0145 void SensorsFeatureSensor::update()
0146 {
0147     if (!isSubscribed()) {
0148         return;
0149     }
0150 
0151     double value;
0152     if (sensors_get_value(m_chipName, m_valueFeature->number, &value) < 0) {
0153         setValue(QVariant());
0154     }
0155     setValue(value);
0156 }
0157 }