From 4b5beeedda5e129018c167dd0a5cd1f17fc5c246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kari=20Hautam=C3=A4ki?= Date: Mon, 13 Feb 2017 10:28:20 +0200 Subject: iot-sensortag: Add sensor tag setup for Embedded World - Added two sensor tags with unique capabilities by faking that each provide only a subset of available sensor data Change-Id: I9b7ad9f7b41ea7c5abaad0bc3fbe063219b19a9e Reviewed-by: Titta Heikkala --- tradeshow/iot-sensortag/bluetoothdataprovider.cpp | 4 +- tradeshow/iot-sensortag/bluetoothdevice.cpp | 17 +- tradeshow/iot-sensortag/bluetoothdevice.h | 1 + tradeshow/iot-sensortag/demodataproviderpool.cpp | 246 ++++++++++++++++++++- tradeshow/iot-sensortag/demodataproviderpool.h | 43 +++- tradeshow/iot-sensortag/main.cpp | 7 +- tradeshow/iot-sensortag/sensortagdataprovider.cpp | 5 + tradeshow/iot-sensortag/sensortagdataprovider.h | 59 ++--- .../iot-sensortag/sensortagdataproviderpool.cpp | 10 +- .../iot-sensortag/sensortagdataproviderpool.h | 1 + 10 files changed, 344 insertions(+), 49 deletions(-) diff --git a/tradeshow/iot-sensortag/bluetoothdataprovider.cpp b/tradeshow/iot-sensortag/bluetoothdataprovider.cpp index 0d2a750..e3c746c 100644 --- a/tradeshow/iot-sensortag/bluetoothdataprovider.cpp +++ b/tradeshow/iot-sensortag/bluetoothdataprovider.cpp @@ -87,7 +87,6 @@ bool BluetoothDataProvider::startDataFetching() timer.setSingleShot(true); connect(&timer, &QTimer::timeout, this, &BluetoothDataProvider::startServiceScan); timer.start(); - qCDebug(boot2QtDemos) << "Active Device is now " << activeDevice->getName() << " at "<< activeDevice->getAddress(); } return true; } @@ -218,6 +217,9 @@ void BluetoothDataProvider::updateState() case BluetoothDevice::Disconnected: setState(Disconnected); break; + case BluetoothDevice::Scanning: + setState(Scanning); + break; case BluetoothDevice::Connected: setState(Connected); break; diff --git a/tradeshow/iot-sensortag/bluetoothdevice.cpp b/tradeshow/iot-sensortag/bluetoothdevice.cpp index 4f6abe9..c37a5ea 100644 --- a/tradeshow/iot-sensortag/bluetoothdevice.cpp +++ b/tradeshow/iot-sensortag/bluetoothdevice.cpp @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include "bluetoothapiconstants.h" @@ -264,6 +263,7 @@ void BluetoothDevice::temperatureDetailsDiscovered(QLowEnergyService::ServiceSta } m_temperatureMeasurementStarted = true; + isDeviceReady(); } } @@ -302,6 +302,7 @@ void BluetoothDevice::barometerDetailsDiscovered(QLowEnergyService::ServiceState } m_barometerMeasurementStarted = true; + isDeviceReady(); } } @@ -341,6 +342,7 @@ void BluetoothDevice::humidityDetailsDiscovered(QLowEnergyService::ServiceState } m_humidityMeasurementStarted = true; + isDeviceReady(); } } @@ -380,6 +382,7 @@ void BluetoothDevice::lightIntensityDetailsDiscovered(QLowEnergyService::Service } m_lightIntensityMeasurementStarted = true; + isDeviceReady(); } } @@ -421,6 +424,7 @@ void BluetoothDevice::motionDetailsDiscovered(QLowEnergyService::ServiceState ne motionService->writeCharacteristic(characteristic, QByteArray::fromHex(SENSORTAG_RAPID_TIMER_TIMEOUT_STR), QLowEnergyService::WriteWithResponse); } m_motionMeasurementStarted = true; + isDeviceReady(); } } @@ -466,6 +470,15 @@ double BluetoothDevice::convertIrTemperatureAPIReadingToCelsius(quint16 rawReadi return t * SCALE_LSB; } +void BluetoothDevice::isDeviceReady() const +{ + if (m_temperatureMeasurementStarted && + m_humidityMeasurementStarted && + m_lightIntensityMeasurementStarted && + m_motionMeasurementStarted) + setState(DeviceState::Connected); +} + void BluetoothDevice::irTemperatureReceived(const QByteArray &value) { const unsigned int rawObjectTemperature = (((quint8)value.at(3)) << 8) + ((quint8)value.at(2)); @@ -551,7 +564,7 @@ void BluetoothDevice::motionReceived(const QByteArray &value) void BluetoothDevice::deviceConnected() { - setState(DeviceState::Connected); + setState(DeviceState::Scanning); statusUpdated("(Discovering services...)"); controller->discoverServices(); } diff --git a/tradeshow/iot-sensortag/bluetoothdevice.h b/tradeshow/iot-sensortag/bluetoothdevice.h index 39a344e..94a12c3 100644 --- a/tradeshow/iot-sensortag/bluetoothdevice.h +++ b/tradeshow/iot-sensortag/bluetoothdevice.h @@ -169,6 +169,7 @@ private: void lightIntensityReceived(const QByteArray &value); void motionReceived(const QByteArray &value); double convertIrTemperatureAPIReadingToCelsius(quint16 rawReading); + void isDeviceReady() const; QBluetoothDeviceDiscoveryAgent *discoveryAgent; QString m_previousAddress; diff --git a/tradeshow/iot-sensortag/demodataproviderpool.cpp b/tradeshow/iot-sensortag/demodataproviderpool.cpp index f31d869..9dfad93 100644 --- a/tradeshow/iot-sensortag/demodataproviderpool.cpp +++ b/tradeshow/iot-sensortag/demodataproviderpool.cpp @@ -50,8 +50,216 @@ #include "demodataproviderpool.h" #include "mockdataprovider.h" +DemoCloudProvider::DemoCloudProvider(QObject *parent) + : SensorTagDataProvider(parent) +{ +} + +void DemoCloudProvider::setDataProviders(const QList &dataProviders) +{ + m_dataProviders = dataProviders; +} + +QString DemoCloudProvider::sensorType() const +{ + if (m_dataProviders.length()) + return m_dataProviders.at(0)->sensorType(); + else + return QString(); +} + +QString DemoCloudProvider::versionString() const +{ + if (m_dataProviders.length()) + return m_dataProviders.at(0)->versionString(); + else + return QString(); +} + +double DemoCloudProvider::getRelativeHumidity() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Humidity) + return p->getRelativeHumidity(); + } + return 0; +} + +double DemoCloudProvider::getInfraredAmbientTemperature() +{ + m_dataProviders.first(); + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::AmbientTemperature) + return p->getInfraredAmbientTemperature(); + } + return 0; +} + +double DemoCloudProvider::getInfraredObjectTemperature() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::ObjectTemperature) + return p->getInfraredObjectTemperature(); + } + return 0; +} + +double DemoCloudProvider::getLightIntensityLux() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Light) + return p->getLightIntensityLux(); + } + return 0; +} + +double DemoCloudProvider::getBarometerCelsiusTemperature() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::AirPressure) + return p->getBarometerCelsiusTemperature(); + } + return 0; +} + +double DemoCloudProvider::getBarometerTemperatureAverage() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::AirPressure) + return p->getBarometerTemperatureAverage(); + } + return 0; +} + +double DemoCloudProvider::getBarometer_hPa() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::AirPressure) + return p->getBarometer_hPa(); + } + return 0; +} + +float DemoCloudProvider::getGyroscopeX_degPerSec() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Magnetometer) + return p->getGyroscopeX_degPerSec(); + } + return 0; +} + +float DemoCloudProvider::getGyroscopeY_degPerSec() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Magnetometer) + return p->getGyroscopeY_degPerSec(); + } + return 0; +} + +float DemoCloudProvider::getGyroscopeZ_degPerSec() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Magnetometer) + return p->getGyroscopeZ_degPerSec(); + } + return 0; +} + +float DemoCloudProvider::getAccelometer_xAxis() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Accelometer) + return p->getAccelometer_xAxis(); + } + return 0; +} + +float DemoCloudProvider::getAccelometer_yAxis() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Accelometer) + return p->getAccelometer_yAxis(); + } + return 0; +} + +float DemoCloudProvider::getAccelometer_zAxis() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Accelometer) + return p->getAccelometer_zAxis(); + } + return 0; +} + +float DemoCloudProvider::getMagnetometerMicroT_xAxis() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Magnetometer) + return p->getMagnetometerMicroT_xAxis(); + } + return 0; +} + +float DemoCloudProvider::getMagnetometerMicroT_yAxis() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Magnetometer) + return p->getMagnetometerMicroT_yAxis(); + } + return 0; +} + +float DemoCloudProvider::getMagnetometerMicroT_zAxis() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Magnetometer) + return p->getMagnetometerMicroT_zAxis(); + } + return 0; +} + +float DemoCloudProvider::getRotationX() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Rotation) + return p->getRotationX(); + } + return 0; +} + +float DemoCloudProvider::getRotationY() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Rotation) + return p->getRotationY(); + } + return 0; +} + +float DemoCloudProvider::getRotationZ() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Rotation) + return p->getRotationZ(); + } + return 0; +} + +float DemoCloudProvider::getAltitude() +{ + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->tagType() & SensorTagDataProvider::Altitude) + return p->getAltitude(); + } + return 0; +} + + DemoDataProviderPool::DemoDataProviderPool(QObject *parent) - : DataProviderPool("Demo", parent) + : SensorTagDataProviderPool("Demo", parent) , m_mockData(false) , m_cloudProvider(0) { @@ -77,24 +285,41 @@ void DemoDataProviderPool::startScanning() emit providerConnected(p->id()); } // Stop scanning as we already have a provider - stopScanning(); + scanFinished(); } else { - DataProviderPool::startScanning(); + SensorTagDataProviderPool::startScanning(); } } -void DemoDataProviderPool::stopScanning() +void DemoDataProviderPool::finishScanning() { - // TODO: get data for cloud update provider from - // all available providers, not just from the first found - if (m_dataProviders.length()) { + if (m_dataProviders.length() && m_mockData) { + // For mock data we have only one provider and + // it servers as the provider to the cloud, too m_cloudProvider = m_dataProviders.at(0); emit providerForCloudChanged(); + } else { + // Fake that we have set of sensors with different capabilities + // by removing some of the sensor data types from each sensor tag + foreach (SensorTagDataProvider *p, m_dataProviders) { + if (p->id() == QStringLiteral("A0:E6:F8:B6:5B:86")) { + p->setTagType(SensorTagDataProvider::ObjectTemperature | + SensorTagDataProvider::Light | + SensorTagDataProvider::Magnetometer | + SensorTagDataProvider::Accelometer); + } + else if (p->id() == QStringLiteral("A0:E6:F8:B6:44:01")) { + p->setTagType(SensorTagDataProvider::AmbientTemperature | + SensorTagDataProvider::Altitude | + SensorTagDataProvider::Humidity | + SensorTagDataProvider::Rotation | + SensorTagDataProvider::AirPressure); + } + } + m_cloudProvider = new DemoCloudProvider(this); + static_cast(m_cloudProvider)->setDataProviders(m_dataProviders); } - - emit dataProvidersChanged(); - emit scanFinished(); } void DemoDataProviderPool::setMockDataMode(bool mode) @@ -106,3 +331,4 @@ SensorTagDataProvider *DemoDataProviderPool::providerForCloud() const { return m_cloudProvider; } + diff --git a/tradeshow/iot-sensortag/demodataproviderpool.h b/tradeshow/iot-sensortag/demodataproviderpool.h index 2bb517f..9692508 100644 --- a/tradeshow/iot-sensortag/demodataproviderpool.h +++ b/tradeshow/iot-sensortag/demodataproviderpool.h @@ -54,22 +54,61 @@ class CloudUpdate; -class DemoDataProviderPool : public DataProviderPool +class DemoDataProviderPool : public SensorTagDataProviderPool { Q_OBJECT public: explicit DemoDataProviderPool(QObject *parent = 0); void startScanning() override; - void stopScanning() override; SensorTagDataProvider* providerForCloud() const override; void setMockDataMode(bool mode); +protected: + void finishScanning() override; + private: + bool m_mockData; SensorTagDataProvider* m_cloudProvider; }; +// Internal class to provide sensor data for cloud update from demo setup +class DemoCloudProvider : public SensorTagDataProvider +{ + Q_OBJECT +public: + explicit DemoCloudProvider(QObject *parent); + + void setDataProviders(const QList& dataProviders); + + QString sensorType() const override; + QString versionString() const override; + + double getRelativeHumidity() override; + double getInfraredAmbientTemperature() override; + double getInfraredObjectTemperature() override; + double getLightIntensityLux() override; + double getBarometerCelsiusTemperature() override; + double getBarometerTemperatureAverage() override; + double getBarometer_hPa() override; + float getGyroscopeX_degPerSec() override; + float getGyroscopeY_degPerSec() override; + float getGyroscopeZ_degPerSec() override; + float getAccelometer_xAxis() override; + float getAccelometer_yAxis() override; + float getAccelometer_zAxis() override; + float getMagnetometerMicroT_xAxis() override; + float getMagnetometerMicroT_yAxis() override; + float getMagnetometerMicroT_zAxis() override; + float getRotationX() override; + float getRotationY() override; + float getRotationZ() override; + float getAltitude() override; + + QList m_dataProviders; +}; + #endif // DEMODATAPROVIDERPOOL_H diff --git a/tradeshow/iot-sensortag/main.cpp b/tradeshow/iot-sensortag/main.cpp index be8ea60..ea2325b 100644 --- a/tradeshow/iot-sensortag/main.cpp +++ b/tradeshow/iot-sensortag/main.cpp @@ -106,8 +106,11 @@ int main(int argc, char *argv[]) #if defined(RUNS_AS_HOST) else if (sensorSource == QString("sensor").toLower()) { qCDebug(boot2QtDemos) << "Running in sensor mode"; - dataProviderPool = new SensorTagDataProviderPool; - static_cast(dataProviderPool)->setMacFilterList(QStringList() << "A0:E6:F8:B6:44:01"); + dataProviderPool = new DemoDataProviderPool; + // List of devices used at EW: "A0:E6:F8:B6:44:01", "A0:E6:F8:B6:5B:86" + static_cast(dataProviderPool)->setMacFilterList(QStringList() << + "A0:E6:F8:B6:44:01" << + "A0:E6:F8:B6:5B:86"); } #endif else if (sensorSource == QString("mock").toLower()){ diff --git a/tradeshow/iot-sensortag/sensortagdataprovider.cpp b/tradeshow/iot-sensortag/sensortagdataprovider.cpp index e6b3b96..10c85a2 100644 --- a/tradeshow/iot-sensortag/sensortagdataprovider.cpp +++ b/tradeshow/iot-sensortag/sensortagdataprovider.cpp @@ -234,6 +234,11 @@ int SensorTagDataProvider::tagType() const return m_tagType; } +void SensorTagDataProvider::setTagType(int tagType) +{ + m_tagType = tagType; +} + QString SensorTagDataProvider::id() const { return m_id; diff --git a/tradeshow/iot-sensortag/sensortagdataprovider.h b/tradeshow/iot-sensortag/sensortagdataprovider.h index c3006e5..9f079e9 100644 --- a/tradeshow/iot-sensortag/sensortagdataprovider.h +++ b/tradeshow/iot-sensortag/sensortagdataprovider.h @@ -91,13 +91,13 @@ class SensorTagDataProvider : public QObject public: enum TagType {AmbientTemperature = 1 << 0, ObjectTemperature = 1 << 1, - Humidity, - AirPressure = 1 << 2, - Light = 1 << 3, - Magnetometer = 1 << 4, - Rotation = 1 << 5, - Accelometer = 1 << 6, - Altitude = 1 << 7}; + Humidity = 1 << 2, + AirPressure = 1 << 3, + Light = 1 << 4, + Magnetometer = 1 << 5, + Rotation = 1 << 6, + Accelometer = 1 << 7, + Altitude = 1 << 8}; enum ProviderState {Disconnected = 0, Scanning, Connected, Error}; explicit SensorTagDataProvider(QObject *parent = 0); @@ -106,33 +106,34 @@ public: virtual bool startDataFetching() {return false;} virtual void endDataFetching() {} QString getRelativeHumidityString(); - double getRelativeHumidity(); - double getInfraredAmbientTemperature(); - double getInfraredObjectTemperature(); + virtual double getRelativeHumidity(); + virtual double getInfraredAmbientTemperature(); + virtual double getInfraredObjectTemperature(); QString getLightIntensityLuxString(); - double getLightIntensityLux(); - double getBarometerCelsiusTemperature(); + virtual double getLightIntensityLux(); + virtual double getBarometerCelsiusTemperature(); QString getBarometerCelsiusTemperatureString(); - double getBarometerTemperatureAverage(); + virtual double getBarometerTemperatureAverage(); QString getBarometer_hPaString(); - double getBarometer_hPa(); - float getGyroscopeX_degPerSec(); - float getGyroscopeY_degPerSec(); - float getGyroscopeZ_degPerSec(); - float getAccelometer_xAxis(); - float getAccelometer_yAxis(); - float getAccelometer_zAxis(); - float getMagnetometerMicroT_xAxis(); - float getMagnetometerMicroT_yAxis(); - float getMagnetometerMicroT_zAxis(); - float getRotationX(); - float getRotationY(); - float getRotationZ(); + virtual double getBarometer_hPa(); + virtual float getGyroscopeX_degPerSec(); + virtual float getGyroscopeY_degPerSec(); + virtual float getGyroscopeZ_degPerSec(); + virtual float getAccelometer_xAxis(); + virtual float getAccelometer_yAxis(); + virtual float getAccelometer_zAxis(); + virtual float getMagnetometerMicroT_xAxis(); + virtual float getMagnetometerMicroT_yAxis(); + virtual float getMagnetometerMicroT_zAxis(); + virtual float getRotationX(); + virtual float getRotationY(); + virtual float getRotationZ(); int getRotationUpdateInterval(); - float getAltitude(); + virtual float getAltitude(); - Q_INVOKABLE int tagType() const; - QString id() const; + Q_INVOKABLE virtual int tagType() const; + void setTagType(int tagType); + virtual QString id() const; ProviderState state() const; void setState(ProviderState state); diff --git a/tradeshow/iot-sensortag/sensortagdataproviderpool.cpp b/tradeshow/iot-sensortag/sensortagdataproviderpool.cpp index bb0ead1..f9edad0 100644 --- a/tradeshow/iot-sensortag/sensortagdataproviderpool.cpp +++ b/tradeshow/iot-sensortag/sensortagdataproviderpool.cpp @@ -119,9 +119,15 @@ void SensorTagDataProviderPool::updateProviderForCloud() void SensorTagDataProviderPool::deviceDiscoveryFinished() { m_deviceScanState = false; + finishScanning(); emit scanFinished(); } +void SensorTagDataProviderPool::finishScanning() +{ + updateProviderForCloud(); +} + void SensorTagDataProviderPool::btDeviceFound(const QBluetoothDeviceInfo &info) { qCDebug(boot2QtDemos) << "Found a Bluetooth device. Name:" << info.name() << ", addr:" << info.address().toString(); @@ -143,7 +149,6 @@ void SensorTagDataProviderPool::btDeviceFound(const QBluetoothDeviceInfo &info) m_dataProviders.append(dataProvider); emit providerConnected(d->getAddress()); emit dataProvidersChanged(); - updateProviderForCloud(); connect(dataProvider, &SensorTagDataProvider::stateChanged, this, &SensorTagDataProviderPool::handleStateChange); } } @@ -153,14 +158,13 @@ void SensorTagDataProviderPool::handleStateChange() { SensorTagDataProvider *provider = static_cast(sender()); - qCDebug(boot2QtDemos) << provider->state(); - switch (provider->state()) { case SensorTagDataProvider::Disconnected: updateProviderForCloud(); emit providerDisconnected(provider->id()); break; case SensorTagDataProvider::Connected: + updateProviderForCloud(); emit providerConnected(provider->id()); break; case SensorTagDataProvider::Error: diff --git a/tradeshow/iot-sensortag/sensortagdataproviderpool.h b/tradeshow/iot-sensortag/sensortagdataproviderpool.h index 712d4cc..d7ac740 100644 --- a/tradeshow/iot-sensortag/sensortagdataproviderpool.h +++ b/tradeshow/iot-sensortag/sensortagdataproviderpool.h @@ -76,6 +76,7 @@ public: protected: SensorTagDataProviderPool(QString poolName, QObject *parent = 0); + virtual void finishScanning(); void updateProviderForCloud(); -- cgit v1.2.3