Libksysguard

SensorDaemonInterface.cpp
1/*
2 SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "SensorDaemonInterface_p.h"
8
9#include <QDBusPendingCallWatcher>
10
11#include "systemstats/DBusInterface.h"
12
13using namespace KSysGuard;
14
15class SensorDaemonInterface::Private
16{
17public:
18 std::unique_ptr<SystemStats::DBusInterface> dbusInterface;
19 std::unique_ptr<QDBusServiceWatcher> serviceWatcher;
20 QStringList subscribedSensors;
21};
22
23SensorDaemonInterface::SensorDaemonInterface(QObject *parent)
24 : QObject(parent)
25 , d(new Private)
26{
27 qDBusRegisterMetaType<SensorData>();
28 qDBusRegisterMetaType<SensorInfo>();
29 qDBusRegisterMetaType<SensorDataList>();
30 qDBusRegisterMetaType<SensorInfoMap>();
31
32 d->serviceWatcher =
33 std::make_unique<QDBusServiceWatcher>(SystemStats::ServiceName, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration);
34 connect(d->serviceWatcher.get(), &QDBusServiceWatcher::serviceUnregistered, this, &SensorDaemonInterface::reconnect);
35 reconnect();
36}
37
38void KSysGuard::SensorDaemonInterface::reconnect()
39{
40 d->dbusInterface = std::make_unique<SystemStats::DBusInterface>();
41 connect(d->dbusInterface.get(), &SystemStats::DBusInterface::sensorMetaDataChanged, this, &SensorDaemonInterface::onMetaDataChanged);
42 connect(d->dbusInterface.get(), &SystemStats::DBusInterface::newSensorData, this, &SensorDaemonInterface::onValueChanged);
43 connect(d->dbusInterface.get(), &SystemStats::DBusInterface::sensorAdded, this, &SensorDaemonInterface::sensorAdded);
44 connect(d->dbusInterface.get(), &SystemStats::DBusInterface::sensorRemoved, this, &SensorDaemonInterface::sensorRemoved);
45 subscribe(d->subscribedSensors);
46}
47
48SensorDaemonInterface::~SensorDaemonInterface()
49{
50}
51
52void SensorDaemonInterface::requestMetaData(const QString &sensorId)
53{
54 requestMetaData(QStringList{sensorId});
55}
56
57void SensorDaemonInterface::requestMetaData(const QStringList &sensorIds)
58{
59 if (sensorIds.isEmpty()) {
60 return;
61 }
62
63 auto watcher = new QDBusPendingCallWatcher{d->dbusInterface->sensors(sensorIds), this};
64 connect(watcher, &QDBusPendingCallWatcher::finished, watcher, [this](QDBusPendingCallWatcher *self) {
65 self->deleteLater();
66
67 const QDBusPendingReply<SensorInfoMap> reply = *self;
68 if (reply.isError()) {
69 return;
70 }
71
72 const auto infos = reply.value();
73 for (auto itr = infos.begin(); itr != infos.end(); ++itr) {
74 Q_EMIT metaDataChanged(itr.key(), itr.value());
75 }
76 });
77}
78
79void SensorDaemonInterface::requestValue(const QString &sensorId)
80{
81 if (sensorId.isEmpty()) {
82 return;
83 }
84
85 auto watcher = new QDBusPendingCallWatcher{d->dbusInterface->sensorData({sensorId}), this};
86 connect(watcher, &QDBusPendingCallWatcher::finished, watcher, [this](QDBusPendingCallWatcher *self) {
87 self->deleteLater();
88
89 const QDBusPendingReply<SensorDataList> reply = *self;
90 if (reply.isError()) {
91 return;
92 }
93
94 const auto allData = reply.value();
95 for (auto data : allData) {
96 Q_EMIT valueChanged(data.sensorProperty, data.payload);
97 }
98 });
99}
100
101QDBusPendingCallWatcher *SensorDaemonInterface::allSensors() const
102{
103 return new QDBusPendingCallWatcher{d->dbusInterface->allSensors()};
104}
105
106void SensorDaemonInterface::subscribe(const QString &sensorId)
107{
108 if (sensorId.isEmpty()) {
109 return;
110 }
111
112 subscribe(QStringList{sensorId});
113}
114
115void KSysGuard::SensorDaemonInterface::subscribe(const QStringList &sensorIds)
116{
117 if (sensorIds.isEmpty()) {
118 return;
119 }
120
121 d->dbusInterface->subscribe(sensorIds);
122 d->subscribedSensors.append(sensorIds);
123}
124
125void SensorDaemonInterface::unsubscribe(const QString &sensorId)
126{
127 if (sensorId.isEmpty()) {
128 return;
129 }
130
131 unsubscribe(QStringList{sensorId});
132}
133
134void KSysGuard::SensorDaemonInterface::unsubscribe(const QStringList &sensorIds)
135{
136 if (sensorIds.isEmpty()) {
137 return;
138 }
139
140 d->dbusInterface->unsubscribe(sensorIds);
141}
142
143SensorDaemonInterface *SensorDaemonInterface::instance()
144{
145 static SensorDaemonInterface instance;
146 return &instance;
147}
148
149void SensorDaemonInterface::onMetaDataChanged(const QHash<QString, SensorInfo> &metaData)
150{
151 for (auto itr = metaData.begin(); itr != metaData.end(); ++itr) {
152 Q_EMIT metaDataChanged(itr.key(), itr.value());
153 }
154}
155
156void SensorDaemonInterface::onValueChanged(const SensorDataList &values)
157{
158 for (auto entry : values) {
159 Q_EMIT valueChanged(entry.sensorProperty, entry.payload);
160 }
161}
Internal helper class to communicate with the daemon.
QDBusConnection sessionBus()
void finished(QDBusPendingCallWatcher *self)
bool isError() const const
typename Select< 0 >::Type value() const const
void serviceUnregistered(const QString &serviceName)
iterator begin()
iterator end()
bool isEmpty() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:02:48 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.