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