浏览代码

split sensors and removed some circular dependencies in lib

Malte Veerman 10 年之前
父节点
当前提交
3137e27870

+ 1 - 1
kcm/src/fancontrolkcm.h

@@ -63,7 +63,7 @@ signals:
     void manualControlChanged();
     
 
-protected:
+private:
     
     GUIBase *const m_base;
     bool m_manualControl;

+ 4 - 1
lib/CMakeLists.txt

@@ -1,6 +1,9 @@
 set(LIB_SRCS src/hwmon.cpp
+             src/sensor.cpp
+             src/temp.cpp
+             src/fan.cpp
+             src/pwmfan.cpp
              src/loader.cpp
-             src/sensors.cpp
              src/guibase.cpp
              src/config.cpp)
                         

+ 1 - 0
lib/src/config.cpp

@@ -20,6 +20,7 @@
  *
  */
 
+
 #include "config.h"
 
 #define CONFIG_NAME "fancontrol-gui"

+ 1 - 0
lib/src/config.h

@@ -20,6 +20,7 @@
  *
  */
 
+
 #ifndef CONFIG_H
 #define CONFIG_H
 

+ 105 - 0
lib/src/fan.cpp

@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#include "fan.h"
+
+#include "hwmon.h"
+
+#include <QTextStream>
+#include <QDir>
+#include <QFile>
+#include <QDebug>
+
+#include <KSharedConfig>
+#include <KConfigGroup>
+
+
+
+Fan::Fan(Hwmon *parent, uint index) : 
+    Sensor(parent, index, QString(parent->name() + QString("/fan") + QString::number(index))),
+    m_rpmStream(new QTextStream)
+{
+    if (QDir(parent->path()).isReadable())
+    {
+        QFile *rpmFile = new QFile(parent->path() + "/fan" + QString::number(index) + "_input", this);
+
+        if (rpmFile->open(QFile::ReadOnly))
+        {
+            m_rpmStream->setDevice(rpmFile);
+            *m_rpmStream >> m_rpm;
+        }
+        else
+            qDebug() << "Can't open rpmFile " << parent->path() + "/fan" + QString::number(index) + "_input";
+    }
+}
+
+Fan::~Fan()
+{
+    delete m_rpmStream;
+}
+
+QString Fan::name() const
+{
+    KConfigGroup names = KSharedConfig::openConfig("fancontrol-gui")->group("names");
+    KConfigGroup localNames = names.group(m_parent->name());
+    QString name = localNames.readEntry("fan" + QString::number(m_index), QString());
+    if (name.isEmpty())
+        return "fan" + QString::number(m_index);
+    return name;
+}
+
+void Fan::setName(const QString &name)
+{
+    KConfigGroup names = KSharedConfig::openConfig("fancontrol-gui")->group("names");
+    KConfigGroup localNames = names.group(m_parent->name());
+    if (name != localNames.readEntry("fan" + QString::number(m_index), QString())
+        && !name.isEmpty())
+    {
+        localNames.writeEntry("fan" + QString::number(m_index), name);
+        emit nameChanged();
+    }
+}
+
+void Fan::reset()
+{
+    QIODevice *oldFile = m_rpmStream->device();
+    delete m_rpmStream;
+    delete oldFile;
+    
+    if (QDir(m_parent->path()).isReadable())
+    {
+        QFile *rpmFile = new QFile(m_parent->path() + "/fan" + QString::number(m_index) + "_input", this);
+
+        if (rpmFile->open(QFile::ReadOnly))
+        {
+            m_rpmStream = new QTextStream(rpmFile);
+            *m_rpmStream >> m_rpm;
+        }
+        else
+            qDebug() << "Can't open rpmFile " << m_parent->path() + "/fan" + QString::number(m_index) + "_input";
+    }
+}
+
+void Fan::update()
+{
+    m_rpmStream->seek(0);
+    *m_rpmStream >> m_rpm;
+    emit rpmChanged();
+}

+ 65 - 0
lib/src/fan.h

@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#ifndef FAN_H
+#define FAN_H
+
+
+#include "sensor.h"
+
+
+class QTextStream;
+
+class Fan : public Sensor
+{
+    Q_OBJECT
+    Q_PROPERTY(int rpm READ rpm NOTIFY rpmChanged)
+
+public:
+
+    explicit Fan(Hwmon *parent, uint index);
+    virtual ~Fan();
+
+    int rpm() const { return m_rpm; }
+    QString name() const Q_DECL_OVERRIDE;
+    void setName(const QString &name) Q_DECL_OVERRIDE;
+    void reset() Q_DECL_OVERRIDE;
+
+    virtual int pwm() const { return 255; }
+    virtual void setPwm(int, bool) { }
+
+
+signals:
+
+    void rpmChanged();
+
+
+public slots:
+
+    void update();
+
+
+protected:
+
+    int m_rpm;
+    QTextStream *m_rpmStream;
+};
+
+#endif // FAN_H

+ 3 - 2
lib/src/guibase.cpp

@@ -20,9 +20,10 @@
  *
  */
 
-#include "config.h"
+
 #include "guibase.h"
-#include "sensors.h"
+
+#include "config.h"
 #include "hwmon.h"
 
 #include <QtQml>

+ 4 - 0
lib/src/guibase.h

@@ -20,6 +20,7 @@
  *
  */
 
+
 #ifndef GUIBASE_H
 #define GUIBASE_H
 
@@ -90,6 +91,9 @@ signals:
 protected:
     
     void emitConfigChanged();
+    
+    
+private:
 
     Config *m_config;
 

+ 19 - 5
lib/src/hwmon.cpp

@@ -17,19 +17,18 @@
  *
  */
 
+
 #include "hwmon.h"
-#include "loader.h"
 
 #include <QDir>
 #include <QTextStream>
 #include <QtQml>
 #include <QDebug>
 
-Hwmon::Hwmon(const QString &path, Loader *parent) : QObject(parent),
-    m_parent(parent),
-    m_path(path)
+Hwmon::Hwmon(const QString &path, QObject *parent) : QObject(parent),
+    m_path(path),
+    m_index(path.split('/').last().remove("hwmon").toInt())
 {
-    m_index = path.split('/').last().remove("hwmon").toInt();
     QFile nameFile(path + "/name");
     if (nameFile.open(QFile::ReadOnly))
         m_name = QTextStream(&nameFile).readLine();
@@ -168,3 +167,18 @@ void Hwmon::testFans()
         m_pwmFans.at(i)->test();
     }
 }
+
+Fan* Hwmon::fan(int i) const
+{
+    return m_fans.value(i, Q_NULLPTR);
+}
+
+PwmFan* Hwmon::pwmFan(int i) const
+{
+    return m_pwmFans.value(i, Q_NULLPTR);
+}
+
+Temp* Hwmon::temp(int i) const
+{
+    return m_temps.value(i, Q_NULLPTR);
+}

+ 13 - 15
lib/src/hwmon.h

@@ -17,6 +17,7 @@
  *
  */
 
+
 #ifndef HWMON_H
 #define HWMON_H
 
@@ -24,12 +25,10 @@
 #include <QString>
 #include <QList>
 
-#include "sensors.h"
+#include "temp.h"
+#include "fan.h"
+#include "pwmfan.h"
 
-class Fan;
-class PwmFan;
-class Temp;
-class Loader;
 
 class Hwmon : public QObject
 {
@@ -44,7 +43,7 @@ class Hwmon : public QObject
 
 public:
 
-    explicit Hwmon(const QString &, Loader *parent);
+    explicit Hwmon(const QString &, QObject *parent = Q_NULLPTR);
 
     void initialize();
     QString name() const { return m_name; }
@@ -53,16 +52,16 @@ public:
     QList<QObject *> fans() const;
     QList<QObject *> pwmFans() const;
     QList<QObject *> temps() const;
-    Fan * fan(int i) const { return m_fans.value(i, Q_NULLPTR); }
-    PwmFan * pwmFan(int i) const { return m_pwmFans.value(i, Q_NULLPTR); }
-    Temp * temp(int i) const { return m_temps.value(i, Q_NULLPTR); }
     Q_INVOKABLE void testFans();
-
+    Fan * fan(int i) const;
+    PwmFan * pwmFan(int i) const;
+    Temp * temp(int i) const;
+    
 
 public slots:
 
     void updateConfig() { emit configUpdateNeeded(); }
-    void updateSensors() { emit sensorsUpdateNeeded(); }
+    void updateSensors() { emit sensorsUpdateNeeded(); }    
 
 
 signals:
@@ -74,12 +73,11 @@ signals:
     void sensorsUpdateNeeded();
 
 
-protected:
+private:
 
-    Loader *m_parent;
     QString m_name;
-    QString m_path;
-    int m_index;
+    const QString m_path;
+    const int m_index;
     QList<Fan *> m_fans;
     QList<PwmFan *> m_pwmFans;
     QList<Temp *> m_temps;

+ 5 - 1
lib/src/loader.cpp

@@ -17,9 +17,13 @@
  *
  */
 
+
 #include "loader.h"
+
 #include "hwmon.h"
-#include "sensors.h"
+#include "fan.h"
+#include "pwmfan.h"
+#include "temp.h"
 
 #include <QFile>
 #include <QDir>

+ 4 - 0
lib/src/loader.h

@@ -17,6 +17,7 @@
  *
  */
 
+
 #ifndef LOADER_H
 #define LOADER_H
 
@@ -81,6 +82,9 @@ protected:
     void setError(const QString &error);
     void success() { setError("Success"); }
     
+    
+private:
+    
     int m_interval;
     QList<Hwmon *> m_hwmons;
     QUrl m_configUrl;

+ 344 - 0
lib/src/pwmfan.cpp

@@ -0,0 +1,344 @@
+/*
+ * <one line to give the library's name and an idea of what it does.>
+ * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "pwmfan.h"
+
+#include "hwmon.h"
+
+#include <QTextStream>
+#include <QTimer>
+#include <QDir>
+#include <QFile>
+#include <QDebug>
+
+#include <KConfigGroup>
+#include <KSharedConfig>
+#include <KF5/KAuth/KAuthExecuteJob>
+
+
+#define MAX_ERRORS_FOR_RPM_ZERO 10
+
+
+PwmFan::PwmFan(Hwmon *parent, uint index) : Fan(parent, index),
+    m_pwmStream(new QTextStream),
+    m_modeStream(new QTextStream),
+    m_testTimer(new QTimer(this)),
+    m_temp(Q_NULLPTR),
+    m_hasTemp(false),
+    m_testing(false),
+    m_minTemp(0),
+    m_maxTemp(100),
+    m_minPwm(255),
+    m_maxPwm(255),
+    m_minStart(255),
+    m_minStop(255),
+    m_zeroRpm(0),
+    m_testStatus(notTesting)
+{
+    m_testTimer->setSingleShot(true);
+
+    connect(this, SIGNAL(tempChanged()), parent, SLOT(updateConfig()));
+    connect(this, SIGNAL(hasTempChanged()), parent, SLOT(updateConfig()));
+    connect(this, SIGNAL(minTempChanged()), parent, SLOT(updateConfig()));
+    connect(this, SIGNAL(maxTempChanged()), parent, SLOT(updateConfig()));
+    connect(this, SIGNAL(minPwmChanged()), parent, SLOT(updateConfig()));
+    connect(this, SIGNAL(maxPwmChanged()), parent, SLOT(updateConfig()));
+    connect(this, SIGNAL(minStartChanged()), parent, SLOT(updateConfig()));
+    connect(this, SIGNAL(minStopChanged()), parent, SLOT(updateConfig()));
+    connect(m_testTimer, SIGNAL(timeout()), this, SLOT(continueTest()));
+
+    if (QDir(parent->path()).isReadable())
+    {
+        QFile *pwmFile = new QFile(parent->path() + "/pwm" + QString::number(index), this);
+        if (pwmFile->open(QFile::ReadWrite))
+        {
+            m_pwmStream->setDevice(pwmFile);
+            *m_pwmStream >> m_pwm;
+        }
+        else if (pwmFile->open(QFile::ReadOnly))
+        {
+            m_pwmStream->setDevice(pwmFile);
+            *m_pwmStream >> m_pwm;
+        }
+        else
+            qDebug() << "Can't open pwmFile " << pwmFile->fileName();
+
+        QFile *pwmModeFile = new QFile(parent->path() + "/pwm" + QString::number(index) + "_mode", this);
+        if (pwmModeFile->open(QFile::ReadWrite))
+        {
+            m_modeStream->setDevice(pwmModeFile);
+            *m_modeStream >> m_pwmMode;
+        }
+        else if (pwmModeFile->open(QFile::ReadOnly))
+        {
+            m_modeStream->setDevice(pwmModeFile);
+            *m_modeStream >> m_pwmMode;
+        }
+        else
+            qDebug() << "Can't open pwmModeFile " << pwmModeFile->fileName();
+    }
+}
+
+PwmFan::~PwmFan()
+{
+    delete m_pwmStream;
+    delete m_modeStream;
+}
+
+void PwmFan::update()
+{
+    Fan::update();
+
+    m_pwmStream->seek(0);
+    setPwm(m_pwmStream->readAll().toInt(), false);
+
+    m_modeStream->seek(0);
+    setPwmMode(m_modeStream->readAll().toInt(), false);
+}
+
+void PwmFan::reset()
+{
+    Fan::reset();
+    
+    QIODevice *oldFile = m_pwmStream->device();
+    delete m_pwmStream;
+    delete oldFile;
+    
+    oldFile = m_modeStream->device();
+    delete m_modeStream;
+    delete oldFile;
+    
+    QFile *pwmFile = new QFile(m_parent->path() + "/pwm" + QString::number(m_index), this);
+        if (pwmFile->open(QFile::ReadWrite))
+        {
+            m_pwmStream = new QTextStream(pwmFile);
+            *m_pwmStream >> m_pwm;
+        }
+        else if (pwmFile->open(QFile::ReadOnly))
+        {
+            m_pwmStream = new QTextStream(pwmFile);
+            *m_pwmStream >> m_pwm;
+        }
+        else
+            qDebug() << "Can't open pwmFile " << pwmFile->fileName();
+
+        QFile *pwmModeFile = new QFile(m_parent->path() + "/pwm" + QString::number(m_index) + "_mode", this);
+        if (pwmModeFile->open(QFile::ReadWrite))
+        {
+            m_modeStream = new QTextStream(pwmModeFile);
+            *m_modeStream >> m_pwmMode;
+        }
+        else if (pwmModeFile->open(QFile::ReadOnly))
+        {
+            m_modeStream = new QTextStream(pwmModeFile);
+            *m_modeStream >> m_pwmMode;
+        }
+        else
+            qDebug() << "Can't open pwmModeFile " << pwmModeFile->fileName();
+}
+
+void PwmFan::setPwm(int pwm, bool write)
+{
+    if (m_pwm != pwm)
+    {
+        m_pwm = pwm;
+        emit pwmChanged();
+
+        if (write)
+        {
+            if (m_pwmStream->device()->isWritable())
+                *m_pwmStream << pwm;
+            else
+            {
+                KAuth::Action action("fancontrol.gui.helper.action");
+                action.setHelperId("fancontrol.gui.helper");
+                QVariantMap map;
+                map["action"] = "write";
+                map["filename"] = qobject_cast<QFile *>(m_pwmStream->device())->fileName();
+                map["content"] = QString::number(pwm);
+                action.setArguments(map);
+                KAuth::ExecuteJob *reply = action.execute();
+
+                if (!reply->exec())
+                    qDebug() << reply->errorString() << reply->errorText();
+            }
+        }
+    }
+}
+
+void PwmFan::setPwmMode(int pwmMode, bool write)
+{
+    if (m_pwmMode != pwmMode)
+    {
+        m_pwmMode = pwmMode;
+        emit pwmModeChanged();
+
+        if (write)
+        {
+            if (m_modeStream->device()->isWritable())
+                *m_modeStream << pwmMode;
+            else
+            {
+                KAuth::Action action("fancontrol.gui.helper.action");
+                action.setHelperId("fancontrol.gui.helper");
+                QVariantMap map;
+                map["action"] = "write";
+                map["filename"] = qobject_cast<QFile *>(m_modeStream->device())->fileName();
+                map["content"] = QString::number(pwmMode);
+                action.setArguments(map);
+                KAuth::ExecuteJob *reply = action.execute();
+
+                if (!reply->exec())
+                    qDebug() << reply->errorString() << reply->errorText();
+            }
+        }
+    }
+}
+
+void PwmFan::test()
+{
+    m_testing = true;
+    emit testingChanged();
+
+    m_testStatus = findingStop1;
+    setPwmMode(1);
+    setPwm(255);
+    m_testTimer->setInterval(500);
+    m_testTimer->start();
+    qDebug() << "Start testing...";
+}
+
+void PwmFan::abortTest()
+{
+    setPwm(255);
+    m_testTimer->stop();
+
+    m_testing = false;
+    emit testingChanged();
+}
+
+void PwmFan::continueTest()
+{
+    update();
+    switch (m_testStatus)
+    {
+    case findingStop1:
+        if (m_rpm > 0)
+        {
+            setPwm(qMin(m_pwm * 0.95, m_pwm - 5.0));
+            m_zeroRpm = 0;
+        }
+        else
+        {
+            if (m_zeroRpm < MAX_ERRORS_FOR_RPM_ZERO)
+            {
+                m_zeroRpm++;
+            }
+            else
+            {
+                m_testStatus = findingStart;
+                m_zeroRpm = 0;
+                m_testTimer->setInterval(500);
+                qDebug() << "Start finding start value...";
+            }
+        }
+        m_testTimer->start();
+        break;
+
+    case findingStart:
+        if (m_rpm == 0)
+            setPwm(m_pwm + 2);
+        else
+        {
+            m_testStatus = findingStop2;
+            m_testTimer->setInterval(1000);
+            setMinStart(m_pwm);
+            qDebug() << "Start finding stop value...";
+        }
+        m_testTimer->start();
+        break;
+
+    case findingStop2:
+        if (m_rpm > 0)
+        {
+            setPwm(m_pwm - 1);
+            m_zeroRpm = 0;
+            m_testTimer->start();
+        }
+        else
+        {
+            if (m_zeroRpm < MAX_ERRORS_FOR_RPM_ZERO)
+            {
+                m_zeroRpm++;
+                m_testTimer->start();
+            }
+            else
+            {
+                m_testStatus = notTesting;
+                m_zeroRpm = 0;
+                m_testing = false;
+                emit testingChanged();
+                setMinStop(m_pwm + 5);
+                qDebug() << "Finished testing!";
+            }
+        }
+        break;
+
+    case notTesting:
+        m_testing = false;
+        emit testingChanged();
+        break;
+
+    default:
+        break;
+    }
+}
+
+// void PwmFan::reset()
+// {
+//     setTemp(Q_NULLPTR);
+//     setMinTemp(0);
+//     setMaxTemp(100);
+//     setMinPwm(255);
+//     setMaxPwm(255);
+//     setMinStart(255);
+//     setMinStop(255);
+// }
+
+bool PwmFan::active() const
+{
+    KConfigGroup active = KSharedConfig::openConfig("fancontrol-gui")->group("active");
+    KConfigGroup localActive = active.group(m_parent->name());
+    return localActive.readEntry("pwmfan" + QString::number(m_index), true);
+}
+
+void PwmFan::setActive(bool a)
+{
+    KConfigGroup active = KSharedConfig::openConfig("fancontrol-gui")->group("active");
+    KConfigGroup localActive = active.group(m_parent->name());
+    if (a != localActive.readEntry("pwmfan" + QString::number(m_index), true))
+    {
+        localActive.writeEntry("pwmfan" + QString::number(m_index), a);
+        emit activeChanged();
+    }
+}

+ 132 - 0
lib/src/pwmfan.h

@@ -0,0 +1,132 @@
+/*
+ * <one line to give the library's name and an idea of what it does.>
+ * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifndef PWMFAN_H
+#define PWMFAN_H
+
+
+#include "temp.h"
+#include "fan.h"
+
+
+class QTimer;
+class QTextStream;
+
+class PwmFan : public Fan
+{
+    Q_OBJECT
+    Q_PROPERTY(int pwm READ pwm WRITE setPwm NOTIFY pwmChanged)
+    Q_PROPERTY(Temp * temp READ temp WRITE setTemp NOTIFY tempChanged)
+    Q_PROPERTY(bool hasTemp READ hasTemp WRITE setHasTemp NOTIFY hasTempChanged)
+    Q_PROPERTY(int minTemp READ minTemp WRITE setMinTemp NOTIFY minTempChanged)
+    Q_PROPERTY(int maxTemp READ maxTemp WRITE setMaxTemp NOTIFY maxTempChanged)
+    Q_PROPERTY(int minPwm READ minPwm WRITE setMinPwm NOTIFY minPwmChanged)
+    Q_PROPERTY(int maxPwm READ maxPwm WRITE setMaxPwm NOTIFY maxPwmChanged)
+    Q_PROPERTY(int minStart READ minStart WRITE setMinStart NOTIFY minStartChanged)
+    Q_PROPERTY(int minStop READ minStop WRITE setMinStop NOTIFY minStopChanged)
+    Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
+    Q_PROPERTY(bool testing READ testing NOTIFY testingChanged)
+    Q_PROPERTY(int pwmMode READ pwmMode WRITE setPwmMode NOTIFY pwmModeChanged)
+
+public:
+
+    explicit PwmFan(Hwmon *parent, uint index);
+    virtual ~PwmFan();
+
+    int pwm() const { return m_pwm; }
+    Temp * temp() const { return m_temp; }
+    bool hasTemp() const { return m_hasTemp; }
+    int minTemp() const { return m_minTemp; }
+    int maxTemp() const { return m_maxTemp; }
+    int minPwm() const { return m_minPwm; }
+    int maxPwm() const { return m_maxPwm; }
+    int minStart() const { return m_minStart; }
+    int minStop() const { return m_minStop; }
+    int pwmMode() const { return m_pwmMode; }
+    bool active() const;
+    bool testing() const { return m_testing; }
+    void setPwm(int pwm, bool write = true);
+    void setTemp(Temp *temp) { setHasTemp(temp != Q_NULLPTR); if (temp != m_temp) { m_temp = temp; emit tempChanged(); } }
+    void setHasTemp(bool hasTemp) { if (hasTemp != m_hasTemp) { m_hasTemp = hasTemp; emit hasTempChanged(); } }
+    void setMinTemp(int minTemp) { if (minTemp != m_minTemp) { m_minTemp = minTemp; emit minTempChanged(); } }
+    void setMaxTemp(int maxTemp) { if (maxTemp != m_maxTemp) { m_maxTemp = maxTemp; emit maxTempChanged(); } }
+    void setMinPwm(int minPwm) { if (minPwm != m_minPwm) { m_minPwm = minPwm; emit minPwmChanged(); } }
+    void setMaxPwm(int maxPwm) { if (maxPwm != m_maxPwm) { m_maxPwm = maxPwm; emit maxPwmChanged(); } }
+    void setMinStart(int minStart) { if (minStart != m_minStart) { m_minStart = minStart; emit minStartChanged(); } }
+    void setMinStop(int minStop) { if (minStop != m_minStop) { m_minStop = minStop; emit minStopChanged(); } }
+    void setPwmMode(int pwmMode, bool write = true);
+    void setActive(bool active);
+    void reset() Q_DECL_OVERRIDE;
+    Q_INVOKABLE void test();
+    Q_INVOKABLE void abortTest();
+
+
+signals:
+
+    void pwmChanged();
+    void tempChanged();
+    void hasTempChanged();
+    void minTempChanged();
+    void maxTempChanged();
+    void minPwmChanged();
+    void maxPwmChanged();
+    void minStartChanged();
+    void minStopChanged();
+    void activeChanged();
+    void testingChanged();
+    void pwmModeChanged();
+
+
+protected slots:
+
+    void update();
+    void continueTest();
+
+
+private:
+
+    int m_pwm;
+    QTextStream *m_pwmStream;
+    QTextStream *m_modeStream;
+    QTimer *m_testTimer;
+    Temp *m_temp;
+    bool m_hasTemp;
+    bool m_testing;
+    int m_minTemp;
+    int m_maxTemp;
+    int m_minPwm;
+    int m_maxPwm;
+    int m_minStart;
+    int m_minStop;
+    int m_pwmMode;
+    int m_zeroRpm;
+
+    enum
+    {
+        findingStop1,
+        findingStop2,
+        findingStart,
+        notTesting
+    } m_testStatus;
+};
+#endif // PWMFAN_H

+ 31 - 0
lib/src/sensor.cpp

@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#include "sensor.h"
+
+#include "hwmon.h"
+
+
+Sensor::Sensor(Hwmon *parent, uint index, const QString &path) : QObject(parent),
+    m_parent(parent),
+    m_index(index),
+    m_path(path)
+{
+}

+ 67 - 0
lib/src/sensor.h

@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#ifndef SENSOR_H
+#define SENSOR_H
+
+#include <QObject>
+#include <QString>
+
+
+class Hwmon;
+
+class Sensor : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(uint index READ index CONSTANT)
+    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+    Q_PROPERTY(QString path READ path CONSTANT)
+    Q_PROPERTY(Hwmon * parent READ parent CONSTANT)
+
+public:
+
+    explicit Sensor(Hwmon *parent, uint index, const QString &path = QString());
+
+    virtual QString name() const = 0;
+    virtual void setName(const QString &name) = 0;
+    virtual void reset() = 0;
+    QString path() const { return m_path; }
+    Hwmon * parent() const { return m_parent; }
+    uint index() const { return m_index; }
+
+
+public slots:
+
+    virtual void update() = 0;
+
+
+signals:
+
+    void nameChanged();
+
+
+protected:
+
+    Hwmon *const m_parent;
+    const uint m_index;
+    const QString m_path;
+};
+
+#endif // SENSOR_H

+ 1 - 0
lib/src/systemdcommunicator.cpp

@@ -17,6 +17,7 @@
  *
  */
 
+
 #include "systemdcommunicator.h"
 
 #include <KF5/KAuth/kauthexecutejob.h>

+ 4 - 0
lib/src/systemdcommunicator.h

@@ -17,6 +17,7 @@
  *
  */
 
+
 #ifndef SYSTEMDCOMMUNICATOR_H
 #define SYSTEMDCOMMUNICATOR_H
 
@@ -68,6 +69,9 @@ protected:
     bool dbusAction(const QString &method, const QVariantList &arguments = QVariantList());
     void setError(const QString &error) { if (error != m_error) { m_error = error; emit errorChanged(); } }
     void success() { setError("Success"); }
+    
+    
+private:
 
     QString m_serviceName;
     QString m_serviceObjectPath;

+ 121 - 0
lib/src/temp.cpp

@@ -0,0 +1,121 @@
+/*
+ * <one line to give the library's name and an idea of what it does.>
+ * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "temp.h"
+
+#include "hwmon.h"
+
+#include <QTextStream>
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+
+#include <KSharedConfig>
+#include <KConfigGroup>
+
+
+Temp::Temp(Hwmon *parent, uint index) : 
+    Sensor(parent, index, QString(parent->name() + QString("/temp") + QString::number(index))),
+    m_valueStream(new QTextStream)
+{
+    if (QDir(parent->path()).isReadable())
+    {
+        QFile *valueFile = new QFile(parent->path() + "/temp" + QString::number(index) + "_input", this);
+        QFile labelFile(parent->path() + "/temp" + QString::number(index) + "_label");
+
+        if (valueFile->open(QFile::ReadOnly))
+        {
+            m_valueStream->setDevice(valueFile);
+            *m_valueStream >> m_value;
+            m_value /= 1000;
+        }
+        else
+            qDebug() << "Can't open valueFile " << parent->path() + "/temp" + QString::number(index) + "_input";
+
+        if (labelFile.open(QFile::ReadOnly))
+            m_label = QTextStream(&labelFile).readLine();
+
+        else
+            qDebug() << "Can't open labelFile " << parent->path() + "/temp" + QString::number(index) + "_label";
+    }
+}
+
+Temp::~Temp()
+{
+    delete m_valueStream;
+}
+
+QString Temp::name() const
+{
+    KConfigGroup names = KSharedConfig::openConfig("fancontrol-gui")->group("names");
+    KConfigGroup localNames = names.group(m_parent->name());
+    QString name = localNames.readEntry("temp" + QString::number(m_index), QString());
+    if (name.isEmpty())
+    {
+        if (m_label.isEmpty())
+            return "temp" + QString::number(m_index);
+        return m_label;
+    }
+    return name;
+}
+
+void Temp::setName(const QString &name)
+{
+    KConfigGroup names = KSharedConfig::openConfig("fancontrol-gui")->group("names");
+    KConfigGroup localNames = names.group(m_parent->name());
+    if (name != localNames.readEntry("temp" + QString::number(m_index), QString())
+        && !name.isEmpty())
+    {
+        localNames.writeEntry(m_parent->name() + "temp" + QString::number(m_index), name);
+        emit nameChanged();
+    }
+}
+
+void Temp::reset()
+{
+    QIODevice *oldFile = m_valueStream->device();
+    delete m_valueStream;
+    delete oldFile;
+    
+    if (QDir(m_parent->path()).isReadable())
+    {
+        QFile *valueFile = new QFile(m_parent->path() + "/temp" + QString::number(m_index) + "_input", this);
+
+        if (valueFile->open(QFile::ReadOnly))
+        {
+            m_valueStream = new QTextStream(valueFile);
+            *m_valueStream >> m_value;
+            m_value /= 1000;
+        }
+        else
+            qDebug() << "Can't open valueFile " << m_parent->path() + "/temp" + QString::number(m_index) + "_input";
+    }
+}
+
+void Temp::update()
+{
+    m_valueStream->seek(0);
+    *m_valueStream >> m_value;
+    m_value /= 1000;
+    emit valueChanged();
+}

+ 69 - 0
lib/src/temp.h

@@ -0,0 +1,69 @@
+/*
+ * <one line to give the library's name and an idea of what it does.>
+ * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifndef TEMP_H
+#define TEMP_H
+
+
+#include "sensor.h"
+
+
+class QTextStream;
+
+class Temp : public Sensor
+{
+    Q_OBJECT
+    Q_PROPERTY(QString label READ label NOTIFY labelChanged)
+    Q_PROPERTY(int value READ value NOTIFY valueChanged)
+
+public:
+
+    explicit Temp(Hwmon *parent, uint index);
+    virtual ~Temp();
+
+    QString label() const { return m_label; }
+    int value() const { return m_value; }
+    QString name() const Q_DECL_OVERRIDE;
+    void setName(const QString &name) Q_DECL_OVERRIDE;
+    void reset() Q_DECL_OVERRIDE;
+
+
+public slots:
+
+    void update();
+
+
+signals:
+
+    void labelChanged();
+    void valueChanged();
+
+
+private:
+
+    QString m_label;
+    int m_value;
+    QTextStream *m_valueStream;
+};
+
+#endif // TEMP_H