Commit 679deb4b authored by Arjen Hiemstra's avatar Arjen Hiemstra
Browse files

Drop ksysguardd plugin

It should no longer be necessary
parent 499f1d5b
# SPDX-License-Identifier: BSD-2-Clause
# SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
# SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
set(KSYSGUARD_KSGRD_PLUGIN_SOURCES
ksgrdiface.cpp
)
add_library(ksysguard_ksgrd MODULE ${KSYSGUARD_KSGRD_PLUGIN_SOURCES})
target_link_libraries(ksysguard_ksgrd Qt::Core Qt::DBus KSysGuard::SystemStats KSysGuard::SysGuard KF5::CoreAddons KF5::I18n)
install(TARGETS ksysguard_ksgrd DESTINATION ${KDE_INSTALL_PLUGINDIR}/ksysguard)
/*
SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "ksgrdiface.h"
#include "AggregateSensor.h"
#include <KLocalizedString>
#include <KPluginFactory>
#include <ksgrd/SensorManager.h>
#include <QEventLoop>
// TODO instantiate multiple instances with args for which host to use
KSGRDIface::KSGRDIface(QObject *parent, const QVariantList &args)
: SensorPlugin(parent, args)
{
KSGRD::SensorMgr = new KSGRD::SensorManager(this);
auto registerSubsystem = [this](const QString &id) {
m_subsystems[id] = new SensorContainer(id, KSGRD::SensorMgr->translateSensorPath(id), this);
};
registerSubsystem("acpi");
registerSubsystem("lmsensors");
registerSubsystem("uptime");
registerSubsystem("system");
KSGRD::SensorMgr->engage(QStringLiteral("localhost"), QLatin1String(""), QStringLiteral("ksysguardd"));
connect(KSGRD::SensorMgr, &KSGRD::SensorManager::update, this, &KSGRDIface::updateMonitorsList);
updateMonitorsList();
// block for sensors to be loaded, but with a guard in case one fails to process
// a non issue when we port things to be in-process
QEventLoop e;
auto t = new QTimer(&e);
t->setInterval(2000);
t->start();
connect(t, &QTimer::timeout, &e, [&e, this]() {
e.quit();
});
connect(this, &KSGRDIface::sensorAdded, &e, [&e, this] {
if (m_sensors.count() == m_sensorIds.count()) {
e.quit();
}
});
e.exec();
}
KSGRDIface::~KSGRDIface()
{
}
void KSGRDIface::subscribe(const QString &sensorPath)
{
if (!m_subscribedSensors.contains(sensorPath)) {
m_subscribedSensors << sensorPath;
const int index = m_sensorIds.indexOf(sensorPath);
if (index != -1) {
m_waitingFor++;
KSGRD::SensorMgr->sendRequest(QStringLiteral("localhost"), sensorPath, (KSGRD::SensorClient *)this, index);
KSGRD::SensorMgr->sendRequest(QStringLiteral("localhost"), QStringLiteral("%1?").arg(sensorPath), (KSGRD::SensorClient *)this, -(index + 2));
}
}
}
void KSGRDIface::unsubscribe(const QString &sensorPath)
{
m_subscribedSensors.removeAll(sensorPath);
}
void KSGRDIface::updateMonitorsList()
{
m_sensorIds.clear();
KSGRD::SensorMgr->sendRequest(QStringLiteral("localhost"), QStringLiteral("monitors"), (KSGRD::SensorClient *)this, -1);
}
void KSGRDIface::onSensorMetaDataRetrieved(int id, const QList<QByteArray> &answer)
{
if (answer.isEmpty() || id > m_sensorIds.count()) {
qDebug() << "sensor info answer was empty, (" << answer.isEmpty() << ") or sensors does not exist to us ";
return;
}
const QStringList newSensorInfo = QString::fromUtf8(answer[0]).split('\t');
if (newSensorInfo.count() < 4) {
qDebug() << "bad sensor info, only" << newSensorInfo.count()
<< "entries, and we were expecting 4. Answer was " << answer;
return;
}
const QString key = m_sensorIds.value(id);
const QString &sensorName = newSensorInfo[0];
const QString &min = newSensorInfo[1];
const QString &max = newSensorInfo[2];
const QString &unit = newSensorInfo[3];
int subsystemIndex = key.indexOf('/');
int propertyIndex = key.lastIndexOf('/');
const QString subsystemId = key.left(subsystemIndex);
const QString objectId = key.mid(subsystemIndex + 1, propertyIndex - (subsystemIndex + 1));
const QString propertyId = key.mid(propertyIndex + 1);
auto subsystem = m_subsystems[subsystemId];
if (!subsystem) {
return;
}
auto sensorObject = subsystem->object(objectId);
if (!sensorObject) {
auto name = KSGRD::SensorMgr->translateSensorPath(objectId);
sensorObject = new SensorObject(objectId, name, subsystem);
}
auto sensor = m_sensors.value(key, nullptr);
if (!sensor) {
sensor = new SensorProperty(propertyId, sensorObject);
}
sensor->setName(sensorName);
sensor->setMin(min.toDouble());
sensor->setMax(max.toDouble());
sensor->setUnit(unitFromString(unit));
if (m_sensors.contains(key)) {
return;
}
auto type = m_pendingTypes.take(key);
if (type == QLatin1String("float")) {
sensor->setVariantType(QVariant::Double);
} else {
sensor->setVariantType(QVariant::Int);
}
connect(sensor, &SensorProperty::subscribedChanged, this, [this, sensor](bool subscribed) {
if (subscribed) {
subscribe(sensor->path());
} else {
unsubscribe(sensor->path());
}
});
m_sensors[key] = sensor;
emit sensorAdded();
}
void KSGRDIface::onSensorListRetrieved(const QList<QByteArray> &answer)
{
QSet<QString> sensors;
int count = 0;
// A list of data types not currently supported
static const QStringList excludedTypes = {
QStringLiteral("logfile"),
QStringLiteral("listview"),
QStringLiteral("table")
};
for (const QByteArray &sens : answer) {
const QString sensStr { QString::fromUtf8(sens) };
const QVector<QStringRef> newSensorInfo = sensStr.splitRef('\t');
if (newSensorInfo.count() < 2) {
continue;
}
auto type = newSensorInfo.at(1);
if (excludedTypes.contains(type)) {
continue;
}
const QString newSensor = newSensorInfo[0].toString();
sensors.insert(newSensor);
m_sensorIds.append(newSensor);
m_pendingTypes.insert(newSensor, type.toString());
//we don't emit sensorAdded yet, instead wait for the meta info to be fetched
KSGRD::SensorMgr->sendRequest(QStringLiteral("localhost"), QStringLiteral("%1?").arg(newSensor), (KSGRD::SensorClient *)this, -(count + 2));
++count;
}
// look for removed sensors
// FIXME?
foreach (const QString &sensor, m_sensorIds) {
if (!sensors.contains(sensor)) {
m_sensorIds.removeOne(sensor);
m_sensors.remove(sensor);
}
}
}
void KSGRDIface::onSensorUpdated(int id, const QList<QByteArray> &answer)
{
m_waitingFor--;
if (answer.isEmpty() || id > m_sensorIds.count()) {
return;
}
const QString sensorName = m_sensorIds.at(id);
if (sensorName.isEmpty()) {
return;
}
QString reply;
if (!answer.isEmpty()) {
reply = QString::fromUtf8(answer[0]);
}
auto sensor = m_sensors[sensorName];
if (sensor) {
if (sensor->info().variantType == QVariant::Double) {
bool rc;
double value = reply.toDouble(&rc);
if (rc) {
sensor->setValue(value);
}
} else if (sensor->info().variantType == QVariant::Int) {
bool rc;
int value = reply.toInt(&rc);
if (rc) {
sensor->setValue(value);
}
} else {
sensor->setValue(reply);
}
}
}
KSysGuard::Unit KSGRDIface::unitFromString(const QString &unitString) const
{
using namespace KSysGuard;
static const QHash<QString, Unit> map({ { "%", UnitPercent },
{ "1/s", UnitRate },
{ "°C", UnitCelsius },
{ "dBm", UnitDecibelMilliWatts },
{ "KB", UnitKiloByte },
{ "KB/s", UnitKiloByteRate },
{ "MHz", UnitMegaHertz },
{ "port", UnitNone },
{ "rpm", UnitRpm },
{ "s", UnitTime },
{ "V", UnitVolt } });
return map.value(unitString, UnitNone);
}
void KSGRDIface::update()
{
for (int i = 0; i < m_subscribedSensors.count(); i++) {
auto sensorName = m_subscribedSensors.at(i);
int index = m_sensorIds.indexOf(sensorName);
if (index < 0) {
return;
}
m_waitingFor++;
KSGRD::SensorMgr->sendRequest(QStringLiteral("localhost"), sensorName, (KSGRD::SensorClient *)this, index);
}
}
void KSGRDIface::sensorLost(int)
{
m_waitingFor--;
}
void KSGRDIface::answerReceived(int id, const QList<QByteArray> &answer)
{
//this is the response to "sensorName?"
if (id < -1) {
onSensorMetaDataRetrieved(-id - 2, answer);
return;
}
//response to "monitors"
if (id == -1) {
onSensorListRetrieved(answer);
return;
}
onSensorUpdated(id, answer);
}
K_PLUGIN_CLASS_WITH_JSON(KSGRDIface, "metadata.json")
#include "ksgrdiface.moc"
/*
SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#pragma once
#include "SensorContainer.h"
#include "SensorObject.h"
#include "SensorPlugin.h"
#include "SensorProperty.h"
#include <QTimer>
#include <ksgrd/SensorClient.h>
class AggregateSensor;
class KSGRDIface : public SensorPlugin, public KSGRD::SensorClient
{
Q_OBJECT
public:
KSGRDIface(QObject *parent, const QVariantList &args);
~KSGRDIface();
virtual QString providerName() const override
{
return QStringLiteral("ksgrd");
}
void update() override;
// From KSGRD::SensorClient
void sensorLost(int sensor) override;
void answerReceived(int id, const QList<QByteArray> &answer) override;
Q_SIGNALS:
void sensorAdded();
private:
void updateMonitorsList();
void onSensorMetaDataRetrieved(int id, const QList<QByteArray> &answer);
void onSensorListRetrieved(const QList<QByteArray> &answer);
void onSensorUpdated(int id, const QList<QByteArray> &answer);
void subscribe(const QString &sensorPath);
void unsubscribe(const QString &sensorPath);
KSysGuard::Unit unitFromString(const QString &unitString) const;
//This qlist is just to have an index mapping because of KSGRD's old API
//Could be an index in SensorInfo subclass
QStringList m_sensorIds;
QStringList m_subscribedSensors;
QHash<QString, SensorContainer *> m_subsystems;
QHash<QString, SensorProperty *> m_sensors;
QHash<QString, QString> m_pendingTypes;
int m_waitingFor;
};
{
"providerName": "ksgrd"
}
SPDX-License-Identifier: CC0-1.0
SPDX-FileCopyrightText: None
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment