Index: sources/drydemo/StateControllerTreatment.cpp =================================================================== diff -u -r4533fba9bf69d25de21536b849b5d9cb09d959ee -r8aa65ae1bbef5f6121783026efeeb99114c14414 --- sources/drydemo/StateControllerTreatment.cpp (.../StateControllerTreatment.cpp) (revision 4533fba9bf69d25de21536b849b5d9cb09d959ee) +++ sources/drydemo/StateControllerTreatment.cpp (.../StateControllerTreatment.cpp) (revision 8aa65ae1bbef5f6121783026efeeb99114c14414) @@ -20,7 +20,6 @@ void StateController::handleBloodPrimeBroadcastData(const float accumulatedVolML, const quint32 primeTimeOutS, const quint32 pauseCountDownS, const Broadcast_Type BCType) { static quint32 broadcastCounter = 0; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } // Broadcast @@ -90,17 +89,14 @@ _treatmentParams.dialysateFlowRateMLPM = DEF_TX_PARAM_DIAL_FLOW_RATE_MLPM; _treatmentParams.treatmentDurationMin = DEF_TX_PARAM_PRESCRIBED_DUR_MIN; _treatmentParams.dialysateTemperatureC = DEF_TX_PARAM_DIA_TEMPERATURE_C; - _treatmentParams.treatmentDurationMin = DEF_TX_PARAM_PRESCRIBED_DUR_MIN; _treatmentParams.fluidBlousVolumeML = DEF_TX_PARAM_SALINE_BOLUS_VOL_ML; _treatmentParams.ufVolumeL = DEF_TX_PARAM_UF_VOLUME_L; } void StateController::initializeTreatmentTimeAndUltrafiltration() { - // The default elapsed time is 2 hours becasue the default tx duration is 4 hours. If the prescribed is less than 2 hours, 0 the elapsed - if ((_treatmentParams.treatmentDurationMin * SECONDS_PER_MINUTE) < DEF_TX_ELAPSED_TIME_S){ _treatmentStatus.treatmentElapsedTimeMS = 0; } + if (_treatmentStatus.hasTxParamsBeenInitialized) { _treatmentStatus.treatmentElapsedTimeMS = 0; } _treatmentStatus.presUFRateMLPM = (_treatmentParams.ufVolumeL * MILLILITERS_PER_LITER) / (static_cast(_treatmentParams.treatmentDurationMin)); - _treatmentStatus.prescribedTreatmentTimeS = _treatmentParams.treatmentDurationMin / SECONDS_PER_MINUTE; float presUFVolL = _treatmentParams.ufVolumeL; float presUFRateLHR = presUFVolL / (static_cast(_treatmentParams.treatmentDurationMin) / static_cast(MINUTES_PER_HOUR)); @@ -111,12 +107,10 @@ qDebug() << "UF Init" << presUFRateLHR << UFVolLMS << _treatmentStatus.ufVolDeliveredL; } - void StateController::handleTreatmentSetpointsBroadcastData(const quint32 bloodFlowMLPM, const quint32 dialFlowMLPM, const float dialTempC, const Broadcast_Type BCType) { static quint32 broadcastCounter = 3; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } QVariantList msg; @@ -131,7 +125,6 @@ void StateController::handleTreatmentStatesBroadcastData(const QList &txStates, const Broadcast_Type BCType) { static quint32 broadcastCounter = 0; - if ((++broadcastCounter % NUN_OF_COUNTS_QART_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } QVariantList msg; @@ -154,12 +147,10 @@ _treatmentStatus.fluidBolusState = FLUID_BOLUS_IDLE_STATE; if (fluidBolusCmd == FLUID_BOLUS_START_CMD){ - _treatmentStatus.fluidBolusState = FLUID_BOLUS_SALINE_IN_PROGRESS_STATE; - _treatmentStatus.dialysisSubState = DIALYSIS_UF_FLUID_BOLUS_STATE; + _treatmentStatus.fluidBolusState = FLUID_BOLUS_SALINE_IN_PROGRESS_STATE; + _treatmentStatus.dialysisSubState = DIALYSIS_UF_FLUID_BOLUS_STATE; } - else { - _treatmentStatus.totalFluidBolusDeliveredML += _treatmentStatus.accumFluidBolusDeliveredML; - } + else { _treatmentStatus.totalFluidBolusDeliveredML += _treatmentStatus.accumFluidBolusDeliveredML; } _treatmentRcvdMessages[ID_UI_FLUID_BOLUS_RQST].clear(); handleUIResponseMessage(ID_TD_FLUID_BOLUS_RESP, ACCEPT_VALUE, {static_cast(REQUEST_REJECT_REASON_NONE), @@ -187,6 +178,7 @@ if (deliveredFluidML >= _treatmentParams.fluidBlousVolumeML) { _treatmentStatus.fluidBolusState = FLUID_BOLUS_IDLE_STATE; + _treatmentStatus.dialysisSubState = DIALYSIS_UF_STATE; _treatmentStatus.accumFluidBolusDeliveredML = 0.0; _treatmentStatus.totalFluidBolusDeliveredML += _treatmentStatus.accumFluidBolusDeliveredML; } @@ -197,7 +189,6 @@ void StateController::handleFluidBolusBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 5; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } QVariantList msg; @@ -215,7 +206,6 @@ void StateController::handleTDPressureProcessAndBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 10; - if (! _treatmentRcvdMessages[ID_UI_PRESSURE_LIMIT_WIDEN_RQST].isNull()){ _treatmentRcvdMessages[ID_UI_PRESSURE_LIMIT_WIDEN_RQST].clear(); // TODo address the increase per request @@ -265,9 +255,8 @@ void StateController::handleTreatmentTimeProcessAndBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 12; - if (_treatmentStatus.fluidBolusState == FLUID_BOLUS_IDLE_STATE) { - _treatmentStatus.treatmentElapsedTimeMS += QOBJECT_TIMER_TIMEOUT_MS; + _treatmentStatus.treatmentElapsedTimeMS += QOBJECT_TIMER_TIMEOUT_MS; } if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } @@ -276,7 +265,7 @@ quint32 elapsedTimeS = _treatmentStatus.treatmentElapsedTimeMS / MILLISECONDS_PER_SECOND; quint32 remainingTimeS = prescribedTimeS - elapsedTimeS; - //qDebug() << "Times" << prescribedTimeS << elapsedTimeS << remainingTimeS; + qDebug() << "Times" << prescribedTimeS << elapsedTimeS << remainingTimeS; QVariantList msg; msg.append(static_cast(ID_TD_TREATMENT_TIME_DATA)); @@ -366,18 +355,18 @@ void StateController::handleDDGenDialysateModeBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 15; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } quint32 dummyData = 1; float dummyFloat = 150.2; + quint32 dialBypass = (_treatmentStatus.fluidBolusState == FLUID_BOLUS_SALINE_IN_PROGRESS_STATE ? BYPASS_DIALYSATE_DELIVER : ALLOW_DIALYSATE_DELIVER); QVariantList msg; msg.append(static_cast(ID_DD_GEN_DIALYSATE_MODE_DATA)); msg.append(Can_Id::eChlid_DD_Sync); msg.append(dummyData); msg.append(dummyData); - msg.append(ALLOW_DIALYSATE_DELIVER); + msg.append(dialBypass); msg.append(dummyFloat); _isBroadcastListReady = false; _broadcastMessages.append(msg); @@ -399,7 +388,6 @@ void StateController::handleDDConductivityBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 22; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } float d27Cond = 250.63; @@ -420,16 +408,16 @@ void StateController::handleTDBloodPressureBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 22; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } // TODO copmlete } void StateController::handleUltrafiltrationBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 31; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } + // Only count for UF when the dialysis state is in UF + if (_treatmentStatus.dialysisSubState != DIALYSIS_UF_STATE) { return; } float presUFVolL = _treatmentParams.ufVolumeL; float presUFRateLHR = presUFVolL / (static_cast(_treatmentParams.treatmentDurationMin) / static_cast(MINUTES_PER_HOUR)); @@ -468,30 +456,28 @@ { if (_treatmentRcvdMessages[ID_UI_UF_PAUSE_RESUME_RQST].isNull()){ return; } - quint32 cmd = extractU32DataFromReceivedMessage(ID_UI_UF_PAUSE_RESUME_RQST, 0); + quint32 cmd = extractU32DataFromReceivedMessage(ID_UI_UF_PAUSE_RESUME_RQST, 0); + quint32 acceptReject = REJECT_VALUE; QVariantList reason; if (_treatmentStatus.txState == TREAT_DIALYSIS_STATE) { // Assume the default state is UF state _treatmentStatus.dialysisSubState = DIALYSIS_UF_STATE; _treatmentStatus.dialysisSubState = (cmd == 0 ? DIALYSIS_UF_PAUSED_STATE : _treatmentStatus.dialysisSubState); + acceptReject = ACCEPT_VALUE; } - else if (_treatmentStatus.txState != TREAT_DIALYSIS_STATE) { - reason.append(static_cast(REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE)); - } + else if (_treatmentStatus.txState != TREAT_DIALYSIS_STATE) { reason.append(REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE); } else { - quint32 r = static_cast(REQUEST_REJECT_REASON_UF_NOT_PAUSED); - - r = (cmd == 0 ? static_cast(REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS) : r); + quint32 r = (cmd == 0 ? REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS : REQUEST_REJECT_REASON_UF_NOT_PAUSED); reason.append(r); } - handleUIResponseMessage(ID_TD_UF_PAUSE_RESUME_RESP, ACCEPT_VALUE, reason); + handleUIResponseMessage(ID_TD_UF_PAUSE_RESUME_RESP, acceptReject, reason); _treatmentRcvdMessages[ID_UI_UF_PAUSE_RESUME_RQST].clear(); } void StateController::handleUltrafiltrationVolumeChangeValidation() { - if (_treatmentRcvdMessages[ID_UI_TREATMENT_UF_VOLUME_VALIDATE_RQST].isNull()){ return; } + if (_treatmentRcvdMessages[ID_UI_TREATMENT_UF_VOLUME_VALIDATE_RQST].isNull()) { return; } QVariantList reason = {REQUEST_REJECT_REASON_NONE, 0.0, 0.0}; quint32 rejReasIndex = 0; quint32 ufGoalIndex = 1; @@ -538,7 +524,6 @@ void StateController::handleTreatmentSettingBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 38; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } quint32 elapsedTimeMin = _treatmentStatus.treatmentElapsedTimeMS / static_cast(SECONDS_PER_MINUTE * MILLISECONDS_PER_SECOND); @@ -553,8 +538,8 @@ float maxUFVol1ML = minUFVolML + (static_cast(_treatmentParams.treatmentDurationMin - elapsedTimeMin) * MAX_UF_RATE_MLPM); float maxUFVol2ML = (_treatmentStatus.presUFRateMLPM > 0.0 ? minUFVolML + static_cast(MAX_TX_TIME_MINS - elapsedTimeMin - 1) : minUFVolML); float maxUFVolML = qMax(maxUFVol1ML, maxUFVol2ML); - //qDebug() << "TIME seetingt" << elapsedTimeMin << minTxTimeMin << maxTxTime1Min << maxTxTime2Min << maxTxTimeMin - // << maxUFVol1ML << maxUFVol2ML << maxUFVolML; + qDebug() << "TIME settings" << elapsedTimeMin << minTxTimeMin << maxTxTime1Min << maxTxTime2Min << maxTxTimeMin + << maxUFVol1ML << maxUFVol2ML << maxUFVolML; QVariantList msg; msg.append(static_cast(ID_TD_TREATMENT_PARAM_RANGES_DATA)); @@ -572,31 +557,124 @@ void StateController::handleUltrafiltrationVolumeChangeConfirm() { - if (_treatmentRcvdMessages[ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST].isNull()){ return; } + if (_treatmentRcvdMessages[ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST].isNull()) { return; } QVariantList reason; quint32 acceptReject = REJECT_VALUE; - float roundedUFRateLHR = qRound(_treatmentStatus.validateUFRateLHR * 100.0) / 100.0; - float requestedUFVolL = extractF32DataFromReceivedMessage(ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST, 0); - float requestedUFRateLHR = extractF32DataFromReceivedMessage(ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST, 4); - bool isUFVolInRange = (qAbs(requestedUFVolL - _treatmentStatus.validateUFVolGoalL) < NEARLY_ZERO ? true : false); - bool isUFRateInRange = (qAbs(requestedUFRateLHR - roundedUFRateLHR) < NEARLY_ZERO ? true : false); + float roundedUFRateLHR = qRound(_treatmentStatus.validateUFRateLHR * 100.0) / 100.0; + float requestedUFVolL = extractF32DataFromReceivedMessage(ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST, 0); + float requestedUFRateLHR = extractF32DataFromReceivedMessage(ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST, 4); + bool isUFVolInRange = (qAbs(requestedUFVolL - _treatmentStatus.validateUFVolGoalL) < NEARLY_ZERO ? true : false); + bool isUFRateInRange = (qAbs(requestedUFRateLHR - roundedUFRateLHR) < NEARLY_ZERO ? true : false); qDebug() << "UF CONFI" << roundedUFRateLHR << requestedUFVolL << requestedUFRateLHR << isUFVolInRange << isUFRateInRange << qAbs(requestedUFRateLHR - roundedUFRateLHR); if (_treatmentStatus.validateUFVolReceived && isUFVolInRange && isUFRateInRange) { _treatmentParams.ufVolumeL = _treatmentStatus.validateUFVolGoalL; // Calcuate the new UF rate after the volume change - _treatmentStatus.presUFRateMLPM = (_treatmentParams.ufVolumeL * MILLILITERS_PER_LITER) / (static_cast(_treatmentParams.treatmentDurationMin)); + _treatmentStatus.presUFRateMLPM = (_treatmentStatus.validateUFRateLHR * MILLILITERS_PER_LITER) / (static_cast(MINUTES_PER_HOUR)); _treatmentStatus.validateUFRateLHR = 0.0; _treatmentStatus.validateUFVolGoalL = 0.0; _treatmentStatus.validateUFVolReceived = false; acceptReject = ACCEPT_VALUE; } - else if (!_treatmentStatus.validateUFVolReceived) { reason.append(REQUEST_REJECT_REASON_CONFIRMATION_NOT_EXPECTED); } + else if (!_treatmentStatus.validateUFVolReceived) { reason.append(REQUEST_REJECT_REASON_CONFIRMATION_NOT_EXPECTED); } else { reason.append(REQUEST_REJECT_REASON_CONFIRMATION_MISMATCH); } handleUIResponseMessage(ID_TD_ULTRAFILTRATION_CHANGE_CONFIRM_RESP, acceptReject, reason); _treatmentRcvdMessages[ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST].clear(); } +void StateController::handleTreatmentTimeChangeValidation() +{ + if (_treatmentRcvdMessages[ID_UI_DURATION_VALIDATE_RQST].isNull()) { return; } + QVariantList reason = {REQUEST_REJECT_REASON_NONE, 0, 0, 0.0, 0.0}; + quint32 acceptReject = REJECT_VALUE; + quint32 rejReasIndex = 0; + quint32 txDurMinsIndex = 1; + quint32 hepDurMinsIndex = 2; + quint32 ufGoalIndex = 3; + quint32 ufRateIndex = 4; + + float prescribedUFVolML = _treatmentParams.ufVolumeL * static_cast(MILLILITERS_PER_LITER); + float elapsedTxTimeMin = _treatmentStatus.treatmentElapsedTimeMS / static_cast(MILLISECONDS_PER_SECOND * SECONDS_PER_MINUTE); + float measUFVolML = _treatmentStatus.ufVolDeliveredL * static_cast(MILLILITERS_PER_LITER); + float remainingUFVolML = prescribedUFVolML - measUFVolML; + quint32 requestedTxDurMin = extractU32DataFromReceivedMessage(ID_UI_DURATION_VALIDATE_RQST, 0); + quint32 txHepDiffMin = 0; + qDebug() << "Tx Dur1" << prescribedUFVolML << elapsedTxTimeMin << measUFVolML << remainingUFVolML << requestedTxDurMin; + reason[txDurMinsIndex] = requestedTxDurMin; + + if ((requestedTxDurMin >= MIN_TX_TIME_MINS) && (requestedTxDurMin <= MAX_TX_TIME_MINS)) { + if (static_cast(requestedTxDurMin) > elapsedTxTimeMin) { + if (remainingUFVolML < 0.0) { remainingUFVolML = 0.0; } + float remainingTxTimeMin = static_cast(requestedTxDurMin) - elapsedTxTimeMin; + float newUFRateMLPM = remainingUFVolML / remainingTxTimeMin; + reason[ufGoalIndex] = prescribedUFVolML / static_cast(MILLILITERS_PER_LITER); + reason[ufRateIndex] = (newUFRateMLPM * static_cast(MINUTES_PER_HOUR)) / static_cast(MILLILITERS_PER_LITER); + + if (newUFRateMLPM <= MAX_UF_RATE_MLPM) { + if (_treatmentParams.treatmentDurationMin > _treatmentParams.heparinDeliveryDurationMin) { + txHepDiffMin = _treatmentParams.treatmentDurationMin - _treatmentParams.heparinDeliveryDurationMin; + qDebug() << "Here" << _treatmentParams.treatmentDurationMin << _treatmentParams.heparinDeliveryDurationMin; + } + if (requestedTxDurMin > txHepDiffMin) { + _treatmentStatus.validateHepDurMin = requestedTxDurMin - txHepDiffMin; + } + else { _treatmentStatus.validateHepDurMin = 0; } + + reason[hepDurMinsIndex] = _treatmentStatus.validateHepDurMin; + acceptReject = ACCEPT_VALUE; + + qDebug() << "Hep time" << txHepDiffMin << requestedTxDurMin << _treatmentParams.heparinDeliveryDurationMin; + qDebug() << "Tx Dur2" << remainingTxTimeMin << newUFRateMLPM << reason[ufGoalIndex] << reason[ufRateIndex] << reason[ufRateIndex]; + + _treatmentStatus.validateTxDurReceived = true; + _treatmentStatus.validateTxDurMin = requestedTxDurMin; + _treatmentStatus.validateUFRateLHR = (newUFRateMLPM * static_cast(MINUTES_PER_HOUR)) / static_cast(MILLILITERS_PER_LITER); + _treatmentStatus.validateHepDurMin = _treatmentStatus.validateHepDurMin; + } + else { reason[rejReasIndex] = REQUEST_REJECT_REASON_UF_RATE_OUT_OF_RANGE; } + } + else { reason[rejReasIndex] = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; } + } + else { reason[rejReasIndex] = REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE; } + + handleUIResponseMessage(ID_TD_DURATION_VALIDATE_RESP, acceptReject, reason); + _treatmentRcvdMessages[ID_UI_DURATION_VALIDATE_RQST].clear(); +} + +void StateController::handleTreatmentTimeChangeConfirm() +{ + if (_treatmentRcvdMessages[ID_UI_DURATION_CONFIRM_RQST].isNull()) { return; } + QVariantList reason; + quint32 acceptReject = REJECT_VALUE; + + float roundedUFRateLHR = qRound(_treatmentStatus.validateUFRateLHR * 100.0) / 100.0; + quint32 requestedTxDurMin = extractU32DataFromReceivedMessage(ID_UI_DURATION_CONFIRM_RQST, 0); + quint32 requestedHepDurMin = extractU32DataFromReceivedMessage(ID_UI_DURATION_CONFIRM_RQST, 4); + float requestedUFRateLHR = extractF32DataFromReceivedMessage(ID_UI_DURATION_CONFIRM_RQST, 8); + bool isUFRateInRage = (qAbs(requestedUFRateLHR - roundedUFRateLHR) < NEARLY_ZERO ? true : false); + + qDebug() << "Tx Dur Confirm" << roundedUFRateLHR << requestedTxDurMin << requestedHepDurMin << requestedUFRateLHR << isUFRateInRage; + + if ((_treatmentStatus.validateTxDurReceived) && (requestedTxDurMin == _treatmentStatus.validateTxDurMin) && + (isUFRateInRage) && (requestedHepDurMin == _treatmentStatus.validateHepDurMin)) { + _treatmentParams.treatmentDurationMin = _treatmentStatus.validateTxDurMin; + _treatmentParams.heparinDeliveryDurationMin = _treatmentStatus.validateHepDurMin; + _treatmentStatus.presUFRateMLPM = (_treatmentStatus.validateUFRateLHR * MILLILITERS_PER_LITER) / (static_cast(MINUTES_PER_HOUR)); + acceptReject = ACCEPT_VALUE; + // Reset the validation values + _treatmentStatus.validateTxDurReceived = false; + _treatmentStatus.validateHepDurMin = 0; + _treatmentStatus.validateTxDurMin = 0; + _treatmentStatus.validateUFRateLHR = 0.0; + } + else if (!_treatmentStatus.validateTxDurReceived) { reason.append(REQUEST_REJECT_REASON_CONFIRMATION_NOT_EXPECTED); } + else { reason.append(REQUEST_REJECT_REASON_CONFIRMATION_MISMATCH); } + + handleUIResponseMessage(ID_TD_DURATION_CONFIRM_RESP, acceptReject, reason); + _treatmentRcvdMessages[ID_UI_DURATION_CONFIRM_RQST].clear(); +} + +