summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOtto Ryynänen <otto.ryynanen@qt.io>2016-12-02 13:53:22 +0200
committerOtto Ryynänen <otto.ryynanen@qt.io>2017-01-30 13:49:33 +0000
commit31bf214d734c6d7ac8773eb97911219825579ae5 (patch)
tree255b652f17560f1b16c6d2b98961097b6a4f7457
parent99fd61e44216bc76f211f1c3bca9172172eef340 (diff)
Added IoT SensorTag demo to tradeshow
iot-sensortag folder added. This is project originally from consultacy repo, moved to here. It's a cross-platform app that shown multiple data values from TI CC2650 SensorTag. Change-Id: I648464ed9a8253e5069bc6fd59e8b92128b60adc Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
-rw-r--r--tradeshow/iot-sensortag/README11
-rw-r--r--tradeshow/iot-sensortag/SensorTagDemo.pro117
-rw-r--r--tradeshow/iot-sensortag/android-sources/AndroidManifest.xml89
-rw-r--r--tradeshow/iot-sensortag/base.qrc22
-rw-r--r--tradeshow/iot-sensortag/bluetoothdataprovider.cpp213
-rw-r--r--tradeshow/iot-sensortag/bluetoothdataprovider.h94
-rw-r--r--tradeshow/iot-sensortag/bluetoothdevice.cpp793
-rw-r--r--tradeshow/iot-sensortag/bluetoothdevice.h221
-rw-r--r--tradeshow/iot-sensortag/characteristicinfo.cpp153
-rw-r--r--tradeshow/iot-sensortag/characteristicinfo.h84
-rw-r--r--tradeshow/iot-sensortag/clouddataprovider.cpp248
-rw-r--r--tradeshow/iot-sensortag/clouddataprovider.h91
-rw-r--r--tradeshow/iot-sensortag/clouddataproviderpool.cpp66
-rw-r--r--tradeshow/iot-sensortag/clouddataproviderpool.h65
-rw-r--r--tradeshow/iot-sensortag/cloudservice.h58
-rw-r--r--tradeshow/iot-sensortag/cloudupdate.cpp184
-rw-r--r--tradeshow/iot-sensortag/cloudupdate.h87
-rw-r--r--tradeshow/iot-sensortag/dataproviderpool.cpp95
-rw-r--r--tradeshow/iot-sensortag/dataproviderpool.h91
-rw-r--r--tradeshow/iot-sensortag/demodataproviderpool.cpp104
-rw-r--r--tradeshow/iot-sensortag/demodataproviderpool.h75
-rw-r--r--tradeshow/iot-sensortag/main.cpp204
-rw-r--r--tradeshow/iot-sensortag/mockdataprovider.cpp222
-rw-r--r--tradeshow/iot-sensortag/mockdataprovider.h84
-rw-r--r--tradeshow/iot-sensortag/resources/base/AirPressureChart.qml82
-rw-r--r--tradeshow/iot-sensortag/resources/base/BaseChart.qml119
-rw-r--r--tradeshow/iot-sensortag/resources/base/BottomToolbar.qml54
-rw-r--r--tradeshow/iot-sensortag/resources/base/ChartPage.qml70
-rw-r--r--tradeshow/iot-sensortag/resources/base/CircularGauge.qml132
-rw-r--r--tradeshow/iot-sensortag/resources/base/GyroChart.qml218
-rw-r--r--tradeshow/iot-sensortag/resources/base/HumidityChart.qml159
-rw-r--r--tradeshow/iot-sensortag/resources/base/LightChart.qml126
-rw-r--r--tradeshow/iot-sensortag/resources/base/LocationPage.qml103
-rw-r--r--tradeshow/iot-sensortag/resources/base/MagnetometerChart.qml226
-rw-r--r--tradeshow/iot-sensortag/resources/base/ObjectTemperatureChart.qml125
-rw-r--r--tradeshow/iot-sensortag/resources/base/SensorTag.qml252
-rw-r--r--tradeshow/iot-sensortag/resources/base/TemperatureChart.qml278
-rw-r--r--tradeshow/iot-sensortag/resources/base/TopToolbar.qml196
-rwxr-xr-xtradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Bold.ttfbin0 -> 59908 bytes
-rwxr-xr-xtradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Regular.ttfbin0 -> 63752 bytes
-rwxr-xr-xtradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-SemiBold.ttfbin0 -> 63044 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/base/main.qml72
-rw-r--r--tradeshow/iot-sensortag/resources/large/MainLarge.qml177
-rw-r--r--tradeshow/iot-sensortag/resources/large/StyleLarge.qml59
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/AirPressure/AirPre_base_gauge.pngbin0 -> 32850 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/AmbientTemperature/ambTemp_display_amb.pngbin0 -> 7084 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/General/icon_sensor.pngbin0 -> 932 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/General/separator.pngbin0 -> 1269 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_base_gauge.pngbin0 -> 40846 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_max_hum.pngbin0 -> 1855 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_min_hum.pngbin0 -> 1926 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/Light/light_base_gauge.pngbin0 -> 21149 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/Light/light_brightness.pngbin0 -> 11928 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_base_circle.pngbin0 -> 49793 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_display_obj.pngbin0 -> 24610 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/MainMedium.qml177
-rw-r--r--tradeshow/iot-sensortag/resources/medium/StyleMedium.qml59
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/AirPressure/AirPre_base_gauge.pngbin0 -> 23594 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/AmbientTemperature/ambTemp_display_amb.pngbin0 -> 4744 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/General/icon_sensor.pngbin0 -> 691 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/General/separator.pngbin0 -> 966 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_base_gauge.pngbin0 -> 29413 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_max_hum.pngbin0 -> 1356 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_min_hum.pngbin0 -> 1432 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/Light/light_base_gauge.pngbin0 -> 15242 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/Light/light_brightness.pngbin0 -> 8479 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_base_circle.pngbin0 -> 35320 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_display_obj.pngbin0 -> 17544 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/MainSmall.qml193
-rw-r--r--tradeshow/iot-sensortag/resources/small/StyleSmall.qml59
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/AirPressure/AirPre_base_gauge.pngbin0 -> 15022 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/AmbientTemperature/ambTemp_display_amb.pngbin0 -> 2890 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/General/icon_sensor.pngbin0 -> 489 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/General/separator.pngbin0 -> 662 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_base_gauge.pngbin0 -> 18601 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_max_hum.pngbin0 -> 880 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_min_hum.pngbin0 -> 940 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Light/light_base_gauge.pngbin0 -> 9677 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Light/light_brightness.pngbin0 -> 5375 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_base_circle.pngbin0 -> 21226 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_display_obj.pngbin0 -> 11591 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_cloud.pngbin0 -> 535 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_sensor.pngbin0 -> 586 bytes
-rw-r--r--tradeshow/iot-sensortag/resources/small/images/Toolbar/topbar_all.pngbin0 -> 1840 bytes
-rw-r--r--tradeshow/iot-sensortag/sensortagdataprovider.cpp251
-rw-r--r--tradeshow/iot-sensortag/sensortagdataprovider.h188
-rw-r--r--tradeshow/iot-sensortag/sensortagdataproviderpool.cpp185
-rw-r--r--tradeshow/iot-sensortag/sensortagdataproviderpool.h96
-rw-r--r--tradeshow/iot-sensortag/serviceinfo.cpp110
-rw-r--r--tradeshow/iot-sensortag/serviceinfo.h76
-rw-r--r--tradeshow/iot-sensortag/uilarge.qrc17
-rw-r--r--tradeshow/iot-sensortag/uimedium.qrc17
-rw-r--r--tradeshow/iot-sensortag/uismall.qrc20
93 files changed, 7367 insertions, 0 deletions
diff --git a/tradeshow/iot-sensortag/README b/tradeshow/iot-sensortag/README
new file mode 100644
index 0000000..8c83e7e
--- /dev/null
+++ b/tradeshow/iot-sensortag/README
@@ -0,0 +1,11 @@
+This is a work-in-progress project targeted for Embedded World conference 2017. With the application you can read sensor information and publish it to the Microsoft Azure cloud service for clients to read it. There is three form factors supported for the client device, and the correct form factor is automatically determined by the screen dimensions.
+
+Data is published to the cloud when the application is run either in sensor or mock mode.
+
+Usage: SensorTagDemo --source[=cloud]
+
+--source cloud sensor data is read from cloud
+ sensor sensor data is read from a Bluetooth sensor
+ mock sensor data is read from a mock data provider
+
+You can also set the environment variable QT_IOS_DEMO_NO_FULLSCREEN to force the application not to go to fullscreen mode. In this case the application is drawn in a window with dimensions specific to the selected screen form factor. Note: this setting is mainly intended for development purposes.
diff --git a/tradeshow/iot-sensortag/SensorTagDemo.pro b/tradeshow/iot-sensortag/SensorTagDemo.pro
new file mode 100644
index 0000000..f1df6d6
--- /dev/null
+++ b/tradeshow/iot-sensortag/SensorTagDemo.pro
@@ -0,0 +1,117 @@
+TEMPLATE = app
+
+QT += 3dcore 3drender 3dinput 3dquick 3dlogic core gui qml quick 3dquickextras widgets
+QT += bluetooth network
+CONFIG += c++11
+
+# Uncomment DEVICE_TYPE and assign either UI_SMALL, UI_MEDIUM, UI_LARGE
+# to force using that UI form factor. Otherwise
+# the form factor is determined based on the platform
+DEVICE_TYPE = UI_SMALL
+
+# If DEVICE_TYPE is not set manually, try to determine
+# the correct device type by the used operating system
+win32|linux:!android:!qnx {
+ CONFIG += BLUETOOTH_LINUX_HOST
+ isEmpty(DEVICE_TYPE) { DEVICE_TYPE = UI_SMALL }
+} else:android {
+ isEmpty(DEVICE_TYPE) { DEVICE_TYPE = UI_MEDIUM }
+ ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources
+ QMAKE_CXX_FLAGS -= -DQT_OPENGL_FORCE_SHADER_DEFINES
+} else:ios {
+ isEmpty(DEVICE_TYPE) { DEVICE_TYPE = UI_MEDIUM }
+}
+
+win32 {
+ # Obtained via NuGet
+ isEmpty(WASTORAGE_LOCATION): WASTORAGE_LOCATION = "C:/Users/mauri/Documents/Visual Studio 2015/Projects/App1/packages/wastorage.v140.2.6.0"
+ INCLUDEPATH += $$WASTORAGE_LOCATION/build/native/include \
+ $$WASTORAGE_LOCATION/build/native/include/was \
+ $$WASTORAGE_LOCATION/build/native/include/wascore
+ LIBS += -L$$WASTORAGE_LOCATION/lib/native/v140/Win32/Release
+
+ isEmpty(CPPRESTSDK_LOCATION): CPPRESTSDK_LOCATION = "C:/Users/mauri/Documents/Visual Studio 2015/Projects/App1/packages/cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1"
+ INCLUDEPATH += $$CPPRESTSDK_LOCATION/build/native/include
+}
+
+SOURCES += main.cpp \
+ mockdataprovider.cpp \
+ sensortagdataprovider.cpp \
+ clouddataprovider.cpp \
+ dataproviderpool.cpp \
+ clouddataproviderpool.cpp \
+ demodataproviderpool.cpp
+
+HEADERS += \
+ sensortagdataprovider.h \
+ mockdataprovider.h \
+ clouddataprovider.h \
+ cloudservice.h \
+ dataproviderpool.h \
+ clouddataproviderpool.h \
+ demodataproviderpool.h
+
+BLUETOOTH_LINUX_HOST {
+ !winrt:CONFIG += UPDATE_TO_CLOUD
+ DEFINES += RUNS_AS_HOST
+
+ SOURCES += \
+ sensortagdataproviderpool.cpp \
+ bluetoothdataprovider.cpp \
+ serviceinfo.cpp \
+ bluetoothdevice.cpp \
+ characteristicinfo.cpp
+
+ HEADERS += \
+ sensortagdataproviderpool.h \
+ bluetoothdataprovider.h \
+ serviceinfo.h \
+ bluetoothdevice.h \
+ characteristicinfo.h
+}
+
+UPDATE_TO_CLOUD {
+ SOURCES += cloudupdate.cpp
+ HEADERS += cloudupdate.h
+ DEFINES += CLOUD_UPLOAD
+ # For Azure libs
+ win32 {
+ LIBS += -lwastorage
+ } else {
+ LIBS += -lboost_system -lcrypto -lssl -lcpprest -lazurestorage
+ QMAKE_CXXFLAGS += -fpermissive
+ QMAKE_CXXFLAGS += -fexceptions
+ }
+ QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
+}
+
+RESOURCES += base.qrc
+
+equals(DEVICE_TYPE, "UI_SMALL") {
+ DEFINES += UI_SMALL
+ RESOURCES += uismall.qrc
+ message("Resource file for SMALL display picked")
+}
+
+equals(DEVICE_TYPE, "UI_MEDIUM") {
+ DEFINES += UI_MEDIUM
+ RESOURCES += uimedium.qrc
+ message("Resource file for MEDIUM display picked")
+}
+
+equals(DEVICE_TYPE, "UI_LARGE") {
+ DEFINES += UI_LARGE
+ RESOURCES += uilarge.qrc
+ message("Resource file for LARGE display picked")
+}
+
+# Additional import path used to resolve QML modules in Qt Creator's code model
+QML_IMPORT_PATH =
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+DISTFILES += \
+ android-sources/AndroidManifest.xml
diff --git a/tradeshow/iot-sensortag/android-sources/AndroidManifest.xml b/tradeshow/iot-sensortag/android-sources/AndroidManifest.xml
new file mode 100644
index 0000000..a40a59c
--- /dev/null
+++ b/tradeshow/iot-sensortag/android-sources/AndroidManifest.xml
@@ -0,0 +1,89 @@
+<?xml version='1.0' encoding='utf-8'?>
+<manifest package="org.qtproject.example.SensorTagDemo" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
+ <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="SensorTagDemo">
+ <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
+ android:name="org.qtproject.qt5.android.bindings.QtActivity"
+ android:label="SensorTagDemo"
+ android:screenOrientation="landscape"
+ android:launchMode="singleTop">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+
+ <!-- Application arguments -->
+ <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
+ <!-- Application arguments -->
+
+ <meta-data android:name="android.app.lib_name" android:value="SensorTagDemo"/>
+ <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
+ <meta-data android:name="android.app.repository" android:value="default"/>
+ <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
+ <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
+ <!-- Deploy Qt libs as part of package -->
+ <meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/>
+ <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
+ <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
+ <!-- Run with local libs -->
+ <meta-data android:name="android.app.use_local_qt_libs" android:value="1"/>
+ <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
+ <meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/bearer/libqandroidbearer.so:plugins/gamepads/libandroidgamepad.so:lib/libQt5QuickParticles.so:plugins/position/libqtposition_android.so"/>
+ <meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroid-bundled.jar:jar/QtAndroidBearer.jar:jar/QtAndroidBearer-bundled.jar:jar/QtAndroidGamepad.jar:jar/QtAndroidGamepad-bundled.jar:jar/QtAndroidBluetooth.jar:jar/QtAndroidBluetooth-bundled.jar:jar/QtPositioning.jar:jar/QtPositioning-bundled.jar"/>
+ <meta-data android:name="android.app.static_init_classes" android:value="org.qtproject.qt5.android.bluetooth.QtBluetoothBroadcastReceiver:org.qtproject.qt5.android.bluetooth.QtBluetoothBroadcastReceiver:org.qtproject.qt5.android.positioning.QtPositioning:org.qtproject.qt5.android.positioning.QtPositioning"/>
+ <!-- Messages maps -->
+ <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
+ <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
+ <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
+ <!-- Messages maps -->
+
+ <!-- Splash screen -->
+ <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
+ <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
+ <!-- Splash screen -->
+
+ <!-- Background running -->
+ <!-- Warning: changing this value to true may cause unexpected crashes if the
+ application still try to draw after
+ "applicationStateChanged(Qt::ApplicationSuspended)"
+ signal is sent! -->
+ <meta-data android:name="android.app.background_running" android:value="false"/>
+ <!-- Background running -->
+
+ <!-- auto screen scale factor -->
+ <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
+ <!-- auto screen scale factor -->
+
+ <!-- extract android style -->
+ <!-- available android:values :
+ * full - useful QWidget & Quick Controls 1 apps
+ * minimal - useful for Quick Controls 2 apps, it is much faster than "full"
+ * none - useful for apps that don't use any of the above Qt modules
+ -->
+ <meta-data android:name="android.app.extract_android_style" android:value="full"/>
+ <!-- extract android style -->
+ </activity>
+
+ <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
+
+ </application>
+
+ <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="16"/>
+ <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
+
+ <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
+ Remove the comment if you do not require these default permissions. -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+
+
+ <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
+ Remove the comment if you do not require these default features. -->
+ <uses-feature android:name="android.hardware.gamepad" android:required="false" />
+ <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+
+</manifest>
diff --git a/tradeshow/iot-sensortag/base.qrc b/tradeshow/iot-sensortag/base.qrc
new file mode 100644
index 0000000..c02e7fb
--- /dev/null
+++ b/tradeshow/iot-sensortag/base.qrc
@@ -0,0 +1,22 @@
+<RCC>
+ <qresource prefix="/">
+ <file>resources/base/AirPressureChart.qml</file>
+ <file>resources/base/BaseChart.qml</file>
+ <file>resources/base/BottomToolbar.qml</file>
+ <file>resources/base/ChartPage.qml</file>
+ <file>resources/base/HumidityChart.qml</file>
+ <file>resources/base/LightChart.qml</file>
+ <file>resources/base/LocationPage.qml</file>
+ <file>resources/base/MagnetometerChart.qml</file>
+ <file>resources/base/main.qml</file>
+ <file>resources/base/ObjectTemperatureChart.qml</file>
+ <file>resources/base/SensorTag.qml</file>
+ <file>resources/base/TemperatureChart.qml</file>
+ <file>resources/base/TopToolbar.qml</file>
+ <file>resources/base/CircularGauge.qml</file>
+ <file>resources/base/GyroChart.qml</file>
+ <file>resources/base/fonts/titilliumweb/TitilliumWeb-Bold.ttf</file>
+ <file>resources/base/fonts/titilliumweb/TitilliumWeb-Regular.ttf</file>
+ <file>resources/base/fonts/titilliumweb/TitilliumWeb-SemiBold.ttf</file>
+ </qresource>
+</RCC>
diff --git a/tradeshow/iot-sensortag/bluetoothdataprovider.cpp b/tradeshow/iot-sensortag/bluetoothdataprovider.cpp
new file mode 100644
index 0000000..8e4f152
--- /dev/null
+++ b/tradeshow/iot-sensortag/bluetoothdataprovider.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bluetoothdataprovider.h"
+#include <QLoggingCategory>
+
+Q_DECLARE_LOGGING_CATEGORY(boot2QtDemos)
+
+BluetoothDataProvider::BluetoothDataProvider(QString id, QObject *parent)
+ : SensorTagDataProvider(id, parent)
+ , activeDevice(Q_NULLPTR)
+ , m_smaSamples(0)
+{
+}
+
+BluetoothDataProvider::~BluetoothDataProvider()
+{
+
+}
+
+bool BluetoothDataProvider::startDataFetching()
+{
+ qCDebug(boot2QtDemos) << Q_FUNC_INFO;
+ if (activeDevice) {
+ connect(activeDevice, &BluetoothDevice::statusUpdated, this, [](const QString& statusMsg) { qCDebug(boot2QtDemos) << "----------" << statusMsg; });
+ connect(activeDevice, &BluetoothDevice::stateChanged, this, &BluetoothDataProvider::updateState);
+ connect(activeDevice, &BluetoothDevice::temperatureChanged, this, &BluetoothDataProvider::temperatureReceived);
+ connect(activeDevice, &BluetoothDevice::barometerChanged, this, &BluetoothDataProvider::barometerReceived);
+ connect(activeDevice, &BluetoothDevice::humidityChanged, this, &BluetoothDataProvider::humidityReceived);
+ connect(activeDevice, &BluetoothDevice::lightIntensityChanged, this, &BluetoothDataProvider::lightIntensityReceived);
+ connect(activeDevice, &BluetoothDevice::motionChanged, this, &BluetoothDataProvider::motionReceived);
+ timer.setInterval(1000);
+ 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;
+}
+
+void BluetoothDataProvider::endDataFetching()
+{
+}
+
+void BluetoothDataProvider::startServiceScan()
+{
+ qCDebug(boot2QtDemos)<<Q_FUNC_INFO;
+ if (activeDevice)
+ activeDevice->scanServices();
+}
+
+void BluetoothDataProvider::temperatureReceived(double temperature)
+{
+ if (temperature == irTemperature)
+ return;
+ irTemperature = temperature;
+ emit infraredCelsiusTemperatureChanged();
+}
+
+void BluetoothDataProvider::barometerReceived(double temperature, double barometer)
+{
+ barometerCelsiusTemperature = temperature;
+ emit barometerCelsiusTemperatureChanged();
+ barometerTemperatureAverage = (temperature + m_smaSamples * barometerTemperatureAverage) / (m_smaSamples + 1);
+ m_smaSamples++;
+ emit barometerCelsiusTemperatureAverageChanged();
+ // Use a limited number of samples. It will eventually give wrong avg values, but this is just a demo...
+ if (m_smaSamples > 10000)
+ m_smaSamples = 0;
+ barometerHPa = barometer;
+ emit barometer_hPaChanged();
+}
+
+void BluetoothDataProvider::humidityReceived(double humidity)
+{
+ this->humidity = humidity;
+ emit relativeHumidityChanged();
+}
+void BluetoothDataProvider::lightIntensityReceived(double lightIntensity)
+{
+ lightIntensityLux = lightIntensity;
+ emit lightIntensityChanged();
+}
+
+float BluetoothDataProvider::countRotationDegrees(double degreesPerSecond, quint64 milliseconds)
+{
+ const quint32 mseconds = milliseconds;
+ const float seconds = ((float)mseconds)/float(1000);
+ return ((float)degreesPerSecond) * seconds;
+}
+
+void BluetoothDataProvider::motionReceived(MotionSensorData &data)
+{
+ qCDebug(boot2QtDemos) << Q_FUNC_INFO << ":" << data.gyroScope_x << "," << data.msSincePreviousData
+ << "=" << countRotationDegrees(data.gyroScope_x, data.msSincePreviousData);
+ gyroscopeX_degPerSec = data.gyroScope_x;
+ gyroscopeY_degPerSec = data.gyroScope_y;
+ gyroscopeZ_degPerSec = data.gyroScope_z;
+ rotation_x += countRotationDegrees(data.gyroScope_x, data.msSincePreviousData);
+ rotation_y += countRotationDegrees(data.gyroScope_y, data.msSincePreviousData);
+ rotation_z += countRotationDegrees(data.gyroScope_z, data.msSincePreviousData);
+ if (rotation_x > 360)
+ rotation_x -= 360;
+ else if (rotation_x < 0)
+ rotation_x += 360;
+ if (rotation_y > 360)
+ rotation_y -= 360;
+ else if (rotation_y < 0)
+ rotation_y += 360;
+ if (rotation_z > 360)
+ rotation_z -= 360;
+ else if (rotation_z < 0)
+ rotation_z += 360;
+ emit gyroscopeDegPerSecChanged();
+ emit rotationXChanged();
+ emit rotationYChanged();
+ emit rotationZChanged();
+ // Signal that all values have changed, for easier
+ // value change handling in clients
+ emit rotationValuesChanged();
+ accelometer_mG_xAxis = data.accelometer_x;
+ accelometer_mG_yAxis = data.accelometer_y;
+ accelometer_mG_zAxis = data.accelometer_z;
+ emit accelometerGChanged();
+ magnetometerMicroT_xAxis = data.magnetometer_x;
+ magnetometerMicroT_yAxis = data.magnetometer_y;
+ magnetometerMicroT_zAxis = data.magnetometer_z;
+ emit magnetometerMicroTChanged();
+}
+
+QString BluetoothDataProvider::sensorType() const
+{
+ return QString("Bluetooth data");
+}
+
+QString BluetoothDataProvider::versionString() const
+{
+ return QString("1.0");
+}
+
+void BluetoothDataProvider::updateState()
+{
+ switch (activeDevice->state()) {
+ case BluetoothDevice::Disconnected:
+ setState(Disconnected);
+ break;
+ case BluetoothDevice::Connected:
+ setState(Connected);
+ break;
+ case BluetoothDevice::Error:
+ setState(Error);
+ break;
+ default:
+ break;
+ }
+}
+
+void BluetoothDataProvider::bindToDevice(BluetoothDevice *device)
+{
+ activeDevice = device;
+ startDataFetching();
+}
+
+BluetoothDevice *BluetoothDataProvider::device()
+{
+ return activeDevice;
+}
diff --git a/tradeshow/iot-sensortag/bluetoothdataprovider.h b/tradeshow/iot-sensortag/bluetoothdataprovider.h
new file mode 100644
index 0000000..0c72673
--- /dev/null
+++ b/tradeshow/iot-sensortag/bluetoothdataprovider.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BLUETOOTHDATAPROVIDER_H
+#define BLUETOOTHDATAPROVIDER_H
+
+#include "sensortagdataprovider.h"
+#include "sensortagdataproviderpool.h"
+#include <QQmlEngine>
+#include <QJSEngine>
+#include <QTimer>
+
+class BluetoothDataProvider : public SensorTagDataProvider
+{
+ Q_OBJECT
+public:
+ BluetoothDataProvider(QString id, QObject* parent = 0);
+
+ virtual ~BluetoothDataProvider();
+
+ bool startDataFetching() override;
+ void endDataFetching() override;
+ QString sensorType() const;
+ QString versionString() const;
+
+ void bindToDevice(BluetoothDevice *device);
+ BluetoothDevice* device();
+
+public slots:
+ void startServiceScan();
+
+ void temperatureReceived(double temperature);
+ void barometerReceived(double temperature, double barometer);
+ void humidityReceived(double humidity);
+ void lightIntensityReceived(double lightIntensity);
+ void motionReceived(MotionSensorData &data);
+
+private:
+ void updateState();
+
+private:
+ float countRotationDegrees(double degreesPerSecond, quint64 milliseconds);
+ BluetoothDevice* activeDevice;
+ QTimer timer;
+ int m_smaSamples;
+};
+
+#endif // BLUETOOTHDATAPROVIDER_H
diff --git a/tradeshow/iot-sensortag/bluetoothdevice.cpp b/tradeshow/iot-sensortag/bluetoothdevice.cpp
new file mode 100644
index 0000000..0e43956
--- /dev/null
+++ b/tradeshow/iot-sensortag/bluetoothdevice.cpp
@@ -0,0 +1,793 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bluetoothdevice.h"
+#include "characteristicinfo.h"
+
+#include <QBluetoothDeviceDiscoveryAgent>
+#include <QBluetoothDeviceInfo>
+#include <QLowEnergyService>
+#include <QLoggingCategory>
+#include <QList>
+#include <QTimer>
+#include <QDebug>
+#include <QtMath>
+
+Q_DECLARE_LOGGING_CATEGORY(boot2QtDemos)
+
+// The average time from read request to read response is 150ms in optimal conditions.
+// With other sensors being read we have to limit it to even longer periods.
+#define RAPID_TIMER_MS 350
+#define MEDIUM_TIMER_MS (1.5*RAPID_TIMER_MS)
+#define SLOW_TIMER_MS 2000
+
+#define START_MEASUREMENT_STR "01" /* 01 start, 00 stop */
+#define DISABLE_NOTIF_STR "0000" /* 0100 enable, 0000 disable */
+#define SLOW_TIMER_TIMEOUT_STR "FA" /* 250 -> 2500ms */
+#define MEDIUM_TIMER_TIMEOUT_STR "32" /* 50 -> 500ms */
+#define RAPID_TIMER_TIMEOUT_STR "0A" /* 10 -> 100ms */
+#define MOVEMENT_ENABLE_SENSORS_BITMASK_VALUE "7F02" /* see below */
+//Enable motion axis: 0b0000_0010_0111_1111 = 0x7F 0x02 (all sensors, 8G, no wake on motion)
+//bits of first byte:
+//MPU9250_GYROSCOPE = 0b0000_0111 all 3 xyz axes, 1 bit per axis
+//MPU9250_ACCELEROMETER = 0b0011_1000 all 3 xyz axes, 1 bit per axis
+//MPU9250_MAGNETOMETER = 0b0100_0000 all 3 xyz axes with one bit
+//MPU9250_WAKEONMOTION = 0b1000_0000 enables wake on motion
+//bits of second byte (only 2 bits used) Accelerometer range in G
+//MPU9250_ACCELEROMETER_RANGE_0 =0b0000_0000 = 2 G
+//MPU9250_ACCELEROMETER_RANGE_1 =0b0000_0001 = 4 G
+//MPU9250_ACCELEROMETER_RANGE_2 =0b0000_0010 = 8 G (default)
+//MPU9250_ACCELEROMETER_RANGE_3 =0b0000_0011 = 16 G
+
+typedef struct {
+ qint16 gyrox;
+ qint16 gyroy;
+ qint16 gyroz;
+ qint16 accelx;
+ qint16 accely;
+ qint16 accelz;
+ qint16 magnetomx;
+ qint16 magnetomy;
+ qint16 magnetomz;
+} movement_data_t;
+
+BluetoothDevice::BluetoothDevice()
+ : discoveryAgent(0)
+ , controller(0)
+ , irTemperatureService(0)
+ , baroService(0)
+ , humidityService(0)
+ , lightService(0)
+ , motionService(0)
+ , m_deviceState(DeviceState::Disconnected)
+ , randomAddress(false)
+ , slowTimer(0)
+ , mediumTimer(0)
+ , rapidTimer(0)
+{
+ statusUpdated("Device created");
+}
+
+BluetoothDevice::BluetoothDevice(const QBluetoothDeviceInfo &d)
+ : BluetoothDevice()
+{
+ m_deviceInfo = d;
+}
+
+BluetoothDevice::~BluetoothDevice()
+{
+ if (slowTimer) {
+ slowTimer->stop();
+ delete slowTimer;
+ }
+ if (mediumTimer) {
+ mediumTimer->stop();
+ delete mediumTimer;
+ }
+ if (rapidTimer) {
+ rapidTimer->stop();
+ delete rapidTimer;
+ }
+ delete discoveryAgent;
+ delete controller;
+ qDeleteAll(m_services);
+ qDeleteAll(m_characteristics);
+ m_services.clear();
+ m_characteristics.clear();
+}
+QString BluetoothDevice::getAddress() const
+{
+#if defined(Q_OS_DARWIN)
+ // On Apple platforms we do not have addresses,
+ // only unique UUIDs generated by Core Bluetooth.
+ return m_deviceInfo.deviceUuid().toString();
+#else
+ return m_deviceInfo.address().toString();
+#endif
+}
+
+QString BluetoothDevice::getName() const
+{
+ return m_deviceInfo.name();
+}
+
+QVariant BluetoothDevice::getServices()
+{
+ return QVariant::fromValue(m_services);
+}
+
+QVariant BluetoothDevice::getCharacteristics()
+{
+ return QVariant::fromValue(m_characteristics);
+}
+
+void BluetoothDevice::scanServices()
+{
+ qDeleteAll(m_characteristics);
+ m_characteristics.clear();
+ emit characteristicsUpdated();
+ qDeleteAll(m_services);
+ m_services.clear();
+ emit servicesUpdated();
+
+ statusUpdated("(Connecting to device...)");
+
+ if (controller && m_previousAddress != getAddress()) {
+ controller->disconnectFromDevice();
+ delete controller;
+ controller = 0;
+ }
+
+ if (!controller) {
+ // Connecting signals and slots for connecting to LE services.
+ controller = new QLowEnergyController(m_deviceInfo);
+ connect(controller, SIGNAL(connected()),
+ this, SLOT(deviceConnected()));
+ connect(controller, SIGNAL(error(QLowEnergyController::Error)),
+ this, SLOT(errorReceived(QLowEnergyController::Error)));
+ connect(controller, SIGNAL(disconnected()),
+ this, SLOT(deviceDisconnected()));
+ connect(controller, SIGNAL(serviceDiscovered(QBluetoothUuid)),
+ this, SLOT(addLowEnergyService(QBluetoothUuid)));
+ connect(controller, SIGNAL(discoveryFinished()),
+ this, SLOT(serviceScanDone()));
+ }
+
+ if (randomAddress)
+ controller->setRemoteAddressType(QLowEnergyController::RandomAddress);
+ else
+ controller->setRemoteAddressType(QLowEnergyController::PublicAddress);
+ controller->connectToDevice();
+}
+
+void BluetoothDevice::addLowEnergyService(const QBluetoothUuid &serviceUuid)
+{
+ QLowEnergyService *service = controller->createServiceObject(serviceUuid);
+ if (!service) {
+ qWarning() << "Cannot create service for uuid";
+ return;
+ }
+ ServiceInfo *serv = new ServiceInfo(service);
+ m_services.append(serv);
+
+ emit servicesUpdated();
+}
+
+void BluetoothDevice::serviceScanDone()
+{
+ statusUpdated("(Service scan done!)");
+ // force UI in case we didn't find anything
+ if (m_services.isEmpty())
+ emit servicesUpdated();
+ else {
+ qCDebug(boot2QtDemos) << "ServiceScan done.";
+ if (!irTemperatureService)
+ {
+ QBluetoothUuid uuid;
+ for (int i = 0; i < controller->services().count(); i++) {
+ QBluetoothUuid id = controller->services().at(i);
+ if (id.toString().contains("f000aa00-0451-4000-b000-000000000000")) {
+ uuid = id;
+ break;
+ }
+ }
+
+ irTemperatureService = controller->createServiceObject(uuid);
+ connect(irTemperatureService, &QLowEnergyService::stateChanged, this, &BluetoothDevice::temperatureDetailsDiscovered);
+ connect(irTemperatureService, &QLowEnergyService::characteristicRead, this, &BluetoothDevice::characteristicsRead);
+ irTemperatureService->discoverDetails();
+ }
+ if (!baroService)
+ {
+ QBluetoothUuid uuid;
+ for (int i = 0; i < controller->services().count(); i++) {
+ QBluetoothUuid id = controller->services().at(i);
+ if (id.toString().contains("f000aa40-0451-4000-b000-000000000000")) {
+ uuid = id;
+ break;
+ }
+ }
+
+ baroService = controller->createServiceObject(uuid);
+ connect(baroService, &QLowEnergyService::stateChanged, this, &BluetoothDevice::barometerDetailsDiscovered);
+ connect(baroService, &QLowEnergyService::characteristicRead, this, &BluetoothDevice::characteristicsRead);
+ baroService->discoverDetails();
+ }
+ if (!humidityService)
+ {
+ QBluetoothUuid uuid;
+ for (int i = 0; i < controller->services().count(); i++) {
+ QBluetoothUuid id = controller->services().at(i);
+ if (id.toString().contains("f000aa20-0451-4000-b000-000000000000")) {
+ uuid = id;
+ break;
+ }
+
+ }
+
+ humidityService = controller->createServiceObject(uuid);
+ connect(humidityService, &QLowEnergyService::stateChanged, this, &BluetoothDevice::humidityDetailsDiscovered);
+ connect(humidityService, &QLowEnergyService::characteristicRead, this, &BluetoothDevice::characteristicsRead);
+ humidityService->discoverDetails();
+ }
+
+ if (!lightService)
+ {
+ QBluetoothUuid uuid;
+ for (int i = 0; i < controller->services().count(); i++) {
+ QBluetoothUuid id = controller->services().at(i);
+ if (id.toString().contains("f000aa70-0451-4000-b000-000000000000")) {
+ uuid = id;
+ break;
+ }
+
+ }
+
+ lightService = controller->createServiceObject(uuid);
+ connect(lightService, &QLowEnergyService::stateChanged, this, &BluetoothDevice::lightIntensityDetailsDiscovered);
+ connect(lightService, &QLowEnergyService::characteristicRead, this, &BluetoothDevice::characteristicsRead);
+ lightService->discoverDetails();
+ }
+ if (!motionService)
+ {
+ QBluetoothUuid uuid;
+ for (int i = 0; i < controller->services().count(); i++) {
+ QBluetoothUuid id = controller->services().at(i);
+ if (id.toString().contains("f000aa80-0451-4000-b000-000000000000")) {
+ uuid = id;
+ break;
+ }
+ }
+ motionService = controller->createServiceObject(uuid);
+ connect(motionService, &QLowEnergyService::stateChanged, this, &BluetoothDevice::motionDetailsDiscovered);
+ connect(motionService, &QLowEnergyService::characteristicRead, this, &BluetoothDevice::characteristicsRead);
+ motionService->discoverDetails();
+ }
+ }
+}
+
+void BluetoothDevice::temperatureDetailsDiscovered(QLowEnergyService::ServiceState newstate)
+{
+ if (newstate == QLowEnergyService::ServiceDiscovered) {
+ connect(irTemperatureService, &QLowEnergyService::characteristicWritten, [=]() {
+ qCDebug(boot2QtDemos) << "Wrote Characteristic - temperature";
+ });
+
+ connect(irTemperatureService, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
+ [=](QLowEnergyService::ServiceError newError) {
+ qCDebug(boot2QtDemos) << "error while writing - temperature:" << newError;
+ });
+
+ for (int i = 0; i < irTemperatureService->characteristics().count(); i++ ) {
+ QLowEnergyCharacteristic characteristic = irTemperatureService->characteristics().at(i);
+ QBluetoothUuid id = characteristic.uuid();
+
+ if (id.toString().contains("f000aa01-0451-4000-b000-000000000000")) {
+ //RN
+ irTemperatureService->writeDescriptor(characteristic.descriptors().at(0), QByteArray::fromHex(DISABLE_NOTIF_STR));
+ }
+ if (id.toString().contains("f000aa02-0451-4000-b000-000000000000")) {
+ //RW
+ irTemperatureService->writeCharacteristic(characteristic, QByteArray::fromHex(START_MEASUREMENT_STR), QLowEnergyService::WriteWithResponse); // Start
+ }
+ if (id.toString().contains("f000aa03-0451-4000-b000-000000000000")) {
+ //RW
+ irTemperatureService->writeCharacteristic(characteristic, QByteArray::fromHex(SLOW_TIMER_TIMEOUT_STR), QLowEnergyService::WriteWithResponse); // Period 1 second
+ }
+ }
+ m_temperatureMeasurementStarted = true;
+ }
+}
+
+void BluetoothDevice::barometerDetailsDiscovered(QLowEnergyService::ServiceState newstate) {
+ if (newstate == QLowEnergyService::ServiceDiscovered) {
+ connect(baroService, &QLowEnergyService::characteristicWritten, [=]() {
+ qCDebug(boot2QtDemos) << "Wrote Characteristic - barometer";
+ });
+
+ connect(baroService, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
+ [=](QLowEnergyService::ServiceError newError) {
+ qCDebug(boot2QtDemos) << "error while writing - barometer:" << newError;
+ });
+
+ for (int i = 0; i < baroService->characteristics().count(); i++ ) {
+ QLowEnergyCharacteristic characteristic = baroService->characteristics().at(i);
+ QBluetoothUuid id = characteristic.uuid();
+ qCDebug(boot2QtDemos)<<"characteristic:"<<id.toString();
+
+ if (id.toString().contains("f000aa41-0451-4000-b000-000000000000")) {
+ baroService->writeDescriptor(characteristic.descriptors().at(0), QByteArray::fromHex(DISABLE_NOTIF_STR));
+ }
+ if (id.toString().contains("f000aa42-0451-4000-b000-000000000000")) {
+ baroService->writeCharacteristic(characteristic, QByteArray::fromHex(START_MEASUREMENT_STR), QLowEnergyService::WriteWithResponse); // Start
+ }
+ if (id.toString().contains("f000aa44-0451-4000-b000-000000000000")) {
+ baroService->writeCharacteristic(characteristic, QByteArray::fromHex(SLOW_TIMER_TIMEOUT_STR), QLowEnergyService::WriteWithResponse); // Period 1 second
+ }
+ }
+ m_barometerMeasurementStarted = true;
+ }
+}
+
+void BluetoothDevice::humidityDetailsDiscovered(QLowEnergyService::ServiceState newstate)
+{
+ if (newstate == QLowEnergyService::ServiceDiscovered) {
+ connect(humidityService, &QLowEnergyService::characteristicWritten, [=]() {
+ qCDebug(boot2QtDemos) << "Wrote Characteristic - humidity";
+ });
+
+ connect(humidityService, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
+ [=](QLowEnergyService::ServiceError newError) {
+ qCDebug(boot2QtDemos) << "error while writing - humidity:" << newError;
+ });
+
+ for (int i = 0; i < humidityService->characteristics().count(); i++ ) {
+ QLowEnergyCharacteristic characteristic = humidityService->characteristics().at(i);
+ QBluetoothUuid id = characteristic.uuid();
+ qCDebug(boot2QtDemos)<<"characteristic:"<<id.toString();
+
+ if (id.toString().contains("f000aa21-0451-4000-b000-000000000000")) {
+ humidityService->writeDescriptor(characteristic.descriptors().at(0), QByteArray::fromHex(DISABLE_NOTIF_STR));
+ }
+ if (id.toString().contains("f000aa22-0451-4000-b000-000000000000")) {
+ humidityService->writeCharacteristic(characteristic, QByteArray::fromHex(START_MEASUREMENT_STR), QLowEnergyService::WriteWithResponse); // Start
+ }
+ if (id.toString().contains("f000aa23-0451-4000-b000-000000000000")) {
+ humidityService->writeCharacteristic(characteristic, QByteArray::fromHex(SLOW_TIMER_TIMEOUT_STR), QLowEnergyService::WriteWithResponse); // Period 1 second
+ }
+ }
+ m_humidityMeasurementStarted = true;
+ }
+}
+
+void BluetoothDevice::lightIntensityDetailsDiscovered(QLowEnergyService::ServiceState newstate)
+{
+ if (newstate == QLowEnergyService::ServiceDiscovered) {
+ connect(lightService, &QLowEnergyService::characteristicWritten, [=]() {
+ qCDebug(boot2QtDemos) << "Wrote Characteristic - light intensity";
+ });
+
+ connect(lightService, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
+ [=](QLowEnergyService::ServiceError newError) {
+ qCDebug(boot2QtDemos) << "error while writing - light intensity:" << newError;
+ });
+
+ for (int i = 0; i < lightService->characteristics().count(); i++ ) {
+ QLowEnergyCharacteristic characteristic = lightService->characteristics().at(i);
+ QBluetoothUuid id = characteristic.uuid();
+ qCDebug(boot2QtDemos)<<"characteristic:"<<id.toString();
+
+ if (id.toString().contains("f000aa71-0451-4000-b000-000000000000")) {
+ lightService->writeDescriptor(characteristic.descriptors().at(0), QByteArray::fromHex(DISABLE_NOTIF_STR));
+ }
+ if (id.toString().contains("f000aa72-0451-4000-b000-000000000000")) {
+ lightService->writeCharacteristic(characteristic, QByteArray::fromHex(START_MEASUREMENT_STR), QLowEnergyService::WriteWithResponse); // Start
+ }
+ if (id.toString().contains("f000aa73-0451-4000-b000-000000000000")) {
+ lightService->writeCharacteristic(characteristic, QByteArray::fromHex(MEDIUM_TIMER_TIMEOUT_STR), QLowEnergyService::WriteWithResponse); // Period 1 second
+ }
+ }
+ m_lightIntensityMeasurementStarted = true;
+ }
+}
+
+void BluetoothDevice::motionDetailsDiscovered(QLowEnergyService::ServiceState newstate)
+{
+ if (newstate == QLowEnergyService::ServiceDiscovered) {
+ connect(motionService, &QLowEnergyService::characteristicWritten, this, &BluetoothDevice::startTimers);
+
+ connect(motionService, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
+ [=](QLowEnergyService::ServiceError newError) {
+ qCDebug(boot2QtDemos) << "error while writing - gyro:" << newError;
+ });
+
+ for (int i = 0; i < motionService->characteristics().count(); i++ ) {
+ QLowEnergyCharacteristic characteristic = motionService->characteristics().at(i);
+ QBluetoothUuid id = characteristic.uuid();
+ qCDebug(boot2QtDemos)<<"characteristic:"<<id.toString();
+
+ if (id.toString().contains("f000aa81-0451-4000-b000-000000000000")) {
+ motionService->writeDescriptor(characteristic.descriptors().at(0), QByteArray::fromHex(DISABLE_NOTIF_STR));
+ }
+ if (id.toString().contains("f000aa82-0451-4000-b000-000000000000")) {
+ motionService->writeCharacteristic(characteristic, QByteArray::fromHex(MOVEMENT_ENABLE_SENSORS_BITMASK_VALUE), QLowEnergyService::WriteWithResponse);
+ }
+ if (id.toString().contains("f000aa83-0451-4000-b000-000000000000")) {
+ motionService->writeCharacteristic(characteristic, QByteArray::fromHex("0a"), QLowEnergyService::WriteWithResponse);
+ }
+ }
+ m_motionMeasurementStarted = true;
+ }
+}
+
+void BluetoothDevice::startTimers() {
+ qCDebug(boot2QtDemos) << "Wrote Characteristic - gyro, starting timers.";
+ if (!slowTimer) {
+ slowTimer = new QTimer(this);
+ connect(slowTimer, SIGNAL(timeout()), this, SLOT(slowTimerExpired()));
+ slowTimer->start(SLOW_TIMER_MS);
+ }
+ if (!mediumTimer) {
+ mediumTimer = new QTimer(this);
+ connect(mediumTimer, SIGNAL(timeout()), this, SLOT(mediumTimerExpired()));
+ mediumTimer->start(MEDIUM_TIMER_MS);
+ }
+ if (!rapidTimer) {
+ rapidTimer = new QTimer(this);
+ connect(rapidTimer, SIGNAL(timeout()), this, SLOT(rapidTimerExpired()));
+ rapidTimer->start(RAPID_TIMER_MS);
+ }
+}
+
+void BluetoothDevice::slowTimerExpired()
+{
+ if (irTemperatureService && m_temperatureMeasurementStarted) {
+ queueReadRequest(temperatureCharacteristic);
+ }
+ if (baroService && m_barometerMeasurementStarted) {
+ queueReadRequest(barometerCharacteristic);
+ }
+ if (humidityService && m_humidityMeasurementStarted){
+ queueReadRequest(humidityCharacteristic);
+ }
+}
+
+void BluetoothDevice::mediumTimerExpired()
+{
+ if (lightService && m_lightIntensityMeasurementStarted){
+ queueReadRequest(lightCharacteristic);
+ }
+}
+
+void BluetoothDevice::rapidTimerExpired()
+{
+ if (motionService && m_motionMeasurementStarted) {
+ queueReadRequest(motionCharacteristic);
+ }
+}
+
+void BluetoothDevice::characteristicsRead(const QLowEnergyCharacteristic &info, const QByteArray &value)
+{
+ switch (info.handle())
+ {
+ case 0x0021:
+ irTemperatureReceived(value);
+ break;
+ case 0x0029:
+ humidityReceived(value);
+ break;
+ case 0x0031:
+ barometerReceived(value);
+ break;
+ case 0x0039:
+ motionReceived(value);
+ break;
+ case 0x0041:
+ lightIntensityReceived(value);
+ break;
+ default:
+ qWarning() << "Invalid handle" << info.handle() << "in characteristicsRead!";
+ break;
+ }
+ delete readRequestQueue.takeFirst();
+ // Response got, now we can send new request.
+ sendFirstFromQueue();
+}
+
+void BluetoothDevice::setState(BluetoothDevice::DeviceState state)
+{
+ if (m_deviceState != state) {
+ m_deviceState = state;
+ emit stateChanged();
+ }
+}
+
+bool BluetoothDevice::isNotInQueue(CharacteristicType characteristic)
+{
+ bool characteristicFound = false;
+ QVector<QueueData*>::const_iterator i;
+ for (i = readRequestQueue.constBegin(); i != readRequestQueue.constEnd(); ++i) {
+ if (characteristic == (*i)->typeToSend) {
+ characteristicFound = true;
+ break;
+ }
+ }
+ return !characteristicFound;
+}
+
+void BluetoothDevice::queueReadRequest(CharacteristicType characteristicToRead)
+{
+ if (isNotInQueue(characteristicToRead)) {
+ readRequestQueue.append(new QueueData(characteristicToRead));
+ // Try to send. If there is a request ongoing, this does nothing.
+ sendFirstFromQueue();
+ } else {
+ qWarning() << "tried to add request of type " << characteristicToRead << " to queue before previous response was received!";
+ }
+}
+
+void BluetoothDevice::sendFirstFromQueue()
+{
+ while (readRequestQueue.length() &&
+ (false == readRequestQueue.first()->alreadySent)) {
+ readRequestQueue.first()->alreadySent = true;
+ switch (readRequestQueue.first()->typeToSend)
+ {
+ case temperatureCharacteristic:
+ if (irTemperatureService)
+ irTemperatureService->readCharacteristic(irTemperatureService->characteristic(QUuid(QString("f000aa01-0451-4000-b000-000000000000"))));
+ break;
+ case humidityCharacteristic:
+ if (humidityService)
+ humidityService->readCharacteristic(humidityService->characteristic(QUuid(QString("f000aa21-0451-4000-b000-000000000000"))));
+ break;
+ case barometerCharacteristic:
+ if (baroService)
+ baroService->readCharacteristic(baroService->characteristic(QUuid(QString("f000aa41-0451-4000-b000-000000000000"))));
+ break;
+ case motionCharacteristic:
+ if (motionService)
+ motionService->readCharacteristic(motionService->characteristic(QUuid(QString("f000aa81-0451-4000-b000-000000000000"))));
+ break;
+ case lightCharacteristic:
+ if (lightService)
+ lightService->readCharacteristic(lightService->characteristic(QUuid(QString("f000aa71-0451-4000-b000-000000000000"))));
+ break;
+ default:
+ delete readRequestQueue.takeFirst();
+ break;
+ }
+ }
+}
+
+void BluetoothDevice::irTemperatureReceived(const QByteArray &value)
+{
+ //Merge bytes
+ unsigned int temperature_raw = (((quint8)value.at(3)) << 8) + ((quint8)value.at(2));
+ double temperature = static_cast<double>(temperature_raw);
+
+ //Compute and filter final value
+ if (temperature < 32768)
+ temperature = temperature/128.0; //Positive temperature values
+ else if (temperature > 32768)
+ temperature = (temperature - 65536) / 128.0; //Negative temperature values
+ emit temperatureChanged(temperature);
+}
+
+void BluetoothDevice::barometerReceived(const QByteArray &value)
+{
+ //Merge bytes
+ unsigned int temperature_raw;
+ unsigned int barometer_raw;
+ if (value.length() == 6) {
+ temperature_raw = (((quint8)value.at(2)) << 16) + (((quint8)value.at(1)) << 8) + ((quint8)value.at(0));
+ barometer_raw = (((quint8)value.at(5)) << 16) + (((quint8)value.at(4)) << 8) + ((quint8)value.at(3));
+ } else {
+ temperature_raw = (((quint8)value.at(1)) << 8) + ((quint8)value.at(0));
+ barometer_raw = (((quint8)value.at(3)) << 8) + ((quint8)value.at(2));
+ }
+
+ double temperature = static_cast<double>(temperature_raw);
+ temperature /= 100;
+
+ double barometer = static_cast<double>(barometer_raw);
+ barometer /= 100;
+ emit barometerChanged(temperature, barometer);
+}
+
+void BluetoothDevice::humidityReceived(const QByteArray &value)
+{
+ //Merge bytes
+ unsigned int humidity_raw = (((quint8)value.at(3)) << 8) + ((quint8)value.at(2));
+ double humidity = static_cast<double>(humidity_raw);
+ humidity = (humidity / 65536)*100;
+ emit humidityChanged(humidity);
+}
+
+void BluetoothDevice::lightIntensityReceived(const QByteArray &value)
+{
+ //Merge bytes
+ uint16_t lightIntensity_raw;
+ lightIntensity_raw = (((quint8)value.at(1)) << 8) + ((quint8)value.at(0));
+ uint16_t e, m;
+ m = lightIntensity_raw & 0x0FFF;
+ e = (lightIntensity_raw & 0xF000) >> 12;
+
+ double lightIntensity = ((double)m) * (0.01 * (double)qPow(2.0,(qreal)e));
+ emit lightIntensityChanged(lightIntensity);
+}
+
+void BluetoothDevice::motionReceived(const QByteArray &value)
+{
+ static MotionSensorData data;
+ data.msSincePreviousData = attitudeChangeInterval.restart();
+ movement_data_t values;
+ quint8* writePtr = (quint8*)(&values);
+
+ for (int i = 0; i < 18; ++i) {
+ *writePtr = (quint8)value.at(i);
+ writePtr++;
+ }
+
+ // Data is in little endian. Fix here if needed.
+
+ //Convert gyroscope and accelometer readings to proper units
+ data.gyroScope_x = (double(values.gyrox) * 500) / 65536;
+ data.gyroScope_y = (double(values.gyroy) * 500) / 65536;
+ data.gyroScope_z = (double(values.gyroz) * 500) / 65536;
+ // Accelometer at 8G
+ data.accelometer_x = (double(values.accelx)*8) / 32.768;
+ data.accelometer_y = (double(values.accely)*8) / 32.768;
+ data.accelometer_z = (double(values.accelz)*8) / 32.768;
+ data.magnetometer_x = double(values.magnetomx);
+ data.magnetometer_y = double(values.magnetomy);
+ data.magnetometer_z = double(values.magnetomz);
+ emit motionChanged(data);
+}
+
+void BluetoothDevice::connectToService(const QString &uuid)
+{
+ QLowEnergyService *service = 0;
+ for (int i = 0; i < m_services.size(); i++) {
+ ServiceInfo *serviceInfo = (ServiceInfo*)m_services.at(i);
+ if (serviceInfo->getUuid() == uuid) {
+ service = serviceInfo->service();
+ break;
+ }
+ }
+
+ if (!service)
+ return;
+
+ qDeleteAll(m_characteristics);
+ m_characteristics.clear();
+ emit characteristicsUpdated();
+
+ if (service->state() == QLowEnergyService::DiscoveryRequired) {
+ connect(service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
+ this, SLOT(serviceDetailsDiscovered(QLowEnergyService::ServiceState)));
+ service->discoverDetails();
+ statusUpdated("(Discovering details...)");
+ return;
+ }
+
+ //discovery already done
+ const QList<QLowEnergyCharacteristic> chars = service->characteristics();
+ foreach (const QLowEnergyCharacteristic &ch, chars) {
+ CharacteristicInfo *cInfo = new CharacteristicInfo(ch);
+ m_characteristics.append(cInfo);
+ }
+
+ QTimer::singleShot(0, this, SIGNAL(characteristicsUpdated()));
+}
+
+void BluetoothDevice::deviceConnected()
+{
+ setState(DeviceState::Connected);
+ statusUpdated("(Discovering services...)");
+ controller->discoverServices();
+}
+
+void BluetoothDevice::errorReceived(QLowEnergyController::Error /*error*/)
+{
+ setState(DeviceState::Error);
+ statusUpdated(QString("Error: %1)").arg(controller->errorString()));
+}
+
+void BluetoothDevice::disconnectFromDevice()
+{
+ // UI always expects disconnect() signal when calling this signal
+ // TODO what is really needed is to extend state() to a multi value
+ // and thus allowing UI to keep track of controller progress in addition to
+ // device scan progress
+
+ if (controller->state() != QLowEnergyController::UnconnectedState)
+ controller->disconnectFromDevice();
+ else
+ deviceDisconnected();
+}
+
+void BluetoothDevice::deviceDisconnected()
+{
+ statusUpdated("Disconnect from device");
+ setState(BluetoothDevice::Disconnected);
+}
+
+void BluetoothDevice::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState)
+{
+ if (newState != QLowEnergyService::ServiceDiscovered) {
+ // do not hang in "Scanning for characteristics" mode forever
+ // in case the service discovery failed
+ // We have to queue the signal up to give UI time to even enter
+ // the above mode
+ if (newState != QLowEnergyService::DiscoveringServices) {
+ QMetaObject::invokeMethod(this, "characteristicsUpdated",
+ Qt::QueuedConnection);
+ }
+ return;
+ }
+
+ QLowEnergyService *service = qobject_cast<QLowEnergyService *>(sender());
+ if (!service)
+ return;
+
+
+ const QList<QLowEnergyCharacteristic> chars = service->characteristics();
+ foreach (const QLowEnergyCharacteristic &ch, chars) {
+ CharacteristicInfo *cInfo = new CharacteristicInfo(ch);
+ m_characteristics.append(cInfo);
+ }
+
+ emit characteristicsUpdated();
+}
+
+BluetoothDevice::DeviceState BluetoothDevice::state() const
+{
+ return m_deviceState;
+}
diff --git a/tradeshow/iot-sensortag/bluetoothdevice.h b/tradeshow/iot-sensortag/bluetoothdevice.h
new file mode 100644
index 0000000..58f17c3
--- /dev/null
+++ b/tradeshow/iot-sensortag/bluetoothdevice.h
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BLUETOOTHDEVICE_H
+#define BLUETOOTHDEVICE_H
+
+#include "serviceinfo.h"
+
+#include <QBluetoothDeviceDiscoveryAgent>
+#include <QLowEnergyController>
+#include <QObject>
+#include <QVariant>
+#include <QList>
+#include <QTimer>
+#include <QElapsedTimer>
+
+class MotionSensorData
+{
+public:
+ double gyroScope_x;
+ double gyroScope_y;
+ double gyroScope_z;
+ double accelometer_x;
+ double accelometer_y;
+ double accelometer_z;
+ double magnetometer_x;
+ double magnetometer_y;
+ double magnetometer_z;
+ quint64 msSincePreviousData;
+ MotionSensorData() {
+ gyroScope_x = 0;
+ gyroScope_y = 0;
+ gyroScope_z = 0;
+ accelometer_x = 0;
+ accelometer_y = 0;
+ accelometer_z = 0;
+ magnetometer_x = 0;
+ magnetometer_y = 0;
+ magnetometer_z = 0;
+ msSincePreviousData = 0;
+ }
+};
+
+typedef enum CharacteristicType {
+ temperatureCharacteristic = 0,
+ humidityCharacteristic,
+ barometerCharacteristic,
+ motionCharacteristic,
+ lightCharacteristic
+} CharacteristicType;
+
+class QueueData {
+public:
+ CharacteristicType typeToSend;
+ bool alreadySent;
+ QueueData(CharacteristicType characteristic) {
+ typeToSend = characteristic;
+ alreadySent = false;
+ }
+
+private:
+ QueueData() {}
+};
+
+class SensorTagDataProvider;
+
+class BluetoothDevice: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString deviceName READ getName CONSTANT)
+ Q_PROPERTY(QString deviceAddress READ getAddress CONSTANT)
+ Q_PROPERTY(DeviceState state READ state NOTIFY stateChanged)
+
+ Q_PROPERTY(QVariant servicesList READ getServices NOTIFY servicesUpdated)
+ Q_PROPERTY(QVariant characteristicList READ getCharacteristics NOTIFY characteristicsUpdated)
+ Q_PROPERTY(bool useRandomAddress MEMBER randomAddress NOTIFY randomAddressChanged)
+
+public:
+ enum DeviceState {Disconnected = 0, Scanning, Connected, Error};
+ Q_ENUM(DeviceState)
+
+ BluetoothDevice();
+ BluetoothDevice(const QBluetoothDeviceInfo &d);
+ ~BluetoothDevice();
+
+ QString getAddress() const;
+ QString getName() const;
+
+ QVariant getServices();
+ QVariant getCharacteristics();
+ DeviceState state() const;
+
+signals:
+ void servicesUpdated();
+ void characteristicsUpdated();
+ void updateChanged();
+ void stateChanged();
+ void randomAddressChanged();
+ void temperatureChanged(double temperature);
+ void barometerChanged(double temperature, double barometer);
+ void humidityChanged(double humidity);
+ void lightIntensityChanged(double intensity);
+ void motionChanged(MotionSensorData& data);
+ void statusUpdated(QString statusMsg);
+
+public slots:
+ void scanServices();
+ void startTimers();
+ void connectToService(const QString &uuid);
+ void disconnectFromDevice();
+ void temperatureDetailsDiscovered(QLowEnergyService::ServiceState newstate);
+ void barometerDetailsDiscovered(QLowEnergyService::ServiceState newstate);
+ void humidityDetailsDiscovered(QLowEnergyService::ServiceState newstate);
+ void lightIntensityDetailsDiscovered(QLowEnergyService::ServiceState newstate);
+ void motionDetailsDiscovered(QLowEnergyService::ServiceState newstate);
+
+private slots:
+ // QLowEnergyController realted
+ void addLowEnergyService(const QBluetoothUuid &uuid);
+ void deviceConnected();
+ void errorReceived(QLowEnergyController::Error);
+ void serviceScanDone();
+ void deviceDisconnected();
+
+ // QLowEnergyService related
+ void serviceDetailsDiscovered(QLowEnergyService::ServiceState newState);
+
+ void slowTimerExpired();
+ void mediumTimerExpired();
+ void rapidTimerExpired();
+ void characteristicsRead(const QLowEnergyCharacteristic &info,
+ const QByteArray &value);
+
+private:
+ void setState(DeviceState state);
+
+private:
+ bool isNotInQueue(const CharacteristicType characteristic);
+ void queueReadRequest(CharacteristicType characteristicToRead);
+ void sendFirstFromQueue();
+ void irTemperatureReceived(const QByteArray &value);
+ void barometerReceived(const QByteArray &value);
+ void humidityReceived(const QByteArray &value);
+ void lightIntensityReceived(const QByteArray &value);
+ void motionReceived(const QByteArray &value);
+
+ QBluetoothDeviceDiscoveryAgent *discoveryAgent;
+ QList<QObject*> m_services;
+ QList<QObject*> m_characteristics;
+ QString m_previousAddress;
+ QLowEnergyController *controller;
+ QLowEnergyService* irTemperatureService;
+ QLowEnergyService* baroService;
+ QLowEnergyService* humidityService;
+ QLowEnergyService* lightService;
+ QLowEnergyService* motionService;
+ DeviceState m_deviceState;
+ bool m_temperatureMeasurementStarted;
+ bool m_barometerMeasurementStarted;
+ bool m_humidityMeasurementStarted;
+ bool m_lightIntensityMeasurementStarted;
+ bool m_motionMeasurementStarted;
+ bool randomAddress;
+ QTimer* slowTimer;
+ QTimer* mediumTimer;
+ QTimer* rapidTimer;
+ QElapsedTimer attitudeChangeInterval;
+ QVector<QueueData*> readRequestQueue;
+
+ QBluetoothDeviceInfo m_deviceInfo;
+
+ SensorTagDataProvider *m_dataProvider;
+};
+
+#endif // BLUETOOTHBLUETOOTHDEVICE_H
diff --git a/tradeshow/iot-sensortag/characteristicinfo.cpp b/tradeshow/iot-sensortag/characteristicinfo.cpp
new file mode 100644
index 0000000..3915293
--- /dev/null
+++ b/tradeshow/iot-sensortag/characteristicinfo.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "characteristicinfo.h"
+#include <QByteArray>
+
+CharacteristicInfo::CharacteristicInfo()
+{
+}
+
+CharacteristicInfo::CharacteristicInfo(const QLowEnergyCharacteristic &characteristic):
+ m_characteristic(characteristic)
+{
+}
+
+void CharacteristicInfo::setCharacteristic(const QLowEnergyCharacteristic &characteristic)
+{
+ m_characteristic = characteristic;
+ emit characteristicChanged();
+}
+
+QString CharacteristicInfo::getName() const
+{
+ QString name = m_characteristic.name();
+ if (!name.isEmpty())
+ return name;
+
+ // find descriptor with CharacteristicUserDescription
+ foreach (const QLowEnergyDescriptor &descriptor, m_characteristic.descriptors()) {
+ if (descriptor.type() == QBluetoothUuid::CharacteristicUserDescription) {
+ name = descriptor.value();
+ break;
+ }
+ }
+
+ if (name.isEmpty())
+ name = "Unknown";
+
+ return name;
+}
+
+QString CharacteristicInfo::getUuid() const
+{
+ const QBluetoothUuid uuid = m_characteristic.uuid();
+ bool success = false;
+ quint16 result16 = uuid.toUInt16(&success);
+ if (success)
+ return QStringLiteral("0x") + QString::number(result16, 16);
+
+ quint32 result32 = uuid.toUInt32(&success);
+ if (success)
+ return QStringLiteral("0x") + QString::number(result32, 16);
+
+ return uuid.toString().remove(QLatin1Char('{')).remove(QLatin1Char('}'));
+}
+
+QString CharacteristicInfo::getValue() const
+{
+ // Show raw string first and hex value below
+ QByteArray a = m_characteristic.value();
+ QString result;
+ if (a.isEmpty()) {
+ result = QStringLiteral("<none>");
+ return result;
+ }
+
+ result = a;
+ result += QLatin1Char('\n');
+ result += a.toHex();
+
+ return result;
+}
+
+QString CharacteristicInfo::getHandle() const
+{
+ return QStringLiteral("0x") + QString::number(m_characteristic.handle(), 16);
+}
+
+QString CharacteristicInfo::getPermission() const
+{
+ QString properties = "( ";
+ int permission = m_characteristic.properties();
+ if (permission & QLowEnergyCharacteristic::Read)
+ properties += QStringLiteral(" Read");
+ if (permission & QLowEnergyCharacteristic::Write)
+ properties += QStringLiteral(" Write");
+ if (permission & QLowEnergyCharacteristic::Notify)
+ properties += QStringLiteral(" Notify");
+ if (permission & QLowEnergyCharacteristic::Indicate)
+ properties += QStringLiteral(" Indicate");
+ if (permission & QLowEnergyCharacteristic::ExtendedProperty)
+ properties += QStringLiteral(" ExtendedProperty");
+ if (permission & QLowEnergyCharacteristic::Broadcasting)
+ properties += QStringLiteral(" Broadcast");
+ if (permission & QLowEnergyCharacteristic::WriteNoResponse)
+ properties += QStringLiteral(" WriteNoResp");
+ if (permission & QLowEnergyCharacteristic::WriteSigned)
+ properties += QStringLiteral(" WriteSigned");
+ properties += " )";
+ return properties;
+}
+
+QLowEnergyCharacteristic CharacteristicInfo::getCharacteristic() const
+{
+ return m_characteristic;
+}
diff --git a/tradeshow/iot-sensortag/characteristicinfo.h b/tradeshow/iot-sensortag/characteristicinfo.h
new file mode 100644
index 0000000..1143ec9
--- /dev/null
+++ b/tradeshow/iot-sensortag/characteristicinfo.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CHARACTERISTICINFO_H
+#define CHARACTERISTICINFO_H
+
+#include <QObject>
+#include <QString>
+#include <QtBluetooth/QLowEnergyCharacteristic>
+
+class CharacteristicInfo: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString characteristicName READ getName NOTIFY characteristicChanged)
+ Q_PROPERTY(QString characteristicUuid READ getUuid NOTIFY characteristicChanged)
+ Q_PROPERTY(QString characteristicValue READ getValue NOTIFY characteristicChanged)
+ Q_PROPERTY(QString characteristicHandle READ getHandle NOTIFY characteristicChanged)
+ Q_PROPERTY(QString characteristicPermission READ getPermission NOTIFY characteristicChanged)
+
+public:
+ CharacteristicInfo();
+ CharacteristicInfo(const QLowEnergyCharacteristic &characteristic);
+ void setCharacteristic(const QLowEnergyCharacteristic &characteristic);
+ QString getName() const;
+ QString getUuid() const;
+ QString getValue() const;
+ QString getHandle() const;
+ QString getPermission() const;
+ QLowEnergyCharacteristic getCharacteristic() const;
+
+Q_SIGNALS:
+ void characteristicChanged();
+
+private:
+ QLowEnergyCharacteristic m_characteristic;
+};
+
+#endif // CHARACTERISTICINFO_H
diff --git a/tradeshow/iot-sensortag/clouddataprovider.cpp b/tradeshow/iot-sensortag/clouddataprovider.cpp
new file mode 100644
index 0000000..ef1efa3
--- /dev/null
+++ b/tradeshow/iot-sensortag/clouddataprovider.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "clouddataprovider.h"
+
+#include <QUrl>
+#include <QLoggingCategory>
+#include <QTimer>
+
+#define MAJOR_VERSION_NUMBER 1
+#define MINOR_VERSION_NUMBER 0
+#ifndef QT_NO_SSL
+static QString dataFetchUrl = "https://ottoryynanenqt.blob.core.windows.net/btsensortagreadings/sensorTagReadings.txt";
+#else
+static QString dataFetchUrl = "http://ottoryynanenqt.blob.core.windows.net/btsensortagreadings/sensorTagReadings.txt";
+#endif
+
+Q_DECLARE_LOGGING_CATEGORY(boot2QtDemos)
+
+CloudDataProvider::CloudDataProvider(QString id, QObject* parent)
+ : SensorTagDataProvider(id, parent)
+ , reply(Q_NULLPTR)
+{
+ connect(&qnam, &QNetworkAccessManager::authenticationRequired,
+ this, &CloudDataProvider::slotAuthenticationRequired);
+#ifndef QT_NO_SSL
+ connect(&qnam, &QNetworkAccessManager::sslErrors,
+ this, &CloudDataProvider::sslErrors);
+#endif
+}
+
+bool CloudDataProvider::startDataFetching()
+{
+ pollTimer = new QTimer(this);
+ connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollTimerExpired()));
+ pollTimer->start(1000); // 1 second update interval
+ return true;
+}
+
+void CloudDataProvider::endDataFetching()
+{
+ httpRequestAborted = true;
+ reply->abort();
+}
+
+void CloudDataProvider::parseReceivedText()
+{
+ QList<QByteArray> dataList = dataFetched.split('\n');
+ if (dataList[2] != "Version:") {
+ qWarning() << Q_FUNC_INFO << "Invalid file header:" << dataList[2];
+ return;
+ }
+
+ QList<QByteArray> versionNumberList = dataList[3].split('.');
+ const int dataMajorVersion = QString(versionNumberList[0]).toInt();
+ const int dataMinorVersion = QString(versionNumberList[1]).toInt();
+ if ((MAJOR_VERSION_NUMBER < dataMajorVersion) || // Major version not supported OR
+ ((MAJOR_VERSION_NUMBER == dataMajorVersion) && // Major version OK but
+ (MINOR_VERSION_NUMBER < dataMinorVersion))) { // Minor version not supported
+ qWarning() << Q_FUNC_INFO << "Version" << dataList[3] << "not supported by version" << QString::number(MAJOR_VERSION_NUMBER)+"."+QString::number(MINOR_VERSION_NUMBER);
+ return;
+ }
+ // Header OK, parse data.
+ bool gyroscopeReadingGot = false;
+ bool accelometerReadingGot = false;
+ bool magnetometerReadingGot = false;
+ for (int stringIndex = 4 ; stringIndex < (dataList.length()-1) ; stringIndex+=2) {
+ const QString headerText(dataList[stringIndex]);
+ const double doubleValue = QString(dataList[stringIndex+1]).toDouble();
+ const float floatValue = QString(dataList[stringIndex+1]).toFloat();
+ if ("Humid:" == headerText) {
+ humidity = doubleValue;
+ emit relativeHumidityChanged();
+ } else if ("Temp(IR):" == headerText) {
+ irTemperature = doubleValue;
+ emit infraredCelsiusTemperatureChanged();
+ } else if ("Light:" == headerText) {
+ lightIntensityLux = doubleValue;
+ emit lightIntensityChanged();
+ } else if ("Temp(Baro):" == headerText) {
+ barometerCelsiusTemperature = doubleValue;
+ emit barometerCelsiusTemperatureChanged();
+ } else if ("hPa:" == headerText) {
+ barometerHPa = doubleValue;
+ emit barometer_hPaChanged();
+ } else if ("gyroX:" == headerText) {
+ gyroscopeReadingGot = true;
+ gyroscopeX_degPerSec = floatValue;
+ } else if ("gyroY:" == headerText) {
+ gyroscopeReadingGot = true;
+ gyroscopeY_degPerSec = floatValue;
+ } else if ("gyroZ:" == headerText) {
+ gyroscopeReadingGot = true;
+ gyroscopeZ_degPerSec = floatValue;
+ } else if ("AccX:" == headerText) {
+ accelometerReadingGot = true;
+ accelometer_mG_xAxis = doubleValue;
+ } else if ("AccY:" == headerText) {
+ accelometerReadingGot = true;
+ accelometer_mG_yAxis = doubleValue;
+ } else if ("AccZ:" == headerText) {
+ accelometerReadingGot = true;
+ accelometer_mG_zAxis = doubleValue;
+ } else if ("MagnX:" == headerText) {
+ magnetometerReadingGot = true;
+ magnetometerMicroT_xAxis = floatValue;
+ } else if ("MagnY:" == headerText) {
+ magnetometerReadingGot = true;
+ magnetometerMicroT_yAxis = floatValue;
+ } else if ("MagnZ:" == headerText) {
+ magnetometerReadingGot = true;
+ magnetometerMicroT_zAxis = floatValue;
+ } else if ("RotX:" == headerText) {
+ rotation_x = floatValue;
+ emit rotationXChanged();
+ } else if ("RotY:" == headerText) {
+ rotation_y = floatValue;
+ emit rotationYChanged();
+ } else if ("RotZ:" == headerText) {
+ rotation_z = floatValue;
+ emit rotationZChanged();
+ } else {
+ qCDebug(boot2QtDemos) << "Unsupported Header:" << headerText;
+ }
+ }
+ if (gyroscopeReadingGot)
+ emit gyroscopeDegPerSecChanged();
+ if (accelometerReadingGot)
+ emit accelometerGChanged();
+ if (magnetometerReadingGot)
+ emit magnetometerMicroTChanged();
+}
+
+void CloudDataProvider::pollTimerExpired()
+{
+ if (!reply) {
+ httpRequestAborted = false;
+ dataFetched.clear();
+ reply = qnam.get(QNetworkRequest(QUrl(dataFetchUrl)));
+ connect(reply, &QNetworkReply::finished, this, &CloudDataProvider::httpFinished);
+ connect(reply, &QIODevice::readyRead, this, &CloudDataProvider::httpReadyRead);
+ } else {
+ qWarning() << "Attempt to fetch before previous http request was completed.";
+ }
+}
+
+void CloudDataProvider::httpFinished()
+{
+ if (httpRequestAborted) {
+ qCDebug(boot2QtDemos) << "http request aborted.";
+ return;
+ }
+ if (reply->error()) {
+ qWarning() << "Failed to fetch data," << reply->errorString();
+ return;
+ }
+
+ parseReceivedText();
+ const QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+
+ reply->deleteLater();
+ reply = Q_NULLPTR;
+}
+
+void CloudDataProvider::httpReadyRead()
+{
+ // this slot gets called every time the QNetworkReply has new data.
+ // We read all of its new data and write it into the file.
+ // That way we use less RAM than when reading it at the finished()
+ // signal of the QNetworkReply
+ dataFetched += reply->readAll();
+}
+
+#ifndef QT_NO_SSL
+void CloudDataProvider::sslErrors(QNetworkReply*, const QList<QSslError> &errors)
+{
+ QString errorString;
+ foreach (const QSslError &error, errors) {
+ if (!errorString.isEmpty())
+ errorString += '\n';
+ errorString += error.errorString();
+ }
+
+ qWarning() << "Ignoring SSL Error(s):" << errorString;
+ reply->ignoreSslErrors();
+}
+#endif
+
+void CloudDataProvider::slotAuthenticationRequired(QNetworkReply*, QAuthenticator *authenticator)
+{
+ Q_UNUSED(authenticator);
+}
+
+QString CloudDataProvider::sensorType() const
+{
+ return QString("cloud data");
+}
+
+QString CloudDataProvider::versionString() const
+{
+ return QString::number(MAJOR_VERSION_NUMBER)+"."+QString::number(MINOR_VERSION_NUMBER);
+}
diff --git a/tradeshow/iot-sensortag/clouddataprovider.h b/tradeshow/iot-sensortag/clouddataprovider.h
new file mode 100644
index 0000000..904431d
--- /dev/null
+++ b/tradeshow/iot-sensortag/clouddataprovider.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CLOUDDATAPROVIDER_H
+#define CLOUDDATAPROVIDER_H
+
+#include "sensortagdataprovider.h"
+#include <QtQml/QQmlEngine>
+#include <QtQml/QJSEngine>
+#include <QtNetwork>
+#include <QNetworkAccessManager>
+
+class QTimer;
+
+class CloudDataProvider : public SensorTagDataProvider
+{
+ Q_OBJECT
+public:
+ explicit CloudDataProvider(QString id, QObject *parent = 0);
+
+ bool startDataFetching();
+ void endDataFetching();
+ QString sensorType() const;
+ QString versionString() const;
+public slots:
+ void pollTimerExpired();
+
+private slots:
+ void httpFinished();
+ void httpReadyRead();
+ void slotAuthenticationRequired(QNetworkReply *, QAuthenticator *);
+#ifndef QT_NO_SSL
+ void sslErrors(QNetworkReply *, const QList<QSslError> &errors);
+#endif
+
+private:
+ void parseReceivedText();
+
+ QTimer *pollTimer;
+ QNetworkAccessManager qnam;
+ QNetworkReply *reply;
+ bool httpRequestAborted;
+ QByteArray dataFetched;
+};
+#endif // CLOUDDATAPROVIDER_H
diff --git a/tradeshow/iot-sensortag/clouddataproviderpool.cpp b/tradeshow/iot-sensortag/clouddataproviderpool.cpp
new file mode 100644
index 0000000..3c1f6b2
--- /dev/null
+++ b/tradeshow/iot-sensortag/clouddataproviderpool.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "clouddataproviderpool.h"
+#include "clouddataprovider.h"
+
+CloudDataProviderPool::CloudDataProviderPool(QObject* parent)
+ : DataProviderPool(parent)
+{
+ m_poolName = "Cloud";
+}
+
+void CloudDataProviderPool::startScanning()
+{
+ m_dataProviders.push_back(new CloudDataProvider("CLOUD_PROVIDER", this));
+ m_dataProviders.at(0)->startDataFetching();
+ emit providerConnected("MS_AZURE_CLOUD");
+ emit providersUpdated();
+ emit scanFinished();
+}
diff --git a/tradeshow/iot-sensortag/clouddataproviderpool.h b/tradeshow/iot-sensortag/clouddataproviderpool.h
new file mode 100644
index 0000000..5a357c0
--- /dev/null
+++ b/tradeshow/iot-sensortag/clouddataproviderpool.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CLOUDDATAPROVIDERPOOL_H
+#define CLOUDDATAPROVIDERPOOL_H
+
+#include "dataproviderpool.h"
+
+class CloudDataProvider;
+
+class CloudDataProviderPool : public DataProviderPool
+{
+public:
+ explicit CloudDataProviderPool(QObject* parent = 0);
+
+ void startScanning() override;
+};
+
+#endif // CLOUDDATAPROVIDERPOOL_H
diff --git a/tradeshow/iot-sensortag/cloudservice.h b/tradeshow/iot-sensortag/cloudservice.h
new file mode 100644
index 0000000..35a9f8e
--- /dev/null
+++ b/tradeshow/iot-sensortag/cloudservice.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CLOUDSERVICE_H
+#define CLOUDSERVICE_H
+
+#define AZURE_ACCOUNT_NAME "ottoryynanenqt"
+#define AZURE_ACCOUNT_KEY "XCZNDmLR7uLrBaO5p7sPGems8AMwNEmEM9AuDQE2cpMYgu3VikoJC0yGwh1KztU0vCCwDv17bIpDO8IpzPDBtw=="
+#define CLOUD_BLOB_NAME "btsensortagreadings"
+#define CLOUD_FILE_NAME "sensorTagReadings.txt"
+
+#endif // CLOUDSERVICE_H
diff --git a/tradeshow/iot-sensortag/cloudupdate.cpp b/tradeshow/iot-sensortag/cloudupdate.cpp
new file mode 100644
index 0000000..54b0558
--- /dev/null
+++ b/tradeshow/iot-sensortag/cloudupdate.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "cloudupdate.h"
+#include "cloudservice.h"
+#include "dataproviderpool.h"
+#include "sensortagdataprovider.h"
+
+#include "demodataproviderpool.h"
+
+#include "was/storage_account.h"
+#include "was/blob.h"
+
+#define ROUNDING_DECIMALS 2
+#define UPDATE_INTERVAL 1000
+
+CloudUpdate::CloudUpdate(QObject *parent)
+ : QObject(parent)
+ , m_providerPool(0)
+ , m_provider(0)
+ , m_timerId(0)
+ , m_updateInterval(UPDATE_INTERVAL)
+{
+}
+
+void CloudUpdate::setDataProviderPool(DataProviderPool *provider)
+{
+ m_providerPool = provider;
+ connect(m_providerPool, &DataProviderPool::providerForCloudChanged, this, [=]() {
+ m_provider = m_providerPool->providerForCloud();
+ if (!m_provider) {
+ stop();
+ }
+ });
+}
+
+int CloudUpdate::updateInterval() const
+{
+ return m_updateInterval;
+}
+
+void CloudUpdate::setUpdateInterval(int interval)
+{
+ m_updateInterval = interval;
+}
+
+void CloudUpdate::restart()
+{
+ killTimer(m_timerId);
+ m_timerId = startTimer(m_updateInterval);
+}
+
+void CloudUpdate::stop()
+{
+ killTimer(m_timerId);
+}
+
+void CloudUpdate::timerEvent(QTimerEvent *event)
+{
+ Q_UNUSED(event);
+
+ if (!m_provider)
+ return;
+
+ writeToCloud();
+}
+
+void CloudUpdate::writeToCloud()
+{
+ if (!m_provider) {
+ qWarning("CloudUpdate: sensor data provider not set. Data not updated");
+ return;
+ }
+
+ // Define the connection-string with your values.
+ QByteArray accStr = QByteArrayLiteral("DefaultEndpointsProtocol=https;AccountName=");
+ accStr += AZURE_ACCOUNT_NAME;
+ accStr += QByteArrayLiteral(";AccountKey=");
+ accStr += AZURE_ACCOUNT_KEY;
+#ifndef Q_OS_WIN
+ const utility::string_t storage_connection_string(U(accStr.data()));
+#else
+ const utility::string_t storage_connection_string(reinterpret_cast<const wchar_t*>(QString(accStr).utf16()));
+#endif
+ azure::storage::cloud_blob_container container;
+
+ try {
+ azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
+
+ // Create the blob client.
+ azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();
+
+ // Retrieve a reference to a container.
+ container = blob_client.get_container_reference(U(CLOUD_BLOB_NAME));
+
+ // Create the container if it doesn't already exist.
+ container.create_if_not_exists();
+ }
+ catch (const std::exception& e)
+ {
+ std::wcout << U("Error: ") << e.what() << std::endl;
+ }
+
+ // Retrieve reference to a blob
+ azure::storage::cloud_block_blob blob = container.get_block_blob_reference(U(CLOUD_FILE_NAME));
+
+ QString sensorData = buildString();
+#ifndef Q_OS_WIN
+ blob.upload_text(U(sensorData.toLocal8Bit().data()));
+#else
+ blob.upload_text(reinterpret_cast<const wchar_t*>(sensorData.utf16()));
+#endif
+}
+
+QString CloudUpdate::buildString() const
+{
+ QString exportString;
+ exportString += QString("Type:\n%1\n").arg(m_provider->sensorType());
+ exportString += QString("Version:\n%1\n").arg(m_provider->versionString());
+ exportString += QString("Humid:\n%1\n").arg(m_provider->getRelativeHumidity(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("Temp(IR):\n%1\n").arg(m_provider->getInfraredCelsiusTemperature(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("Light:\n%1\n").arg(m_provider->getLightIntensityLux(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("Temp(Baro):\n%1\n").arg(m_provider->getBarometerCelsiusTemperature(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("hPa:\n%1\n").arg(m_provider->getBarometer_hPa(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("gyroX:\n%1\n").arg(m_provider->getGyroscopeX_degPerSec(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("gyroY:\n%1\n").arg(m_provider->getGyroscopeY_degPerSec(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("gyroZ:\n%1\n").arg(m_provider->getGyroscopeZ_degPerSec(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("AccX:\n%1\n").arg(m_provider->getAccelometer_mG_xAxis());
+ exportString += QString("AccY:\n%1\n").arg(m_provider->getAccelometer_mG_yAxis());
+ exportString += QString("AccZ:\n%1\n").arg(m_provider->getAccelometer_mG_zAxis());
+ exportString += QString("MagnX:\n%1\n").arg(m_provider->getMagnetometerMicroT_xAxis(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("MagnY:\n%1\n").arg(m_provider->getMagnetometerMicroT_yAxis(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("MagnZ:\n%1\n").arg(m_provider->getMagnetometerMicroT_zAxis(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("RotX:\n%1\n").arg(m_provider->getRotationX(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("RotY:\n%1\n").arg(m_provider->getRotationY(), 0, 'f', ROUNDING_DECIMALS);
+ exportString += QString("RotZ:\n%1").arg(m_provider->getRotationZ(), 0, 'f', ROUNDING_DECIMALS);
+ return exportString;
+}
diff --git a/tradeshow/iot-sensortag/cloudupdate.h b/tradeshow/iot-sensortag/cloudupdate.h
new file mode 100644
index 0000000..9fa81cf
--- /dev/null
+++ b/tradeshow/iot-sensortag/cloudupdate.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CLOUDUPDATE_H
+#define CLOUDUPDATE_H
+
+#include <QObject>
+
+class DataProviderPool;
+class SensorTagDataProvider;
+
+class CloudUpdate : public QObject
+{
+public:
+ explicit CloudUpdate(QObject *parent = 0);
+
+ void setDataProviderPool(DataProviderPool *provider);
+
+ int updateInterval() const;
+ void setUpdateInterval(int interval);
+ void restart();
+ void stop();
+
+protected:
+ void timerEvent(QTimerEvent* event);
+
+ virtual void writeToCloud();
+
+private:
+ QString buildString() const;
+
+protected:
+ DataProviderPool *m_providerPool;
+
+private:
+ SensorTagDataProvider *m_provider;
+ int m_timerId;
+ int m_updateInterval;
+};
+
+#endif // CLOUDUPDATE_H
diff --git a/tradeshow/iot-sensortag/dataproviderpool.cpp b/tradeshow/iot-sensortag/dataproviderpool.cpp
new file mode 100644
index 0000000..040809d
--- /dev/null
+++ b/tradeshow/iot-sensortag/dataproviderpool.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "dataproviderpool.h"
+
+DataProviderPool::DataProviderPool(QObject *parent)
+ : QObject(parent)
+{
+}
+
+DataProviderPool::DataProviderPool(QString poolName, QObject *parent)
+ : QObject(parent)
+ , m_poolName(poolName)
+{
+
+}
+
+void DataProviderPool::startScanning()
+{
+}
+
+void DataProviderPool::stopScanning()
+{
+ emit scanFinished();
+}
+
+SensorTagDataProvider *DataProviderPool::getProvider(SensorTagDataProvider::TagType type) const
+{
+ auto it = m_dataProviders.constBegin();
+ SensorTagDataProvider* p = 0;
+ while (it != m_dataProviders.end()) {
+ if ((*it)->tagType() & type) {
+ p = *it;
+ break;
+ }
+ it++;
+ }
+ return p;
+}
+
+QQmlListProperty<SensorTagDataProvider> DataProviderPool::dataProviders()
+{
+ return QQmlListProperty<SensorTagDataProvider>(this, m_dataProviders);
+}
+
+SensorTagDataProvider *DataProviderPool::providerForCloud() const
+{
+ return 0;
+}
diff --git a/tradeshow/iot-sensortag/dataproviderpool.h b/tradeshow/iot-sensortag/dataproviderpool.h
new file mode 100644
index 0000000..e8d50e6
--- /dev/null
+++ b/tradeshow/iot-sensortag/dataproviderpool.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef DATAPROVIDERPOOL_H
+#define DATAPROVIDERPOOL_H
+
+#include <QObject>
+#include <QQmlListProperty>
+
+#include "sensortagdataprovider.h"
+
+class DataProviderPool : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY (QQmlListProperty<SensorTagDataProvider> dataProviders READ dataProviders NOTIFY dataProvidersChanged)
+ Q_PROPERTY(QString name MEMBER m_poolName CONSTANT)
+
+public:
+ Q_INVOKABLE virtual void startScanning();
+ Q_INVOKABLE virtual void stopScanning();
+ Q_INVOKABLE virtual SensorTagDataProvider* getProvider(SensorTagDataProvider::TagType type) const;
+
+ QQmlListProperty<SensorTagDataProvider> dataProviders();
+
+ virtual SensorTagDataProvider* providerForCloud() const;
+
+signals:
+ void providerConnected(QString id);
+ void providerDisconnected(QString id);
+ void providerInError(QString id);
+ void providersUpdated();
+ void scanFinished();
+ void providerForCloudChanged();
+ void dataProvidersChanged();
+
+protected:
+ explicit DataProviderPool(QObject *parent = 0);
+ DataProviderPool(QString poolName, QObject* parent = 0);
+
+protected:
+ QList<SensorTagDataProvider*> m_dataProviders;
+ QString m_poolName;
+};
+
+#endif // DATAPROVIDERPOOL_H
diff --git a/tradeshow/iot-sensortag/demodataproviderpool.cpp b/tradeshow/iot-sensortag/demodataproviderpool.cpp
new file mode 100644
index 0000000..a1369d7
--- /dev/null
+++ b/tradeshow/iot-sensortag/demodataproviderpool.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "demodataproviderpool.h"
+#include "mockdataprovider.h"
+
+DemoDataProviderPool::DemoDataProviderPool(QObject *parent)
+ : DataProviderPool("Demo", parent)
+ , m_mockData(false)
+ , m_cloudProvider(0)
+{
+}
+
+void DemoDataProviderPool::startScanning()
+{
+ if (m_mockData) {
+ MockDataProvider* p = new MockDataProvider("MOCK_PROVIDER_1", this);
+ p->setTagType(SensorTagDataProvider::ObjectTemperature | SensorTagDataProvider::AmbientTemperature | SensorTagDataProvider::Rotation);
+ m_dataProviders.push_back(p);
+ p = new MockDataProvider("MOCK_PROVIDER_2", this);
+ p->setTagType(SensorTagDataProvider::Humidity | SensorTagDataProvider::Light);
+ m_dataProviders.push_back(p);
+ p = new MockDataProvider("MOCK_PROVIDER_3", this);
+ p->setTagType(SensorTagDataProvider::Magnetometer | SensorTagDataProvider::AirPressure);
+ m_dataProviders.push_back(p);
+ for (int i=0; i < m_dataProviders.length(); i++) {
+ m_dataProviders.at(i)->startDataFetching();
+ emit providerConnected(p->id());
+ }
+ // Stop scanning as we already have a provider
+ stopScanning();
+ }
+ else {
+ DataProviderPool::startScanning();
+ }
+}
+
+void DemoDataProviderPool::stopScanning()
+{
+ // TODO: get data for cloud update provider from
+ // all available providers, not just from the first found
+ if (m_dataProviders.length()) {
+ m_cloudProvider = m_dataProviders.at(0);
+ }
+
+ emit dataProvidersChanged();
+ emit scanFinished();
+}
+
+void DemoDataProviderPool::setMockDataMode(bool mode)
+{
+ m_mockData = mode;
+}
+
+SensorTagDataProvider *DemoDataProviderPool::providerForCloud() const
+{
+ return m_cloudProvider;
+}
diff --git a/tradeshow/iot-sensortag/demodataproviderpool.h b/tradeshow/iot-sensortag/demodataproviderpool.h
new file mode 100644
index 0000000..2bb517f
--- /dev/null
+++ b/tradeshow/iot-sensortag/demodataproviderpool.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef DEMODATAPROVIDERPOOL_H
+#define DEMODATAPROVIDERPOOL_H
+
+#include "sensortagdataproviderpool.h"
+
+class CloudUpdate;
+
+class DemoDataProviderPool : public DataProviderPool
+{
+ Q_OBJECT
+public:
+ explicit DemoDataProviderPool(QObject *parent = 0);
+
+ void startScanning() override;
+ void stopScanning() override;
+
+ SensorTagDataProvider* providerForCloud() const override;
+
+ void setMockDataMode(bool mode);
+
+private:
+ bool m_mockData;
+ SensorTagDataProvider* m_cloudProvider;
+};
+
+#endif // DEMODATAPROVIDERPOOL_H
diff --git a/tradeshow/iot-sensortag/main.cpp b/tradeshow/iot-sensortag/main.cpp
new file mode 100644
index 0000000..2fcc749
--- /dev/null
+++ b/tradeshow/iot-sensortag/main.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QApplication>
+#include <QQmlApplicationEngine>
+#include <QQuickWindow>
+#include <QQmlContext>
+#include <QCommandLineParser>
+#include <QFontDatabase>
+#include <QScreen>
+
+#if defined(RUNS_AS_HOST)
+#include "bluetoothdataprovider.h"
+#include "sensortagdataprovider.h"
+#include "sensortagdataproviderpool.h"
+#endif
+#include "clouddataprovider.h"
+#include "clouddataproviderpool.h"
+#include "mockdataprovider.h"
+#include "demodataproviderpool.h"
+#ifdef CLOUD_UPLOAD
+#include "cloudupdate.h"
+#endif
+
+Q_DECLARE_LOGGING_CATEGORY(boot2QtDemos)
+Q_LOGGING_CATEGORY(boot2QtDemos, "boot2qt.demos.iot")
+
+int main(int argc, char *argv[])
+{
+ // QtChars mandate using QApplication as it uses the graphics view fw
+ QApplication app(argc, argv);
+
+ QFontDatabase::addApplicationFont(QString::fromLatin1(":/resources/base/fonts/titilliumweb/TitilliumWeb-Regular.ttf"));
+ app.setFont(QFont("Titillium Web", 13));
+
+ DataProviderPool *dataProviderPool = 0;
+
+ QCommandLineParser parser;
+ parser.addOptions({{"source", "Sensor data source", "cloud | sensor | mock"}, {"fullscreen", "Fullscreen mode", "true | false"}});
+ parser.addHelpOption();
+ parser.process(app);
+
+ QString sensorSource = parser.value("source");
+
+ if (sensorSource.isEmpty())
+ sensorSource = qgetenv("QT_IOT_DEMO_DATA_SOURCE");
+
+ if (sensorSource.isEmpty())
+ // There is no wastorage package available for WinRT
+#ifdef Q_OS_WINRT
+ sensorSource = "mock";
+#else
+ sensorSource = "cloud";
+#endif
+
+ if (sensorSource == QString("cloud").toLower()) {
+ qCDebug(boot2QtDemos) << "Running in cloud mode";
+ dataProviderPool = new CloudDataProviderPool;
+ }
+#if defined(RUNS_AS_HOST)
+ else if (sensorSource == QString("sensor").toLower()) {
+ qCDebug(boot2QtDemos) << "Running in sensor mode";
+ dataProviderPool = new SensorTagDataProviderPool;
+ static_cast<SensorTagDataProviderPool*>(dataProviderPool)->setMacFilterList(QStringList() << "A0:E6:F8:B6:44:01");
+ }
+#endif
+ else if (sensorSource == QString("mock").toLower()){
+ qCDebug(boot2QtDemos) << "Running in mock data mode";
+ // Replace this with modified DemoDataProviderPoool,
+ // which combines data from three devices
+ dataProviderPool = new DemoDataProviderPool;
+ static_cast<DemoDataProviderPool*>(dataProviderPool)->setMockDataMode(true);
+ }
+ else {
+ qCDebug(boot2QtDemos) << "Unknown mode: " << sensorSource;
+ return 1;
+
+ }
+
+ qmlRegisterType<SensorTagDataProvider>("SensorTag.DataProvider", 1, 0, "SensorTagData");
+ qmlRegisterType<SensorTagDataProvider>("SensorTag.DataProvider", 1, 0, "ProviderState");
+ qmlRegisterType<DataProviderPool>("SensorTag.DataProvider", 1, 0, "DataProviderPool");
+
+#if defined(RUNS_AS_HOST) && defined(CLOUD_UPLOAD)
+ CloudUpdate update;
+ if (sensorSource == "sensor" || sensorSource == "mock") {
+ update.setDataProviderPool(dataProviderPool);
+ update.restart();
+ }
+#endif
+
+ QString mainFile;
+ QUrl styleFile;
+ QString uiVariant;
+ bool fullScreen;
+ int appWidth = 0;
+ int appHeight = 0;
+
+ QScreen* scr = qApp->screens().at(0);
+
+ QByteArray sf = qgetenv("QT_SCREEN_SCALE_FACTORS");
+ qCDebug(boot2QtDemos) << "screen dimensions" << scr->geometry().size();
+ qCDebug(boot2QtDemos) << "Scale factor:" << sf.data();
+
+#if defined(UI_SMALL)
+ mainFile = QStringLiteral("qrc:/resources/small/MainSmall.qml");
+ styleFile = QUrl("qrc:/resources/small/StyleSmall.qml");
+ uiVariant = "small";
+ fullScreen = true;
+ appWidth = 1920;
+ appHeight = 1080;
+ qCDebug(boot2QtDemos) << "Using SMALL UI variant";
+#elif defined(UI_MEDIUM)
+ mainFile =QStringLiteral("qrc:/resources/medium/MainMedium.qml");
+ styleFile = QUrl("qrc:/resources/medium/StyleMedium.qml");
+ uiVariant = "medium";
+ fullScreen = true;
+ appWidth = 1920;
+ appHeight = 1080;
+ qCDebug(boot2QtDemos) << "Using MEDIUM UI variant";
+#elif defined(UI_LARGE)
+ mainFile = QStringLiteral("qrc:/resources/large/MainLarge.qml");
+ styleFile = QUrl("qrc:/resources/large/StyleLarge.qml");
+ uiVariant = "large";
+ fullScreen = true;
+ appWidth = 3840;
+ appHeight = 2160;
+ qCDebug(boot2QtDemos) << "Using LARGE UI variant";
+#else
+#error "Unknown UI form factor set in the project file"
+#endif
+
+ qmlRegisterSingletonType(styleFile, "Style", 1,0, "Style");
+
+ if (qEnvironmentVariableIsSet("QT_IOS_DEMO_NO_FULLSCREEN")) {
+ qCDebug(boot2QtDemos) << "Application forced not to obey fullscreen setting";
+ fullScreen = false;
+ }
+
+ QQmlApplicationEngine engine;
+ engine.rootContext()->setContextProperty("pathPrefix", "/resources/" + uiVariant + "/images/");
+ engine.load(QUrl(QStringLiteral("qrc:/resources/base/main.qml")));
+
+ QQuickWindow *item = qobject_cast<QQuickWindow *>(engine.rootObjects()[0]);
+ if (item) {
+ item->setWidth(appWidth);
+ item->setHeight(appHeight);
+
+ if (fullScreen)
+ item->showFullScreen();
+
+ item->setProperty("dataProviderPool", QVariant::fromValue(dataProviderPool));
+ item->setProperty("contentFile", mainFile);
+ }
+ int returnValue = app.exec();
+ dataProviderPool->stopScanning();
+ return returnValue;
+}
diff --git a/tradeshow/iot-sensortag/mockdataprovider.cpp b/tradeshow/iot-sensortag/mockdataprovider.cpp
new file mode 100644
index 0000000..8a34790
--- /dev/null
+++ b/tradeshow/iot-sensortag/mockdataprovider.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mockdataprovider.h"
+#include <QtCore/QDateTime>
+
+MockDataProvider::MockDataProvider(QString id, QObject* parent)
+ : SensorTagDataProvider(id, parent),
+ xAxisG(-10),
+ zAxisG(0),
+ luxIncrease(100),
+ m_smaSamples(0)
+{
+ humidity = 40;
+ irTemperature = 25;
+ barometerCelsiusTemperature = 25;
+ barometerHPa = 1040;
+ magnetometerMicroT_xAxis = 333;
+ magnetometerMicroT_yAxis = 666;
+ magnetometerMicroT_zAxis = 999;
+}
+
+bool MockDataProvider::startDataFetching()
+{
+ // Mock data is immediately available
+ m_state = Connected;
+
+ qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
+ oneSecondTimer = new QTimer(this);
+ connect(oneSecondTimer, SIGNAL(timeout()), this, SLOT(oneSecondTimerExpired()));
+ oneSecondTimer->start(1000);
+ twentyMillisecondTimer = new QTimer(this);
+ connect(twentyMillisecondTimer, SIGNAL(timeout()), this, SLOT(twentyMsTimerExpired()));
+ twentyMillisecondTimer->start(200);
+ return true;
+}
+
+void MockDataProvider::endDataFetching()
+{
+ oneSecondTimer->stop();
+}
+
+QString MockDataProvider::sensorType() const
+{
+ return QLatin1String("Mock data");
+}
+
+QString MockDataProvider::versionString() const
+{
+ return QLatin1String("1.0");
+}
+
+void MockDataProvider::setTagType(int tagType)
+{
+ m_tagType = tagType;
+}
+
+void MockDataProvider::oneSecondTimerExpired()
+{
+ // Humidity goes randomly up and down between 20% and 60%
+ humidity += static_cast<double>((qrand() % 11)-5)/10;
+ if (humidity > 60)
+ humidity = 60;
+ if (humidity < 20)
+ humidity = 20;
+ emit relativeHumidityChanged();
+
+ // IR temperature goes randomly up OR down by half of a degree. So does barometer temperature.
+ if (qrand() % 2)
+ irTemperature -= 0.5;
+ else
+ irTemperature += 0.5;
+ if (irTemperature > 38)
+ irTemperature = 38;
+ if (irTemperature < 15)
+ irTemperature = 15;
+ emit infraredCelsiusTemperatureChanged();
+ if (qrand() % 2)
+ barometerCelsiusTemperature -= 0.5;
+ else
+ barometerCelsiusTemperature += 0.5;
+ if (barometerCelsiusTemperature > 38)
+ barometerCelsiusTemperature = 38;
+ if (barometerCelsiusTemperature < 15)
+ barometerCelsiusTemperature = 15;
+ emit barometerCelsiusTemperatureChanged();
+ barometerTemperatureAverage = (barometerCelsiusTemperature + m_smaSamples * barometerTemperatureAverage) / (m_smaSamples + 1);
+ emit barometerCelsiusTemperatureAverageChanged();
+ m_smaSamples++;
+ // Use a limited number of samples. It will eventually give wrong avg values, but this is just a demo...
+ if (m_smaSamples > 10000)
+ m_smaSamples = 0;
+
+ // Light intensity switches between bright and dark (~0 and ~400)
+ lightIntensityLux += luxIncrease;
+ if (lightIntensityLux <= 0)
+ luxIncrease = 100;
+ if (lightIntensityLux >= 400)
+ luxIncrease = -100;
+ emit lightIntensityChanged();
+
+ // Air pressure goes between 1030 and 1050, in 0.05 steps
+ if (qrand() % 2)
+ barometerHPa -= 0.05;
+ else
+ barometerHPa += 0.05;
+ if (barometerHPa > 1050)
+ barometerHPa = 1050;
+ if (barometerHPa < 1030)
+ barometerHPa = 1030;
+ emit barometer_hPaChanged();
+
+}
+
+void MockDataProvider::twentyMsTimerExpired()
+{
+ //Rotate counter-clockwise around Z axis
+ if ((zAxisG > -10) &&
+ (xAxisG <= 0)) {
+ if (zAxisG <= 0) {
+ xAxisG += 2;
+ zAxisG -= 2;
+ } else {
+ xAxisG -= 2;
+ zAxisG -= 2;
+ }
+ } else {
+ if (zAxisG < 0) {
+ xAxisG += 2;
+ zAxisG += 2;
+ } else {
+ xAxisG -= 2;
+ zAxisG += 2;
+ }
+ }
+ accelometer_mG_xAxis = xAxisG * 100;
+ accelometer_mG_zAxis = zAxisG * 100;
+ emit accelometerGChanged();
+ magnetometerMicroT_xAxis += 50;
+ magnetometerMicroT_yAxis += 50;
+ magnetometerMicroT_zAxis += 50;
+ if (magnetometerMicroT_xAxis > 1000)
+ magnetometerMicroT_xAxis -= 1000;
+ if (magnetometerMicroT_yAxis > 1000)
+ magnetometerMicroT_yAxis -= 1000;
+ if (magnetometerMicroT_zAxis > 1000)
+ magnetometerMicroT_zAxis -= 1000;
+ emit magnetometerMicroTChanged();
+
+ rotation_x += 1;
+ if (rotation_x > 360)
+ rotation_x -= 360;
+ rotation_y += 4;
+ if (rotation_y > 360)
+ rotation_y -= 360;
+ rotation_z += 9;
+ if (rotation_z > 360)
+ rotation_z -= 360;
+ emit rotationXChanged();
+ emit rotationYChanged();
+ emit rotationZChanged();
+ // Signal that all values have changed, for easier
+ // value change handling in clients
+ emit rotationValuesChanged();
+
+ gyroscopeX_degPerSec += 1;
+ if (gyroscopeX_degPerSec > 360)
+ gyroscopeX_degPerSec -= 360;
+ gyroscopeY_degPerSec += 4;
+ if (gyroscopeY_degPerSec > 360)
+ gyroscopeY_degPerSec -= 360;
+ gyroscopeZ_degPerSec += 9;
+ if (gyroscopeZ_degPerSec > 360)
+ gyroscopeZ_degPerSec -= 360;
+ emit gyroscopeDegPerSecChanged();
+}
diff --git a/tradeshow/iot-sensortag/mockdataprovider.h b/tradeshow/iot-sensortag/mockdataprovider.h
new file mode 100644
index 0000000..8383cfd
--- /dev/null
+++ b/tradeshow/iot-sensortag/mockdataprovider.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MOCKDATAPROVIDER_H
+#define MOCKDATAPROVIDER_H
+#include "sensortagdataprovider.h"
+#include <QtQml/QQmlEngine>
+#include <QtQml/QJSEngine>
+#include <QtCore/QTimer>
+
+class MockDataProvider : public SensorTagDataProvider
+{
+ Q_OBJECT
+public:
+ explicit MockDataProvider(QString id, QObject* parent = 0);
+
+ bool startDataFetching();
+ void endDataFetching();
+
+ QString sensorType() const;
+ QString versionString() const;
+
+ void setTagType(int tagType);
+
+public slots:
+ void oneSecondTimerExpired();
+ void twentyMsTimerExpired();
+
+private:
+ QTimer *oneSecondTimer;
+ QTimer *twentyMillisecondTimer;
+ int xAxisG;
+ int zAxisG;
+ int luxIncrease;
+ int m_smaSamples;
+};
+
+#endif // MOCKDATAPROVIDER_H
diff --git a/tradeshow/iot-sensortag/resources/base/AirPressureChart.qml b/tradeshow/iot-sensortag/resources/base/AirPressureChart.qml
new file mode 100644
index 0000000..df10674
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/AirPressureChart.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+import SensorTag.DataProvider 1.0
+
+BaseChart {
+ property string airPressureTxt
+
+ antialiasing: true
+ title: qsTr("Air Pressure")
+
+ onSensorChanged: if (sensor) {
+ sensor.barometer_hPaChanged.connect(this, function() { airPressureTxt = sensor.barometerHPa.toFixed(1); });
+ }
+
+ content: Item {
+ id: container
+
+ anchors.fill: parent
+
+ Image {
+ source: pathPrefix + "AirPressure/AirPre_base_gauge.png"
+ anchors.centerIn: parent
+
+ Text {
+ id: pressureText
+
+ text: airPressureTxt + "\nhPa"
+ horizontalAlignment: Text.AlignHCenter
+ anchors.centerIn: parent
+ color: "white"
+ }
+ }
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/BaseChart.qml b/tradeshow/iot-sensortag/resources/base/BaseChart.qml
new file mode 100644
index 0000000..d148acf
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/BaseChart.qml
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+import Style 1.0
+import SensorTag.DataProvider 1.0
+
+Item {
+ id: baseChart
+
+ property var sensor: null
+ property string title
+ property alias contentItem: loader.item
+ property alias content: loader.sourceComponent
+ property bool rightSide: false
+ property alias titlePaneHeight: titleIcon.height
+ property bool hasData: baseChart.sensor ? baseChart.sensor.state === SensorTagData.Connected : false
+
+ signal clicked
+
+ Image {
+ id: titleIcon
+
+ anchors.top: parent.top
+ source: pathPrefix + "General/icon_sensor.png"
+ }
+
+ Text {
+ color: "white"
+ text: title.toUpperCase()
+ font.pixelSize: Style.indicatorTitleFontSize
+ anchors.left: titleIcon.right
+ anchors.leftMargin: 14
+ anchors.top: parent.top
+ anchors.topMargin: -8
+ }
+
+ Loader {
+ id: loader
+
+ anchors.top: titleIcon.bottom
+ anchors.bottom: separator.bottom
+ anchors.bottomMargin: 16
+ anchors.left: parent.left
+ anchors.right: parent.right
+ }
+
+ Image {
+ id: separator
+
+ source: pathPrefix + "General/separator.png"
+ anchors.bottom: parent.bottom
+ transform: Rotation {
+ origin.x: separator.width / 2
+ origin.y: separator.height / 2
+ axis.x: 0
+ axis.y: 1
+ axis.z: 0
+ angle: rightSide ? 180 : 0
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: baseChart.clicked()
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ visible: baseChart.sensor ? baseChart.sensor.state !== SensorTagData.Connected : true
+ opacity: 0.3
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/BottomToolbar.qml b/tradeshow/iot-sensortag/resources/base/BottomToolbar.qml
new file mode 100644
index 0000000..1c6f2f1
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/BottomToolbar.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+
+Item {
+
+}
diff --git a/tradeshow/iot-sensortag/resources/base/ChartPage.qml b/tradeshow/iot-sensortag/resources/base/ChartPage.qml
new file mode 100644
index 0000000..8a58246
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/ChartPage.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+
+Flickable{
+ id: view
+
+ contentWidth: col.width
+ contentHeight: col.height
+
+ Column {
+ id: col
+ width: view.width
+
+ TemperatureChart{}
+ ObjectTemperatureChart{}
+ HumidityChart{}
+ LightChart{}
+ AirPressureChart{}
+ MagnetometerChart{}
+ }
+}
+
diff --git a/tradeshow/iot-sensortag/resources/base/CircularGauge.qml b/tradeshow/iot-sensortag/resources/base/CircularGauge.qml
new file mode 100644
index 0000000..5ee5b53
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/CircularGauge.qml
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+Item {
+ id: gauge
+
+ property real min: 0
+ property real max: 360
+ property real value: 20
+ property real stepCount: 18
+ property bool discreteSteps: true
+
+ property alias background: bgLoader.sourceComponent
+ property alias foreground: fgLoader.sourceComponent
+
+ property real increment: 360 / stepCount
+
+ function incrementStep() {
+ if (value < max - increment)
+ value += increment
+ }
+
+ function decrementStep() {
+ if (value > min + increment)
+ value -= increment;
+ }
+
+ width: bgLoader.item.width
+ height: bgLoader.item.height
+ onValueChanged: maskCanvas.requestPaint()
+
+ Loader {
+ id: bgLoader
+ }
+
+ Loader {
+ id: fgLoader
+
+ visible: false
+ }
+
+ Item {
+ id: mask
+
+ property real range: max - min
+ property real offsetAngle: -77
+ property real startAngle: mask.offsetAngle / 360 * Math.PI * 2
+ property real angleStep: Math.PI * 2 / stepCount
+
+ width: fgLoader.item.width
+ height: fgLoader.item.height
+ visible: false
+
+ Canvas {
+ id: maskCanvas
+
+ anchors.fill: parent
+ onPaint: {
+ var ctx = getContext("2d");
+
+ // could optimize this by clearing only when decrementing value
+ ctx.clearRect(0, 0, width, height);
+
+ var endAngle = mask.startAngle + (value - min) / mask.range * Math.PI * 2;
+ if (discreteSteps)
+ endAngle = Math.floor(endAngle / mask.angleStep) * mask.angleStep;
+ ctx.beginPath();
+ ctx.arc(Math.floor(width / 2), Math.floor(height / 2), mask.width / 2, mask.startAngle, endAngle);
+ ctx.lineTo(mask.width / 2, mask.height / 2)
+ ctx.closePath();
+ ctx.fill();
+ }
+ }
+ }
+
+ OpacityMask {
+ width: mask.width
+ height: mask.height
+ source: fgLoader.item
+ maskSource: mask
+ anchors.centerIn: gauge
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/GyroChart.qml b/tradeshow/iot-sensortag/resources/base/GyroChart.qml
new file mode 100644
index 0000000..681d218
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/GyroChart.qml
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+import QtCharts 2.1
+import SensorTag.DataProvider 1.0
+
+BaseChart {
+ id: gyroHolderRect
+
+ // Replace with actual gyro properties
+ property int gyroSeriesIndex: 0
+ property int maxGyroReadings: 24
+
+ readonly property color chartColor: "#15bdff"
+ readonly property color gridColor: "#005b80"
+ readonly property string xColor: "#15bdff"
+ readonly property string yColor: "white"
+ readonly property string zColor: "fuchsia"
+ readonly property color textColor: "white"
+
+ onSensorChanged: {
+ if (sensor) {
+ sensor.rotationValuesChanged.connect(contentItem.updateRotation);
+ }
+ }
+
+ title: qsTr("Gyroscope")
+ rightSide: true
+
+ content: Item {
+ anchors.fill: parent
+
+ function updateRotation() {
+ gyroSeriesX.append(gyroSeriesIndex, sensor.rotationX);
+ gyroSeriesY.append(gyroSeriesIndex, sensor.rotationY);
+ gyroSeriesZ.append(gyroSeriesIndex, sensor.rotationZ);
+
+ if (gyroSeriesIndex >= maxGyroReadings) {
+ gyroSeriesX.remove(gyroSeriesX.at(gyroSeriesIndex-maxGyroReadings));
+ gyroSeriesY.remove(gyroSeriesY.at(gyroSeriesIndex-maxGyroReadings));
+ gyroSeriesZ.remove(gyroSeriesZ.at(gyroSeriesIndex-maxGyroReadings));
+ valueAxisX.min++;
+ valueAxisX.max++;
+ }
+ gyroSeriesIndex++;
+ }
+
+ ChartView {
+ id: chartView
+
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 8
+ anchors.left: parent.left
+ anchors.leftMargin: -40
+ anchors.right: parent.right
+ anchors.rightMargin: -28
+ antialiasing: true
+ backgroundColor: "transparent"
+ legend.visible: false
+ margins.top: 0
+ margins.right: 0
+
+ // Hide the value axis labels; labels are drawn separately.
+ ValueAxis {
+ id: valueAxisX
+ labelsVisible: false
+ min: 0
+ max: maxGyroReadings + 1
+ tickCount: 13
+ minorTickCount: 1
+ color: chartColor
+ gridLineColor: gridColor
+ minorGridLineColor: gridColor
+ }
+
+ ValueAxis {
+ id: valueAxisY
+ labelsVisible: false
+ min: 0
+ max: 360
+ tickCount: 11
+ minorTickCount: 1
+ color: chartColor
+ gridLineColor: gridColor
+ minorGridLineColor: gridColor
+ }
+
+ Column {
+ id: col
+
+ property int step: (valueAxisY.max - valueAxisY.min) / (valueAxisY.tickCount - 1)
+
+ spacing: -7
+
+ y: chartView.plotArea.y - 10
+ x: 30
+
+ Repeater {
+ model: valueAxisY.tickCount
+
+ Text {
+ text: valueAxisY.max - index * col.step
+ horizontalAlignment: Text.AlignRight
+ width: 50
+ color: textColor
+ }
+ }
+ }
+
+ ScatterSeries {
+ id: gyroSeriesX
+ axisX: valueAxisX
+ axisY: valueAxisY
+ color: xColor
+ borderWidth: 0
+ markerSize: 6
+ name: "Gyro X"
+ }
+ ScatterSeries {
+ id: gyroSeriesY
+ axisX: valueAxisX
+ axisY: valueAxisY
+ color: yColor
+ borderWidth: 0
+ markerSize: 6
+ name: "Gyro Y"
+ }
+ ScatterSeries {
+ id: gyroSeriesZ
+ axisX: valueAxisX
+ axisY: valueAxisY
+ color: zColor
+ borderWidth: 0
+ markerSize: 6
+ name: "Gyro Z"
+ }
+ }
+
+ Row {
+ id: xLabelRow
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 28
+ anchors.left: parent.left
+ anchors.leftMargin: chartView.plotArea.x - 40
+ anchors.right: parent.right
+
+ Text {
+ id: xLabel
+ horizontalAlignment: Text.AlignHCenter
+ text: "<font color=\"" + xColor + "\">Roll<br><font color=\"white\">" + (sensor ? sensor.rotationX : 0)
+ lineHeight: 0.7
+ width: (gyroHolderRect.width - xLabelRow.x) / 3
+ }
+
+ Text {
+ horizontalAlignment: Text.AlignHCenter
+ text: "<font color=\"" + yColor + "\">Pitch<br><font color=\"white\">" + (sensor ? sensor.rotationY : 0)
+ lineHeight: 0.7
+ width: xLabel.width
+ }
+
+ Text {
+ horizontalAlignment: Text.AlignHCenter
+ text: "<font color=\"" + zColor + "\">Yaw<br><font color=\"white\">" + (sensor ? sensor.rotationZ : 0)
+ lineHeight: 0.7
+ width: xLabel.width
+ }
+ }
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/HumidityChart.qml b/tradeshow/iot-sensortag/resources/base/HumidityChart.qml
new file mode 100644
index 0000000..0a74a68
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/HumidityChart.qml
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+import QtQuick.Controls 2.0
+import QtQuick.Controls.Styles 1.4
+import QtCharts 2.1
+import SensorTag.DataProvider 1.0
+import QtQuick.Extras 1.4
+
+BaseChart {
+ property int humiditySeriesIndex: 0
+ property int maxNumOfHumiReadings: 30
+ property real humidityValue: 0
+
+ antialiasing: true
+ title: qsTr("Humidity")
+
+ onSensorChanged: if (sensor) {
+ sensor.relativeHumidityChanged.connect(contentItem.getMaxOchMinHum)
+ }
+
+ content: Item {
+ anchors.fill: parent
+
+ property alias humiText: humidityMainText.text
+ property real maxHumi: 0
+ property real minHumi: 1000
+
+ function getMaxOchMinHum()
+ {
+ humidityValue = sensor.relativeHumidity;
+ contentItem.humiText = humidityValue.toFixed(1) + " %";
+
+ if (humidityValue > contentItem.maxHumi)
+ {
+ contentItem.maxHumi = humidityValue
+ }
+
+ if (humidityValue < contentItem.minHumi)
+ {
+ contentItem.minHumi = humidityValue;
+ }
+ }
+
+ Image {
+ id: humidityMainImg
+
+ source: pathPrefix + "Humidity/humidity_base_gauge.png"
+ anchors.left: parent.left
+ anchors.leftMargin: 8
+ anchors.bottom: parent.bottom
+
+ Text {
+ id: humidityMainText
+
+ anchors.centerIn: parent
+ color: "white"
+ }
+ }
+
+ Image {
+ source: pathPrefix + "Humidity/humidity_min_hum.png"
+ anchors.left: humidityMainImg.right
+ anchors.leftMargin: -11
+ anchors.bottom: humidityMainImg.bottom
+
+ Text {
+ anchors.bottom: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.horizontalCenterOffset: -10
+ text: "min"
+ color: "white"
+ }
+
+ Text{
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.verticalCenterOffset: 10
+ text: minHumi.toFixed(1) + " %"
+ font.pixelSize: 12
+ horizontalAlignment: Text.AlignRight
+ color: "white"
+ }
+ }
+
+ Image {
+ source: pathPrefix + "Humidity/humidity_max_hum.png"
+ anchors.left: humidityMainImg.right
+ anchors.leftMargin: -22
+ anchors.top: humidityMainImg.top
+
+ Text {
+ anchors.top: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.horizontalCenterOffset: -10
+ text: "max"
+ color: "white"
+ }
+
+ Text{
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ text: maxHumi.toFixed(1) + "%"
+ font.pixelSize: 14
+ horizontalAlignment: Text.AlignRight
+ color: "white"
+ }
+ }
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/LightChart.qml b/tradeshow/iot-sensortag/resources/base/LightChart.qml
new file mode 100644
index 0000000..34da38a
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/LightChart.qml
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+import SensorTag.DataProvider 1.0
+
+BaseChart {
+ height: view.height * 0.4
+ width: view.width
+ antialiasing: true
+ title: qsTr("Light Intensity")
+ rightSide: true
+
+ onSensorChanged: if (sensor) {
+ sensor.lightIntensityChanged.connect(contentItem.getLightText)
+ }
+
+ content: Item {
+ id: container
+
+ anchors.fill: parent
+
+ property alias lightText: lightMainText.text
+ property alias lightImg: brightnessImg
+ property real lightValue: 0
+ property real maxLightValue: 1
+ property real normalizedLightValue: 0
+
+ function getLightText()
+ {
+ lightValue = sensor.lightIntensityLux;
+ contentItem.lightText = lightValue.toFixed(1);
+
+ if (lightValue > maxLightValue)
+ {
+ maxLightValue = lightValue;
+ }
+ normalizedLightValue = lightValue / maxLightValue;
+ lightImg.opacity = normalizedLightValue;
+ }
+
+ Image {
+ id: lightMainImg
+
+ source: pathPrefix + "Light/light_base_gauge.png"
+ anchors.top: parent.top
+ anchors.topMargin: 16
+ anchors.left: container.left
+ anchors.leftMargin: 12
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 500
+ }
+ }
+
+ Text {
+ id: lightMainText
+
+ anchors.centerIn: parent
+ color: "white"
+ }
+ }
+
+ Image {
+ id: brightnessImg
+
+ source: pathPrefix + "Light/light_brightness.png"
+ anchors.left: lightMainImg.right
+ anchors.leftMargin: 24
+ anchors.verticalCenter: lightMainImg.verticalCenter
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 500
+ }
+ }
+ }
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/LocationPage.qml b/tradeshow/iot-sensortag/resources/base/LocationPage.qml
new file mode 100644
index 0000000..e479ce2
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/LocationPage.qml
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.6
+import QtPositioning 5.5
+import QtLocation 5.6
+
+Rectangle {
+ id: locationMain
+ property string location: "Home"
+ property string address: "Home address"
+
+ Plugin {
+ id: myPlugin
+ name: "osm"
+ //specify plugin parameters as necessary
+ //PluginParameter {...}
+ //PluginParameter {...}
+ //...
+ }
+
+ GeocodeModel {
+ id: addressProvider
+ plugin: myPlugin
+ autoUpdate: false
+ onLocationsChanged: {
+ if (count)
+ locationMain.address = get(0).address.text;
+ else
+ console.log("no matches");
+ }
+ }
+
+ PositionSource {
+ id: positionProvider
+ updateInterval: 1000
+ active: true
+
+ onPositionChanged: {
+ var coord = positionProvider.position.coordinate;
+ addressProvider.query = coord;
+ addressProvider.update();
+ locationMain.location = "Coordinate: N" + coord.latitude + " E" + coord.longitude;
+ console.log(locationMain.location);
+ }
+ }
+ Column {
+ anchors.left: parent.left
+ anchors.top: parent.top
+ Text {
+ text: locationMain.location
+ }
+ Text {
+ text: locationMain.address
+ }
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/MagnetometerChart.qml b/tradeshow/iot-sensortag/resources/base/MagnetometerChart.qml
new file mode 100644
index 0000000..0f18f87
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/MagnetometerChart.qml
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+import QtCharts 2.1
+import SensorTag.DataProvider 1.0
+
+BaseChart {
+ id: magnetHolderRect
+
+ property int magneticSeriesIndex: 0
+ property int maxNumOfMagnReadings: 24
+
+ readonly property color chartColor: "#15bdff"
+ readonly property string xColor: "green"
+ readonly property string yColor: "purple"
+ readonly property string zColor: "yellow"
+ readonly property color textColor: "white"
+
+ onSensorChanged: if (sensor) sensor.magnetometerMicroTChanged.connect(contentItem.updateMagneticGraph)
+
+ title: qsTr("Magnetometer")
+ rightSide: true
+
+ content: Item {
+ anchors.fill: parent
+
+ function updateMagneticGraph()
+ {
+ magnSeriesX.append(magneticSeriesIndex, sensor.magnetometerMicroT_xAxis);
+ magnSeriesY.append(magneticSeriesIndex, sensor.magnetometerMicroT_yAxis);
+ magnSeriesZ.append(magneticSeriesIndex, sensor.magnetometerMicroT_zAxis);
+
+ if (magneticSeriesIndex >= maxNumOfMagnReadings) {
+ magnSeriesX.remove(magnSeriesX.at(magneticSeriesIndex-maxNumOfMagnReadings));
+ magnSeriesY.remove(magnSeriesY.at(magneticSeriesIndex-maxNumOfMagnReadings));
+ magnSeriesZ.remove(magnSeriesY.at(magneticSeriesIndex-maxNumOfMagnReadings));
+ valueAxisX.min++;
+ valueAxisX.max++;
+ }
+ magneticSeriesIndex++;
+ }
+
+ Text {
+ id: historyLabel
+ text: "MAGNETIC FIELD HISTORY"
+ color: textColor
+ anchors.top: parent.top
+ anchors.topMargin: 16
+ anchors.left: parent.left
+ anchors.leftMargin: chartView.plotArea.x - 40
+ }
+
+ ChartView {
+ id: chartView
+
+ anchors.top: historyLabel.bottom
+ anchors.topMargin: -26
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 8
+ anchors.left: parent.left
+ anchors.leftMargin: -40
+ anchors.right: parent.right
+ anchors.rightMargin: -28
+ antialiasing: true
+ backgroundColor: "transparent"
+ legend.visible: false
+ margins.top: 0
+ margins.right: 0
+
+ // Hide the value axis labels; labels are drawn separately.
+ ValueAxis {
+ id: valueAxisX
+ labelsVisible: false
+ gridVisible: false
+ min: 0
+ max: maxNumOfMagnReadings + 1
+ tickCount: 2
+ color: chartColor
+ }
+
+ ValueAxis {
+ id: valueAxisY
+
+ min: 0
+ max: 1000
+ color: chartColor
+ gridLineColor: "darkgray"
+ labelsVisible: false
+ tickCount: 11
+ }
+
+ Column {
+ id: col
+
+ property int step: (valueAxisY.max - valueAxisY.min) / (valueAxisY.tickCount - 1)
+
+ spacing: -9
+ y: chartView.plotArea.y - 10
+ x: 30
+
+ Repeater {
+ model: valueAxisY.tickCount
+
+ Text {
+ text: valueAxisY.max - index * col.step
+ horizontalAlignment: Text.AlignRight
+ width: 50
+ color: textColor
+ }
+ }
+ }
+
+ SplineSeries {
+ id: magnSeriesX
+ axisX: valueAxisX
+ axisY: valueAxisY
+ width: 1
+ color: xColor
+ name: "Magnet X"
+ }
+ SplineSeries {
+ id: magnSeriesY
+ axisX: valueAxisX
+ axisY: valueAxisY
+ width: 1
+ color: yColor
+ name: "Magnet Y"
+ }
+ SplineSeries {
+ id: magnSeriesZ
+ axisX: valueAxisX
+ axisY: valueAxisY
+ width: 1
+ color: zColor
+ name: "Magnet Z"
+ }
+ }
+
+ Text {
+ text: "µT"
+ anchors.top: xLabelRow.top
+ anchors.right: xLabelRow.left
+ anchors.rightMargin: 8
+ color: textColor
+ width: 20
+ font.pixelSize: 14
+ }
+
+ Row {
+ id: xLabelRow
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 28
+ anchors.left: historyLabel.left
+ anchors.right: parent.right
+
+ Text {
+ id: xLabel
+ horizontalAlignment: Text.AlignHCenter
+ text: "<font color=\"" + xColor + "\">X<br><font color=\"white\">" + (sensor ? sensor.magnetometerMicroT_xAxis : 0)
+ lineHeight: 0.7
+ width: (magnetHolderRect.width - xLabelRow.x) / 3
+ }
+
+ Text {
+ horizontalAlignment: Text.AlignHCenter
+ text: "<font color=\"" + yColor + "\">Y<br><font color=\"white\">" + (sensor ? sensor.magnetometerMicroT_yAxis : 0)
+ lineHeight: 0.7
+ width: xLabel.width
+ }
+
+ Text {
+ horizontalAlignment: Text.AlignHCenter
+ text: "<font color=\"" + zColor + "\">Z<br><font color=\"white\">" + (sensor ? sensor.magnetometerMicroT_zAxis : 0)
+ lineHeight: 0.7
+ width: xLabel.width
+ }
+ }
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/ObjectTemperatureChart.qml b/tradeshow/iot-sensortag/resources/base/ObjectTemperatureChart.qml
new file mode 100644
index 0000000..e0e612e
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/ObjectTemperatureChart.qml
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+import SensorTag.DataProvider 1.0
+
+BaseChart {
+ id: objTempHolderRect
+
+ property real minValue: Number.MAX_VALUE
+ property real maxValue: Number.MIN_VALUE
+ property real value
+
+ function updateTemps(){
+ value = sensor.infraredCelsiusTemperature.toFixed(1);
+ if (minValue > value)
+ minValue = value;
+ if (maxValue < value)
+ maxValue = value;
+ }
+
+ title: qsTr("Object Temperature")
+
+ onSensorChanged: if (sensor) {
+ sensor.infraredCelsiusTemperatureChanged.connect(updateTemps)
+ }
+
+ content: Item {
+ id: container
+
+ anchors.fill: parent
+
+ CircularGauge {
+ id: gauge
+
+ min: 10
+ max: 40
+ value: objTempHolderRect.value
+ anchors.centerIn: parent
+ background: Image {
+ source: pathPrefix + "ObjectTemperature/objTemp_base_circle.png"
+ }
+ foreground: Image {
+ source: pathPrefix + "ObjectTemperature/objTemp_display_obj.png"
+ }
+ }
+
+ Text {
+ text: (minValue !== Number.MAX_VALUE ? minValue : "--") + "\nLowest"
+ lineHeight: 0.7
+ width: 60
+ horizontalAlignment: Text.Center
+ color: "white"
+ anchors.bottom: gauge.bottom
+ anchors.bottomMargin: 24
+ anchors.right: gauge.left
+ anchors.rightMargin: 12
+ }
+
+ Text {
+ text: value
+ color: "white"
+ anchors.centerIn: gauge
+ }
+
+ Text {
+ text: "Highest\n" + (maxValue !== Number.MIN_VALUE ? maxValue : "--")
+ lineHeight: 0.8
+ width: 60
+ horizontalAlignment: Text.Center
+ color: "white"
+ anchors.top: gauge.top
+ anchors.topMargin: 24
+ anchors.left: gauge.right
+ anchors.leftMargin: 12
+ }
+
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/SensorTag.qml b/tradeshow/iot-sensortag/resources/base/SensorTag.qml
new file mode 100644
index 0000000..a8d38d5
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/SensorTag.qml
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.7
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+import Qt3D.Input 2.0
+import Qt3D.Extras 2.0
+import SensorTag.DataProvider 1.0
+
+Entity {
+ id: sceneRoot
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: 16/9
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d( 1.0, 1.0, 1.0 )
+ upVector: Qt.vector3d( 1.0, -1.0, 1.0 )
+ viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
+ }
+
+ OrbitCameraController {
+ camera: camera
+ }
+
+ components: [
+ RenderSettings {
+ activeFrameGraph: ForwardRenderer {
+ clearColor: Qt.rgba(0, 0, 0, 1)
+ camera: camera
+ }
+ },
+ InputSettings { }
+ ]
+
+ Mesh {
+ id: innerTorusMesh
+ source: "3dModel/innerRing.obj"
+ }
+
+// PhongMaterial {
+// id: temperatureLightMaterial
+// ambient: sensor ? sensor.lightIntensityColor : Qt.rgba(0, 0, 0)
+// diffuse: sensor ? sensor.temperatureColor : Qt.rgba(0, 0, 0)
+// }
+
+// TorusMesh {
+// id: innerTorusMesh
+// radius: 5
+// minorRadius: 1
+// rings: 40
+// slices: 10
+// }
+
+ Transform {
+ id: innerTorusTransform
+ rotationX: sensor ? sensor.gyroscopeX_degPerSec : 0
+ scale3D: Qt.vector3d(1, 1, 1)
+// Behavior on rotationX {
+// NumberAnimation {
+// easing.type: Easing.Linear
+// duration: 1000
+// }
+// }
+ }
+
+ SimpleMaterial {
+ id: temperatureLightMaterial
+
+ diffuse: "texture/gyroscopeSmall.jpg"
+ }
+
+// DiffuseMapMaterial {
+// id: temperatureLightMaterial
+
+// diffuse: "qrc:/resources/base/texture/gyroscope.png"
+// ambient: Qt.rgba(1, 1, 1)
+// //diffuse: Qt.rgba(1, 1, 1)
+// }
+
+// Entity {
+// id: innerTorusEntity
+
+// components: [ innerTorusMesh, temperatureLightMaterial, innerTorusTransform ]
+// }
+
+
+ Mesh {
+ id: middleTorusMesh
+ source: "3dModel/centerRing.obj"
+ }
+
+// TorusMesh {
+// id: middleTorusMesh
+// radius: 8
+// minorRadius: 1
+// rings: 40
+// slices: 10
+// }
+
+ Transform {
+ id: middleTorusTransform
+ rotationY: sensor ? sensor.gyroscopeY_degPerSec : 0
+ scale3D: Qt.vector3d(1, 1, 1)
+// Behavior on rotationY {
+// NumberAnimation {
+// easing.type: Easing.Linear
+// duration: 1000
+// }
+// }
+ }
+
+// Entity {
+// id: middleTorusEntity
+
+// components: [ middleTorusMesh,temperatureLightMaterial, middleTorusTransform ]
+// }
+
+ Mesh {
+ id: outerTorusMesh
+ source: "3dModel/outerRing.obj"
+ }
+
+// TorusMesh {
+// id: outerTorusMesh
+// radius: 11
+// minorRadius: 1
+// rings: 40
+// slices: 10
+// }
+
+ Transform {
+ id: outerTorusTransform
+ /* First rotate on X axis, 90-degree rotation over Y will end up with the result we wish to have. */
+ rotationX: sensor ? sensor.gyroscopeZ_degPerSec : 0
+ rotationY: 90
+ scale3D: Qt.vector3d(1, 1, 1)
+// Behavior on rotationX {
+// NumberAnimation {
+// easing.type: Easing.Linear
+// duration: 1000
+// }
+// }
+ }
+
+ Entity {
+ id: outerTorusEntity
+
+ components: [ outerTorusMesh, temperatureLightMaterial, outerTorusTransform ]
+
+ Entity {
+ id: middleTorusEntity
+
+ components: [ middleTorusMesh,temperatureLightMaterial, middleTorusTransform ]
+
+ Entity {
+ id: innerTorusEntity
+
+ components: [ innerTorusMesh, temperatureLightMaterial, innerTorusTransform ]
+ }
+ }
+ }
+
+// TorusMesh {
+// id: scaleDiskMesh
+// radius: 16
+// minorRadius: 2
+// rings: 40
+// slices: 6
+// }
+
+ Mesh {
+ id: scaleDiskMesh
+
+ source: "3dModel/center.obj"
+ }
+
+ Transform {
+ id: scaleDiskTrasform
+ /* First rotate on X axis, 90-degree rotation over Y will end up with the result we wish to have. */
+ rotationY: 70
+ //scale3D: Qt.vector3d(1, 1, 0.1)
+ }
+
+// PhongMaterial {
+// id: scaleDiskMaterial
+// ambient: Qt.rgba(0.2, 0.2, 0.2, 1)
+// diffuse: Qt.rgba(1, 1, 1, 1)
+// shininess: 0.2
+// }
+
+// SimpleMaterial {
+// id: temperatureLightMaterial
+
+// diffuse: "texture/gyroscope.png"
+// }
+
+ Entity {
+ id: scaleDiskEntity
+ components: [ scaleDiskMesh, temperatureLightMaterial, scaleDiskTrasform ]
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/TemperatureChart.qml b/tradeshow/iot-sensortag/resources/base/TemperatureChart.qml
new file mode 100644
index 0000000..0e0b94c
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/TemperatureChart.qml
@@ -0,0 +1,278 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.7
+import QtCharts 2.1
+import SensorTag.DataProvider 1.0
+
+BaseChart {
+ id: tempHolderRect
+
+ property int temperatureSeriesIndex: 0
+ property int maxNumOfTempReadings: 240
+ property real minimum: 10
+ property real maximum: 40
+
+ property real minValue: Number.MAX_VALUE
+ property real maxValue: Number.MIN_VALUE
+ readonly property real avgValue: (maxValue - minValue) / 2
+ property real value
+
+ readonly property color legendColor: "white"
+ readonly property color chartColor: "#15bdff"
+
+ onSensorChanged: if (sensor) {
+ sensor.barometerCelsiusTemperatureChanged.connect(contentItem.updateTemperatureGraph)
+ }
+
+ title: qsTr("Temperature")
+
+ content: Item {
+ anchors.fill: parent
+
+ function updateTemperatureGraph() {
+ avgTempSeries.append(temperatureSeriesIndex, sensor.barometerCelsiusTemperature);
+
+ if (temperatureSeriesIndex >= maxNumOfTempReadings) {
+ avgTempSeries.remove(avgTempSeries.at(temperatureSeriesIndex-maxNumOfTempReadings));
+ valueAxisX.min++;
+ valueAxisX.max++;
+ }
+ temperatureSeriesIndex++;
+
+ var value = sensor.barometerCelsiusTemperature;
+ if (minValue > value)
+ minValue = value;
+ if (maxValue < value)
+ maxValue = value;
+ }
+
+ Item {
+ id: valueReading
+
+ anchors.right: parent.right
+ anchors.top: chartView.top
+ anchors.topMargin: chartView.plotArea.y - 16
+ width: childrenRect.width
+ height: childrenRect.height
+
+ Text {
+ id: highValue
+
+ text: "Highest\n" + (maxValue !== Number.MIN_VALUE ? maxValue : "--")
+ lineHeight: 0.7
+ width: 60
+ horizontalAlignment: Text.Center
+ anchors.horizontalCenter: reading.horizontalCenter
+ color: "white"
+ }
+
+ Image {
+ id: reading
+
+ source: pathPrefix + "AmbientTemperature/ambTemp_display_amb.png"
+ anchors.top: highValue.bottom
+ anchors.topMargin: 10
+
+ Text {
+ anchors.centerIn: parent
+ text: sensor.barometerCelsiusTemperature
+ color: "white"
+ }
+ }
+
+ Text {
+ text: (minValue !== Number.MAX_VALUE ? minValue : "--") + "\nLowest"
+ lineHeight: 0.8
+ width: 60
+ horizontalAlignment: Text.Center
+ color: "white"
+ anchors.top: reading.bottom
+ anchors.topMargin: 6
+ anchors.horizontalCenter: reading.horizontalCenter
+ }
+
+ Text {
+ text: "Avg\n" + sensor.barometerTemperatureAverage.toFixed(1)
+ lineHeight: 0.8
+ width: 60
+ horizontalAlignment: Text.Center
+ color: "white"
+ anchors.left: reading.right
+ anchors.verticalCenter: reading.verticalCenter
+ }
+ }
+
+ ChartView {
+ id: chartView
+
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: xLegend.height + 8
+ anchors.left: parent.left
+ anchors.leftMargin: -25
+ anchors.right: valueReading.left
+ anchors.rightMargin: -20
+ antialiasing: true
+ backgroundColor: "transparent"
+ legend.visible: false
+ margins.top: 0
+ margins.bottom: 0
+ margins.left: 0
+
+ // Hide the value axis labels; labels are drawn separately.
+ ValueAxis {
+ id: valueAxisX
+
+ labelsVisible: false
+ min: 0
+ max: maxNumOfTempReadings + 1
+ tickCount: 6
+ labelsColor: legendColor
+ color: chartColor
+ gridLineColor: chartColor
+ }
+
+ ValueAxis {
+ id: valueAxisY
+
+ labelsVisible: false
+ min: minimum
+ max: maximum
+ tickCount: 7
+ color: chartColor
+ gridLineColor: chartColor
+ }
+
+ LineSeries {
+ id: avgTempSeries
+
+ axisX: valueAxisX
+ axisY: valueAxisY
+ color: chartColor
+ width: 1
+ useOpenGL: true
+ }
+
+ Column {
+ id: col
+ property int step: (valueAxisY.max - valueAxisY.min) / (valueAxisY.tickCount - 1)
+ spacing: (valueAxisY.tickCount - 0.7) / 2
+ y: chartView.plotArea.y - 10
+ x: 24
+ z: 5
+
+ Repeater {
+ model: valueAxisY.tickCount
+
+ Text {
+ text: valueAxisY.max - index * col.step
+ horizontalAlignment: Text.AlignRight
+ width: 20
+ color: legendColor
+ font: fontMetrics.font
+ }
+ }
+ }
+
+ Row {
+ id: xLegend
+
+ x: chartView.plotArea.x
+ y: chartView.plotArea.y + chartView.plotArea.height + height + 6
+ spacing: (chartView.plotArea.width) / (valueAxisX.tickCount - 0.7) + 1
+
+ Repeater {
+ model: valueAxisX.tickCount
+
+ // Enclosing Text inside Item allows layouting Text correctly on the axis
+ Item {
+ width: 1
+ height: 1
+
+ Text {
+ id: legendText
+
+ text: index
+ color: legendColor
+ anchors.horizontalCenter: parent.horizontalCenter
+ font: fontMetrics.font
+ }
+ }
+ }
+ }
+
+ Text {
+ text: "°C"
+ anchors.top: parent.top
+ anchors.topMargin: chartView.plotArea.y - height - 4
+ anchors.right: col.right
+ color: legendColor
+ font: fontMetrics.font
+ }
+
+ Text {
+ text: "h"
+ anchors.top: xLegend.top
+ x: chartView.plotArea.x + chartView.plotArea.width + 16
+ color: legendColor
+ font: fontMetrics.font
+ }
+ }
+ }
+
+ // Create TextMetrics to allow easy use of the same font in the ChartView
+ TextMetrics {
+ id: fontMetrics
+
+ font.family: "Titillium Web"
+ font.pixelSize: 14
+ text: "m"
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/TopToolbar.qml b/tradeshow/iot-sensortag/resources/base/TopToolbar.qml
new file mode 100644
index 0000000..f3e7e2b
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/TopToolbar.qml
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+import SensorTag.DataProvider 1.0
+import Style 1.0
+
+Item {
+ id: topToolbar
+
+ height: 100
+ width: implicitWidth
+
+ Rectangle {
+ id: sensorList
+
+ property alias listModelCount: list.count
+
+ width: 200
+ height: 200
+ x: sensorItem.x
+ y: parent.height
+ color: "darkgray"
+ visible: false
+
+ ListView {
+ id: list
+ anchors.fill: parent
+ model: dataProviderPool.dataProviders
+ delegate: Text {
+ text: providerId
+ color: modelData.state === SensorTagData.Connected ? "blue" : "lightsteelblue"
+ }
+ }
+ }
+
+ Item {
+ id: cloudItem
+ height: topToolbar.height
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.leftMargin: 8
+ width: icon.width + cloudText.width + 3 * anchors.leftMargin
+ opacity: dataProviderPool.name === "Cloud" || dataProviderPool.name === "Demo" ? 1.0 : 0.0
+
+ Image {
+ id: icon
+ width: 58
+ height: 40
+ anchors.top: parent.top
+ anchors.margins: 8
+ source: pathPrefix + "Toolbar/icon_topbar_cloud.png"
+ }
+
+ Text {
+ id: cloudText
+ color: "white"
+ text: "CLOUD"
+ width: contentWidth
+ font.pixelSize: Style.topToolbarSmallFontSize
+ anchors.verticalCenter: icon.verticalCenter
+ anchors.left: icon.right
+ anchors.margins: 8
+ }
+ }
+
+ Item {
+ id: sensorItem
+ height: topToolbar.height
+ anchors.top: parent.top
+ anchors.left: cloudItem.right
+ Image {
+ id: sensorIcon
+
+ width: 40
+ height: 40
+ anchors.top: parent.top
+ anchors.margins: 8
+ source: pathPrefix + "Toolbar/icon_topbar_sensor.png"
+
+ Text {
+ anchors.centerIn: parent
+ text: sensorList.listModelCount
+ color: "white"
+ font.pixelSize: Style.topToolbarSmallFontSize
+ }
+ }
+
+ Text {
+ id: sensorButton
+
+ color: "white"
+ text: "SENSORS"
+ font.pixelSize: Style.topToolbarSmallFontSize
+ anchors.verticalCenter: sensorIcon.verticalCenter
+ anchors.left: sensorIcon.right
+ anchors.margins: 8
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: sensorList.visible = !sensorList.visible
+ }
+ }
+ }
+
+ Text {
+ text: Qt.formatDateTime(new Date, "dddd, MMMM d, yyyy")
+ color: "white"
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 16
+ anchors.right: timeLabel.left
+ anchors.rightMargin: 16
+ horizontalAlignment: Text.AlignRight
+ font.pixelSize: Style.topToolbarSmallFontSize
+ font.capitalization: Font.AllUppercase
+ }
+
+ Text {
+ id: timeLabel
+ text: Qt.formatTime(new Date, "HH:mm")
+ color: "white"
+ font.pixelSize: Style.topToolbarLargeFontSize
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ }
+
+ Text {
+ text: "UTC/GMT"
+ color: "white"
+ anchors.left: timeLabel.right
+ anchors.leftMargin: 16
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 16
+ font.pixelSize: Style.topToolbarSmallFontSize
+ Component.onCompleted: {
+ var date = new Date
+ var offsetString = -date.getTimezoneOffset() / 60
+ if (offsetString < 0)
+ text = text + "-"
+ else
+ text = text + "+"
+ text = text + offsetString
+ }
+ }
+
+ Image {
+ anchors.bottom: parent.bottom
+ source: pathPrefix + "Toolbar/topbar_all.png"
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Bold.ttf b/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Bold.ttf
new file mode 100755
index 0000000..0af0fe7
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Bold.ttf
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Regular.ttf b/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Regular.ttf
new file mode 100755
index 0000000..6da8219
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-Regular.ttf
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-SemiBold.ttf b/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-SemiBold.ttf
new file mode 100755
index 0000000..dfdcdbe
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/fonts/titilliumweb/TitilliumWeb-SemiBold.ttf
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/base/main.qml b/tradeshow/iot-sensortag/resources/base/main.qml
new file mode 100644
index 0000000..8f092ba
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/base/main.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.6
+import QtQuick.Window 2.0
+import SensorTag.DataProvider 1.0
+
+Window {
+ id: mainWindow
+
+ property alias contentFile: contentLoader.source
+ property DataProviderPool dataProviderPool
+
+ // Size defaults to the small display
+ width: 1920
+ height: 1080
+ visible: true
+ color: "black"
+
+ Loader {
+ id: contentLoader
+
+ anchors.fill: parent
+ anchors.centerIn: parent
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/large/MainLarge.qml b/tradeshow/iot-sensortag/resources/large/MainLarge.qml
new file mode 100644
index 0000000..d855c0e
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/MainLarge.qml
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.6
+import SensorTag.DataProvider 1.0
+import "../base"
+
+Item {
+ id: main
+
+ width: 1920
+ height: 1080
+
+ Component.onCompleted: {
+ dataProviderPool.startScanning()
+ }
+
+ Connections {
+ target: dataProviderPool
+ onScanFinished: {
+ ambientTemp.sensor = dataProviderPool.getProvider(SensorTagData.AmbientTemperature);
+ objectTemp.sensor = dataProviderPool.getProvider(SensorTagData.ObjectTemperature);
+ humidity.sensor = dataProviderPool.getProvider(SensorTagData.Humidity);
+ //airPressure.sensor = dataProviderPool.getProvider(SensorTagData.AirPressure);
+ light.sensor = dataProviderPool.getProvider(SensorTagData.Light);
+ magnetometer.sensor = dataProviderPool.getProvider(SensorTagData.Magnetometer);
+ rotation.sensor = dataProviderPool.getProvider(SensorTagData.Rotation);
+ }
+ }
+
+ Column {
+ id: leftPane
+
+ property int indicatorHeight: height / 4 - spacing
+
+ anchors.left: parent.left
+ anchors.leftMargin: 8
+ anchors.top: main.top
+ anchors.bottom: main.bottom
+ width: 360
+ spacing: 16
+
+ TemperatureChart {
+ id: ambientTemp
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+ ObjectTemperatureChart {
+ id: objectTemp
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+ HumidityChart {
+ id: humidity
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+// AirPressureChart {
+// id: airPressure
+
+// width: leftPane.width
+// height: leftPane.indicatorHeight
+// }
+ }
+
+ Column {
+ id: rightPane
+
+ anchors.right: parent.right
+ anchors.rightMargin: 8
+ anchors.top: main.top
+ anchors.bottom: main.bottom
+ width: 360
+ spacing: 16
+
+ LightChart {
+ id: light
+
+ width: rightPane.width
+ height: leftPane.height / 4
+ }
+
+ MagnetometerChart {
+ id: magnetometer
+
+ width: rightPane.width
+ height: leftPane.height / 4
+ }
+
+ GyroPage {
+ id: rotation
+
+ width: rightPane.width
+ height: leftPane.height / 4
+ onClicked: mainContainer.source = "../base/GyroPage.qml"
+ }
+ }
+
+ Loader {
+ id: mainContainer
+
+ anchors.top: topToolbar.bottom
+ anchors.left: leftPane.right
+ anchors.leftMargin: 32
+ anchors.right: rightPane.left
+ anchors.rightMargin: 32
+ anchors.bottom: bottomToolbar.top
+ }
+
+ TopToolbar {
+ id: topToolbar
+
+ anchors.left: leftPane.right
+ anchors.right: rightPane.left
+ }
+
+ BottomToolbar {
+ id: bottomToolbar
+
+ anchors.left: leftPane.right
+ anchors.right: rightPane.left
+ anchors.bottom: main.bottom
+ height: 30
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/large/StyleLarge.qml b/tradeshow/iot-sensortag/resources/large/StyleLarge.qml
new file mode 100644
index 0000000..e4d439d
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/StyleLarge.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+pragma Singleton
+import QtQuick 2.0
+
+QtObject {
+ property int indicatorTitleFontSize: 22
+ property int indicatorTitleSize: 41
+
+ property int topToolbarSmallFontSize: 20
+ property int topToolbarLargeFontSize: 62
+}
diff --git a/tradeshow/iot-sensortag/resources/large/images/AirPressure/AirPre_base_gauge.png b/tradeshow/iot-sensortag/resources/large/images/AirPressure/AirPre_base_gauge.png
new file mode 100644
index 0000000..30a24b8
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/AirPressure/AirPre_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/AmbientTemperature/ambTemp_display_amb.png b/tradeshow/iot-sensortag/resources/large/images/AmbientTemperature/ambTemp_display_amb.png
new file mode 100644
index 0000000..5a4bcf0
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/AmbientTemperature/ambTemp_display_amb.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/General/icon_sensor.png b/tradeshow/iot-sensortag/resources/large/images/General/icon_sensor.png
new file mode 100644
index 0000000..8157ef7
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/General/icon_sensor.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/General/separator.png b/tradeshow/iot-sensortag/resources/large/images/General/separator.png
new file mode 100644
index 0000000..4dae4f8
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/General/separator.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_base_gauge.png b/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_base_gauge.png
new file mode 100644
index 0000000..0d0331c
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_max_hum.png b/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_max_hum.png
new file mode 100644
index 0000000..381c4dd
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_max_hum.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_min_hum.png b/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_min_hum.png
new file mode 100644
index 0000000..c3f9442
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/Humidity/humidity_min_hum.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/Light/light_base_gauge.png b/tradeshow/iot-sensortag/resources/large/images/Light/light_base_gauge.png
new file mode 100644
index 0000000..6a68729
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/Light/light_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/Light/light_brightness.png b/tradeshow/iot-sensortag/resources/large/images/Light/light_brightness.png
new file mode 100644
index 0000000..45b1e2b
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/Light/light_brightness.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_base_circle.png b/tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_base_circle.png
new file mode 100644
index 0000000..a506d2a
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_base_circle.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_display_obj.png b/tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_display_obj.png
new file mode 100644
index 0000000..bc320ac
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/large/images/ObjectTemperature/objTemp_display_obj.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/MainMedium.qml b/tradeshow/iot-sensortag/resources/medium/MainMedium.qml
new file mode 100644
index 0000000..d855c0e
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/MainMedium.qml
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.6
+import SensorTag.DataProvider 1.0
+import "../base"
+
+Item {
+ id: main
+
+ width: 1920
+ height: 1080
+
+ Component.onCompleted: {
+ dataProviderPool.startScanning()
+ }
+
+ Connections {
+ target: dataProviderPool
+ onScanFinished: {
+ ambientTemp.sensor = dataProviderPool.getProvider(SensorTagData.AmbientTemperature);
+ objectTemp.sensor = dataProviderPool.getProvider(SensorTagData.ObjectTemperature);
+ humidity.sensor = dataProviderPool.getProvider(SensorTagData.Humidity);
+ //airPressure.sensor = dataProviderPool.getProvider(SensorTagData.AirPressure);
+ light.sensor = dataProviderPool.getProvider(SensorTagData.Light);
+ magnetometer.sensor = dataProviderPool.getProvider(SensorTagData.Magnetometer);
+ rotation.sensor = dataProviderPool.getProvider(SensorTagData.Rotation);
+ }
+ }
+
+ Column {
+ id: leftPane
+
+ property int indicatorHeight: height / 4 - spacing
+
+ anchors.left: parent.left
+ anchors.leftMargin: 8
+ anchors.top: main.top
+ anchors.bottom: main.bottom
+ width: 360
+ spacing: 16
+
+ TemperatureChart {
+ id: ambientTemp
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+ ObjectTemperatureChart {
+ id: objectTemp
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+ HumidityChart {
+ id: humidity
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+// AirPressureChart {
+// id: airPressure
+
+// width: leftPane.width
+// height: leftPane.indicatorHeight
+// }
+ }
+
+ Column {
+ id: rightPane
+
+ anchors.right: parent.right
+ anchors.rightMargin: 8
+ anchors.top: main.top
+ anchors.bottom: main.bottom
+ width: 360
+ spacing: 16
+
+ LightChart {
+ id: light
+
+ width: rightPane.width
+ height: leftPane.height / 4
+ }
+
+ MagnetometerChart {
+ id: magnetometer
+
+ width: rightPane.width
+ height: leftPane.height / 4
+ }
+
+ GyroPage {
+ id: rotation
+
+ width: rightPane.width
+ height: leftPane.height / 4
+ onClicked: mainContainer.source = "../base/GyroPage.qml"
+ }
+ }
+
+ Loader {
+ id: mainContainer
+
+ anchors.top: topToolbar.bottom
+ anchors.left: leftPane.right
+ anchors.leftMargin: 32
+ anchors.right: rightPane.left
+ anchors.rightMargin: 32
+ anchors.bottom: bottomToolbar.top
+ }
+
+ TopToolbar {
+ id: topToolbar
+
+ anchors.left: leftPane.right
+ anchors.right: rightPane.left
+ }
+
+ BottomToolbar {
+ id: bottomToolbar
+
+ anchors.left: leftPane.right
+ anchors.right: rightPane.left
+ anchors.bottom: main.bottom
+ height: 30
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/medium/StyleMedium.qml b/tradeshow/iot-sensortag/resources/medium/StyleMedium.qml
new file mode 100644
index 0000000..e4d439d
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/StyleMedium.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+pragma Singleton
+import QtQuick 2.0
+
+QtObject {
+ property int indicatorTitleFontSize: 22
+ property int indicatorTitleSize: 41
+
+ property int topToolbarSmallFontSize: 20
+ property int topToolbarLargeFontSize: 62
+}
diff --git a/tradeshow/iot-sensortag/resources/medium/images/AirPressure/AirPre_base_gauge.png b/tradeshow/iot-sensortag/resources/medium/images/AirPressure/AirPre_base_gauge.png
new file mode 100644
index 0000000..2f1d658
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/AirPressure/AirPre_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/AmbientTemperature/ambTemp_display_amb.png b/tradeshow/iot-sensortag/resources/medium/images/AmbientTemperature/ambTemp_display_amb.png
new file mode 100644
index 0000000..cad440a
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/AmbientTemperature/ambTemp_display_amb.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/General/icon_sensor.png b/tradeshow/iot-sensortag/resources/medium/images/General/icon_sensor.png
new file mode 100644
index 0000000..49cc090
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/General/icon_sensor.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/General/separator.png b/tradeshow/iot-sensortag/resources/medium/images/General/separator.png
new file mode 100644
index 0000000..dbd25a4
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/General/separator.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_base_gauge.png b/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_base_gauge.png
new file mode 100644
index 0000000..494a0e6
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_max_hum.png b/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_max_hum.png
new file mode 100644
index 0000000..c4a7d7b
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_max_hum.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_min_hum.png b/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_min_hum.png
new file mode 100644
index 0000000..75b83d1
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/Humidity/humidity_min_hum.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/Light/light_base_gauge.png b/tradeshow/iot-sensortag/resources/medium/images/Light/light_base_gauge.png
new file mode 100644
index 0000000..9c66fbb
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/Light/light_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/Light/light_brightness.png b/tradeshow/iot-sensortag/resources/medium/images/Light/light_brightness.png
new file mode 100644
index 0000000..fc8e82a
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/Light/light_brightness.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_base_circle.png b/tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_base_circle.png
new file mode 100644
index 0000000..86c966f
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_base_circle.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_display_obj.png b/tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_display_obj.png
new file mode 100644
index 0000000..77d53f3
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/medium/images/ObjectTemperature/objTemp_display_obj.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/MainSmall.qml b/tradeshow/iot-sensortag/resources/small/MainSmall.qml
new file mode 100644
index 0000000..4044b32
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/MainSmall.qml
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.6
+import SensorTag.DataProvider 1.0
+import "../base"
+
+Item {
+ id: main
+
+ anchors.fill: parent
+
+ Component.onCompleted: {
+ dataProviderPool.startScanning()
+ }
+
+ Connections {
+ target: dataProviderPool
+ onScanFinished: {
+ ambientTemp.sensor = dataProviderPool.getProvider(SensorTagData.AmbientTemperature);
+ objectTemp.sensor = dataProviderPool.getProvider(SensorTagData.ObjectTemperature);
+ humidity.sensor = dataProviderPool.getProvider(SensorTagData.Humidity);
+ airPressure.sensor = dataProviderPool.getProvider(SensorTagData.AirPressure);
+ light.sensor = dataProviderPool.getProvider(SensorTagData.Light);
+ magnetometer.sensor = dataProviderPool.getProvider(SensorTagData.Magnetometer);
+ rotation.sensor = dataProviderPool.getProvider(SensorTagData.Rotation);
+ }
+ }
+
+ TopToolbar {
+ id: topToolbar
+
+ anchors.top: main.top
+ anchors.left: main.left
+ anchors.right: main.right
+ }
+
+ Column {
+ id: leftPane
+
+ property int indicatorHeight: (height - 3 * spacing) / 4
+
+ anchors.left: parent.left
+ anchors.leftMargin: 8
+ anchors.top: topToolbar.bottom
+ anchors.bottom: main.bottom
+ width: 360
+ spacing: 16
+
+ TemperatureChart {
+ id: ambientTemp
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+ ObjectTemperatureChart {
+ id: objectTemp
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+ HumidityChart {
+ id: humidity
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+
+ AirPressureChart {
+ id: airPressure
+
+ width: leftPane.width
+ height: leftPane.indicatorHeight
+ }
+ }
+
+ Column {
+ id: rightPane
+
+ anchors.right: parent.right
+ anchors.rightMargin: 8
+ anchors.top: topToolbar.bottom
+ anchors.bottom: main.bottom
+ width: 360
+ spacing: 16
+
+ LightChart {
+ id: light
+
+ width: rightPane.width
+ height: leftPane.height / 4
+ }
+
+ MagnetometerChart {
+ id: magnetometer
+
+ width: rightPane.width
+ height: leftPane.height * 0.3
+ }
+
+ GyroChart {
+ id: rotation
+
+ width: rightPane.width
+ height: leftPane.height * 0.3
+ onClicked: {
+ //mainContainer.source = "../base/GyroPage.qml";
+ gyroConnection.enabled = true;
+ }
+
+ Connections {
+ id: gyroConnection
+
+ target: mainContainer
+ enabled: false
+ onStatusChanged: {
+ if (status == Loader.Ready) {
+ mainContainer.item.sensor = rotation.sensor;
+ gyroConnection.enabled = false;
+ }
+ }
+ }
+ }
+ }
+
+ Loader {
+ id: mainContainer
+
+ anchors.top: topToolbar.bottom
+ anchors.left: leftPane.right
+ anchors.leftMargin: 32
+ anchors.right: rightPane.left
+ anchors.rightMargin: 32
+ anchors.bottom: bottomToolbar.top
+ }
+
+ BottomToolbar {
+ id: bottomToolbar
+
+ anchors.left: leftPane.right
+ anchors.right: rightPane.left
+ anchors.bottom: main.bottom
+ height: 30
+ }
+}
diff --git a/tradeshow/iot-sensortag/resources/small/StyleSmall.qml b/tradeshow/iot-sensortag/resources/small/StyleSmall.qml
new file mode 100644
index 0000000..e4d439d
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/StyleSmall.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+pragma Singleton
+import QtQuick 2.0
+
+QtObject {
+ property int indicatorTitleFontSize: 22
+ property int indicatorTitleSize: 41
+
+ property int topToolbarSmallFontSize: 20
+ property int topToolbarLargeFontSize: 62
+}
diff --git a/tradeshow/iot-sensortag/resources/small/images/AirPressure/AirPre_base_gauge.png b/tradeshow/iot-sensortag/resources/small/images/AirPressure/AirPre_base_gauge.png
new file mode 100644
index 0000000..16b819b
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/AirPressure/AirPre_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/AmbientTemperature/ambTemp_display_amb.png b/tradeshow/iot-sensortag/resources/small/images/AmbientTemperature/ambTemp_display_amb.png
new file mode 100644
index 0000000..64f15a6
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/AmbientTemperature/ambTemp_display_amb.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/General/icon_sensor.png b/tradeshow/iot-sensortag/resources/small/images/General/icon_sensor.png
new file mode 100644
index 0000000..e7aed60
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/General/icon_sensor.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/General/separator.png b/tradeshow/iot-sensortag/resources/small/images/General/separator.png
new file mode 100644
index 0000000..59fbb96
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/General/separator.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_base_gauge.png b/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_base_gauge.png
new file mode 100644
index 0000000..3ecd62d
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_max_hum.png b/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_max_hum.png
new file mode 100644
index 0000000..8bff102
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_max_hum.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_min_hum.png b/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_min_hum.png
new file mode 100644
index 0000000..416e376
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Humidity/humidity_min_hum.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Light/light_base_gauge.png b/tradeshow/iot-sensortag/resources/small/images/Light/light_base_gauge.png
new file mode 100644
index 0000000..8bc33a9
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Light/light_base_gauge.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Light/light_brightness.png b/tradeshow/iot-sensortag/resources/small/images/Light/light_brightness.png
new file mode 100644
index 0000000..e47ce5f
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Light/light_brightness.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_base_circle.png b/tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_base_circle.png
new file mode 100644
index 0000000..cdf7961
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_base_circle.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_display_obj.png b/tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_display_obj.png
new file mode 100644
index 0000000..53ac672
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/ObjectTemperature/objTemp_display_obj.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_cloud.png b/tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_cloud.png
new file mode 100644
index 0000000..b443a48
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_cloud.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_sensor.png b/tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_sensor.png
new file mode 100644
index 0000000..c7ef624
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Toolbar/icon_topbar_sensor.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/resources/small/images/Toolbar/topbar_all.png b/tradeshow/iot-sensortag/resources/small/images/Toolbar/topbar_all.png
new file mode 100644
index 0000000..85d85dc
--- /dev/null
+++ b/tradeshow/iot-sensortag/resources/small/images/Toolbar/topbar_all.png
Binary files differ
diff --git a/tradeshow/iot-sensortag/sensortagdataprovider.cpp b/tradeshow/iot-sensortag/sensortagdataprovider.cpp
new file mode 100644
index 0000000..e278f94
--- /dev/null
+++ b/tradeshow/iot-sensortag/sensortagdataprovider.cpp
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "sensortagdataprovider.h"
+
+#include <QtCore/QtMath>
+#include <QLoggingCategory>
+
+Q_DECLARE_LOGGING_CATEGORY(boot2QtDemos)
+
+SensorTagDataProvider::SensorTagDataProvider(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+SensorTagDataProvider::SensorTagDataProvider(QString id, QObject* parent)
+ : QObject(parent),
+ humidity(0),
+ irTemperature(0),
+ lightIntensityLux(0),
+ barometerCelsiusTemperature(0),
+ barometerHPa(0),
+ gyroscopeX_degPerSec(0),
+ gyroscopeY_degPerSec(0),
+ gyroscopeZ_degPerSec(0),
+ accelometer_mG_xAxis(0),
+ accelometer_mG_yAxis(0),
+ accelometer_mG_zAxis(0),
+ /* Object is not "walking in the air" so have one axis at 1G */
+ magnetometerMicroT_xAxis(-1000),
+ magnetometerMicroT_yAxis(0),
+ magnetometerMicroT_zAxis(0),
+ rotation_x(0),
+ rotation_y(0),
+ rotation_z(0),
+ m_tagType(AmbientTemperature | ObjectTemperature | Humidity | AirPressure | Light | Magnetometer | Rotation),
+ m_id(id),
+ m_state(Disconnected)
+{
+}
+
+QString SensorTagDataProvider::getRelativeHumidityString()
+{
+ return QString::number(humidity) + QLatin1String("%");
+}
+
+double SensorTagDataProvider::getRelativeHumidity()
+{
+ return humidity;
+}
+
+QString SensorTagDataProvider::getInfraredCelsiusTemperatureString()
+{
+ return QString::number(irTemperature) + QString("\u00B0C");
+}
+
+double SensorTagDataProvider::getInfraredCelsiusTemperature()
+{
+ return irTemperature;
+}
+
+QString SensorTagDataProvider::getLightIntensityLuxString()
+{
+ return QString::number(lightIntensityLux) + QLatin1String(" Lux");
+}
+
+double SensorTagDataProvider::getLightIntensityLux()
+{
+ return lightIntensityLux;
+}
+
+double SensorTagDataProvider::getBarometerCelsiusTemperature()
+{
+ return barometerCelsiusTemperature;
+}
+
+QString SensorTagDataProvider::getBarometerCelsiusTemperatureString()
+{
+ return QString::number(barometerCelsiusTemperature) + QString("\u00B0C");
+}
+
+double SensorTagDataProvider::getBarometerTemperatureAverage()
+{
+ return barometerTemperatureAverage;
+}
+
+QString SensorTagDataProvider::getBarometer_hPaString()
+{
+ return QString::number(barometerHPa) + QLatin1String(" hPa");
+}
+double SensorTagDataProvider::getBarometer_hPa()
+{
+ return barometerHPa;
+}
+
+float SensorTagDataProvider::getGyroscopeX_degPerSec()
+{
+ return gyroscopeX_degPerSec;
+}
+
+float SensorTagDataProvider::getGyroscopeY_degPerSec()
+{
+ return gyroscopeY_degPerSec;
+}
+
+float SensorTagDataProvider::getGyroscopeZ_degPerSec()
+{
+ return gyroscopeZ_degPerSec;
+}
+
+float SensorTagDataProvider::getAccelometer_mG_xAxis()
+{
+ return accelometer_mG_xAxis;
+}
+
+float SensorTagDataProvider::getAccelometer_mG_yAxis()
+{
+ return accelometer_mG_yAxis;
+}
+
+float SensorTagDataProvider::getAccelometer_mG_zAxis()
+{
+ return accelometer_mG_zAxis;
+}
+
+float SensorTagDataProvider::getMagnetometerMicroT_xAxis()
+{
+ return magnetometerMicroT_xAxis;
+}
+
+float SensorTagDataProvider::getMagnetometerMicroT_yAxis()
+{
+ return magnetometerMicroT_yAxis;
+}
+
+float SensorTagDataProvider::getMagnetometerMicroT_zAxis()
+{
+ return magnetometerMicroT_zAxis;
+}
+
+QColor SensorTagDataProvider::getTemperatureColor()
+{
+ // Get average and limit it between 15 and 38 degrees celsius.
+ double averageTemperature = (irTemperature + barometerCelsiusTemperature) / 2;
+ averageTemperature = std::min(averageTemperature, double(38));
+ averageTemperature = std::max(averageTemperature, double(15));
+ double relativeTemperature = ((averageTemperature-15)*255)/23;
+ int red;
+ int green = 128;
+ int blue;
+ if (relativeTemperature < 128) {
+ blue = 255;
+ red = relativeTemperature*2;
+ } else {
+ red = 255;
+ blue = 255 - ((relativeTemperature-128)*2);
+ }
+ return QColor(red, green, blue);
+}
+
+QColor SensorTagDataProvider::getLightIntensityColor()
+{
+ double relativeLightIntensityLux = std::min(lightIntensityLux, double(1000));
+ relativeLightIntensityLux = 10+((relativeLightIntensityLux*40) / 1000);
+ return QColor(relativeLightIntensityLux, relativeLightIntensityLux, relativeLightIntensityLux);
+}
+
+float SensorTagDataProvider::getRotationX()
+{
+ return rotation_x;
+}
+
+float SensorTagDataProvider::getRotationY()
+{
+ return rotation_y;
+}
+
+float SensorTagDataProvider::getRotationZ()
+{
+ return rotation_z;
+}
+
+int SensorTagDataProvider::tagType() const
+{
+ return m_tagType;
+}
+
+QString SensorTagDataProvider::id() const
+{
+ return m_id;
+}
+
+SensorTagDataProvider::ProviderState SensorTagDataProvider::state() const
+{
+ return m_state;
+}
+
+void SensorTagDataProvider::setState(SensorTagDataProvider::ProviderState state)
+{
+ if (state != m_state) {
+ m_state = state;
+ emit stateChanged();
+ }
+}
diff --git a/tradeshow/iot-sensortag/sensortagdataprovider.h b/tradeshow/iot-sensortag/sensortagdataprovider.h
new file mode 100644
index 0000000..510fc6f
--- /dev/null
+++ b/tradeshow/iot-sensortag/sensortagdataprovider.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SENSORTAGDATAPROVIDER_H
+#define SENSORTAGDATAPROVIDER_H
+#include <QObject>
+#include <QString>
+#include <QColor>
+#include <QQmlEngine>
+
+class SensorTagDataProvider : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(TagType)
+ Q_ENUMS(ProviderState)
+ Q_PROPERTY(ProviderState state READ state NOTIFY stateChanged)
+ Q_PROPERTY(QString name MEMBER m_name CONSTANT)
+ Q_PROPERTY(QString providerId MEMBER m_id CONSTANT)
+ Q_PROPERTY(QString relativeHumidityString READ getRelativeHumidityString NOTIFY relativeHumidityChanged)
+ Q_PROPERTY(double relativeHumidity READ getRelativeHumidity NOTIFY relativeHumidityChanged)
+ Q_PROPERTY(QString infraredCelsiusTemperatureString READ getInfraredCelsiusTemperatureString NOTIFY infraredCelsiusTemperatureChanged)
+ Q_PROPERTY(double infraredCelsiusTemperature READ getInfraredCelsiusTemperature NOTIFY infraredCelsiusTemperatureChanged)
+ Q_PROPERTY(QString lightIntensityLuxString READ getLightIntensityLuxString NOTIFY lightIntensityChanged)
+ Q_PROPERTY(double lightIntensityLux READ getLightIntensityLux NOTIFY lightIntensityChanged)
+ Q_PROPERTY(double barometerCelsiusTemperature READ getBarometerCelsiusTemperature NOTIFY barometerCelsiusTemperatureChanged)
+ Q_PROPERTY(QString barometerCelsiusTemperatureString READ getBarometerCelsiusTemperatureString NOTIFY barometerCelsiusTemperatureChanged)
+ Q_PROPERTY(QString barometer_hPaString READ getBarometer_hPaString NOTIFY barometer_hPaChanged)
+ Q_PROPERTY(double barometerTemperatureAverage READ getBarometerTemperatureAverage NOTIFY barometerCelsiusTemperatureAverageChanged)
+ Q_PROPERTY(double barometerHPa READ getBarometer_hPa NOTIFY barometer_hPaChanged)
+ Q_PROPERTY(float gyroscopeX_degPerSec READ getGyroscopeX_degPerSec NOTIFY gyroscopeDegPerSecChanged)
+ Q_PROPERTY(float gyroscopeY_degPerSec READ getGyroscopeY_degPerSec NOTIFY gyroscopeDegPerSecChanged)
+ Q_PROPERTY(float gyroscopeZ_degPerSec READ getGyroscopeZ_degPerSec NOTIFY gyroscopeDegPerSecChanged)
+ Q_PROPERTY(int accelometer_mG_xAxis READ getAccelometer_mG_xAxis NOTIFY accelometerGChanged)
+ Q_PROPERTY(int accelometer_mG_yAxis READ getAccelometer_mG_yAxis NOTIFY accelometerGChanged)
+ Q_PROPERTY(int accelometer_mG_zAxis READ getAccelometer_mG_zAxis NOTIFY accelometerGChanged)
+ Q_PROPERTY(float magnetometerMicroT_xAxis READ getMagnetometerMicroT_xAxis NOTIFY magnetometerMicroTChanged)
+ Q_PROPERTY(float magnetometerMicroT_yAxis READ getMagnetometerMicroT_yAxis NOTIFY magnetometerMicroTChanged)
+ Q_PROPERTY(float magnetometerMicroT_zAxis READ getMagnetometerMicroT_zAxis NOTIFY magnetometerMicroTChanged)
+ Q_PROPERTY(QColor temperatureColor READ getTemperatureColor NOTIFY infraredCelsiusTemperatureChanged)
+ Q_PROPERTY(QColor lightIntensityColor READ getLightIntensityColor NOTIFY lightIntensityChanged)
+ Q_PROPERTY(float rotationX READ getRotationX NOTIFY rotationXChanged)
+ Q_PROPERTY(float rotationY READ getRotationY NOTIFY rotationYChanged)
+ Q_PROPERTY(float rotationZ READ getRotationZ NOTIFY rotationZChanged)
+
+public:
+ enum TagType {AmbientTemperature = 1 << 0,
+ ObjectTemperature = 1 << 1,
+ Humidity,
+ AirPressure = 1 << 2,
+ Light = 1 << 3,
+ Magnetometer = 1 << 4,
+ Rotation = 1 << 5};
+ enum ProviderState {Disconnected = 0, Scanning, Connected, Error};
+
+ explicit SensorTagDataProvider(QObject *parent = 0);
+ SensorTagDataProvider(QString id, QObject *parent = 0);
+
+ virtual bool startDataFetching() {return false;}
+ virtual void endDataFetching() {}
+ QString getRelativeHumidityString();
+ double getRelativeHumidity();
+ QString getInfraredCelsiusTemperatureString();
+ double getInfraredCelsiusTemperature();
+ QString getLightIntensityLuxString();
+ double getLightIntensityLux();
+ double getBarometerCelsiusTemperature();
+ QString getBarometerCelsiusTemperatureString();
+ double getBarometerTemperatureAverage();
+ QString getBarometer_hPaString();
+ double getBarometer_hPa();
+ float getGyroscopeX_degPerSec();
+ float getGyroscopeY_degPerSec();
+ float getGyroscopeZ_degPerSec();
+ float getAccelometer_mG_xAxis();
+ float getAccelometer_mG_yAxis();
+ float getAccelometer_mG_zAxis();
+ float getMagnetometerMicroT_xAxis();
+ float getMagnetometerMicroT_yAxis();
+ float getMagnetometerMicroT_zAxis();
+ QColor getTemperatureColor();
+ QColor getLightIntensityColor();
+ float getRotationX();
+ float getRotationY();
+ float getRotationZ();
+
+ Q_INVOKABLE int tagType() const;
+ QString id() const;
+ ProviderState state() const;
+ void setState(ProviderState state);
+
+ virtual QString providerName() const { return m_name;}
+ virtual QString sensorType() const { return QString();}
+ virtual QString versionString() const{ return QString();}
+
+
+signals:
+ void stateChanged();
+ void relativeHumidityChanged();
+ void infraredCelsiusTemperatureChanged();
+ void lightIntensityChanged();
+ void barometerCelsiusTemperatureChanged();
+ void barometerCelsiusTemperatureAverageChanged();
+ void barometer_hPaChanged();
+ void gyroscopeDegPerSecChanged();
+ void accelometerGChanged();
+ void magnetometerMicroTChanged();
+ void rotationXChanged();
+ void rotationYChanged();
+ void rotationZChanged();
+ void rotationValuesChanged();
+
+protected:
+ double humidity;
+ double irTemperature;
+ double lightIntensityLux;
+ double barometerCelsiusTemperature;
+ double barometerTemperatureAverage;
+ double barometerHPa;
+ //double temperatureAverage;
+ float gyroscopeX_degPerSec;
+ float gyroscopeY_degPerSec;
+ float gyroscopeZ_degPerSec;
+ int accelometer_mG_xAxis;
+ int accelometer_mG_yAxis;
+ int accelometer_mG_zAxis;
+ float magnetometerMicroT_xAxis;
+ float magnetometerMicroT_yAxis;
+ float magnetometerMicroT_zAxis;
+ float rotation_x;
+ float rotation_y;
+ float rotation_z;
+
+ int m_tagType;
+ QString m_id;
+ QString m_name;
+ ProviderState m_state;
+};
+
+Q_DECLARE_METATYPE(SensorTagDataProvider::TagType)
+Q_DECLARE_METATYPE(SensorTagDataProvider::ProviderState)
+
+#endif // SENSORTAGDATAPROVIDER_H
diff --git a/tradeshow/iot-sensortag/sensortagdataproviderpool.cpp b/tradeshow/iot-sensortag/sensortagdataproviderpool.cpp
new file mode 100644
index 0000000..bb0ead1
--- /dev/null
+++ b/tradeshow/iot-sensortag/sensortagdataproviderpool.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bluetoothdataprovider.h"
+#include "sensortagdataproviderpool.h"
+
+#include <QLoggingCategory>
+
+Q_DECLARE_LOGGING_CATEGORY(boot2QtDemos)
+
+SensorTagDataProviderPool::SensorTagDataProviderPool(QObject *parent)
+ : SensorTagDataProviderPool("SensorTag", parent)
+{
+
+}
+
+SensorTagDataProviderPool::SensorTagDataProviderPool(QString poolName, QObject* parent)
+ : DataProviderPool(poolName, parent)
+{
+ m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
+ connect(m_discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
+ this, SLOT(btDeviceFound(const QBluetoothDeviceInfo&)));
+ connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
+ this, SLOT(deviceScanError(QBluetoothDeviceDiscoveryAgent::Error)));
+ connect(m_discoveryAgent, SIGNAL(finished()), this, SLOT(deviceDiscoveryFinished()));
+}
+
+void SensorTagDataProviderPool::startScanning()
+{
+ qDeleteAll(m_dataProviders);
+ m_dataProviders.clear();
+
+ m_discoveryAgent->start();
+
+ if (m_discoveryAgent->isActive()) {
+ m_deviceScanState = true;
+ }
+}
+
+void SensorTagDataProviderPool::setMacFilterList(const QStringList &addressList)
+{
+ m_macFilters = addressList;
+}
+
+QStringList SensorTagDataProviderPool::macFilters() const
+{
+ return m_macFilters;
+}
+
+void SensorTagDataProviderPool::setnameFilteList(const QStringList &nameList)
+{
+ m_nameFilters = nameList;
+}
+
+SensorTagDataProvider *SensorTagDataProviderPool::providerForCloud() const
+{
+ return m_providerForCloud;
+}
+
+// Currently, return simply the first provider found.
+// It might be better to somehow collect the results from
+// all providers and combine them
+void SensorTagDataProviderPool::updateProviderForCloud()
+{
+ if (m_dataProviders.length())
+ m_providerForCloud = m_dataProviders.at(0);
+ else
+ m_providerForCloud = 0;
+ emit providerForCloudChanged();
+}
+
+void SensorTagDataProviderPool::deviceDiscoveryFinished()
+{
+ m_deviceScanState = false;
+ emit scanFinished();
+}
+
+void SensorTagDataProviderPool::btDeviceFound(const QBluetoothDeviceInfo &info)
+{
+ qCDebug(boot2QtDemos) << "Found a Bluetooth device. Name:" << info.name() << ", addr:" << info.address().toString();
+
+ if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
+ bool filtered = m_macFilters.length() || m_nameFilters.length();
+ bool found = filtered ? false : true;
+
+ if (m_macFilters.length() && m_macFilters.contains(info.address().toString()))
+ found = true;
+ else if (m_nameFilters.length() && m_nameFilters.contains(info.name()))
+ found = true;
+
+ if (found) {
+ qCDebug(boot2QtDemos) << " Adding to the available devices";
+ BluetoothDataProvider* dataProvider = new BluetoothDataProvider(info.address().toString(), this);
+ BluetoothDevice *d = new BluetoothDevice(info);
+ dataProvider->bindToDevice(d);
+ m_dataProviders.append(dataProvider);
+ emit providerConnected(d->getAddress());
+ emit dataProvidersChanged();
+ updateProviderForCloud();
+ connect(dataProvider, &SensorTagDataProvider::stateChanged, this, &SensorTagDataProviderPool::handleStateChange);
+ }
+ }
+}
+
+void SensorTagDataProviderPool::handleStateChange()
+{
+ SensorTagDataProvider *provider = static_cast<SensorTagDataProvider*>(sender());
+
+ qCDebug(boot2QtDemos) << provider->state();
+
+ switch (provider->state()) {
+ case SensorTagDataProvider::Disconnected:
+ updateProviderForCloud();
+ emit providerDisconnected(provider->id());
+ break;
+ case SensorTagDataProvider::Connected:
+ emit providerConnected(provider->id());
+ break;
+ case SensorTagDataProvider::Error:
+ emit providerInError(provider->id());
+ break;
+ default:
+ break;
+ }
+}
+
+void SensorTagDataProviderPool::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
+{
+ if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
+ qCDebug(boot2QtDemos) << "The Bluetooth adaptor is powered off, power it on before doing discovery.";
+ else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
+ qCDebug(boot2QtDemos) << "Writing or reading from the device resulted in an error.";
+ else
+ qCDebug(boot2QtDemos) << "An unknown error has occurred.";
+
+ m_deviceScanState = false;
+ emit scanFinished();
+}
diff --git a/tradeshow/iot-sensortag/sensortagdataproviderpool.h b/tradeshow/iot-sensortag/sensortagdataproviderpool.h
new file mode 100644
index 0000000..712d4cc
--- /dev/null
+++ b/tradeshow/iot-sensortag/sensortagdataproviderpool.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SENSORTAGDATAPROVIDERPOOL_H
+#define SENSORTAGDATAPROVIDERPOOL_H
+
+#include "dataproviderpool.h"
+#include "bluetoothdevice.h"
+
+#include <QObject>
+#include <QBluetoothDeviceDiscoveryAgent>
+#include <QBluetoothDeviceInfo>
+#include <QList>
+
+class SensorTagDataProviderPool : public DataProviderPool
+{
+ Q_OBJECT
+
+public:
+ explicit SensorTagDataProviderPool(QObject *parent = 0);
+
+ void startScanning() override;
+
+ // setMacFilterList takes presence over name filter
+ Q_INVOKABLE void setMacFilterList(const QStringList& addressList);
+ QStringList macFilters() const;
+ Q_INVOKABLE void setnameFilteList(const QStringList& nameList);
+
+ SensorTagDataProvider* providerForCloud() const override;
+
+protected:
+ SensorTagDataProviderPool(QString poolName, QObject *parent = 0);
+
+ void updateProviderForCloud();
+
+private slots:
+ void deviceDiscoveryFinished();
+ void btDeviceFound(const QBluetoothDeviceInfo &info);
+ void handleStateChange();
+ void deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error);
+
+private:
+ QStringList m_macFilters;
+ QStringList m_nameFilters;
+ bool m_deviceScanState;
+ QBluetoothDeviceDiscoveryAgent *m_discoveryAgent;
+ SensorTagDataProvider *m_providerForCloud;
+};
+
+#endif // SENSORTAGDATAPROVIDERPOOL_H
diff --git a/tradeshow/iot-sensortag/serviceinfo.cpp b/tradeshow/iot-sensortag/serviceinfo.cpp
new file mode 100644
index 0000000..686e8f6
--- /dev/null
+++ b/tradeshow/iot-sensortag/serviceinfo.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "serviceinfo.h"
+
+ServiceInfo::ServiceInfo()
+{
+}
+
+ServiceInfo::ServiceInfo(QLowEnergyService *service):
+ m_service(service)
+{
+ m_service->setParent(this);
+}
+
+QLowEnergyService *ServiceInfo::service() const
+{
+ return m_service;
+}
+
+QString ServiceInfo::getName() const
+{
+ if (!m_service)
+ return QString();
+
+ return m_service->serviceName();
+}
+
+QString ServiceInfo::getType() const
+{
+ if (!m_service)
+ return QString();
+
+ QString result;
+ if (m_service->type() & QLowEnergyService::PrimaryService)
+ result += QStringLiteral("primary");
+ else
+ result += QStringLiteral("secondary");
+
+ if (m_service->type() & QLowEnergyService::IncludedService)
+ result += QStringLiteral(" included");
+
+ result.prepend('<').append('>');
+
+ return result;
+}
+
+QString ServiceInfo::getUuid() const
+{
+ if (!m_service)
+ return QString();
+
+ const QBluetoothUuid uuid = m_service->serviceUuid();
+ bool success = false;
+ const quint16 result16 = uuid.toUInt16(&success);
+ if (success)
+ return QStringLiteral("0x") + QString::number(result16, 16);
+
+ const quint32 result32 = uuid.toUInt32(&success);
+ if (success)
+ return QStringLiteral("0x") + QString::number(result32, 16);
+
+ return uuid.toString().remove(QLatin1Char('{')).remove(QLatin1Char('}'));
+}
diff --git a/tradeshow/iot-sensortag/serviceinfo.h b/tradeshow/iot-sensortag/serviceinfo.h
new file mode 100644
index 0000000..e6c1e51
--- /dev/null
+++ b/tradeshow/iot-sensortag/serviceinfo.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of Qt for Device Creation.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SERVICEINFO_H
+#define SERVICEINFO_H
+
+#include <QtBluetooth/QLowEnergyService>
+
+class ServiceInfo: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString serviceName READ getName NOTIFY serviceChanged)
+ Q_PROPERTY(QString serviceUuid READ getUuid NOTIFY serviceChanged)
+ Q_PROPERTY(QString serviceType READ getType NOTIFY serviceChanged)
+public:
+ ServiceInfo();
+ ServiceInfo(QLowEnergyService *service);
+ QLowEnergyService *service() const;
+ QString getUuid() const;
+ QString getName() const;
+ QString getType() const;
+
+Q_SIGNALS:
+ void serviceChanged();
+
+private:
+ QLowEnergyService *m_service;
+};
+
+#endif // SERVICEINFO_H
diff --git a/tradeshow/iot-sensortag/uilarge.qrc b/tradeshow/iot-sensortag/uilarge.qrc
new file mode 100644
index 0000000..6885e21
--- /dev/null
+++ b/tradeshow/iot-sensortag/uilarge.qrc
@@ -0,0 +1,17 @@
+<RCC>
+ <qresource prefix="/">
+ <file>resources/large/MainLarge.qml</file>
+ <file>resources/large/StyleLarge.qml</file>
+ <file>resources/large/images/General/icon_sensor.png</file>
+ <file>resources/large/images/General/separator.png</file>
+ <file>resources/large/images/AmbientTemperature/ambTemp_display_amb.png</file>
+ <file>resources/large/images/Humidity/humidity_base_gauge.png</file>
+ <file>resources/large/images/Humidity/humidity_max_hum.png</file>
+ <file>resources/large/images/Humidity/humidity_min_hum.png</file>
+ <file>resources/large/images/ObjectTemperature/objTemp_base_circle.png</file>
+ <file>resources/large/images/ObjectTemperature/objTemp_display_obj.png</file>
+ <file>resources/large/images/Light/light_base_gauge.png</file>
+ <file>resources/large/images/Light/light_brightness.png</file>
+ <file>resources/large/images/AirPressure/AirPre_base_gauge.png</file>
+ </qresource>
+</RCC>
diff --git a/tradeshow/iot-sensortag/uimedium.qrc b/tradeshow/iot-sensortag/uimedium.qrc
new file mode 100644
index 0000000..bb4324c
--- /dev/null
+++ b/tradeshow/iot-sensortag/uimedium.qrc
@@ -0,0 +1,17 @@
+<RCC>
+ <qresource prefix="/">
+ <file>resources/medium/MainMedium.qml</file>
+ <file>resources/medium/StyleMedium.qml</file>
+ <file>resources/medium/images/AmbientTemperature/ambTemp_display_amb.png</file>
+ <file>resources/medium/images/General/icon_sensor.png</file>
+ <file>resources/medium/images/General/separator.png</file>
+ <file>resources/medium/images/Humidity/humidity_max_hum.png</file>
+ <file>resources/medium/images/Humidity/humidity_min_hum.png</file>
+ <file>resources/medium/images/Humidity/humidity_base_gauge.png</file>
+ <file>resources/medium/images/ObjectTemperature/objTemp_base_circle.png</file>
+ <file>resources/medium/images/ObjectTemperature/objTemp_display_obj.png</file>
+ <file>resources/medium/images/Light/light_base_gauge.png</file>
+ <file>resources/medium/images/Light/light_brightness.png</file>
+ <file>resources/medium/images/AirPressure/AirPre_base_gauge.png</file>
+ </qresource>
+</RCC>
diff --git a/tradeshow/iot-sensortag/uismall.qrc b/tradeshow/iot-sensortag/uismall.qrc
new file mode 100644
index 0000000..303fecd
--- /dev/null
+++ b/tradeshow/iot-sensortag/uismall.qrc
@@ -0,0 +1,20 @@
+<RCC>
+ <qresource prefix="/">
+ <file>resources/small/StyleSmall.qml</file>
+ <file>resources/small/MainSmall.qml</file>
+ <file>resources/small/images/General/icon_sensor.png</file>
+ <file>resources/small/images/General/separator.png</file>
+ <file>resources/small/images/AmbientTemperature/ambTemp_display_amb.png</file>
+ <file>resources/small/images/Humidity/humidity_max_hum.png</file>
+ <file>resources/small/images/Humidity/humidity_min_hum.png</file>
+ <file>resources/small/images/Humidity/humidity_base_gauge.png</file>
+ <file>resources/small/images/ObjectTemperature/objTemp_base_circle.png</file>
+ <file>resources/small/images/ObjectTemperature/objTemp_display_obj.png</file>
+ <file>resources/small/images/Light/light_base_gauge.png</file>
+ <file>resources/small/images/Light/light_brightness.png</file>
+ <file>resources/small/images/AirPressure/AirPre_base_gauge.png</file>
+ <file>resources/small/images/Toolbar/icon_topbar_sensor.png</file>
+ <file>resources/small/images/Toolbar/topbar_all.png</file>
+ <file>resources/small/images/Toolbar/icon_topbar_cloud.png</file>
+ </qresource>
+</RCC>