From 40a60f155028f63480a5736da49cbea7af9f8ba0 Mon Sep 17 00:00:00 2001
From: Florent Revest <revestflo@gmail.com>
Date: Tue, 30 Apr 2019 22:16:11 +0200
Subject: [PATCH 1/6] Add heart rate monitor sensor with sensorfw backend

---
 src/imports/sensors/qmlhrmsensor.cpp          | 144 ++++++++++++++
 src/imports/sensors/qmlhrmsensor.h            |  90 +++++++++
 src/imports/sensors/sensors.cpp               |   4 +
 src/imports/sensors/sensors.pro               |   6 +-
 src/plugins/sensors/sensorfw/Sensors.conf     |   1 +
 src/plugins/sensors/sensorfw/main.cpp         |   3 +
 src/plugins/sensors/sensorfw/sensorfw.pri     |   4 +-
 .../sensors/sensorfw/sensorfwhrmsensor.cpp    | 100 ++++++++++
 .../sensors/sensorfw/sensorfwhrmsensor.h      |  70 +++++++
 src/sensors/doc/src/compatmap.qdoc            |  10 +
 src/sensors/qhrmsensor.cpp                    | 184 ++++++++++++++++++
 src/sensors/qhrmsensor.h                      | 104 ++++++++++
 src/sensors/qhrmsensor_p.h                    |  83 ++++++++
 src/sensors/sensors.pro                       |   3 +-
 14 files changed, 802 insertions(+), 4 deletions(-)
 create mode 100644 src/imports/sensors/qmlhrmsensor.cpp
 create mode 100644 src/imports/sensors/qmlhrmsensor.h
 create mode 100644 src/plugins/sensors/sensorfw/sensorfwhrmsensor.cpp
 create mode 100644 src/plugins/sensors/sensorfw/sensorfwhrmsensor.h
 create mode 100644 src/sensors/qhrmsensor.cpp
 create mode 100644 src/sensors/qhrmsensor.h
 create mode 100644 src/sensors/qhrmsensor_p.h

diff --git a/src/imports/sensors/qmlhrmsensor.cpp b/src/imports/sensors/qmlhrmsensor.cpp
new file mode 100644
index 0000000..361f176
--- /dev/null
+++ b/src/imports/sensors/qmlhrmsensor.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlhrmsensor.h"
+
+/*!
+    \qmltype HrmSensor
+    \instantiates QmlHrmSensor
+    \ingroup qml-sensors_type
+    \inqmlmodule QtSensors
+    \since QtSensors 5.0
+    \inherits Sensor
+    \brief The HrmSensor element reports on the user's heart rate in bpm.
+
+    The HrmSensor element reports on the user's heart rate in bpm.
+
+    This element wraps the QHrmSensor class. Please see the documentation for
+    QHrmSensor for details.
+
+    \sa HrmReading
+*/
+
+QmlHrmSensor::QmlHrmSensor(QObject *parent)
+    : QmlSensor(parent)
+    , m_sensor(new QHrmSensor(this))
+{
+    connect(m_sensor, SIGNAL(statusChanged(QHrmSensor::Status)),
+            this, SIGNAL(statusChanged(QHrmSensor::Status)));
+}
+
+QmlHrmSensor::~QmlHrmSensor()
+{
+}
+
+QmlSensorReading *QmlHrmSensor::createReading() const
+{
+    return new QmlHrmSensorReading(m_sensor);
+}
+
+QSensor *QmlHrmSensor::sensor() const
+{
+    return m_sensor;
+}
+
+/*!
+    \qmlproperty qreal HrmSensor::status
+    This property holds a value indicating the status of the heart rate monitor.
+
+    Please see QHrmSensor::status for information about this property.
+*/
+
+QHrmSensor::Status QmlHrmSensor::status() const
+{
+    return m_sensor->status();
+}
+
+/*!
+    \qmltype HrmReading
+    \instantiates QmlHrmSensorReading
+    \ingroup qml-sensors_reading
+    \inqmlmodule QtSensors
+    \since QtSensors 5.0
+    \inherits SensorReading
+    \brief The HrmReading element holds the most recent HrmSensor reading.
+
+    The HrmReading element holds the most recent HrmSensor reading.
+
+    This element wraps the QHrmReading class. Please see the documentation for
+    QHrmReading for details.
+
+    This element cannot be directly created.
+*/
+
+QmlHrmSensorReading::QmlHrmSensorReading(QHrmSensor *sensor)
+    : QmlSensorReading(sensor)
+    , m_sensor(sensor)
+{
+}
+
+QmlHrmSensorReading::~QmlHrmSensorReading()
+{
+}
+
+/*!
+    \qmlproperty qreal HrmReading::bpm
+    This property holds the number of beats per minute.
+
+    Please see QHrmReading::bpm for information about this property.
+*/
+
+int QmlHrmSensorReading::bpm() const
+{
+    return m_bpm;
+}
+
+QSensorReading *QmlHrmSensorReading::reading() const
+{
+    return m_sensor->reading();
+}
+
+void QmlHrmSensorReading::readingUpdate()
+{
+    int bpm = m_sensor->reading()->bpm();
+    if (m_bpm != bpm) {
+        m_bpm = bpm;
+        Q_EMIT bpmChanged();
+    }
+}
diff --git a/src/imports/sensors/qmlhrmsensor.h b/src/imports/sensors/qmlhrmsensor.h
new file mode 100644
index 0000000..e83290c
--- /dev/null
+++ b/src/imports/sensors/qmlhrmsensor.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLHRMSENSOR_H
+#define QMLHRMSENSOR_H
+
+#include "qmlsensor.h"
+#include <QtSensors/QHrmSensor>
+
+QT_BEGIN_NAMESPACE
+
+class QHrmSensor;
+
+class QmlHrmSensor : public QmlSensor
+{
+    Q_OBJECT
+    Q_PROPERTY(QHrmSensor::Status status READ status NOTIFY statusChanged)
+public:
+    explicit QmlHrmSensor(QObject *parent = 0);
+    ~QmlHrmSensor();
+
+    QHrmSensor::Status status() const;
+
+Q_SIGNALS:
+    void statusChanged(QHrmSensor::Status status);
+
+private:
+    QSensor *sensor() const override;
+    QHrmSensor *m_sensor;
+    QmlSensorReading *createReading() const override;
+};
+
+class QmlHrmSensorReading : public QmlSensorReading
+{
+    Q_OBJECT
+    Q_PROPERTY(int bpm READ bpm NOTIFY bpmChanged)
+public:
+    explicit QmlHrmSensorReading(QHrmSensor *sensor);
+    ~QmlHrmSensorReading();
+
+    int bpm() const;
+
+Q_SIGNALS:
+    void bpmChanged();
+
+private:
+    QSensorReading *reading() const override;
+    void readingUpdate() override;
+    QHrmSensor *m_sensor;
+    int m_bpm;
+};
+
+QT_END_NAMESPACE
+#endif
diff --git a/src/imports/sensors/sensors.cpp b/src/imports/sensors/sensors.cpp
index ffa09d8..1a365e6 100644
--- a/src/imports/sensors/sensors.cpp
+++ b/src/imports/sensors/sensors.cpp
@@ -56,6 +56,7 @@
 #include <QtSensors/qirproximitysensor.h>
 #include <QtSensors/qtiltsensor.h>
 #include <QtSensors/qlidsensor.h>
+#include <QtSensors/qhrmsensor.h>
 
 #include "qmlsensorglobal.h"
 #include "qmlsensor.h"
@@ -77,6 +78,7 @@
 #include "qmltiltsensor.h"
 #include "qmlsensorgesture.h"
 #include "qmllidsensor.h"
+#include "qmlhrmsensor.h"
 
 static void initResources()
 {
@@ -161,6 +163,8 @@ public:
         qmlRegisterUncreatableType<QmlGyroscopeReading         >(package, major, minor, "GyroscopeReading",     QLatin1String("Cannot create GyroscopeReading"));
         qmlRegisterType           <QmlHolsterSensor            >(package, major, minor, "HolsterSensor");
         qmlRegisterUncreatableType<QmlHolsterReading           >(package, major, minor, "HolsterReading",       QLatin1String("Cannot create HolsterReading"));
++        qmlRegisterType           <QmlHrmSensor                >(package, major, minor, "HrmSensor");
++        qmlRegisterUncreatableType<QmlHrmSensorReading         >(package, major, minor, "HrmReading",          QLatin1String("Cannot create HrmReading"));
         qmlRegisterType           <QmlIRProximitySensor        >(package, major, minor, "IRProximitySensor");
         qmlRegisterUncreatableType<QmlIRProximitySensorReading >(package, major, minor, "IRProximityReading",   QLatin1String("Cannot create IRProximityReading"));
         qmlRegisterType           <QmlLightSensor              >(package, major, minor, "LightSensor");
diff --git a/src/imports/sensors/sensors.pro b/src/imports/sensors/sensors.pro
index d627916..e114dbb 100644
--- a/src/imports/sensors/sensors.pro
+++ b/src/imports/sensors/sensors.pro
@@ -23,7 +23,8 @@ HEADERS += \
     qmltiltsensor.h \
     qmlsensorgesture.h \
     qmlhumiditysensor.h \
-    qmllidsensor.h
+    qmllidsensor.h \
+    qmlhrmsensor.h
 
 SOURCES += sensors.cpp \
     qmlsensor.cpp \
@@ -48,7 +49,8 @@ SOURCES += sensors.cpp \
     qmltiltsensor.cpp \
     qmlsensorgesture.cpp \
     qmlhumiditysensor.cpp \
-    qmllidsensor.cpp
+    qmllidsensor.cpp \
+    qmlhrmsensor.cpp
 
 load(qml_plugin)
 
diff --git a/src/plugins/sensors/sensorfw/Sensors.conf b/src/plugins/sensors/sensorfw/Sensors.conf
index b3db5ff..cd2985c 100644
--- a/src/plugins/sensors/sensorfw/Sensors.conf
+++ b/src/plugins/sensors/sensorfw/Sensors.conf
@@ -11,3 +11,4 @@ QLightSensor=sensorfw.lightsensor
 QIRProximitySensor=sensorfw.irproximitysensor
 QGyroscope=sensorfw.gyroscope
 QLidSensor=sensorfw.lidsensor
+QHrmSensor=sensorfw.hrmsensor
diff --git a/src/plugins/sensors/sensorfw/main.cpp b/src/plugins/sensors/sensorfw/main.cpp
index c1a02a5..3c7587d 100644
--- a/src/plugins/sensors/sensorfw/main.cpp
+++ b/src/plugins/sensors/sensorfw/main.cpp
@@ -49,6 +49,7 @@
 #include "sensorfwgyroscope.h"
 #include "sensorfwlightsensor.h"
 #include "sensorfwlidsensor.h"
+#include "sensorfwhrmsensor.h"
 
 #include <QtSensors/qsensorplugin.h>
 #include <QtSensors/qsensorbackend.h>
@@ -104,6 +105,8 @@ public:
             return new SensorfwLightSensor(sensor);
         if (sensor->identifier() == SensorfwIrProximitySensor::id)
             return new SensorfwIrProximitySensor(sensor);
+        if (sensor->identifier() == SensorfwHrmSensor::id)
+            return new SensorfwHrmSensor(sensor);
         return 0;
     }
 };
diff --git a/src/plugins/sensors/sensorfw/sensorfw.pri b/src/plugins/sensors/sensorfw/sensorfw.pri
index ce8e3ab..6b21201 100644
--- a/src/plugins/sensors/sensorfw/sensorfw.pri
+++ b/src/plugins/sensors/sensorfw/sensorfw.pri
@@ -10,7 +10,8 @@ HEADERS += sensorfwsensorbase.h \
     sensorfwtapsensor.h    \
     sensorfwlightsensor.h  \
     sensorfwirproximitysensor.h \
-    sensorfwlidsensor.h
+    sensorfwlidsensor.h \
+    sensorfwhrmsensor.h
 
 SOURCES += sensorfwsensorbase.cpp \
     sensorfwaccelerometer.cpp \
@@ -25,4 +26,5 @@ SOURCES += sensorfwsensorbase.cpp \
     sensorfwtapsensor.cpp \
     sensorfwlightsensor.cpp \
     sensorfwlidsensor.cpp \
+    sensorfwhrmsensor.cpp \
     main.cpp
diff --git a/src/plugins/sensors/sensorfw/sensorfwhrmsensor.cpp b/src/plugins/sensors/sensorfw/sensorfwhrmsensor.cpp
new file mode 100644
index 0000000..38126a5
--- /dev/null
+++ b/src/plugins/sensors/sensorfw/sensorfwhrmsensor.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sensorfwhrmsensor.h"
+
+char const * const SensorfwHrmSensor::id("sensorfw.hrmsensor");
+
+SensorfwHrmSensor::SensorfwHrmSensor(QSensor *sensor)
+    : SensorfwSensorBase(sensor)
+    , m_initDone(false)
+{
+    init();
+    setReading<QHrmReading>(&m_reading);
+    sensor->setDataRate(10);//set a default rate
+    m_sensor = (QHrmSensor *)sensor;
+}
+
+void SensorfwHrmSensor::slotDataAvailable(const HeartRate& data)
+{
+    m_reading.setBpm(data.heartRateData().bpm_);
+    m_reading.setTimestamp(data.heartRateData().timestamp_);
+    switch(data.heartRateData().status_) {
+        case HrmUnreliable:
+            m_sensor->setStatus(QHrmSensor::Unreliable);
+            break;
+        case HrmAccuracyLow:
+            m_sensor->setStatus(QHrmSensor::AccuracyLow);
+            break;
+        case HrmAccuracyMedium:
+            m_sensor->setStatus(QHrmSensor::AccuracyMedium);
+            break;
+        case HrmAccuracyHigh:
+            m_sensor->setStatus(QHrmSensor::AccuracyHigh);
+            break;
+        case HrmNoContact:
+            m_sensor->setStatus(QHrmSensor::NoContact);
+    }
+    newReadingAvailable();
+}
+
+bool SensorfwHrmSensor::doConnect()
+{
+    Q_ASSERT(m_sensorInterface);
+    return QObject::connect(m_sensorInterface, SIGNAL(HrmChanged(HeartRate)),
+                            this, SLOT(slotDataAvailable(HeartRate)));
+}
+
+QString SensorfwHrmSensor::sensorName() const
+{
+    return "hrmsensor";
+}
+
+void SensorfwHrmSensor::init()
+{
+    m_initDone = false;
+    initSensor<HrmSensorChannelInterface>(m_initDone);
+}
+
+void SensorfwHrmSensor::start()
+{
+    if (reinitIsNeeded)
+        init();
+    SensorfwSensorBase::start();
+}
diff --git a/src/plugins/sensors/sensorfw/sensorfwhrmsensor.h b/src/plugins/sensors/sensorfw/sensorfwhrmsensor.h
new file mode 100644
index 0000000..21f5bc9
--- /dev/null
+++ b/src/plugins/sensors/sensorfw/sensorfwhrmsensor.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef SENSORFWHRMSENSOR_H
+#define SENSORFWHRMSENSOR_H
+
+#include "sensorfwsensorbase.h"
+#include <QtSensors/qhrmsensor.h>
+
+#include <hrmsensor_i.h>
+
+
+class SensorfwHrmSensor : public SensorfwSensorBase
+{
+    Q_OBJECT
+
+public:
+    static char const * const id;
+    SensorfwHrmSensor(QSensor *sensor);
+protected:
+    bool doConnect() override;
+    QString sensorName() const override;
+    void start() override;
+    virtual void init();
+private:
+    QHrmReading m_reading;
+    QHrmSensor *m_sensor;
+    bool m_initDone;
+private slots:
+    void slotDataAvailable(const HeartRate& data);
+};
+
+#endif
diff --git a/src/sensors/doc/src/compatmap.qdoc b/src/sensors/doc/src/compatmap.qdoc
index d91c0c5..41461f9 100644
--- a/src/sensors/doc/src/compatmap.qdoc
+++ b/src/sensors/doc/src/compatmap.qdoc
@@ -142,6 +142,16 @@
     <td bgcolor="gray"></td>
     </tr>
     <tr>
+    <td nowrap="nowrap">Heart Rate Monitor</td>
+    <td bgcolor="gray"></td>
+    <td bgcolor="gray"></td>
+    <td bgcolor="gray"></td>
+    <td bgcolor="gray"></td>
+    <td bgcolor="gray"></td>
+    <td bgcolor="green"></td>
+    <td bgcolor="gray"></td>
+    </tr>
+    <tr>
     <td nowrap="nowrap">Humidity Sensor</td>
     <td bgcolor="gray"></td>
     <td bgcolor="gray"></td>
diff --git a/src/sensors/qhrmsensor.cpp b/src/sensors/qhrmsensor.cpp
new file mode 100644
index 0000000..7b09e7d
--- /dev/null
+++ b/src/sensors/qhrmsensor.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhrmsensor.h"
+#include "qhrmsensor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+IMPLEMENT_READING(QHrmReading)
+
+/*!
+    \class QHrmReading
+    \ingroup sensors_reading
+    \inmodule QtSensors
+    \since 5.1
+
+    \brief The QHrmReading class represents one reading from the
+           heart rate monitor.
+
+    \section2 QHemReading Units
+    The heart rate monitor returns the user's heart rate in beats per minute.
+*/
+
+/*!
+    \property QHrmReading::bpm
+    \brief the beats per minute.
+
+    Measured as Hz.
+    \sa {QHrmReading Units}
+*/
+
+int QHrmReading::bpm() const
+{
+    return d->bpm;
+}
+
+/*!
+    Sets the beats per minute to \a bpm.
+*/
+void QHrmReading::setBpm(int bpm)
+{
+    d->bpm = bpm;
+}
+
+// =====================================================================
+
+/*!
+    \class QHrmFilter
+    \ingroup sensors_filter
+    \inmodule QtSensors
+    \since 5.1
+
+    \brief The QHrmFilter class is a convenience wrapper around QSensorFilter.
+
+    The only difference is that the filter() method features a pointer to QHrmReading
+    instead of QSensorReading.
+*/
+
+/*!
+    \fn QHrmFilter::filter(QHrmReading *reading)
+
+    Called when \a reading changes. Returns false to prevent the reading from propagating.
+
+    \sa QSensorFilter::filter()
+*/
+
+bool QHrmFilter::filter(QSensorReading *reading)
+{
+    return filter(static_cast<QHrmReading*>(reading));
+}
+
+char const * const QHrmSensor::type("QHrmSensor");
+
+/*!
+    \class QHrmSensor
+    \ingroup sensors_type
+    \inmodule QtSensors
+    \since 5.1
+
+    \brief The QHrmSensor class is a convenience wrapper around QSensor.
+
+    The only behavioural difference is that this class sets the type properly.
+
+    This class also features a reading() function that returns a QHrmReading instead of a QSensorReading.
+
+    For details about how the sensor works, see \l QHrmReading.
+
+    \sa QHrmReading
+*/
+
+/*!
+    Construct the sensor as a child of \a parent.
+*/
+QHrmSensor::QHrmSensor(QObject *parent)
+    : QSensor(QHrmSensor::type, *new QHrmSensorPrivate, parent)
+{
+}
+
+/*!
+    Destroy the sensor. Stops the sensor if it has not already been stopped.
+*/
+QHrmSensor::~QHrmSensor()
+{
+}
+
+/*!
+    \fn QHrmSensor::reading() const
+
+    Returns the reading class for this sensor.
+
+    \sa QSensor::reading()
+*/
+
+QHrmReading *QHrmSensor::reading() const
+{
+    return static_cast<QHrmReading*>(QSensor::reading());
+}
+
+/*!
+    \property QHrmSensor::status
+    \brief a value indicating the status of the heart rate monitor.
+
+    This is an enum that represents the status of the sensor.
+*/
+
+QHrmSensor::Status QHrmSensor::status() const
+{
+    Q_D(const QHrmSensor);
+    return d->status;
+}
+
+/*!
+    \since 5.1
+
+    Sets the status to \a status. This is to be called from the backend.
+*/
+void QHrmSensor::setStatus(QHrmSensor::Status status)
+{
+    Q_D(QHrmSensor);
+    if (d->status != status) {
+        d->status = status;
+        emit statusChanged(status);
+    }
+}
+
+#include "moc_qhrmsensor.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/sensors/qhrmsensor.h b/src/sensors/qhrmsensor.h
new file mode 100644
index 0000000..241fb2b
--- /dev/null
+++ b/src/sensors/qhrmsensor.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHRMSENSOR_H
+#define QHRMSENSOR_H
+
+#include <QtSensors/qsensor.h>
+
+QT_BEGIN_NAMESPACE
+
+class QHrmReadingPrivate;
+
+class Q_SENSORS_EXPORT QHrmReading : public QSensorReading
+{
+    Q_OBJECT
+    Q_PROPERTY(int bpm READ bpm)
+    DECLARE_READING(QHrmReading)
+public:
+    int bpm() const;
+    void setBpm(int bpm);
+};
+
+class Q_SENSORS_EXPORT QHrmFilter : public QSensorFilter
+{
+public:
+    virtual bool filter(QHrmReading *reading) = 0;
+private:
+    bool filter(QSensorReading *reading) override;
+};
+
+class QHrmSensorPrivate;
+
+class Q_SENSORS_EXPORT QHrmSensor : public QSensor
+{
+    Q_OBJECT
+    Q_ENUMS (Status)
+    Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+
+public:
+    enum Status
+    {
+        NoContact,
+        Unreliable,
+        AccuracyLow,
+        AccuracyMedium,
+        AccuracyHigh
+    };
+
+    explicit QHrmSensor(QObject *parent = Q_NULLPTR);
+    virtual ~QHrmSensor();
+    QHrmReading *reading() const;
+    static char const * const type;
+
+    QHrmSensor::Status status() const;
+    void setStatus(Status status);
+
+Q_SIGNALS:
+    void statusChanged(Status status);
+
+private:
+    Q_DECLARE_PRIVATE(QHrmSensor)
+    Q_DISABLE_COPY(QHrmSensor)
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/sensors/qhrmsensor_p.h b/src/sensors/qhrmsensor_p.h
new file mode 100644
index 0000000..2968a99
--- /dev/null
+++ b/src/sensors/qhrmsensor_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHRMSENSOR_P_H
+#define QHRMSENSOR_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsensor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QHrmReadingPrivate : public QSensorReadingPrivate
+{
+public:
+    QHrmReadingPrivate()
+        : bpm(0)
+    {
+    }
+
+    int bpm;
+};
+
+class QHrmSensorPrivate : public QSensorPrivate
+{
+public:
+    QHrmSensorPrivate()
+        : status(QHrmSensor::NoContact)
+    {
+    }
+
+    QHrmSensor::Status status;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/sensors/sensors.pro b/src/sensors/sensors.pro
index eaaa73f..f5d303f 100644
--- a/src/sensors/sensors.pro
+++ b/src/sensors/sensors.pro
@@ -71,7 +71,8 @@ SENSORS=\
     qgyroscope\
     qpressuresensor \
     qhumiditysensor \
-    qlidsensor
+    qlidsensor \
+    qhrmsensor
 
 for(s,SENSORS) {
     # Client API
-- 
2.31.1

