Index: denali.pro =================================================================== diff -u -r7c895d9b6c198a48ab75ac2090b0a61d99bbd1ab -rbe1b2d8f110b741f3d630df438da07d411110543 --- denali.pro (.../denali.pro) (revision 7c895d9b6c198a48ab75ac2090b0a61d99bbd1ab) +++ denali.pro (.../denali.pro) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -1,4 +1,4 @@ -QT += widgets qml quick serialbus concurrent +QT += widgets qml quick serialbus concurrent bluetooth CONFIG += c++17 warn_on QMAKE_CXXFLAGS += -Wall -Werror -Wimplicit-fallthrough # -save-temps # see .ii and .s files @@ -31,6 +31,7 @@ sources/storage \ sources/gui \ sources/canbus \ + sources/bluetooth \ sources/utility \ sources/abstract \ sources/model \ @@ -107,11 +108,15 @@ sources/canbus/MessageBuilder.h \ sources/canbus/MessageInterpreter.h \ sources/canbus/MessageDispatcher.h \ + \ # Bluetooth + sources/bluetooth/BLEScanner.h \ \ # Gui sources/gui/GuiGlobals.h \ sources/gui/GuiView.h \ sources/gui/GuiController.h \ \ # ---------- Views ---------- + sources/view/VBluetooth.h \ + sources/view/VBluetoothDeviceInfo.h \ sources/view/VTreatmentCreate.h \ sources/view/VTreatmentEnd.h \ sources/view/VTreatmentBegin.h \ @@ -219,11 +224,15 @@ sources/canbus/MessageBuilder.cpp \ sources/canbus/MessageDispatcher.cpp \ sources/canbus/MessageInterpreter.cpp \ + \ # Bluetooth + sources/bluetooth/BLEScanner.cpp \ \ # Gui sources/gui/GuiGlobals.cpp \ sources/gui/GuiView.cpp \ sources/gui/GuiController.cpp \ \ # ---------- Views ---------- + sources/view/VBluetooth.cpp \ + sources/view/VBluetoothDeviceInfo.cpp \ sources/view/VTreatmentCreate.cpp \ sources/view/VTreatmentEnd.cpp \ sources/view/VTreatmentBegin.cpp \ Index: denali.pro.user =================================================================== diff -u -re58be51c4aa52938af250db3ee579e98de08542c -rbe1b2d8f110b741f3d630df438da07d411110543 --- denali.pro.user (.../denali.pro.user) (revision e58be51c4aa52938af250db3ee579e98de08542c) +++ denali.pro.user (.../denali.pro.user) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -89,7 +89,7 @@ Desktop Qt 5.12.5 GCC 64bit Desktop Qt 5.12.5 GCC 64bit qt.qt5.5125.gcc_64_kit - 1 + 0 0 0 Index: denali.qrc =================================================================== diff -u -re58be51c4aa52938af250db3ee579e98de08542c -rbe1b2d8f110b741f3d630df438da07d411110543 --- denali.qrc (.../denali.qrc) (revision e58be51c4aa52938af250db3ee579e98de08542c) +++ denali.qrc (.../denali.qrc) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -5,6 +5,7 @@ sources/gui/qml/pages/SettingsHome.qml sources/gui/qml/pages/Diagnostics.qml sources/gui/qml/pages/ManagerHome.qml + sources/gui/qml/pages/SettingsBluetooth.qml sources/gui/qml/dialogs/PowerOff.qml Index: main.cpp =================================================================== diff -u -r6cad9b004e904200b71de7431c745795256080df -rbe1b2d8f110b741f3d630df438da07d411110543 --- main.cpp (.../main.cpp) (revision 6cad9b004e904200b71de7431c745795256080df) +++ main.cpp (.../main.cpp) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -47,6 +47,7 @@ #include "GuiController.h" #include "Logger.h" #include "DriveWatcher.h" +#include "BLEScanner.h" #include "Threads.h" // kernel @@ -316,6 +317,9 @@ _MessageDispatcher.enableConsoleOut(gConsoleoutFrameInterface); } + //! - Initializing BLE Interface + _BLEScanner.init(); + //! - Initializing Application Controller _ApplicationController.init(Threads::_Application_Thread); Index: sources/Threads.cpp =================================================================== diff -u --- sources/Threads.cpp (revision 0) +++ sources/Threads.cpp (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -0,0 +1,98 @@ +/*! + * + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * \copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * \file Threads.cpp + * \author (last) Behrouz NematiPour + * \date (last) 31-Aug-2020 + * \author (original) Behrouz NematiPour + * \date (original) 26-Aug-2020 + * + */ +#include "Threads.h" + +// Qt +#include +#include + +// Application +#include "MessageGlobals.h" +#include "Logger.h" + +/*! + * \details All the Thread has been and shall be defined in here + * And will be assigned to a required class from main thread. + * \note quitThreads() needs to be called when the application execution event loop is done + * this has currently been done in main.cpp in main() after the qpp.exe() is done. + */ +namespace Threads { + QThread _CanFrame_Thread ; + QThread _CanAcknow_Thread ; + QThread _CanMessage_Thread ; + QThread _DriveWatcher_Thread ; + QThread _Logger_Thread ; + QThread _Application_Thread ; + QThread _BLEScanner_Thread ; + + /*! + * \brief registerTypes + * \details this method has to be called before any class which uses these types + * and also is handled by threads + * It seems qt is using the meta objects for threading signal/slots + * and it requires any type which has been used in this context to be registered. + */ + void registerTypes() + { + // Logger : This is required for Signal/Slots in threading. + qRegisterMetaType("LogType"); + + // CanInterface : This is required for Signal/Slots in threading. + qRegisterMetaType("QCanBusFrame"); + + // FrameInterface : This is required for Signal/Slots in threading. + qRegisterMetaType("Can_Id"); + + // MessageAcknowModel : This is required for Signal/Slots in threading. + qRegisterMetaType("Sequence"); + + // MessageAcknowModel : This is required for Signal/Slots in threading. + qRegisterMetaType("FrameList"); + } + + /*! + * \brief quitThread + * \details quits the thread vThread and wait for it to be destroyed. + * \param vThread - the thread + */ + void quitThread(QThread &vThread) + { + // coco begin validated: Application termination is not correctly done in coco!!! + // it has been tested and works perfectly fine in normal run. + // runs in main thread + vThread.quit(); // validated + vThread.wait(); // validated + } + // coco end + + /*! + * \brief quitThreads + * \details quits the list of the threads which has been defined + * int the Threads namespace + * \note It requires to be updated by developer if any more thread has been added + */ + void quitThreads() + { + // coco begin validated: Application termination is not correctly done in coco!!! + // it has been tested and works perfectly fine in normal run. + quitThread(_CanFrame_Thread ); // validated + quitThread(_CanAcknow_Thread ); // validated + quitThread(_CanMessage_Thread ); // validated + quitThread(_DriveWatcher_Thread ); // validated + quitThread(_Logger_Thread ); // validated + quitThread(_Application_Thread ); // validated + } + // coco end +} Index: sources/bluetooth/BLEScanner.cpp =================================================================== diff -u -r0470ff6f209ff0c5089f8f0849b6da04f60f8f41 -rbe1b2d8f110b741f3d630df438da07d411110543 --- sources/bluetooth/BLEScanner.cpp (.../BLEScanner.cpp) (revision 0470ff6f209ff0c5089f8f0849b6da04f60f8f41) +++ sources/bluetooth/BLEScanner.cpp (.../BLEScanner.cpp) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -7,10 +7,8 @@ // Project #include "main.h" -#include "logger.h" +#include "Logger.h" - - BLEScanner::BLEScanner(QObject *parent) : QObject(parent) { discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); Index: sources/gui/GuiGlobals.cpp =================================================================== diff -u --- sources/gui/GuiGlobals.cpp (revision 0) +++ sources/gui/GuiGlobals.cpp (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -0,0 +1,136 @@ +/*! + * + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * \copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * \file GuiGlobals.cpp + * \author (last) Peter Lucia + * \date (last) 15-Oct-2020 + * \author (original) Behrouz NematiPour + * \date (original) 26-Aug-2020 + * + */ +#include "GuiGlobals.h" + +// Qt +#include + +// Project +#include "Logger.h" +#include "GuiView.h" +#include "VEventSpy.h" + +// Project +#include "MModel.h" +#include "VView.h" + +#include "VAlarmStatus.h" +#include "VPowerOff.h" + +#include "VTreatmentBloodFlow.h" +#include "VTreatmentDialysateFlow.h" +#include "VTreatmentUltrafiltration.h" +#include "VTreatmentAdjustmentUltrafiltrationState.h" +#include "VTreatmentPressureOcclusion.h" +#include "VTreatmentTime.h" +#include "VTreatmentRanges.h" +#include "VHDOperationModeData.h" +#include "VTreatmentSalineData.h" +#include "VHDTreatmentStatesData.h" + +#include "VDGDrainPumpData.h" +#include "VDGHeatersData.h" +#include "VDGLoadCellReadingsData.h" +#include "VDGOperationModeData.h" +#include "VDGPressuresData.h" +#include "VDGROPumpData.h" +#include "VDGReservoirData.h" +#include "VDGTemperaturesData.h" +#include "VDGValvesStatesData.h" +#include "VTreatmentCreate.h" +#include "VBluetooth.h" +#include "VBluetoothDeviceInfo.h" +#include "VPriming.h" +#include "VTreatmentBegin.h" +#include "VTreatmentEnd.h" +#include "VTreatmentAdjustmentDuration.h" +#include "VTreatmentAdjustmentFlows.h" +#include "VTreatmentAdjustmentUltrafiltrationEdit.h" +#include "VTreatmentAdjustmentUltrafiltrationConfirm.h" +#include "VTreatmentAdjustmentSaline.h" + +namespace Gui { + MainView *_viewer = nullptr; + + /*! + * \brief registerTypes + * \details registering meta types + */ + void registerTypes() + { + qRegisterMetaType ("GuiActionType" ); + qRegisterMetaType ("GuiActionData" ); + + qRegisterMetaType ("GuiAlarmID" ); + qRegisterMetaType ("GuiAlarmPriority"); + + qRegisterMetaType ("GuiRequestReasons"); + + // Note that this Models are not used in the QML + // but Qt needs them to be registered to be able to use them in between threads queue + // by their metadata information. + REGISTER_MODEL_METATYPES + LOG_DEBUG("Models Registered"); + } + + /*! + * \brief registerQmlTypes + * \details registering QML types + */ + void registerQmlTypes() + { + //using namespace View; + qmlRegisterType ("Gui.View" , 0, 1, "GuiView"); + qmlRegisterUncreatableType ("Gui.Actions" , 0, 1, "GuiActions" , QStringLiteral("Used only for enumerations no need to have an object")); + qmlRegisterSingletonType ("Gui.VEventSpy", 0, 1, "GuiEventSpy", [](QQmlEngine *, QJSEngine *) -> QObject * { + return &_VEventSpy; + }); + + REGISTER_VIEW_TYPES + LOG_DEBUG("Views Registered"); + } + + /*! + * \brief startGui + * \details the GUI initializer/starter function + */ + bool startGui() { + _viewer = new MainView; + registerTypes(); + registerQmlTypes(); + + QObject::connect(_viewer, &MainView::statusChanged, qApp, [=](MainView::Status vStatus) { + // coco begin validated: this portion of the code is handling application initialization + // and if not initialized correctly will terminate the application . + // So it had been manually tested. + bool ok = vStatus == MainView::Ready; + if (ok) { + _viewer->show(); + } + else if (vStatus == MainView::Error || vStatus == MainView::Null) { + for (const auto &error : _viewer->errors()) { + LOG_DEBUG(QString("Application Terminated: %1").arg(error.toString())); + } + QCoreApplication::exit(-1); + } + // coco end + }, Qt::QueuedConnection ); + + LOG_DEBUG("MainView Starting"); + _viewer->setSource(QStringLiteral("qrc:/main.qml")); + LOG_DEBUG("MainView started"); + return true; + } +} Index: sources/gui/qml/globals/Variables.qml =================================================================== diff -u -rb62ab443e75b76a91e35aca6ba2efd84e7199602 -rbe1b2d8f110b741f3d630df438da07d411110543 --- sources/gui/qml/globals/Variables.qml (.../Variables.qml) (revision b62ab443e75b76a91e35aca6ba2efd84e7199602) +++ sources/gui/qml/globals/Variables.qml (.../Variables.qml) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -111,6 +111,8 @@ readonly property int notificationBarIconHeight : 30 readonly property int notificationBarIconWidth : 30 + readonly property int settingsBLEButtonWidth : 300 + readonly property int settingsBLEButtonHeight : 75 readonly property int settingsOptionWidth : 550 readonly property int settingsOptionHeight : 50 Index: sources/gui/qml/main.qml =================================================================== diff -u -re58be51c4aa52938af250db3ee579e98de08542c -rbe1b2d8f110b741f3d630df438da07d411110543 --- sources/gui/qml/main.qml (.../main.qml) (revision e58be51c4aa52938af250db3ee579e98de08542c) +++ sources/gui/qml/main.qml (.../main.qml) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -36,6 +36,7 @@ import VTreatmentAdjustmentFlows 0.1; import VTreatmentCreate 0.1; +import VBluetooth 0.1; import VDGDrainPump 0.1; import VDGHeaters 0.1; import VDGLoadCellReadings 0.1; @@ -103,6 +104,7 @@ VTreatmentAdjustmentDuration { id: vTreatmentAdjustmentDuration } VTreatmentAdjustmentFlows { id: vTreatmentAdjustmentFlows } VTreatmentCreate { id: vTreatmentCreate } + VBluetooth { id: vBluetooth } VPriming { id: vPriming } VTreatmentBegin { id: vTreatmentBegin } VTreatmentEnd { id: vTreatmentEnd } Index: sources/gui/qml/pages/SettingsHome.qml =================================================================== diff -u -r53134008481fd775533e8988b7436f2f75e47336 -rbe1b2d8f110b741f3d630df438da07d411110543 --- sources/gui/qml/pages/SettingsHome.qml (.../SettingsHome.qml) (revision 53134008481fd775533e8988b7436f2f75e47336) +++ sources/gui/qml/pages/SettingsHome.qml (.../SettingsHome.qml) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -28,6 +28,7 @@ * which is the default screen in the "Settings" stack */ ScreenItem { id: _root + backgroundRect.color: Colors.backgroundMenu USBButton { id: _usbButton anchors { top : parent.top @@ -80,35 +81,40 @@ vTreatmentEnd.doEndTreatmentRequest(); } } -} -/* TitleText { id: _titleText anchors.horizontalCenter: parent.horizontalCenter; anchors.top: parent.top anchors.topMargin: 150 width: parent.width text: qsTr("Device Settings") - - } + /* Diagnostics { id: _diagnostics onBackClicked: pop() } + */ + SettingsBluetooth { + id: _bluetooth + onClickedBack: pop() + + } + Column { anchors.centerIn: parent; // add each settings page here. - SettingsItem { id: _item_diagnostics - title : qsTr("Diagnostics") - onClicked: push(_diagnostics); + SettingsItem { id: _item_bluetooth + title : qsTr("Bluetooth") + onClicked: push(_bluetooth); + } } -*/ +} Index: sources/view/VBluetooth.h =================================================================== diff -u -r0470ff6f209ff0c5089f8f0849b6da04f60f8f41 -rbe1b2d8f110b741f3d630df438da07d411110543 --- sources/view/VBluetooth.h (.../VBluetooth.h) (revision 0470ff6f209ff0c5089f8f0849b6da04f60f8f41) +++ sources/view/VBluetooth.h (.../VBluetooth.h) (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -7,7 +7,7 @@ // Project #include "VBluetoothDeviceInfo.h" -#include "guicontroller.h" +#include "GuiController.h" using namespace Gui; Index: sources/view/VView.h =================================================================== diff -u --- sources/view/VView.h (revision 0) +++ sources/view/VView.h (revision be1b2d8f110b741f3d630df438da07d411110543) @@ -0,0 +1,140 @@ +/*! + * + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * \copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * \file vview.h + * \author (last) Behrouz NematiPour + * \date (last) 13-Aug-2020 + * \author (original) Behrouz NematiPour + * \date (original) 10-Mar-2020 + * + */ +#pragma once + +/*! + * \page MessageView Denali Message View usage instruction in QML + * \details This comment explains how to use a Denali Message populated data in Denali UI Application + \verbatim + 1 - Look at the message structure in the "message list.xlsx" + + 2 - View Implementation : + Implement a view like VDGPressures by copy/paste the closest model .h/.cpp file + and adding it to project and modify to fit the new model. + + 3 - Register View : + - Add the required lines like the other models in the VView.h file. + - Also add the #include in the GuiGlobals.cpp + + 4 - Usage in UI : + Import : import VDGPressures 0.1; + Instantiate : VDGPressures { id: vDGPressures } + Access : value: vDGPressures.drainInletPSI + \endverbatim + */ +//--------------------------------------------------------------------------------// +//--------------------------------------------------------------------------------// +// The child declaration in header +#define VIEW_DEC_CLASS(vCLASS) \ +private: \ + /*! \brief Connection Initializer + \details All the class signal/slot connections are defined here. + */\ + void initConnections(); \ +public: \ + /*! \brief Class Constructor + \details Only calls initConnections to initialize the signal/slot connection(s). + \param parent - The QObject parent pointer which is passed as nullptr and is not set. + */\ + explicit vCLASS(QObject *parent = nullptr); \ +//--------------------------------------------------------------------------------// +#define VIEW_DEC_SLOT(vDATATYPE) \ +private Q_SLOTS: \ + /*! \brief Model data received message handler. + \details When signal received this method is called to update the view properties. + \param vData - Model data + */\ + void onActionReceive (const vDATATYPE &vData); \ +//--------------------------------------------------------------------------------// +#define VIEW_DEC(vCLASS, vDATATYPE) \ + VIEW_DEC_CLASS(vCLASS) \ + VIEW_DEC_SLOT(vDATATYPE) \ +//--------------------------------------------------------------------------------// + +//--------------------------------------------------------------------------------// +// The child definition in cpp +#define VIEW_DEF_CLASS(vCLASS) \ +using namespace View; \ +vCLASS::vCLASS(QObject *parent) : QObject(parent) { \ + initConnections(); \ +} \ +//--------------------------------------------------------------------------------// +#define VIEW_DEF_CONNECTION(vCLASS, vDATATYPE) \ +void vCLASS::initConnections() { \ + ACTION_RECEIVE_BRIDGE_CONNECTION( \ + Gui::_GuiController, vDATATYPE); \ +} \ +//--------------------------------------------------------------------------------// +#define VIEW_DEF(vCLASS, vDATATYPE) \ + VIEW_DEF_CLASS(vCLASS) \ + VIEW_DEF_CONNECTION(vCLASS, vDATATYPE) \ +//--------------------------------------------------------------------------------// + +//--------------------------------------------------------------------------------// +// The Adjustment child definition in cpp +#define VIEW_DEC_CLASS_ADJUSTMENT(vCLASS, vDATATYPE)\ + VIEW_DEC_CLASS(vCLASS) \ + VIEW_DEC_SLOT(vDATATYPE) \ +//--------------------------------------------------------------------------------// +#define VIEW_DEF_CLASS_ADJUSTMENT(vCLASS, vDATATYPE) \ + using namespace View; \ + vCLASS::vCLASS(QObject *parent) : VTreatmentAdjustmentResponseBase(parent) { \ + initConnections(); \ + } \ +//--------------------------------------------------------------------------------// + +//--------------------------------------------------------------------------------// +//--------- Please add the view type to the lists below to register them ---------// +//--------------------------------------------------------------------------------// +//--------------------------------------------------------------------------------// +#define REGISTER_VIEW_TYPES \ + using namespace View; \ + \ + REGISTER_TYPE( VAlarmStatus ) \ + REGISTER_TYPE( VPowerOff ) \ + \ + REGISTER_TYPE( VTreatmentBloodFlow ) \ + REGISTER_TYPE( VTreatmentDialysateFlow ) \ + REGISTER_TYPE( VTreatmentUltrafiltration ) \ + REGISTER_TYPE( VTreatmentPressureOcclusion ) \ + REGISTER_TYPE( VTreatmentTime ) \ + REGISTER_TYPE( VTreatmentRanges ) \ + REGISTER_TYPE( VTreatmentSaline ) \ + REGISTER_TYPE( VHDOperationMode ) \ + REGISTER_TYPE( VHDTreatmentStates ) \ + \ + REGISTER_TYPE( VDGDrainPump ) \ + REGISTER_TYPE( VDGHeaters ) \ + REGISTER_TYPE( VDGLoadCellReadings ) \ + REGISTER_TYPE( VDGOperationMode ) \ + REGISTER_TYPE( VDGPressures ) \ + REGISTER_TYPE( VDGROPump ) \ + REGISTER_TYPE( VDGReservoir ) \ + REGISTER_TYPE( VDGTemperatures ) \ + REGISTER_TYPE( VDGValvesStates ) \ + \ + REGISTER_TYPE( VTreatmentAdjustmentDuration ) \ + REGISTER_TYPE( VTreatmentAdjustmentFlows ) \ + REGISTER_TYPE( VTreatmentAdjustmentUltrafiltrationState ) \ + REGISTER_TYPE( VTreatmentAdjustmentUltrafiltrationEdit ) \ + REGISTER_TYPE( VTreatmentAdjustmentUltrafiltrationConfirm ) \ + REGISTER_TYPE( VTreatmentCreate ) \ + REGISTER_TYPE( VBluetooth ) \ + REGISTER_TYPE( VPriming ) \ + REGISTER_TYPE( VTreatmentBegin ) \ + REGISTER_TYPE( VTreatmentEnd ) \ + REGISTER_TYPE( VTreatmentAdjustmentSaline ) + +//--------------------------------------------------------------------------------//