Index: sources/canbus/messageinterpreter.cpp =================================================================== diff -u -r8c5f54b53a19dd29a3b9731d8ec1bf3d1ba3be62 -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d --- sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision 8c5f54b53a19dd29a3b9731d8ec1bf3d1ba3be62) +++ sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) @@ -16,8 +16,9 @@ // Qt // Project -#include "logger.h" +#include "types.h" #include "format.h" +#include "logger.h" using namespace Can; @@ -106,6 +107,21 @@ } /*! + * \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 @@ -135,50 +151,28 @@ break; } - case GuiActionType::BloodFlow: { - 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; - } + case GuiActionType::BloodFlow: + ok = bloodFlowData (vMessage, vData); break; - } + case GuiActionType::DialysateFlow: + ok = dialysateFlowData (vMessage, vData); + break; + case GuiActionType::AlarmStatus: - printUnhandled(vMessage); + ok = alarmStatus (vMessage, vData); break; case GuiActionType::AlarmTriggered: - printUnhandled(vMessage); + printUnhandled (vMessage); break; case GuiActionType::AlarmCleared: - printUnhandled(vMessage); + printUnhandled (vMessage); break; default: - printUnhandled(vMessage); + printUnhandled (vMessage); break; } return ok; @@ -207,11 +201,37 @@ } /*! + * \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 + */ +bool MessageInterpreter::getPowerOffData(const Message &vMessage, quint8 &vShowHide) +{ + bool ok = true; + int l = vMessage.data.length(); + quint8 ix = static_cast(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; + } + return ok; +} + +/*! * \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 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 @@ -222,9 +242,9 @@ */ 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) + Types::S32 &vFlowSetPoint , + Types::F32 &vMeasuredFlow , Types::F32 &vRotorSpeed , Types::F32 &vMotorSpeed, + Types::F32 &vMotorCtlSpeed , Types::F32 &vMotorCtlCurrent , Types::F32 &vPWMDtCycle) { if ( vMessage.actionId != GuiActionType::BloodFlow ) { return false; @@ -234,106 +254,212 @@ LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); return false; } - int i = 0; - int p = 0; - int j = 0; - p += 4; - j = 0; - while (i < p) { - vFlowSetPoint.bytes[j] = vMessage.data[i]; - j++; - i++; - } + 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 ); - p += 4; - j = 0; - while (i < p) { - vMeasuredFlow.bytes[j] = vMessage.data[i]; - j++; - i++; - } + return true; +} - p += 4; - j = 0; - while (i < p) { - vRotorSpeed.bytes[j] = vMessage.data[i]; - j++; - i++; +bool MessageInterpreter::bloodFlowData(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; } + return ok; +} - p += 4; - j = 0; - while (i < p) { - vMotorSpeed.bytes[j] = vMessage.data[i]; - j++; - i++; - } +/*! + * \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. + */ +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) - p += 4; - j = 0; - while (i < p) { - vMotorCtlSpeed.bytes[j] = vMessage.data[i]; - j++; - i++; +{ + if ( vMessage.actionId != GuiActionType::DialysateFlow ) { + return false; } - - p += 4; - j = 0; - while (i < p) { - vMotorCtlCurrent.bytes[j] = vMessage.data[i]; - j++; - i++; + if ( vMessage.data.length() < payloadLen[GuiActionType::DialysateFlow] ) { + QString mActionIdHexString = Format::toHexString(vMessage.actionId); + LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); + return false; } - p += 4; - j = 0; - while (i < p) { - vPWMDtCycle.bytes[j] = vMessage.data[i]; - j++; - i++; - } + 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 ); return true; } +bool MessageInterpreter::dialysateFlowData(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; + } + return ok; +} + /*! - * \brief MessageInterpreter::getPowerOffData - * \details This is the method which interprets the PowerOff message data + * \brief MessageInterpreter::getAlarmStatus + * \details This method interprets AlarmStatus 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 + * \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 vEscalateTo - EscalateTo 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 */ -bool MessageInterpreter::getPowerOffData(const Message &vMessage, quint8 &vShowHide) +bool MessageInterpreter::getAlarmStatus(const Message &vMessage, + Types::U32 &vState , Types::U32 &vTop , + Types::U32 &vMuteTimeout, Types::U32 &vEscalatesIn, + Types::Flags &vFlags) { - bool ok = true; - int l = vMessage.data.length(); - quint8 ix = static_cast(GuiActionIndx::PowerOff_ShowHide); - if (l >= ix + 1) { - quint8 tmp = vMessage.data[ix]; - vShowHide = tmp; - } else { + if ( vMessage.actionId != GuiActionType::AlarmStatus ) { + return false; + } + if ( vMessage.data.length() < payloadLen[GuiActionType::AlarmStatus] ) { QString mActionIdHexString = Format::toHexString(vMessage.actionId); LOG_ERROR(tr("Incorrect data for Message ID (HD) '%1'").arg(mActionIdHexString)); - ok = false; + return false; } - 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 , 16); + 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) +bool MessageInterpreter::alarmStatus(const Message &vMessage, QVariantList &vData) { - QString mActionIdHexString = Format::toHexString(vMessage.actionId, false, eLenMessageIDDigits); - qDebug() << "WARNG :" << tr("Unhandled Message ID (HD)"); - qDebug().noquote() << QString(mActionIdHexString + " " + vMessage.data.toHex('.')).toLatin1(); - qDebug() << ""; + 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); + } + } + + // --- 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; + return ok; }