Index: sources/canbus/messageinterpreter.cpp =================================================================== diff -u -r1b8d8fdf90d57822dde33cf1428438847238b10b -r24dfaab03aaabc7b7714c5a4264dfbfca65aa41a --- sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision 1b8d8fdf90d57822dde33cf1428438847238b10b) +++ sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision 24dfaab03aaabc7b7714c5a4264dfbfca65aa41a) @@ -1,27 +1,32 @@ /*! * * 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. + * \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 messageinterpreter.cpp - * date 12/11/2019 - * author Behrouz NematiPour + * \file messageinterpreter.cpp + * \author (last) Behrouz NematiPour + * \date (last) 20-Aug-2020 + * \author (original) Behrouz NematiPour + * \date (original) 13-Dec-2019 * */ #include "messageinterpreter.h" // Qt +#include +// #include // Project #include "logger.h" #include "format.h" - using namespace Can; +using namespace Model; +#define DEBUG_RECEIVE_SIGNAL(vID, vMODEL) //qDebug() << vID << vMODEL; + /*! * \brief MessageInterpreter::MessageInterpreter * \details Constructor @@ -31,6 +36,138 @@ MessageInterpreter::MessageInterpreter(QObject *parent) : QObject(parent) { } /*! + * \brief MessageInterpreter::notify + * \details Checks and prepares the model with the Message Data + * Regarding the type of message logs the message received. + * Notifies observers by emitting the didActionReceive( < Data > ) signal + * \param vMessage - The Denali message + * \param vID - The Message ID to be checked against + * \param vModel - The appropriate model for the Message Data + * \param vData - A QVariant list of the Message Data which will be used for debugging if needed. + * \return true on successful check and prepare. + */ +template +bool MessageInterpreter::notify(const Message &vMessage, QVariantList &vData, Gui::GuiActionType vIdCheck) +{ + bool ok = false; + TModel tModel; + if ( ! isValidMessage(vMessage, vIdCheck) ) return ok; + ok = tModel.fromByteArray(vMessage.data); + tModel.toVariantList(vData); + // coco begin validated : Tested manually. This code will never go false + // because the isValidMessage is catching errors. + // only is checking here for developer safety if logic has changed. + if ( ! ok ) return false; + // coco end + emit didActionReceive(tModel.data()); + logReceivedMessage(tModel); + DEBUG_RECEIVE_SIGNAL(vIdCheck, typeid(TModel).name()) + return ok; +} + +/*! + * \brief MessageInterpreter::isType + * \details Checks if this is the message intended to be + * \param vMessage - The message + * \param vType - The type of the message to be checked against + * \return true on correct type + */ +bool MessageInterpreter::isType(const Message &vMessage, Gui::GuiActionType vType) const +{ + if ( vMessage.actionId != vType ) { + return false; + } + return true; +} + +/*! + * \brief MessageInterpreter::isPayloadLenValid + * \details Checks if the Data length has been defined for this type of message + * if not logs Undefined Data Length error + * if defined checks if the correct length of data is provided for this type of message. + * if not logs Incorrect Data Length error + * otherwise returns true + * \param vMessage - The message + * \param vType - The type of the message to be checked against + * \return true on correct data length for the type vType + */ +bool MessageInterpreter::isPayloadLenValid(const Message &vMessage, Gui::GuiActionType vType) const +{ + QString mActionIdHexString = Format::toHexString(vMessage.actionId); + if ( ! payloadLen.contains(vType) ) { + LOG_DEBUG(QString("Undefined data length for received Message with ID '%1'").arg(mActionIdHexString)); + return false; + } + if ( vMessage.data.length() < payloadLen[vType] ) { + LOG_DEBUG(QString("Incorrect data length for received Message with ID '%1'").arg(mActionIdHexString)); + return false; + } + return true; +} + +/*! + * \brief MessageInterpreter::logInvalidLength + * \details Logs invalid data length for the message type vActionId + * \param vActionId - Message Type + */ +void MessageInterpreter::logInvalidLength(const Gui::GuiActionType &vActionId) +{ + QString mActionIdHexString = Format::toHexString(vActionId); + LOG_DEBUG(QString("Incorrect data length for transmit message with ID '%1'") + .arg(mActionIdHexString)); +} + +/*! + * \brief MessageInterpreter::validateMessage + * \details Validate the message by checking its type and data + * \param vMessage - The message + * \param vType - The type of the message to be checked against + * \return true on valid massage + */ +bool MessageInterpreter::isValidMessage(const Message &vMessage, Gui::GuiActionType vType) const +{ + if ( ! isType (vMessage, vType) ) return false; + if ( ! isPayloadLenValid(vMessage, vType) ) return false; + return true; +} + +/*! + * \brief MessageInterpreter::printUnhandled + * \details Prints out the formatted string of the vMessage of type Message + * In case the Message ID of received CANBUS message + * is known to the interpreter but has not been handled/implemented. + * \param vMessage - The message contains Unhandled Message ID + */ +void MessageInterpreter::printUnhandled(const Message &vMessage) const +{ + if ( gDisableUnhandledReport ) return; + QString mActionIdHexString = Format::toHexString(vMessage.actionId, false, eLenMessageIDDigits); + QString logMessage = tr("Unhandled Message ID (HD)") + '\n' + + QString("%1 # %2 %3") + .arg(int(vMessage.can_id), 3, 16, QChar('0')) + .arg(mActionIdHexString) + .arg(QString(vMessage.data.toHex('.'))); + LOG_DEBUG(logMessage); +} + +/*! + * \brief MessageInterpreter::logReceived + * \details Regarding the type of message logs the message received. + * \param vModel - the MAbstract model type + */ +void MessageInterpreter::logReceivedMessage(const Model::MAbstract &vModel) +{ + switch (vModel.typeText()) { + case Model::MAbstract::Type_Enum::eDatum: + LOG_DATUM(vModel.toString()); + break; + case Model::MAbstract::Type_Enum::eEvent: + LOG_EVENT(vModel.toString()); + break; + } +} + +/*! * \brief MessageInterpreter::interpretMessage * \details This method will be called * to interpret messages from UI regarding vActionId. @@ -45,42 +182,121 @@ bool MessageInterpreter::interpretMessage(const Gui::GuiActionType &vActionId, const QVariantList &vData, QByteArray &vPayload) { bool ok = true; + QString mSenderID = "UI,"; + vPayload.clear(); - int l = vData.length(); - quint8 ix = 0; + int count = vData.length(); + + LOG_EVENT(QString("%0").arg(vActionId)); + switch (vActionId) { // notice we are in transmit mode - case Gui::GuiActionType::PowerOff: - ix = static_cast(Gui::GuiActionIndx::PowerOff_Response); - if (l >= ix + 1) { - quint8 tmp = vData[ix].toUInt(); - vPayload += tmp; - } else { - QString mActionIdHexString = Format::toHexString(vActionId); - LOG_ERROR(tr("Incorrect data for Message ID (UI) '%1'").arg(mActionIdHexString)); - ok = false; - } - break; - case Gui::GuiActionType::KeepAlive: - // Nothing needs to be done. - // KeepAlive has No data. - // Mentioned in the switch/case to be registered as a valid message. - break; + case Gui::GuiActionType::ID_Acknow: // len: 0, can have zero len + break; // No data, Just registered - case Gui::GuiActionType::Acknow: - // Nothing needs to be done. - // Acknow has No data. - // Mentioned in the switch/case to be registered as a valid message. - break; + case Gui::GuiActionType::ID_KeepAlive: // len: 255, can have any len + { + if ( count ) { // this message has a variable length + vPayload = Format::fromVariant(vData[0]); + } + LOG_EVENT(mSenderID + QString("CheckIn")); + } break; - case Gui::GuiActionType::String: - vPayload = Format::fromVariant(vData[0]); - break; + case Gui::GuiActionType::ID_RawData: // len: 255, can have any len + { + if ( count ) { // this message has a variable length + vPayload = Format::fromVariant(vData[0]); + } + LOG_EVENT(mSenderID + QString("RawData")); - default: - QString mActionIdHexString = Format::toHexString(vActionId); - LOG_ERROR(tr("Unknown Message ID (UI) '%1'").arg(mActionIdHexString)); - ok = false; - break; + } break; + + case Gui::GuiActionType::ID_PowerOff: + { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload += Format::fromVariant(vData); + LOG_EVENT(AdjustPowerOffRequestData::toString(vData)); + + } break; + + case Gui::GuiActionType::ID_AdjustBloodDialysateReq: + { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AdjustBloodDialysateRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_AdjustDurationReq: + { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AdjustDurationRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_AdjustUltrafiltrationStateReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AdjustUltrafiltrationStateRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_AdjustUltrafiltrationEditReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AdjustUltrafiltrationEditRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_AdjustUltrafiltrationConfirmReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AdjustUltrafiltrationConfirmRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_AdjustSalineReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AdjustSalineRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_AlarmSilenceReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AlarmSilenceRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_AlarmUserAckReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AlarmAcknowledgeRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_StartTreatmentReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(StartTreatmentRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_ConfirmTreatmentReq: { + if ( count != 0 ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(ConfirmTreatmentRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_EndTreatmentReq: { + if ( count != 0 ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(EndTreatmentRequestData::toString(vData)); + } break; + + case Gui::GuiActionType::ID_CreateTreatmentReq: { + if ( ! count ) { logInvalidLength(vActionId); return false; } + vPayload = Format::fromVariant(vData); + LOG_EVENT(AdjustTreatmentParametersRequestData::toString(vData)); + } break; + + default: { + QString mActionIdHexString = Format::toHexString(vActionId); + LOG_DEBUG(mSenderID + tr("Unknown transmit Message with ID '%1'").arg(mActionIdHexString)); + ok = false; + } break; } return ok; } @@ -102,38 +318,23 @@ { bool ok = false; switch (vMessage.can_id) { - case eChlid_HD_UI: + case eChlid_HD_UI : case eChlid_HD_Alarm: - case eChlid_HD_Sync: - ok = interpretMessage_HD(vMessage, vData); - break; - case eChlid_DG_UI: - //case eChlid_DG_Alarm: - //case eChlid_DG_Sync: - ok = interpretMessage_DG(vMessage, vData); - break; + case eChlid_HD_Sync : ok = interpretMessage_HD(vMessage, vData); break; + + case eChlid_DG_HD : + + case eChlid_DG_UI : + // case eChlid_DG_Alarm: // commented out for now. Currently there is no message in this category. + case eChlid_DG_Sync : ok = interpretMessage_DG(vMessage, vData); break; + default: break; } return ok; } /*! - * \brief MessageInterpreter::printUnhandled - * \details Prints out the formatted string of the vMessage of type Message - * In case the Message ID of received CANBUS message - * is known to the interpreter but has not been handled/implemented. - * \param vMessage - The message contains Unhandled Message ID - */ -void MessageInterpreter::printUnhandled(const Message &vMessage) -{ - QString mActionIdHexString = Format::toHexString(vMessage.actionId, false, eLenMessageIDDigits); - qDebug() << "WARNG :" << tr("Unhandled Message ID (HD)"); - qDebug().noquote() << QString(mActionIdHexString + " " + vMessage.data.toHex('.')).toLatin1(); - qDebug() << ""; -} - -/*! * \brief MessageInterpreter::interpretMessage_HD * \details This method will be called * for received messages from HD to interpret the vMessage of type Message @@ -148,47 +349,55 @@ */ bool MessageInterpreter::interpretMessage_HD(const Message &vMessage, QVariantList &vData) { - bool ok = true; + bool ok = false; vData.clear(); - switch (vMessage.actionId) { // notice we are in receive mode - case Gui::GuiActionType::PowerOff: { - quint8 mShowHide; - ok = getPowerOffData(vMessage, mShowHide); - if (ok) { - vData += mShowHide; - } - LOG_DATUM(QString("Power Off (%1)").arg(mShowHide)); - break; - } - case Gui::GuiActionType::Acknow: - ok = true; - break; + // ----- Debug + case Gui::GuiActionType::ID_CANBusFaultCount : ok = canbusFaultCountData (vMessage, vData); break; // TODO : implement notify<>() - case Gui::GuiActionType::BloodFlow: - ok = bloodFlowData (vMessage, vData); - break; + // ----- Datum + case Gui::GuiActionType::ID_TreatmentTime : ok = notify(vMessage, vData, Gui::GuiActionType::ID_TreatmentTime ); break; + case Gui::GuiActionType::ID_BloodFlow : ok = notify(vMessage, vData, Gui::GuiActionType::ID_BloodFlow ); break; + case Gui::GuiActionType::ID_DialysateInletFlow : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DialysateInletFlow ); break; + case Gui::GuiActionType::ID_DialysateOutletFlow : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DialysateOutletFlow ); break; + case Gui::GuiActionType::ID_TreatmentRanges : ok = notify(vMessage, vData, Gui::GuiActionType::ID_TreatmentRanges ); break; + case Gui::GuiActionType::ID_PressureOcclusion : ok = notify(vMessage, vData, Gui::GuiActionType::ID_PressureOcclusion ); break; + case Gui::GuiActionType::ID_TreatmentStates : ok = notify(vMessage, vData, Gui::GuiActionType::ID_TreatmentStates ); break; + case Gui::GuiActionType::ID_PrimingData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_PrimingData ); break; + case Gui::GuiActionType::ID_Saline : ok = notify(vMessage, vData, Gui::GuiActionType::ID_Saline ); break; - case Gui::GuiActionType::DialysateFlow: - ok = dialysateFlowData (vMessage, vData); - break; + // ----- Events + case Gui::GuiActionType::ID_HDOperationModeData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_HDOperationModeData ); break; + case Gui::GuiActionType::ID_HDDebugText : ok = notify(vMessage, vData, Gui::GuiActionType::ID_HDDebugText ); break; - case Gui::GuiActionType::AlarmStatus: - ok = alarmStatus (vMessage, vData); - break; + case Gui::GuiActionType::ID_Acknow : ok = true; break; // TODO : implement notify<>() + case Gui::GuiActionType::ID_PowerOff : ok = notify(vMessage, vData, Gui::GuiActionType::ID_PowerOff ); break; + case Gui::GuiActionType::ID_ShuttingDown : ok = true; LOG_EVENT("HD,ShuttingDown"); break; // TODO : implement notify<>() + case Gui::GuiActionType::ID_AlarmStatus : ok = alarmStatus (vMessage, vData); break; // TODO : implement notify<>() + case Gui::GuiActionType::ID_AlarmTriggered : ok = alarmTriggered (vMessage, vData); break; // TODO : implement notify<>() + case Gui::GuiActionType::ID_AlarmCleared : ok = alarmCleared (vMessage, vData); break; // TODO : implement notify<>() + case Gui::GuiActionType::ID_CreateTreatmentRsp : ok = notify(vMessage, vData, Gui::GuiActionType::ID_CreateTreatmentRsp ); break; - case Gui::GuiActionType::AlarmTriggered: - printUnhandled (vMessage); - break; + // Adjustment Response Messages + case Gui::GuiActionType::ID_AdjustDurationRsp : ok = notify(vMessage, vData, Gui::GuiActionType::ID_AdjustDurationRsp ); break; + case Gui::GuiActionType::ID_AdjustBloodDialysateRsp : ok = notify(vMessage, vData, Gui::GuiActionType::ID_AdjustBloodDialysateRsp); break; + case Gui::GuiActionType::ID_AdjustSalineRsp : ok = notify(vMessage, vData, Gui::GuiActionType::ID_AdjustSalineRsp ); break; - case Gui::GuiActionType::AlarmCleared: - printUnhandled (vMessage); - break; + // ok = notify(vMessage, vData, Gui::GuiActionType::ID_AdjustUltrafiltrationStateReq); break; + // this message has been inherited from MAbstract and should use notify but since the response message is not standard can't use notify yet. + // when received gets payload len error and can't be interpreted. + case Gui::GuiActionType::ID_AdjustUltrafiltrationStateReq : ok = adjustUltrafiltrationState (vMessage, vData); break; // TODO : implement notify<>() + case Gui::GuiActionType::ID_AdjustUltrafiltrationEditRsp : ok = adjustUltrafiltrationEdit (vMessage, vData); break; // TODO : implement notify<>() + case Gui::GuiActionType::ID_AdjustUltrafiltrationConfirmRsp : ok = adjustUltrafiltrationConfirm (vMessage, vData); break; // TODO : implement notify<>() - default: - printUnhandled (vMessage); - break; + case Gui::GuiActionType::ID_StartTreatmentRsp : ok = notify (vMessage, vData, Gui::GuiActionType::ID_StartTreatmentRsp ); break; + case Gui::GuiActionType::ID_EndTreatmentRsp : ok = notify (vMessage, vData, Gui::GuiActionType::ID_EndTreatmentRsp ); break; + + // unhandles messages: these will only be logged as received message + // there has nothing been defined for these messages. + default : printUnhandled (vMessage ); break; } + return ok; } @@ -207,299 +416,215 @@ */ bool MessageInterpreter::interpretMessage_DG(const Message &vMessage, QVariantList &vData) { - Q_UNUSED(vMessage ); - Q_UNUSED(vData ); - // No data have been interpreted from DG yet - return false; + bool ok = false; + vData.clear(); + switch (vMessage.actionId) { // notice we are in receive mode + case Gui::GuiActionType::ID_DGCheckIn: // TODO : implement notify<>() + ok = true; + LOG_EVENT(QString("DG,CheckIn," + QVariant(vData).toStringList().join(','))); + break; + + case Gui::GuiActionType::ID_DGROPumpData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGROPumpData ); break; + case Gui::GuiActionType::ID_DGPressuresData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGPressuresData ); break; + case Gui::GuiActionType::ID_DGDrainPumpData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGDrainPumpData ); break; + case Gui::GuiActionType::ID_DGOperationModeData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGOperationModeData ); break; + case Gui::GuiActionType::ID_DGReservoirData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGReservoirData ); break; + case Gui::GuiActionType::ID_DGValvesStatesData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGValvesStatesData ); break; + case Gui::GuiActionType::ID_DGHeatersData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGHeatersData ); break; + case Gui::GuiActionType::ID_DGLoadCellReadingsData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGLoadCellReadingsData); break; + case Gui::GuiActionType::ID_DGTemperaturesData : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGTemperaturesData ); break; + case Gui::GuiActionType::ID_DGDebugText : ok = notify(vMessage, vData, Gui::GuiActionType::ID_DGDebugText ); break; + + // unhandled messages: these will only be logged as received message + // there has nothing been defined for these messages. + default: + printUnhandled (vMessage); + break; + + } + + return ok; } +// ---------- ---------- Message handlers ---------- ---------- // + +// ---------- ---------- ---------- ---------- ---------- Debug ---------- ---------- ---------- ---------- ---------- // /*! - * \brief MessageInterpreter::getPowerOffData - * \details This is the method which interprets the PowerOff message data - * in vMessage of type Message. - * to its elements of data. - * \param vMessage - The vMessage of type Message which contains all the data, - * require to be interpreted. - * \param vShowHide - The return value of extracted fro - * \return true if the data can be extracted as defined for PowerOff Message ID + * \brief MessageInterpreter::canbusFaultCountData + * \details This method interprets Fault Count message data + * in vMessage of type Message. This message is only used for debugging purposes. + * \param vMessage - The vMessage of type Message which contains all the data, + * require to be interpreted. + * \param vData - Fault Count data + * \return true if the data can be extracted as defined for Fault Count Message ID */ -bool MessageInterpreter::getPowerOffData(const Message &vMessage, quint8 &vShowHide) +bool MessageInterpreter::canbusFaultCountData(const Message &vMessage, QVariantList &vData) { - bool ok = true; - int l = vMessage.data.length(); - quint8 ix = static_cast(Gui::GuiActionIndx::PowerOff_ShowHide); - if (l >= ix + 1) { - quint8 tmp = vMessage.data[ix]; - vShowHide = tmp; - } else { - QString mActionIdHexString = Format::toHexString(vMessage.actionId); - LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); - ok = false; + // TODO : review other methods + bool ok = false; + if ( ! isValidMessage(vMessage, Gui::GuiActionType::ID_CANBusFaultCount) ) return ok; + + QVariantList mData; + int index = 0; + Types::U32 mCanBUSFaultCount; + ok = GetValue(vMessage.data, index, mCanBUSFaultCount); + // coco begin validated : developer safety if for any reason length of CanBUSFaultCount set to 0 + if (ok) { + // coco end + vData += mCanBUSFaultCount.value; } return ok; } +// ---------- ---------- ---------- ---------- ---------- Events ---------- ---------- ---------- ---------- ---------- // +// ---------- ---------- ---------- ---------- ---------- - HD ---------- ---------- ---------- ---------- ---------- // + /*! - * \brief MessageInterpreter::getBloodFlowData - * \details This is the method which interprets the Blood Flow message data in vMessage of type Message - * to its elements of data. - * \param vMessage - The vMessage of type Message which contains all the data, require to be interpreted. - * \param vFlowSetPoint - Flow Set Point value of type signed int extracted out - * \param vMeasuredFlow - Measured Flow value of type float extracted out - * \param vRotorSpeed - Rotor Speed value of type float extracted out - * \param vMotorSpeed - Motor Speed value of type float extracted out - * \param vMotorCtlSpeed - Motor Controller Speed value of type float extracted out - * \param vMotorCtlCurrent - Motor Controller Current value of type float extracted out - * \param vPWMDtCycle - PWM Duty Cycle in % value of type float extracted out - * \return true if the message can be successfully converted to the Blood Flow data elements. + * \brief MessageInterpreter::alarmStatus + * \details This method interprets Alarm Status message data + * in vMessage of type Message. + * \param vMessage - The vMessage of type Message which contains all the data, + * require to be interpreted. + * \param vData - Alarm Status data + * \return true if the data can be extracted as defined for Alarm Status Message ID */ -bool MessageInterpreter::getBloodFlowData( - const Message &vMessage , - Types::S32 &vFlowSetPoint , - Types::F32 &vMeasuredFlow , Types::F32 &vRotorSpeed , Types::F32 &vMotorSpeed, - Types::F32 &vMotorCtlSpeed , Types::F32 &vMotorCtlCurrent , Types::F32 &vPWMDtCycle) -{ - if ( vMessage.actionId != Gui::GuiActionType::BloodFlow ) { - return false; - } - if ( vMessage.data.length() < payloadLen[Gui::GuiActionType::BloodFlow] ) { - QString mActionIdHexString = Format::toHexString(vMessage.actionId); - LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); - return false; - } +bool MessageInterpreter::alarmStatus(const Message &vMessage, QVariantList &vData) { + // TODO : review other methods + bool ok = false; + if ( ! isValidMessage(vMessage, Gui::GuiActionType::ID_AlarmStatus) ) return ok; - int index = 0; // message data start position - Types::getValue<>(vMessage.data, index, vFlowSetPoint ); - Types::getValue<>(vMessage.data, index, vMeasuredFlow ); - Types::getValue<>(vMessage.data, index, vRotorSpeed ); - Types::getValue<>(vMessage.data, index, vMotorSpeed ); - Types::getValue<>(vMessage.data, index, vMotorCtlSpeed ); - Types::getValue<>(vMessage.data, index, vMotorCtlCurrent); - Types::getValue<>(vMessage.data, index, vPWMDtCycle ); + Model::MAlarmStatus mData; + ok = mData.fromByteArray(vMessage.data); + LOG_EVENT("HD," + mData.toString()); - return true; + mData.toVariantList(vData); + emit didActionReceive(mData.data()); + + return ok; } /*! - * \brief MessageInterpreter::bloodFlowData - * \details Used the getBloodFlowData method and converts each parameter - * in vData of type QVaranitList, to be used in the GUI - * Also logs the data - * \param vMessage - The message - * \param vData - the output data - * \return return value of the method getBloodFlowData + * \brief MessageInterpreter::alarmTriggered + * \details This method interprets Alarm Triggered message data + * in vMessage of type Message. + * \param vMessage - The vMessage of type Message which contains all the data, + * require to be interpreted. + * \param vData - Alarm Triggered data + * \return true if the data can be extracted as defined for Alarm Triggered Message ID */ -bool MessageInterpreter::bloodFlowData(const Message &vMessage, QVariantList &vData) +bool MessageInterpreter::alarmTriggered(const Message &vMessage, QVariantList &vData) { - bool ok; - Types::S32 mFlowSetPoint ; - Types::F32 mMeasuredFlow ; - Types::F32 mRotorSpeed ; - Types::F32 mMotorSpeed ; - Types::F32 mMotorCtlSpeed ; - Types::F32 mMotorCtlCurrent ; - Types::F32 mPWMDtCycle ; - ok = getBloodFlowData(vMessage , - mFlowSetPoint , - mMeasuredFlow , - mRotorSpeed , - mMotorSpeed , - mMotorCtlSpeed , - mMotorCtlCurrent , - mPWMDtCycle ); - LOG_DATUM(QString("Blood Flow(%1, %2, %3, %4, %5, %6, %7)") - .arg(mFlowSetPoint .value) - .arg(mMeasuredFlow .value) - .arg(mRotorSpeed .value) - .arg(mMotorSpeed .value) - .arg(mMotorCtlSpeed .value) - .arg(mMotorCtlCurrent .value) - .arg(mPWMDtCycle .value) - ); - if (ok) { - vData += mFlowSetPoint .value; - vData += mMeasuredFlow .value; - vData += mRotorSpeed .value; - vData += mMotorSpeed .value; - vData += mMotorCtlSpeed .value; - vData += mMotorCtlCurrent.value; - vData += mPWMDtCycle .value; - } + // TODO : review other methods + bool ok = false; + if ( ! isValidMessage(vMessage, Gui::GuiActionType::ID_AlarmTriggered) ) return ok; + + Model::MAlarmTriggered mData; + ok = mData.fromByteArray(vMessage.data); + LOG_EVENT("HD," + mData.toString()); + + mData.toVariantList(vData); + emit didActionReceive(mData.data()); + return ok; } /*! - * \brief MessageInterpreter::getDialysateFlowData - * \details This is the method which interprets the Dialysate Flow message data in vMessage of type Message - * to its elements of data. - * \param vMessage - The vMessage of type Message which contains all the data, require to be interpreted. - * \param vFlowSetPoint - Flow Set Point value of type signed int extracted out - * \param vMeasuredFlow - Measured Flow value of type float extracted out - * \param vRotorSpeed - Rotor Speed value of type float extracted out - * \param vMotorSpeed - Motor Speed value of type float extracted out - * \param vMotorCtlSpeed - Motor Controller Speed value of type float extracted out - * \param vMotorCtlCurrent - Motor Controller Current value of type float extracted out - * \param vPWMDtCycle - PWM Duty Cycle in % value of type float extracted out - * \return true if the message can be successfully converted to the Blood Flow data elements. + * \brief MessageInterpreter::alarmCleared + * \details This method interprets Alarm Cleared message data + * in vMessage of type Message. + * \param vMessage - The vMessage of type Message which contains all the data, + * require to be interpreted. + * \param vData - Alarm Cleared data + * \return true if the data can be extracted as defined for Alarm Cleared Message ID */ -bool MessageInterpreter::getDialysateFlowData( - const Message &vMessage , - Types::S32 &vFlowSetPoint , - Types::F32 &vMeasuredFlow , Types::F32 &vRotorSpeed , Types::F32 &vMotorSpeed, - Types::F32 &vMotorCtlSpeed , Types::F32 &vMotorCtlCurrent , Types::F32 &vPWMDtCycle) - +bool MessageInterpreter::alarmCleared(const Message &vMessage, QVariantList &vData) { - if ( vMessage.actionId != Gui::GuiActionType::DialysateFlow ) { - return false; - } - if ( vMessage.data.length() < payloadLen[Gui::GuiActionType::DialysateFlow] ) { - QString mActionIdHexString = Format::toHexString(vMessage.actionId); - LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); - return false; - } + // TODO : review other methods + bool ok = false; + if ( ! isValidMessage(vMessage, Gui::GuiActionType::ID_AlarmCleared) ) return ok; - int index = 0; // message data start position - Types::getValue<>(vMessage.data, index, vFlowSetPoint ); - Types::getValue<>(vMessage.data, index, vMeasuredFlow ); - Types::getValue<>(vMessage.data, index, vRotorSpeed ); - Types::getValue<>(vMessage.data, index, vMotorSpeed ); - Types::getValue<>(vMessage.data, index, vMotorCtlSpeed ); - Types::getValue<>(vMessage.data, index, vMotorCtlCurrent); - Types::getValue<>(vMessage.data, index, vPWMDtCycle ); + Model::MAlarmCleared mData; + ok = mData.fromByteArray(vMessage.data); + LOG_EVENT("HD," + mData.toString()); - return true; + mData.toVariantList(vData); + emit didActionReceive(mData.data()); + + return ok; } +// ---------- ---------- ---------- ---------- ---------- Adjustments ---------- ---------- ---------- ---------- ---------- // + /*! - * \brief MessageInterpreter::dialysateFlowData - * \details Used the getDialysateFlowData method and converts each parameter - * in vData of type QVaranitList, to be used in the GUI - * Also logs the data - * \param vMessage - The message - * \param vData - the output data - * \return return value of the method getDialysateFlowData + * \brief MessageInterpreter::ultrafiltrationState + * \details This method interprets Treatment Ultrafiltration State Adjustment Response message data + * in vMessage of type Message. + * \param vMessage - The vMessage of type Message which contains all the data, + * require to be interpreted. + * \param vData - Treatment Ultrafiltration State Adjustment Response data + * \return true if the data can be extracted as defined for Treatment Ultrafiltration State Adjustment Response Message ID */ -bool MessageInterpreter::dialysateFlowData(const Message &vMessage, QVariantList &vData) +bool MessageInterpreter::adjustUltrafiltrationState(const Message &vMessage, QVariantList &vData) { - bool ok; - Types::S32 mFlowSetPoint ; - Types::F32 mMeasuredFlow ; - Types::F32 mRotorSpeed ; - Types::F32 mMotorSpeed ; - Types::F32 mMotorCtlSpeed ; - Types::F32 mMotorCtlCurrent ; - Types::F32 mPWMDtCycle ; - ok = getBloodFlowData(vMessage , - mFlowSetPoint , - mMeasuredFlow , - mRotorSpeed , - mMotorSpeed , - mMotorCtlSpeed , - mMotorCtlCurrent , - mPWMDtCycle ); - LOG_DATUM(QString("Dialysate Flow(%1, %2, %3, %4, %5, %6, %7)") - .arg(mFlowSetPoint .value) - .arg(mMeasuredFlow .value) - .arg(mRotorSpeed .value) - .arg(mMotorSpeed .value) - .arg(mMotorCtlSpeed .value) - .arg(mMotorCtlCurrent .value) - .arg(mPWMDtCycle .value) - ); - if (ok) { - vData += mFlowSetPoint .value; - vData += mMeasuredFlow .value; - vData += mRotorSpeed .value; - vData += mMotorSpeed .value; - vData += mMotorCtlSpeed .value; - vData += mMotorCtlCurrent.value; - vData += mPWMDtCycle .value; - } + bool ok = false; + // TODO : In HD the Ultrafiltration State change shall have the rejection reason like other responses. + if ( ! isType (vMessage, Gui::GuiActionType::ID_AdjustUltrafiltrationStateReq) ) return ok; + if ( ! isPayloadLenValid(vMessage, Gui::GuiActionType::ID_AcknowGeneric ) ) return ok; // This is an exception It has to be changed. + + Model::MAdjustUltrafiltrationStateResponse mData; + ok = mData.fromByteArray(vMessage.data); + LOG_EVENT(mData.toString()); + + mData.toVariantList(vData); + emit didActionReceive(mData.data()); + return ok; } /*! - * \brief MessageInterpreter::getAlarmStatus - * \details This method interprets AlarmStatus message data + * \brief MessageInterpreter::adjustUltrafiltrationEditData + * \details This method interprets Treatment Ultrafiltration Volume Adjustment Response message data * in vMessage of type Message. - * \param vMessage - The vMessage of type Message which contains all the data, - * require to be interpreted. - * \param vState - Alarm Priority value of type unsigned int as 4 bytes extracted out - * \param vTop - Top value of type unsigned int as 4 bytes extracted out - * \param vMuteTimeout - MuteTimeout value of type unsigned int as 4 bytes extracted out - * \param vEscalatesIn - EscalatesIn value of type unsigned int as 4 bytes extracted out - * \param vFlags - Flags value of type unsigned int as 1 byte extracted out - * \return true if the data can be extracted as defined for PowerOff Message ID + * \param vMessage - The vMessage of type Message which contains all the data, + * require to be interpreted. + * \param vData - Treatment Ultrafiltration Volume Adjustment Response data + * \return true if the data can be extracted as defined for Treatment Ultrafiltration Volume Adjustment Response Message ID */ -bool MessageInterpreter::getAlarmStatus(const Message &vMessage, - Types::U32 &vState , Types::U32 &vTop , - Types::U32 &vMuteTimeout, Types::U32 &vEscalatesIn, - Types::Flags &vFlags) +bool MessageInterpreter::adjustUltrafiltrationEdit(const Message &vMessage, QVariantList &vData) { - if ( vMessage.actionId != Gui::GuiActionType::AlarmStatus ) { - return false; - } - if ( vMessage.data.length() < payloadLen[Gui::GuiActionType::AlarmStatus] ) { - QString mActionIdHexString = Format::toHexString(vMessage.actionId); - LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); - return false; - } + bool ok = false; + if ( ! isValidMessage(vMessage, Gui::GuiActionType::ID_AdjustUltrafiltrationEditRsp) ) return ok; - int index = 0; // message data start position - Types::getValue<>(vMessage.data, index, vState ); - Types::getValue<>(vMessage.data, index, vTop ); - Types::getValue<>(vMessage.data, index, vMuteTimeout ); - Types::getValue<>(vMessage.data, index, vEscalatesIn ); - Types::getBits (vMessage.data, index, vFlags, static_cast(Gui::GuiActionIndx::AlarmStatus_Flag_Bits_Length)); - return true; + Model::MAdjustUltrafiltrationEditResponse mData; + ok = mData.fromByteArray(vMessage.data); + LOG_EVENT("HD," + mData.toString()); + + mData.toVariantList(vData); + emit didActionReceive(mData.data()); + + return ok; } /*! - * \brief MessageInterpreter::alarmStatus - * \details Used the getAlarmStatus method and converts each parameter - * in vData of type QVaranitList, to be used in the GUI - * Also logs the data - * \param vMessage - The message - * \param vData - the output data - * \return return value of the method getAlarmStatus + * \brief MessageInterpreter::adjustUltrafiltrationConfirmData + * \details This method interprets Treatment Ultrafiltration Volume Adjustment Confirm Response message data + * in vMessage of type Message. + * \param vMessage - The vMessage of type Message which contains all the data, + * require to be interpreted. + * \param vData - Treatment Ultrafiltration Volume Adjustment Confirm Response data + * \return true if the data can be extracted as defined for Treatment Ultrafiltration Volume Adjustment Confirm Response Message ID */ -bool MessageInterpreter::alarmStatus(const Message &vMessage, QVariantList &vData) +bool MessageInterpreter::adjustUltrafiltrationConfirm(const Message &vMessage, QVariantList &vData) { - bool ok; - Types::U32 mState ; - Types::U32 mTop ; - Types::U32 mMuteTimeout ; - Types::U32 mEscalatesIn ; - Types::Flags mFlags ; - ok = getAlarmStatus(vMessage , - mState , - mTop , - mMuteTimeout , - mEscalatesIn , - mFlags ); - LOG_DATUM(QString("Alarm Status(%1, %2, %3, %4, %5)") - .arg(mState .value ) - .arg(mTop .value ) - .arg(mMuteTimeout .value ) - .arg(mEscalatesIn .value ) - .arg(mFlags .toString()) - ); - if (ok) { - vData += mState .value ; - vData += mTop .value ; - vData += mMuteTimeout .value ; - vData += mEscalatesIn .value ; - for (int i = 0; i < mFlags.count(); i++) { - vData += mFlags.at(i); - } - } + bool ok = false; + if ( ! isValidMessage(vMessage, Gui::GuiActionType::ID_AdjustUltrafiltrationConfirmRsp) ) return ok; - // --- an example of unit test --- // - // Types::Flags flag; - // int i = 0; - // QByteArray ba; - // ba += 0x83; ba += 0xf8; ba += 0x28; ba += 0xa1; - // Types::getBits(ba, i, flag, 32); - // qDebug() << '@' << flag << flag.toString() << ba; + Model::MAdjustUltrafiltrationConfirmResponse mData; + ok = mData.fromByteArray(vMessage.data); + LOG_EVENT("HD," + mData.toString()); + + mData.toVariantList(vData); + emit didActionReceive(mData.data()); + return ok; }