/* This software is subject to the license described in the License.txt file included with this software distribution. You may not use this file except in compliance with this license. Copyright (c) Dynastream Innovations Inc. 2012 All rights reserved. */ #include "StdAfx.h" #include "WeightScaleDisplay.h" /************************************************************************** * WeightScaleDisplay::ANT_eventNotification * * Process ANT channel event * * ucEventCode_: code of ANT channel event * pucEventBuffer_: pointer to buffer containing data received from ANT, * or a pointer to the transmit buffer in the case of an EVENT_TX * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::ANT_eventNotification(UCHAR ucEventCode_, UCHAR* pucEventBuffer_) { switch(ucEventCode_) { case EVENT_RX_BROADCAST: HandleReceive((UCHAR*) pucEventBuffer_); // Decode current data break; default: break; } } /************************************************************************** * WeightScaleDisplay::InitializeSim * * Initializes simulator variables * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::InitializeSim() { // Initialization of simulation variables wsPages->usBodyWeight100 = WeightScale::WEIGHT_INVALID; uprofUndef = gcnew WeightScaleUserProfile(); // Set the display's U.P. to be the same as what is defaulted in the custom boxes if (this->radioButtonFemale->Checked == TRUE) { if(this->radioButtonAthleteTrue->Checked == TRUE) uprofCustom = gcnew WeightScaleUserProfile((USHORT) this->numericUpDownProfile->Value, WeightScaleUserProfile::GENDER_FEMALE, (UCHAR) this->numericUpDownAge->Value, (UCHAR) this->numericUpDownHeight->Value, (UCHAR) this->numericUpDownActivityLevel->Value, WeightScaleUserProfile::PRIORITY_WATCH, WeightScaleUserProfile::IS_ATHLETE); else uprofCustom = gcnew WeightScaleUserProfile((USHORT) this->numericUpDownProfile->Value, WeightScaleUserProfile::GENDER_FEMALE, (UCHAR) this->numericUpDownAge->Value, (UCHAR) this->numericUpDownHeight->Value, (UCHAR) this->numericUpDownActivityLevel->Value, WeightScaleUserProfile::PRIORITY_WATCH, WeightScaleUserProfile::NOT_ATHLETE); } else { if(this->radioButtonAthleteTrue->Checked == TRUE) uprofCustom = gcnew WeightScaleUserProfile((USHORT) this->numericUpDownProfile->Value, WeightScaleUserProfile::GENDER_MALE, (UCHAR) this->numericUpDownAge->Value, (UCHAR) this->numericUpDownHeight->Value, (UCHAR) this->numericUpDownActivityLevel->Value, WeightScaleUserProfile::PRIORITY_WATCH, WeightScaleUserProfile::IS_ATHLETE); else uprofCustom = gcnew WeightScaleUserProfile((USHORT) this->numericUpDownProfile->Value, WeightScaleUserProfile::GENDER_MALE, (UCHAR) this->numericUpDownAge->Value, (UCHAR) this->numericUpDownHeight->Value, (UCHAR) this->numericUpDownActivityLevel->Value, WeightScaleUserProfile::PRIORITY_WATCH, WeightScaleUserProfile::NOT_ATHLETE); } WeightScaleUserProfile::copyProfile(uprofCustom, wsPages->uprofDisplay); WeightScaleUserProfile::copyProfile(wsPages->uprofDisplay, wsPages->uprofActive); // Extended bSentProfile = FALSE; bRxAdvanced = FALSE; bRxMain = FALSE; } /************************************************************************** * WeightScaleDisplay::HandleReceive * * Decode incoming transmissions * pucRxBuffer_: pointer to receive buffer * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::HandleReceive(UCHAR* pucRxBuffer_) { UCHAR ucPageNum = pucRxBuffer_[0]; switch(ucPageNum) { case WeightScale::PAGE_BODY_WEIGHT: case WeightScale::PAGE_BODY_COMPOSITION: case WeightScale::PAGE_METABOLIC_INFO: case WeightScale::PAGE_BODY_MASS: case WeightScale::PAGE_USER_PROFILE: // Intentional fall thru try { wsPages->Decode(pucRxBuffer_); } catch(CommonData::Error^ errorWeightScale) { } ProcessReceivedMessage(ucPageNum); break; case CommonData::PAGE80: case CommonData::PAGE81: // Intentional fall thru try { commonPages->Decode(pucRxBuffer_); } catch(CommonData::Error^ errorCommon) { } break; default: break; } UpdateDisplay(ucPageNum); } /************************************************************************** * WeightScaleDisplay::HandleTransmit * * Encode data into Tx Buffer * ucPageNum_: Page to transmit * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::HandleTransmit(UCHAR ucPageNum_) { UCHAR aucTxBuffer[8]; memset(aucTxBuffer, 8, 0x00); if(ucPageNum_ == WeightScale::PAGE_USER_PROFILE) // Encode user profile { try { wsPages->Encode(ucPageNum_, aucTxBuffer); } catch(WeightScale::Error^ errorWeightScale) { } requestBcastMsg(aucTxBuffer); // Send as broadcast message } } /************************************************************************** * WeightScaleDisplay::ProcessReceivedMessage * * Processes capabilities and user profile received from the scale * Device specific decision tree for personal display * ucPageNum_: Page where profile was received * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::ProcessReceivedMessage(UCHAR ucPageNum_) { // Weight message? if(ucPageNum_ == WeightScale::PAGE_BODY_WEIGHT) { // Does display support profiles? if(wsPages->capabDisplay->bDisplayExchange) { // Process scale capabilities wsPages->capabDisplay->bScaleExchange = wsPages->capabScale->bScaleExchange; wsPages->capabDisplay->bScaleSet = wsPages->capabScale->bScaleSet; // Is user profile set on scale? if(wsPages->capabScale->bScaleSet) { // Has display sent user profile? if(bSentProfile) { // Does user profile ID match? // Compare scale user profile ID against profile loaded on display (active profile) if(wsPages->uprofActive->usID == wsPages->uprofScale->usID) { // Display all defined weight data bRxAdvanced = TRUE; bRxMain = TRUE; } else { SendUserProfile(); // Transmit user profile } } else { SendUserProfile(); // Transmit user profile } } else { if(!bSentProfile) SendUserProfile(); // Transmit user profile } } else { // Display does not support profiles // Weight only bRxMain = TRUE; } } // User profile message? else if(ucPageNum_ == WeightScale::PAGE_USER_PROFILE) { // User profile defined on display? if(wsPages->uprofActive->usID == WeightScaleUserProfile::PROFILE_UNDEF) { this->labelStatusProfileNew->Text = L"New User Profile"; // Accept new user profile WeightScaleUserProfile::copyProfile(wsPages->uprofScale, wsPages->uprofActive); // Apply a higher priority user ID (display generated) to the new profile wsPages->uprofActive->usID = 1754; UpdateDisplayActiveProfile(); } } } /************************************************************************** * WeightScaleDisplay::SendUserProfile * * Send user profile * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::SendUserProfile() { if(wsPages->capabScale->bScaleExchange) { HandleTransmit(WeightScale::PAGE_USER_PROFILE); bSentProfile = TRUE; this->labelStatusProfileSent->Text = L"User Profile Sent"; UpdateDisplayActiveProfile(); // Disable changes to the user profile after it has been sent this->numericUpDownProfile->Enabled = FALSE; this->numericUpDownAge->Enabled = FALSE; this->numericUpDownHeight->Enabled = FALSE; this->radioButtonFemale->Enabled = FALSE; this->radioButtonMale->Enabled = FALSE; this->numericUpDownActivityLevel->Enabled = FALSE; this->groupBoxAthlete->Enabled = FALSE; } } /************************************************************************** * WeightScaleDisplay::UpdateDisplay * * Update display of incoming transmissions * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::UpdateDisplay(UCHAR ucPageNum_) { this->labelPage->Text = System::Convert::ToString(ucPageNum_); switch(ucPageNum_) { case WeightScale::PAGE_BODY_WEIGHT: this->labelPage2->Text = L"MAIN"; // Display capabilities UpdateDisplayCapabilities(); // Display the recieved weight data if(wsPages->usBodyWeight100 == WeightScale::WEIGHT_COMPUTING) this->labelWeight->Text = "Comp"; else if (wsPages->usBodyWeight100 == WeightScale::WEIGHT_INVALID) this->labelWeight->Text = "Invalid"; else this->labelWeight->Text = System::Convert::ToString((double) wsPages->usBodyWeight100 / 100); // Weight in kg this->label_adv_weight->Text = this->labelWeight->Text; break; case WeightScale::PAGE_BODY_COMPOSITION: this->labelPage2->Text = L"BCOMP"; if(bRxAdvanced) { if(wsPages->usHydrationP100 == WeightScale::WEIGHT_COMPUTING) this->label_Hydration->Text = "Comp"; else if (wsPages->usHydrationP100 == WeightScale::WEIGHT_INVALID) this->label_Hydration->Text = "Invalid"; else this->label_Hydration->Text = System::Convert::ToString((double) wsPages->usHydrationP100 / 100); // Hydration (%) if(wsPages->usBodyFatP100 == WeightScale::WEIGHT_COMPUTING) this->label_BodyFat->Text = "Comp"; else if (wsPages->usBodyFatP100 == WeightScale::WEIGHT_INVALID) this->label_BodyFat->Text = "Invalid"; else this->label_BodyFat->Text = System::Convert::ToString((double) wsPages->usBodyFatP100 / 100); // Body Fat (%) } else { this->label_Hydration->Text = "---"; this->label_BodyFat->Text = "---"; } this->label_adv_hydration->Text = this->label_Hydration->Text; this->label_adv_bodyfat->Text = this->label_BodyFat->Text; break; case WeightScale::PAGE_METABOLIC_INFO: this->labelPage2->Text = L"METAB"; if(bRxAdvanced) { if(wsPages->usActiveMetRate4 == WeightScale::WEIGHT_COMPUTING) this->label_ActiveMetRate->Text = "Comp"; else if (wsPages->usActiveMetRate4 == WeightScale::WEIGHT_INVALID) this->label_ActiveMetRate->Text = "Invalid"; else this->label_ActiveMetRate->Text = System::Convert::ToString((double) wsPages->usActiveMetRate4 / 4); // Active Metabolic Rate (kcal) if(wsPages->usBasalMetRate4 == WeightScale::WEIGHT_COMPUTING) this->label_BasalMetRate->Text = "Comp"; else if (wsPages->usBasalMetRate4 == WeightScale::WEIGHT_INVALID) this->label_BasalMetRate->Text = "Invalid"; else this->label_BasalMetRate->Text = System::Convert::ToString((double) wsPages->usBasalMetRate4 / 4); // Basal Metabolic Rate (kcal) } else { this->label_ActiveMetRate->Text = "---"; this->label_BasalMetRate->Text = "---"; } this->label_adv_activerate->Text = this->label_ActiveMetRate->Text; this->label_adv_basalrate->Text = this->label_BasalMetRate->Text; break; case WeightScale::PAGE_BODY_MASS: this->labelPage2->Text = L"MASS"; if(bRxAdvanced) { if(wsPages->usMuscleMass100 == WeightScale::WEIGHT_COMPUTING) this->label_adv_musclemass->Text = "Comp"; else if (wsPages->usMuscleMass100 == WeightScale::WEIGHT_INVALID) this->label_adv_musclemass->Text = "Invalid"; else this->label_adv_musclemass->Text = System::Convert::ToString((double) wsPages->usMuscleMass100/100); // Muscle mass (1/100kg) if(wsPages->ucBoneMass10 == WeightScale::MASS_COMPUTING) this->label_adv_bonemass->Text = "Comp"; else if (wsPages->ucBoneMass10 == WeightScale::MASS_INVALID) this->label_adv_bonemass->Text = "Invalid"; else this->label_adv_bonemass->Text = System::Convert::ToString((double) wsPages->ucBoneMass10/10); // Bone mass (1/10kg) } else { this->label_adv_musclemass->Text = "---"; this->label_adv_bonemass->Text = "---"; } break; case WeightScale::PAGE_USER_PROFILE: this->labelPage2->Text = L"UPR"; UpdateDisplayCapabilities(); this->labelStatusProfileRx->Text = L"User Profile Received"; break; case CommonData::PAGE80: this->labelPage2->Text = L"MFG"; this->labelHwVer->Text = System::Convert::ToString(commonPages->ucHwVersion); this->labelMfgID->Text = System::Convert::ToString(commonPages->usMfgID); this->labelModelNum->Text = System::Convert::ToString(commonPages->usModelNum); break; case CommonData::PAGE81: this->labelPage2->Text = L"PRD"; this->labelSwVer->Text = System::Convert::ToString(commonPages->ucSwVersion); if(commonPages->ulSerialNum != 0xFFFFFFFF) this->labelSerialNum->Text = System::Convert::ToString((unsigned int) commonPages->ulSerialNum); else this->labelSerialNum->Text = "N/A"; break; default: break; } } /************************************************************************** * WeightScaleDisplay::UpdateDisplayCapabilities * * Update display of the capabilities received from the scale * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::UpdateDisplayCapabilities() { if(wsPages->capabScale->bScaleSet) this->labelProfileSetScale->Text = L"Yes"; else this->labelProfileSetScale->Text = L"No"; if(wsPages->capabScale->bScaleExchange) this->labelExchangeScale->Text = L"Yes"; else this->labelExchangeScale->Text = L"No"; if(wsPages->capabScale->bAntfs) this->labelAntfsRx->Text = L"Yes"; else this->labelAntfsRx->Text = L"No"; if(wsPages->capabScale->bDisplayExchange) this->labelExchangeDisplay->Text = L"Yes"; else this->labelExchangeDisplay->Text = L"No"; } /************************************************************************** * WeightScaleDisplay::UpdateDisplayActiveProfile * * Update display of the active profile * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::UpdateDisplayActiveProfile() { this->labelProfileActive->Text = System::Convert::ToString(wsPages->uprofActive->usID); this->labelProfileActive2->Text = System::Convert::ToString(wsPages->uprofActive->usID); if(wsPages->uprofActive->ucGender == WeightScaleUserProfile::GENDER_FEMALE) this->labelGenderActive->Text = L"Female"; else this->labelGenderActive->Text = L"Male"; this->labelAgeActive->Text = System::Convert::ToString(wsPages->uprofActive->ucAge); this->labelHeightActive->Text = System::Convert::ToString(wsPages->uprofActive->ucHeight); this->labelDescriptionActive->Text = System::Convert::ToString(wsPages->uprofActive->ucDescription); if(wsPages->uprofActive->bAthlete == TRUE) this->labelLifestyle->Text = "Athlete"; else this->labelLifestyle->Text = "Standard"; } /************************************************************************** * WeightScaleDisplay::checkBoxProfileSet_CheckedChanged * * Set user profile * * returns: N/A * **************************************************************************/ System::Void WeightScaleDisplay::checkBoxProfileSet_CheckedChanged(System::Object^ sender, System::EventArgs^ e) { if(this->checkBoxProfileSet->Checked) { // Enable Custom Profile this->numericUpDownProfile->Enabled = TRUE; this->numericUpDownAge->Enabled = TRUE; this->numericUpDownHeight->Enabled = TRUE; this->radioButtonFemale->Enabled = TRUE; this->radioButtonMale->Enabled = TRUE; this->numericUpDownActivityLevel->Enabled = TRUE; this->groupBoxAthlete->Enabled = TRUE; // Display current active profile values in Custom Profile if (wsPages->uprofActive->usID == WeightScaleUserProfile::PROFILE_UNDEF) wsPages->uprofActive->usID = 1754; // choose random user ID (eg. lowest two bytes of display serial number) this->numericUpDownProfile->Value = wsPages->uprofActive->usID; this->numericUpDownAge->Value = wsPages->uprofActive->ucAge; this->numericUpDownHeight->Value = wsPages->uprofActive->ucHeight; if(wsPages->uprofActive->ucGender == WeightScaleUserProfile::GENDER_FEMALE) this->radioButtonFemale->Checked = TRUE; else this->radioButtonMale->Checked = TRUE; if(wsPages->uprofActive->bAthlete == TRUE) this->radioButtonAthleteTrue->Checked = TRUE; else this->radioButtonAthleteFalse->Checked = TRUE; } else { // Unset user profile WeightScaleUserProfile::copyProfile(uprofUndef, wsPages->uprofActive); // Disble Custom Profile this->numericUpDownProfile->Enabled = FALSE; this->numericUpDownAge->Enabled = FALSE; this->numericUpDownHeight->Enabled = FALSE; this->radioButtonFemale->Enabled = FALSE; this->radioButtonMale->Enabled = FALSE; this->numericUpDownActivityLevel->Enabled = FALSE; this->groupBoxAthlete->Enabled = FALSE; } UpdateDisplayActiveProfile(); } /************************************************************************** * WeightScaleDisplay::buttonReset_Click * * Reset session (without modifying user profiles) * * returns: N/A * **************************************************************************/ System::Void WeightScaleDisplay::buttonReset_Click(System::Object^ sender, System::EventArgs^ e) { // Reset session bSentProfile = FALSE; // Send user profile again after a weight message from the scale bRxAdvanced = FALSE; // Clear status this->labelStatusProfileMatch->Text = "---"; this->labelStatusProfileNew->Text = "---"; this->labelStatusProfileRx->Text = "---"; this->labelStatusProfileSent->Text = "---"; this->labelStatusProfileUpdate->Text = "---"; // Clear Rx data this->labelWeight->Text = "---"; // Enable custom profile this->numericUpDownProfile->Enabled = TRUE; this->numericUpDownAge->Enabled = TRUE; this->numericUpDownHeight->Enabled = TRUE; this->radioButtonFemale->Enabled = TRUE; this->radioButtonMale->Enabled = TRUE; this->numericUpDownActivityLevel->Enabled = TRUE; this->groupBoxAthlete->Enabled = TRUE; } /************************************************************************** * WeightScaleDisplay::checkBoxAntfs_CheckedChanged * * Enable/disable ANT-FS (not implemented yet, for future capabilities) * * returns: N/A * **************************************************************************/ System::Void WeightScaleDisplay::checkBoxAntfs_CheckedChanged(System::Object^ sender, System::EventArgs^ e) { if(this->checkBoxAntfs->Checked) wsPages->capabDisplay->bAntfs = TRUE; else wsPages->capabDisplay->bAntfs = FALSE; } /************************************************************************** * WeightScaleDisplay::checkBoxExchange_CheckedChanged * * Enable/disable user profile exchange * * returns: N/A * **************************************************************************/ System::Void WeightScaleDisplay::checkBoxExchange_CheckedChanged(System::Object^ sender, System::EventArgs^ e) { if(this->checkBoxExchange->Checked) wsPages->capabDisplay->bDisplayExchange = TRUE; else wsPages->capabDisplay->bDisplayExchange = FALSE; } /************************************************************************** * WeightScaleDisplay::SelectCustomProfile * * Updates custom profile set on display * Application specific * * returns: N/A * **************************************************************************/ void WeightScaleDisplay::SelectCustomProfile() { // Read user profile from GUI wsPages->uprofActive->usID = (USHORT) (this->numericUpDownProfile->Value); // ID wsPages->uprofActive->ucAge = (UCHAR) (this->numericUpDownAge->Value); // Age wsPages->uprofActive->ucHeight = (UCHAR) (this->numericUpDownHeight->Value); // Height wsPages->uprofActive->ucDescription = (UCHAR) (this->numericUpDownActivityLevel->Value); // Activity Level if(this->radioButtonFemale->Checked) wsPages->uprofActive->ucGender = WeightScaleUserProfile::GENDER_FEMALE; // Gender else if(this->radioButtonMale->Checked) wsPages->uprofActive->ucGender = WeightScaleUserProfile::GENDER_MALE; else wsPages->uprofActive->ucGender = WeightScaleUserProfile::GENDER_UNDEF; if (this->radioButtonAthleteTrue->Checked == TRUE) // Lifetime activity wsPages->uprofActive->bAthlete = TRUE; else wsPages->uprofActive->bAthlete = FALSE; UpdateDisplayActiveProfile(); }