diff --git a/debian/control b/debian/control index fb5ca241..e34a7229 100644 --- a/debian/control +++ b/debian/control @@ -749,6 +749,20 @@ Description: nymea.io plugin to send and receive strings over a serial port . This package will install the nymea.io plugin for serial ports +Package: nymea-plugin-systemmonitor +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, + nymea-plugins-translations, +Description: nymea.io plugin to monitor the system + The nymea daemon is a plugin based IoT (Internet of Things) server. The + server works like a translator for devices, things and services and + allows them to interact. + With the powerful rule engine you are able to connect any device available + in the system and create individual scenes and behaviors for your environment. + . + This package will install the nymea.io plugin for system monitoring + Package: nymea-plugins-translations Section: misc @@ -818,6 +832,7 @@ Depends: nymea-plugin-boblight, nymea-plugin-remotessh, nymea-plugin-unipi, nymea-plugin-serialportcommander, + nymea-plugin-systemmonitor, Replaces: guh-plugins-maker Description: Plugins for nymea IoT server - Meta package for makers, tinkers and hackers The nymea daemon is a plugin based IoT (Internet of Things) server. The diff --git a/debian/nymea-plugin-systemmonitor.install.in b/debian/nymea-plugin-systemmonitor.install.in new file mode 100644 index 00000000..77eef007 --- /dev/null +++ b/debian/nymea-plugin-systemmonitor.install.in @@ -0,0 +1 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_devicepluginsystemmonitor.so diff --git a/nymea-plugins.pro b/nymea-plugins.pro index f0d5856d..82a638c5 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -33,6 +33,7 @@ PLUGIN_DIRS = \ osdomotics \ philipshue \ pushbullet \ + systemmonitor \ remotessh \ senic \ serialportcommander \ diff --git a/systemmonitor/README.md b/systemmonitor/README.md new file mode 100644 index 00000000..e6fe822b --- /dev/null +++ b/systemmonitor/README.md @@ -0,0 +1,9 @@ +# Systemmonitor + +Displays the system usage of nymea, containing: + +* CPU usage (in percent) +* Memory usage (in percent) +* RSS memory usage (in KiloByte) +* Virtual memory usage (in KiloByte) + diff --git a/systemmonitor/devicepluginsystemmonitor.cpp b/systemmonitor/devicepluginsystemmonitor.cpp new file mode 100644 index 00000000..adb45f78 --- /dev/null +++ b/systemmonitor/devicepluginsystemmonitor.cpp @@ -0,0 +1,113 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Michael Zanetti . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "devicepluginsystemmonitor.h" +#include "plugininfo.h" + + +DevicePluginSystemMonitor::DevicePluginSystemMonitor() +{ + +} + +DevicePluginSystemMonitor::~DevicePluginSystemMonitor() +{ + if (m_refreshTimer) { + hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); + } +} + +Device::DeviceSetupStatus DevicePluginSystemMonitor::setupDevice(Device *device) +{ + Q_UNUSED(device) + + if (!m_refreshTimer) { + m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2); + connect(m_refreshTimer, &PluginTimer::timeout, this, &DevicePluginSystemMonitor::onRefreshTimer); + } + + + return Device::DeviceSetupStatusSuccess; +} + +void DevicePluginSystemMonitor::deviceRemoved(Device *device) +{ + Q_UNUSED(device) + + if (myDevices().isEmpty()) { + hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); + m_refreshTimer = nullptr; + + } +} + +void DevicePluginSystemMonitor::onRefreshTimer() +{ + QProcess *p = new QProcess(this); + connect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onProcessFinished(int,QProcess::ExitStatus))); + p->start("ps", {"-C", "nymead", "-o", "%mem=,vsz=,rss=,pcpu="}); +} + +void DevicePluginSystemMonitor::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + QProcess *p = static_cast(sender()); + p->deleteLater(); + + if (exitCode != 0 || exitStatus != QProcess::NormalExit) { + qWarning(dcSystemMonitor) << "Error reading process memory usage:" << p->readAllStandardError(); + return; + } + QString data = QString(p->readAllStandardOutput().trimmed()).replace(QRegExp("[ ]{2,}"), " "); + QStringList parts = data.split(' '); + if (parts.count() != 4) { + qCWarning(dcSystemMonitor()) << "Unexpected result from ps" << data << parts; + return; + } + bool ok; + qreal percentMem = parts.at(0).toDouble(&ok); + if (!ok) { + qWarning(dcSystemMonitor) << "Failed to parse % memory value to a number:" << parts.at(0); + return; + } + qint64 virtualMem = parts.at(1).toLongLong(&ok); + if (!ok) { + qWarning(dcSystemMonitor) << "Failed to parse virtual memory value to a number:" << parts.at(1); + return; + } + quint64 rssMem = parts.at(2).toLongLong(&ok); + if (!ok) { + qWarning(dcSystemMonitor) << "Failed to parse RSS memory value to a number:" << data; + return; + } + qreal cpuUsage = parts.at(3).toDouble(&ok); + if (!ok) { + qWarning(dcSystemMonitor) << "Failed to parse CPU usage value to a number:" << parts.at(3); + return; + } + foreach (Device *dev, myDevices()) { + dev->setStateValue(systemMonitorRssMemoryStateTypeId, rssMem); + dev->setStateValue(systemMonitorPercentMemoryStateTypeId, percentMem); + dev->setStateValue(systemMonitorVirtualMemoryStateTypeId, virtualMem); + dev->setStateValue(systemMonitorCpuUsageStateTypeId, cpuUsage); + } +} + diff --git a/systemmonitor/devicepluginsystemmonitor.h b/systemmonitor/devicepluginsystemmonitor.h new file mode 100644 index 00000000..727fcc23 --- /dev/null +++ b/systemmonitor/devicepluginsystemmonitor.h @@ -0,0 +1,56 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Michael Zanetti . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef DEVICEPLUGINSYSTEMMONITOR_H +#define DEVICEPLUGINSYSTEMMONITOR_H + +#include "devices/devicemanager.h" +#include "devices/deviceplugin.h" +#include "plugintimer.h" + +#include +#include +#include + + +class DevicePluginSystemMonitor: public DevicePlugin { + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginsystemmonitor.json") + Q_INTERFACES(DevicePlugin) + +public: + explicit DevicePluginSystemMonitor(); + ~DevicePluginSystemMonitor() override; + + Device::DeviceSetupStatus setupDevice(Device *device) override; + void deviceRemoved(Device *device) override; + +private slots: + void onRefreshTimer(); + void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + +private: + PluginTimer *m_refreshTimer = nullptr; + +}; + +#endif // DEVICEPLUGINSYSTEMMONITOR_H diff --git a/systemmonitor/devicepluginsystemmonitor.json b/systemmonitor/devicepluginsystemmonitor.json new file mode 100644 index 00000000..940e60d7 --- /dev/null +++ b/systemmonitor/devicepluginsystemmonitor.json @@ -0,0 +1,63 @@ +{ + "name": "systemMonitor", + "displayName": "System Monitor", + "id": "908b4f18-dc0c-4940-a6f7-c0c01a2861b8", + "vendors": [ + { + "displayName": "nymea", + "name": "nymea", + "id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6", + "deviceClasses": [ + { + "id": "a3a15700-c251-4803-a608-0f3ddfcbd7a8", + "name": "systemMonitor", + "displayName": "System monitor", + "interfaces": [ "system" ], + "paramTypes": [ ], + "stateTypes": [ + { + "id": "56f8fac2-1021-4b96-bf15-23b21bb85b4c", + "name": "cpuUsage", + "displayName": "CPU usage", + "displayNameEvent": "CPU usage changed", + "type": "double", + "unit": "Percentage", + "defaultValue": 0, + "minValue": 0, + "maxValue": 100 + }, + { + "id": "efe2d520-3b35-4668-b6f5-db3df0c8bf0d", + "name": "percentMemory", + "displayName": "memory usage", + "displayNameEvent": "memory usage changed", + "type": "double", + "unit": "Percentage", + "defaultValue": 0, + "minValue": 0, + "maxValue": 100 + }, + { + "id": "d9671ee3-51be-4cf8-8601-125c0684aec9", + "name": "rssMemory", + "displayName": "RSS memory usage", + "displayNameEvent": "RSS memory usage changed", + "type": "int", + "unit": "KiloByte", + "defaultValue": 0 + }, + { + "id": "6d71b001-c7fe-4f08-941d-47009b710d94", + "name": "virtualMemory", + "displayName": "virtual memory usage", + "displayNameEvent": "virtual memory usage changed", + "type": "int", + "unit": "KiloByte", + "defaultValue": 0 + } + ] + } + ] + } + ] +} diff --git a/systemmonitor/systemmonitor.pro b/systemmonitor/systemmonitor.pro new file mode 100644 index 00000000..3d40dee4 --- /dev/null +++ b/systemmonitor/systemmonitor.pro @@ -0,0 +1,9 @@ +include(../plugins.pri) + +TARGET = $$qtLibraryTarget(nymea_devicepluginsystemmonitor) + +SOURCES += \ + devicepluginsystemmonitor.cpp \ + +HEADERS += \ + devicepluginsystemmonitor.h \ diff --git a/systemmonitor/translations/908b4f18-dc0c-4940-a6f7-c0c01a2861b8-en_US.ts b/systemmonitor/translations/908b4f18-dc0c-4940-a6f7-c0c01a2861b8-en_US.ts new file mode 100644 index 00000000..f7f66d85 --- /dev/null +++ b/systemmonitor/translations/908b4f18-dc0c-4940-a6f7-c0c01a2861b8-en_US.ts @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/systemmonitor/translations/b82bce59-59bf-48b3-b781-54a6f45800f3-en_US.ts b/systemmonitor/translations/b82bce59-59bf-48b3-b781-54a6f45800f3-en_US.ts new file mode 100644 index 00000000..f7f66d85 --- /dev/null +++ b/systemmonitor/translations/b82bce59-59bf-48b3-b781-54a6f45800f3-en_US.ts @@ -0,0 +1,4 @@ + + + + \ No newline at end of file