Merge PR #460: Make use of gpio classes from libnymea-gpio

pull/470/merge
Jenkins nymea 2021-10-04 12:10:41 +02:00
commit 51c02e350a
10 changed files with 6 additions and 834 deletions

1
debian/control vendored
View File

@ -12,6 +12,7 @@ Build-Depends: debhelper (>= 9.0.0),
libnymea-networkmanager-dev (>= 0.4.0),
libnymea-remoteproxyclient-dev (>= 0.1.13),
libnymea-zigbee-dev (>= 0.1.0),
libnymea-gpio-dev,
libpython3-dev,
libqt5websockets5-dev,
libqt5bluetooth5,

View File

@ -57,7 +57,7 @@
#include "radio433brennenstuhl.h"
#include "loggingcategories.h"
#include "hardware/gpio.h"
#include "gpio.h"
#include <QFileInfo>

View File

@ -38,7 +38,7 @@
#include <QDebug>
#include "libnymea.h"
#include "hardware/gpio.h"
#include "gpio.h"
namespace nymeaserver {

View File

@ -8,7 +8,7 @@ INCLUDEPATH += $$top_srcdir/libnymea $$top_builddir
LIBS += -L$$top_builddir/libnymea/ -lnymea -lssl -lcrypto
CONFIG += link_pkgconfig
PKGCONFIG += nymea-mqtt nymea-networkmanager nymea-zigbee nymea-remoteproxyclient
PKGCONFIG += nymea-mqtt nymea-networkmanager nymea-zigbee nymea-remoteproxyclient nymea-gpio
CONFIG(withoutpython) {
message("Building without python support.")

View File

@ -1,483 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class Gpio
\brief The Gpio class allows to interact with the GPIOs.
\ingroup hardware
\inmodule libnymea
A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
digital signal. They are provided from many kinds of chip, and are familiar
to Linux developers working with embedded and custom hardware. Each GPIO
represents a bit connected to a particular pin, or "ball" on Ball Grid Array
(BGA) packages. Board schematics show which external hardware connects to
which GPIOs. Drivers can be written generically, so that board setup code
passes such pin configuration data to drivers
(\l{https://www.kernel.org/doc/Documentation/gpio/gpio.txt}{source}).
General Purpose Input/Output (a.k.a. GPIO) is a generic pin on a chip whose
behavior (including whether it is an input or output pin) can be controlled
through this class. An object of of the Gpio class represents a pin.
\code
Gpio *gpioOut = new Gpio(23, this);
// Export Gpio
if (!gpioOut->exportGpio()) {
qWarning() << "Could not export Gpio" << gpioOut->gpioNumber();
gpioOut->deleteLater();
return;
}
// Configure Gpio direction
if (!gpioOut->setDirection(PiGpio::DirectionOutput)) {
qWarning() << "Could not set direction of Gpio" << gpioOut->gpioNumber();
gpioOut->deleteLater();
return;
}
gpioOut->setValue(Gpio::ValueHigh)
\endcode
\code
Gpio *gpioIn = new Gpio(24, this);
// Export Gpio
if (!gpioIn->exportGpio()) {
qWarning() << "Could not export Gpio" << gpioIn->gpioNumber();
gpioIn->deleteLater();
return;
}
// Configure Gpio direction
if (!gpioIn->setDirection(PiGpio::DirectionInput)) {
qWarning() << "Could not set direction of Gpio" << gpioIn->gpioNumber();
gpioIn->deleteLater();
return;
}
qDebug() << "Current value" << (bool)gpioIn->value();
\endcode
\sa GpioMonitor
*/
/*! \enum Gpio::Direction
This enum type specifies the dirction a \l{Gpio}.
\value DirectionInput
The \l{Gpio} is configured as \b input.
\value DirectionOutput
The \l{Gpio} is configured as \b output.
\value DirectionInvalid
The direction is not valid.
*/
/*! \enum Gpio::Value
This enum type specifies the value a \l{Gpio}.
\value ValueLow
The \l{Gpio} is low.
\value ValueHigh
The \l{Gpio} is high.
\value ValueInvalid
The value is not valid.
*/
/*! \enum Gpio::Edge
This enum type specifies the edge interrupt type of a \l{Gpio}.
\value EdgeFalling
The \l{Gpio} reacts on falling edge interrupt.
\value EdgeRising
The \l{Gpio} reacts on rising edge interrupt.
\value EdgeBoth
The \l{Gpio} reacts on both, rising and falling edge interrupt.
\value EdgeNone
The \l{Gpio} does not react on interrupts.
*/
#include "gpio.h"
#include "loggingcategories.h"
#include <QDebug>
/*! Constructs a \l{Gpio} object to represent a GPIO with the given \a gpio number and \a parent. */
Gpio::Gpio(const int &gpio, QObject *parent) :
QObject(parent),
m_gpio(gpio),
m_direction(Gpio::DirectionInvalid),
m_gpioDirectory(QDir(QString("/sys/class/gpio/gpio%1/").arg(QString::number(gpio))))
{
m_direction = direction();
}
/*! Destroys and unexports the \l{Gpio}. */
Gpio::~Gpio()
{
unexportGpio();
}
/*! Returns the directory \tt {/sys/class/gpio/gpio<number>} of this Gpio. */
QString Gpio::gpioDirectory() const
{
return m_gpioDirectory.canonicalPath();
}
/*! Returns the number of this \l{Gpio}. \note The Gpio number is mostly not equivalent with the pin number. */
int Gpio::gpioNumber() const
{
return m_gpio;
}
/*! Returns true if the directories \tt {/sys/class/gpio} and \tt {/sys/class/gpio/export} do exist. */
bool Gpio::isAvailable()
{
return QFile("/sys/class/gpio/export").exists();
}
/*! Returns true if this \l{Gpio} could be exported in the system file \tt {/sys/class/gpio/export}. If this Gpio is already exported, this function will return true. */
bool Gpio::exportGpio()
{
// Check if already exported
if (m_gpioDirectory.exists())
return true;
QFile exportFile("/sys/class/gpio/export");
if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO export file:" << exportFile.errorString();
return false;
}
QTextStream out(&exportFile);
out << m_gpio;
exportFile.close();
return true;
}
/*! Returns true if this \l{Gpio} could be unexported in the system file \tt {/sys/class/gpio/unexport}. */
bool Gpio::unexportGpio()
{
QFile unexportFile("/sys/class/gpio/unexport");
if (!unexportFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO unexport file:" << unexportFile.errorString();
return false;
}
QTextStream out(&unexportFile);
out << m_gpio;
unexportFile.close();
return true;
}
/*! Returns true if the \a direction of this GPIO could be set. \sa Gpio::Direction, */
bool Gpio::setDirection(Gpio::Direction direction)
{
if (direction == Gpio::DirectionInvalid) {
qCWarning(dcHardware()) << "Gpio: Setting an invalid direction is forbidden.";
return false;
}
QFile directionFile(m_gpioDirectory.path() + "/direction");
if (!directionFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "direction file:" << directionFile.errorString();
return false;
}
m_direction = direction;
QTextStream out(&directionFile);
switch (m_direction) {
case DirectionInput:
out << "in";
break;
case DirectionOutput:
out << "out";
break;
default:
break;
}
directionFile.close();
return true;
}
/*! Returns the direction of this \l{Gpio}. */
Gpio::Direction Gpio::direction()
{
QFile directionFile(m_gpioDirectory.path() + "/direction");
if (!directionFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "direction file:" << directionFile.errorString();
return Gpio::DirectionInvalid;
}
QString direction;
QTextStream in(&directionFile);
in >> direction;
directionFile.close();
if (direction == "in") {
m_direction = DirectionInput;
return Gpio::DirectionInput;
} else if (direction == "out") {
m_direction = DirectionOutput;
return Gpio::DirectionOutput;
}
return Gpio::DirectionInvalid;
}
/*! Returns true if the digital \a value of this \l{Gpio} could be set correctly. */
bool Gpio::setValue(Gpio::Value value)
{
// Check given value
if (value == Gpio::ValueInvalid) {
qCWarning(dcHardware()) << "Gpio: Setting an invalid value is forbidden.";
return false;
}
// Check current direction
if (m_direction == Gpio::DirectionInput) {
qCWarning(dcHardware()) << "Gpio: Setting the value of an input GPIO is forbidden.";
return false;
}
if (m_direction == Gpio::DirectionInvalid) {
qCWarning(dcHardware()) << "Gpio: The direction of GPIO" << m_gpio << "is invalid.";
return false;
}
QFile valueFile(m_gpioDirectory.path() + "/value");
if (!valueFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "value file:" << valueFile.errorString();
return false;
}
QTextStream out(&valueFile);
switch (value) {
case ValueLow:
out << "0";
break;
case ValueHigh:
out << "1";
break;
default:
valueFile.close();
return false;
}
valueFile.close();
return true;
}
/*! Returns the current digital value of this \l{Gpio}. */
Gpio::Value Gpio::value()
{
QFile valueFile(m_gpioDirectory.path() + "/value");
if (!valueFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "value file:" << valueFile.errorString();
return Gpio::ValueInvalid;
}
QString value;
QTextStream in(&valueFile);
in >> value;
valueFile.close();
if (value == "0") {
return Gpio::ValueLow;
} else if (value == "1") {
return Gpio::ValueHigh;
}
return Gpio::ValueInvalid;
}
/*! This method allows to invert the logic of this \l{Gpio}. Returns true, if the GPIO could be set \a activeLow. */
bool Gpio::setActiveLow(bool activeLow)
{
QFile activeLowFile(m_gpioDirectory.path() + "/active_low");
if (!activeLowFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "active_low file:" << activeLowFile.errorString();
return false;
}
QTextStream out(&activeLowFile);
if (activeLow) {
out << "0";
} else {
out << "1";
}
activeLowFile.close();
return true;
}
/*! Returns true if the logic of this \l{Gpio} is inverted (1 = low, 0 = high). */
bool Gpio::activeLow()
{
QFile activeLowFile(m_gpioDirectory.path() + "/active_low");
if (!activeLowFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "active_low file:" << activeLowFile.errorString();
return false;
}
QString value;
QTextStream in(&activeLowFile);
in >> value;
activeLowFile.close();
if (value == "0")
return true;
return false;
}
/*! Returns true if the \a edge of this GPIO could be set correctly. The \a edge parameter specifies,
* when an interrupt occurs. */
bool Gpio::setEdgeInterrupt(Gpio::Edge edge)
{
if (m_direction == Gpio::DirectionOutput) {
qCWarning(dcHardware()) << "Gpio: Could not set edge interrupt, GPIO is configured as an output.";
return false;
}
QFile edgeFile(m_gpioDirectory.path() + "/edge");
if (!edgeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "edge file:" << edgeFile.errorString();
return false;
}
QTextStream out(&edgeFile);
switch (edge) {
case EdgeFalling:
out << "falling";
break;
case EdgeRising:
out << "rising";
break;
case EdgeBoth:
out << "both";
break;
case EdgeNone:
out << "none";
break;
default:
return false;
}
edgeFile.close();
return true;
}
/*! Returns the edge interrupt of this \l{Gpio}. */
Gpio::Edge Gpio::edgeInterrupt()
{
QFile edgeFile(m_gpioDirectory.path() + "/edge");
if (!edgeFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(dcHardware()) << "Gpio: Could not open GPIO" << m_gpio << "edge file:" << edgeFile.errorString();
return Gpio::EdgeNone;
}
QString edge;
QTextStream in(&edgeFile);
in >> edge;
edgeFile.close();
if (edge.contains("falling")) {
return Gpio::EdgeFalling;
} else if (edge.contains("rising")) {
return Gpio::EdgeRising;
} else if (edge.contains("both")) {
return Gpio::EdgeBoth;
} else if (edge.contains("none")) {
return Gpio::EdgeNone;
}
return Gpio::EdgeNone;
}
QDebug operator<<(QDebug debug, Gpio *gpio)
{
debug.nospace() << "Gpio(" << gpio->gpioNumber() << ", ";
if (gpio->direction() == Gpio::DirectionInput) {
debug.nospace() << "Input, ";
} else if (gpio->direction() == Gpio::DirectionOutput) {
debug.nospace() << "Output, ";
} else {
debug.nospace() << "Invalid, ";
}
switch (gpio->edgeInterrupt()) {
case Gpio::EdgeFalling:
debug.nospace() << "Ir: Falling, ";
break;
case Gpio::EdgeRising:
debug.nospace() << "Ir: Rising, ";
break;
case Gpio::EdgeBoth:
debug.nospace() << "Ir: Both, ";
break;
case Gpio::EdgeNone:
debug.nospace() << "Ir: None, ";
break;
default:
break;
}
if (gpio->activeLow()) {
debug.nospace() << "Active Low: 1, ";
} else {
debug.nospace() << "Active Low: 0, ";
}
if (gpio->value() == Gpio::ValueHigh) {
debug.nospace() << "Value: 1)";
} else if (gpio->value() == Gpio::ValueLow) {
debug.nospace() << "Value: 0)";
} else {
debug.nospace() << "Value: Invalid)";
}
return debug;
}

View File

@ -1,98 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef GPIO_H
#define GPIO_H
#include <QObject>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include "libnymea.h"
class LIBNYMEA_EXPORT Gpio : public QObject
{
Q_OBJECT
public:
enum Direction {
DirectionInput,
DirectionOutput,
DirectionInvalid
};
enum Value {
ValueLow = 0,
ValueHigh = 1,
ValueInvalid = -1
};
enum Edge {
EdgeFalling,
EdgeRising,
EdgeBoth,
EdgeNone
};
explicit Gpio(const int &gpio, QObject *parent = nullptr);
~Gpio();
QString gpioDirectory() const;
int gpioNumber() const;
static bool isAvailable();
bool exportGpio();
bool unexportGpio();
bool setDirection(Gpio::Direction direction);
Gpio::Direction direction();
bool setValue(Gpio::Value value);
Gpio::Value value();
bool setActiveLow(bool activeLow);
bool activeLow();
bool setEdgeInterrupt(Gpio::Edge edge);
Gpio::Edge edgeInterrupt();
private:
int m_gpio;
Gpio::Direction m_direction;
QDir m_gpioDirectory;
};
QDebug operator<< (QDebug debug, Gpio *gpio);
#endif // GPIO_H

View File

@ -1,172 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class GpioMonitor
\brief The GpioMonitor class allows to monitor GPIOs.
\ingroup hardware
\inmodule libnymea
An instance of this class creates a thread, which monitors each of the added GPIOs. The object
emits a signal if one of the added GPIOs changes its value. The GpioMonitor configures a GPIO as an
input, with the edge interrupt EDGE_BOTH (\l{Gpio::setEdgeInterrupt()}{setEdgeInterrupt}).
\chapter Example
Following example shows how to use the GpioMonitor class for a button on the Raspberry Pi. There are two possibilitys
to connect a button. Following picture shows the schematics:
\image Raspberry_Pi_Button_Example.png "Raspberry Pi button example"
Button A represents a clean solutin with a 10 k\unicode{0x2126} resistor (set up as activeLow = false).
Button B represents a "dirty" solution, were the 3.3V will be directly connected to the GPIO if the button is pressed (set activeLow = true).
Here is the code example for a button class:
\code
Button::Button(QObject *parent) :
QObject(parent)
{
m_button = new GpioMonitor(110, this);
connect(m_button, &GpioMonitor::valueChanged, this, &Button::stateChanged);
}
bool Button::init()
{
return m_button->enable();
}
void Button::stateChanged(const bool &value)
{
if (m_pressed != value) {
m_pressed = value;
if (value) {
emit buttonPressed();
} else {
emit buttonReleased();
}
}
}
\endcode
*/
/*! \fn void GpioMonitor::valueChanged(const bool &value);
* This signal will be emitted, if the monitored \l{Gpio}{Gpios} changed his \a value. */
#include "gpiomonitor.h"
#include "loggingcategories.h"
/*! Constructs a \l{GpioMonitor} object with the given \a gpio number and \a parent. */
GpioMonitor::GpioMonitor(int gpio, QObject *parent) :
QObject(parent),
m_gpioNumber(gpio)
{
m_valueFile.setFileName("/sys/class/gpio/gpio" + QString::number(m_gpioNumber) + "/value");
}
/*! Returns true if this \l{GpioMonitor} could be enabled successfully. With the \a activeLow parameter the values can be inverted.
With the \a edgeInterrupt parameter the interrupt type can be specified. */
bool GpioMonitor::enable(bool activeLow, Gpio::Edge edgeInterrupt)
{
if (!Gpio::isAvailable())
return false;
m_gpio = new Gpio(m_gpioNumber, this);
if (!m_gpio->exportGpio() ||
!m_gpio->setDirection(Gpio::DirectionInput) ||
!m_gpio->setActiveLow(activeLow) ||
!m_gpio->setEdgeInterrupt(edgeInterrupt)) {
qCWarning(dcHardware()) << "GpioMonitor: Error while initializing GPIO" << m_gpio->gpioNumber();
return false;
}
if (!m_valueFile.open(QFile::ReadOnly)) {
qWarning(dcHardware()) << "GpioMonitor: Could not open value file for gpio monitor" << m_gpio->gpioNumber();
return false;
}
m_notifier = new QSocketNotifier(m_valueFile.handle(), QSocketNotifier::Exception);
connect(m_notifier, &QSocketNotifier::activated, this, &GpioMonitor::readyReady);
m_notifier->setEnabled(true);
return true;
}
/*! Disables this \l{GpioMonitor}. */
void GpioMonitor::disable()
{
delete m_notifier;
delete m_gpio;
m_notifier = 0;
m_gpio = 0;
m_valueFile.close();
}
/*! Returns true if this \l{GpioMonitor} is running. */
bool GpioMonitor::isRunning() const
{
if (!m_notifier)
return false;
return m_notifier->isEnabled();
}
/*! Returns the current value of this \l{GpioMonitor}. */
bool GpioMonitor::value() const
{
return m_currentValue;
}
/*! Returns the \l{Gpio} of this \l{GpioMonitor}. */
Gpio *GpioMonitor::gpio()
{
return m_gpio;
}
void GpioMonitor::readyReady(const int &ready)
{
Q_UNUSED(ready)
m_valueFile.seek(0);
QByteArray data = m_valueFile.readAll();
bool value = false;
if (data[0] == '1') {
value = true;
} else if (data[0] == '0') {
value = false;
} else {
return;
}
m_currentValue = value;
emit valueChanged(value);
}

View File

@ -1,72 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef GPIOMONITOR_H
#define GPIOMONITOR_H
#include <QObject>
#include <QDebug>
#include <QSocketNotifier>
#include <QFile>
#include "libnymea.h"
#include "gpio.h"
class LIBNYMEA_EXPORT GpioMonitor : public QObject
{
Q_OBJECT
public:
explicit GpioMonitor(int gpio, QObject *parent = nullptr);
bool enable(bool activeLow = false, Gpio::Edge edgeInterrupt = Gpio::EdgeBoth);
void disable();
bool isRunning() const;
bool value() const;
Gpio* gpio();
private:
int m_gpioNumber;
Gpio *m_gpio;
QSocketNotifier *m_notifier;
QFile m_valueFile;
bool m_currentValue;
signals:
void valueChanged(const bool &value);
private slots:
void readyReady(const int &ready);
};
#endif // GPIOMONITOR_H

View File

@ -65,7 +65,7 @@
#include "radio433.h"
#include "loggingcategories.h"
#include "hardware/gpio.h"
#include "gpio.h"
#include <QFileInfo>

View File

@ -9,7 +9,7 @@ QT -= gui
DEFINES += LIBNYMEA_LIBRARY
CONFIG += link_pkgconfig
PKGCONFIG += nymea-zigbee nymea-mqtt
PKGCONFIG += nymea-zigbee nymea-mqtt nymea-gpio
QMAKE_LFLAGS += -fPIC
@ -65,8 +65,6 @@ HEADERS += \
typeutils.h \
loggingcategories.h \
nymeasettings.h \
hardware/gpio.h \
hardware/gpiomonitor.h \
hardware/pwm.h \
hardware/radio433/radio433.h \
network/upnp/upnpdiscovery.h \
@ -162,8 +160,6 @@ SOURCES += \
nymeasettings.cpp \
platform/package.cpp \
platform/repository.cpp \
hardware/gpio.cpp \
hardware/gpiomonitor.cpp \
hardware/pwm.cpp \
hardware/radio433/radio433.cpp \
network/upnp/upnpdiscovery.cpp \