WeightScaleSensor.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except in compliance
  4. with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2012
  6. All rights reserved.
  7. */
  8. #include "StdAfx.h"
  9. #include "WeightScaleSensor.h"
  10. #include "antmessage.h"
  11. /**************************************************************************
  12. * WeightScaleSensor::ANT_eventNotification
  13. *
  14. * Process ANT channel event
  15. *
  16. * ucEventCode_: code of ANT channel event
  17. * pucEventBuffer_: pointer to buffer containing data received from ANT,
  18. * or a pointer to the transmit buffer in the case of an EVENT_TX
  19. *
  20. * returns: N/A
  21. *
  22. **************************************************************************/
  23. void WeightScaleSensor::ANT_eventNotification(UCHAR ucEventCode_, UCHAR* pucEventBuffer_)
  24. {
  25. switch(ucEventCode_)
  26. {
  27. case EVENT_TX:
  28. HandleTransmit((UCHAR*) pucEventBuffer_);
  29. break;
  30. case EVENT_RX_BROADCAST:
  31. HandleReceive((UCHAR*) pucEventBuffer_);
  32. break;
  33. case MESG_OPEN_CHANNEL_ID:
  34. AllowChangesProfile(FALSE);
  35. break;
  36. case MESG_CLOSE_CHANNEL_ID:
  37. AllowChangesProfile(TRUE);
  38. break;
  39. default:
  40. break;
  41. }
  42. }
  43. /**************************************************************************
  44. * WeightScaleSensor::InitializeSim
  45. *
  46. * Initializes simulator variables
  47. *
  48. * returns: N/A
  49. *
  50. **************************************************************************/
  51. void WeightScaleSensor::InitializeSim()
  52. {
  53. // Initialization of ANT+ simulation variables
  54. wsPages->usBodyWeight100 = WeightScale::WEIGHT_COMPUTING;
  55. wsPages->usHydrationP100 = (USHORT) (this->numericUpDown_Hydration->Value * 100); // Hydration in 0.01%
  56. wsPages->usBodyFatP100 = (USHORT) (this->numericUpDown_BodyFat->Value * 100); // Body fat in 0.01%
  57. wsPages->usActiveMetRate4 = (USHORT) (this->numericUpDown_ActiveMetRate->Value * 4); // Active metabolic rate (1/4 kcal)
  58. wsPages->usBasalMetRate4= (USHORT) (this->numericUpDown_BasalMetRate->Value * 4); // Basal metabolic rate (1/4 kcal)
  59. wsPages->usMuscleMass100 = (USHORT) (this->numericUpDown_MuscleMass->Value * 100); // Muscle mass (1/100 kg)
  60. wsPages->ucBoneMass10 = (UCHAR) (this->numericUpDown_BoneMass->Value * 10); // Bone mass (1/10 kg)
  61. // Common Pages (Read from UI values)
  62. commonPages->usMfgID = System::Convert::ToUInt16(this->textboxMfgID->Text);
  63. commonPages->usModelNum = System::Convert::ToUInt16(this->textboxModelNum->Text);
  64. commonPages->ucHwVersion= System::Convert::ToByte(this->textboxHwVer->Text);
  65. commonPages->ucSwVersion = System::Convert::ToByte(this->textboxSwVer->Text);
  66. commonPages->ulSerialNum = System::Convert::ToUInt32(this->textboxSerialNum->Text);
  67. // Preset User Profiles
  68. uprofUndef = gcnew WeightScaleUserProfile();
  69. uprofU1 = gcnew WeightScaleUserProfile((USHORT) 1, WeightScaleUserProfile::GENDER_MALE, (UCHAR) 47, (UCHAR) 170, WeightScaleUserProfile::ACTIVITY_LOW, WeightScaleUserProfile::PRIORITY_WATCH, WeightScaleUserProfile::NOT_ATHLETE);
  70. uprofU2 = gcnew WeightScaleUserProfile((USHORT) 5, WeightScaleUserProfile::GENDER_FEMALE, (UCHAR) 25, (UCHAR) 162, WeightScaleUserProfile::ACTIVITY_HIGH, WeightScaleUserProfile::PRIORITY_WATCH, WeightScaleUserProfile::IS_ATHLETE);
  71. uprofU3 = gcnew WeightScaleUserProfile((USHORT) 12, WeightScaleUserProfile::GENDER_MALE, (UCHAR) 8, (UCHAR) 117, WeightScaleUserProfile::ACTIVITY_CHILD, WeightScaleUserProfile::PRIORITY_WATCH, WeightScaleUserProfile::NOT_ATHLETE);
  72. // Status
  73. bTxAdvanced = FALSE;
  74. bTxUserProfile = FALSE;
  75. bTxPage2 = TRUE;
  76. bTxPage3 = TRUE;
  77. bTxPage4 = TRUE;
  78. }
  79. /**************************************************************************
  80. * WeightScaleSensor::HandleTransmit
  81. *
  82. * Encode data into Tx Buffer
  83. * pucTxBuffer_: pointer to the Tx buffer
  84. *
  85. * returns: N/A
  86. *
  87. **************************************************************************/
  88. void WeightScaleSensor::HandleTransmit(UCHAR* pucTxBuffer_)
  89. {
  90. static UCHAR ucMsgCount = 0;
  91. UCHAR ucPageNum = WeightScale::PAGE_BODY_WEIGHT;
  92. if(bTxAdvanced && wsPages->usBodyWeight100 < WeightScale::WEIGHT_COMPUTING) // Make sure profile has been enabled, and body weight is calculated
  93. {
  94. if(ucMsgCount % 4 == 1 && bTxAdvanced && bTxPage2) // Interleaving advanced data pages
  95. ucPageNum = WeightScale::PAGE_BODY_COMPOSITION;
  96. if(ucMsgCount % 4 == 2 && bTxAdvanced && bTxPage3)
  97. ucPageNum = WeightScale::PAGE_METABOLIC_INFO;
  98. if(ucMsgCount % 4 == 3 && bTxAdvanced && bTxPage4)
  99. ucPageNum = WeightScale::PAGE_BODY_MASS;
  100. }
  101. if(ucMsgCount == (WeightScale::INTERVAL_COMMON-1)) // Interleaving common pages
  102. ucPageNum = CommonData::PAGE80;
  103. if(++ucMsgCount >= (WeightScale::INTERVAL_COMMON*2))
  104. {
  105. ucPageNum = CommonData::PAGE81;
  106. ucMsgCount = 0;
  107. }
  108. if(bTxUserProfile)
  109. {
  110. ucPageNum = WeightScale::PAGE_USER_PROFILE; // Transmit user profile
  111. bTxUserProfile = FALSE; // Only once
  112. }
  113. switch(ucPageNum)
  114. {
  115. case WeightScale::PAGE_BODY_WEIGHT:
  116. case WeightScale::PAGE_BODY_COMPOSITION:
  117. case WeightScale::PAGE_METABOLIC_INFO:
  118. case WeightScale::PAGE_BODY_MASS:
  119. case WeightScale::PAGE_USER_PROFILE: // Intentional fall thru
  120. try
  121. {
  122. wsPages->Encode(ucPageNum, pucTxBuffer_); // Encode weight scale pages
  123. }
  124. catch(WeightScale::Error^ errorWeightScale)
  125. {
  126. }
  127. break;
  128. case CommonData::PAGE80:
  129. case CommonData::PAGE81: // Intentional fall thru
  130. try
  131. {
  132. commonPages->Encode(ucPageNum, pucTxBuffer_); // Encode common pages
  133. }
  134. catch(CommonData::Error^ errorCommon)
  135. {
  136. }
  137. break;
  138. default:
  139. break;
  140. }
  141. UpdateDisplay();
  142. }
  143. /**************************************************************************
  144. * WeightScaleSensor::HandleReceive
  145. *
  146. * Decode incoming transmissions
  147. *
  148. * returns: N/A
  149. *
  150. **************************************************************************/
  151. void WeightScaleSensor::HandleReceive(UCHAR* pucRxBuffer_)
  152. {
  153. UCHAR ucPageNum = pucRxBuffer_[0];
  154. if(ucPageNum == WeightScale::PAGE_USER_PROFILE) // Only decode user profile
  155. {
  156. try
  157. {
  158. wsPages->Decode(pucRxBuffer_);
  159. }
  160. catch(WeightScale::Error^ errorWeightScale)
  161. {
  162. }
  163. UpdateDisplayCapabilities();
  164. ProcessReceivedProfile(); // Process incoming profile
  165. }
  166. }
  167. /**************************************************************************
  168. * WeightScaleSensor::ProcessReceivedProfile
  169. *
  170. * Process incoming profile (device specific decision tree)
  171. *
  172. * returns: N/A
  173. *
  174. **************************************************************************/
  175. void WeightScaleSensor::ProcessReceivedProfile()
  176. {
  177. this->labelStatusProfileRx->Text = L"User Profile Received";
  178. // Process capabilities
  179. wsPages->capabScale->bDisplayExchange = wsPages->capabDisplay->bDisplayExchange; // Update display exchange support field as received from display
  180. // Does display support profile exchange?
  181. if(wsPages->capabDisplay->bDisplayExchange)
  182. {
  183. // Is user profile ID received from display valid?
  184. if(wsPages->uprofDisplay->usID != WeightScaleUserProfile::PROFILE_UNDEF)
  185. {
  186. // User profile ID match?
  187. // This implementation only looks for a match in the active profile of the scale
  188. // It could also be possible to look for a match in all profiles stored on the scale
  189. if(wsPages->uprofActive->usID == wsPages->uprofDisplay->usID)
  190. {
  191. this->labelStatusProfileMatch->Text = L"User Profile Match"; // Profile ID match
  192. // Check for changes to user profile for this ID
  193. if(!(WeightScaleUserProfile::isEqual(wsPages->uprofActive, wsPages->uprofDisplay)))
  194. this->labelStatusProfileUpdate->Text = L"User Profile Updated"; // Changes detected, profile will be updated
  195. }
  196. else
  197. {
  198. this->labelStatusProfileNew->Text = L"New User Profile"; // New user profile
  199. }
  200. // Apply user profile to calculations
  201. WeightScaleUserProfile::copyProfile(wsPages->uprofDisplay, wsPages->uprofActive);
  202. UpdateDisplayActiveProfile();
  203. wsPages->capabScale->bScaleSet = TRUE;
  204. bTxAdvanced = TRUE; // Enable advanced calculations
  205. }
  206. else
  207. {
  208. // No valid user profile in display
  209. // Is user profile set on scale?
  210. // In this implementation, the scale only looks for a valid active user profile
  211. if(wsPages->uprofActive->usID != WeightScaleUserProfile::PROFILE_UNDEF)
  212. {
  213. // Transmit User Profile
  214. bTxUserProfile = TRUE;
  215. this->labelStatusProfileSent->Text = L"Sent User Profile";
  216. // Apply profile to calculations
  217. bTxAdvanced = TRUE;
  218. }
  219. }
  220. }
  221. }
  222. /**************************************************************************
  223. * WeightScaleSensor::UpdateDisplay
  224. *
  225. * Updates display of current transmission
  226. *
  227. * returns: N/A
  228. *
  229. **************************************************************************/
  230. void WeightScaleSensor::UpdateDisplay()
  231. {
  232. // Update display
  233. if(wsPages->usBodyWeight100 == WeightScale::WEIGHT_COMPUTING)
  234. this->labelWeight->Text = "Comp";
  235. else if (wsPages->usBodyWeight100 == WeightScale::WEIGHT_INVALID)
  236. this->labelWeight->Text = "Invalid";
  237. else
  238. this->labelWeight->Text = System::Convert::ToString((double) wsPages->usBodyWeight100 / 100); // Weight (kg)
  239. this->labelProfileActive->Text = Convert::ToString(wsPages->uprofActive->usID); // Active profile
  240. if(bTxPage2 && bTxAdvanced && wsPages->usBodyWeight100 < WeightScale::WEIGHT_COMPUTING)
  241. {
  242. if(wsPages->usHydrationP100 == WeightScale::WEIGHT_COMPUTING)
  243. this->label_Hydration->Text = "Comp";
  244. else if (wsPages->usHydrationP100 == WeightScale::WEIGHT_INVALID)
  245. this->label_Hydration->Text = "Invalid";
  246. else
  247. this->label_Hydration->Text = System::Convert::ToString((double) wsPages->usHydrationP100 / 100); // Hydration (%)
  248. if(wsPages->usBodyFatP100 == WeightScale::WEIGHT_COMPUTING)
  249. this->label_BodyFat->Text = "Comp";
  250. else if (wsPages->usBodyFatP100 == WeightScale::WEIGHT_INVALID)
  251. this->label_BodyFat->Text = "Invalid";
  252. else
  253. this->label_BodyFat->Text = System::Convert::ToString((double) wsPages->usBodyFatP100 / 100); // Body Fat (%)
  254. }
  255. else
  256. {
  257. this->label_Hydration->Text = "---";
  258. this->label_BodyFat->Text = "---";
  259. }
  260. if(bTxPage3 && bTxAdvanced && wsPages->usBodyWeight100 < WeightScale::WEIGHT_COMPUTING)
  261. {
  262. if(wsPages->usActiveMetRate4 == WeightScale::WEIGHT_COMPUTING)
  263. this->label_ActiveMetRate->Text = "Comp";
  264. else if (wsPages->usActiveMetRate4 == WeightScale::WEIGHT_INVALID)
  265. this->label_ActiveMetRate->Text = "Invalid";
  266. else
  267. this->label_ActiveMetRate->Text = System::Convert::ToString((double) wsPages->usActiveMetRate4 / 4); // Active Metabolic Rate (kcal)
  268. if(wsPages->usBasalMetRate4 == WeightScale::WEIGHT_COMPUTING)
  269. this->label_BasalMetRate->Text = "Comp";
  270. else if (wsPages->usBasalMetRate4 == WeightScale::WEIGHT_INVALID)
  271. this->label_BasalMetRate->Text = "Invalid";
  272. else
  273. this->label_BasalMetRate->Text = System::Convert::ToString((double) wsPages->usBasalMetRate4 / 4); // Basal Metabolic Rate (kcal)
  274. }
  275. else
  276. {
  277. this->label_ActiveMetRate->Text = "---";
  278. this->label_BasalMetRate->Text = "---";
  279. }
  280. }
  281. /**************************************************************************
  282. * WeightScaleSensor::UpdateDisplayActiveProfile
  283. *
  284. * Updates display of current active user profile
  285. *
  286. * returns: N/A
  287. *
  288. **************************************************************************/
  289. void WeightScaleSensor::UpdateDisplayActiveProfile()
  290. {
  291. // Updates field on active profile tab
  292. this->labelProfileActive->Text = System::Convert::ToString(wsPages->uprofActive->usID); // Active profile ID
  293. this->labelProfileActive2->Text = System::Convert::ToString(wsPages->uprofActive->usID);
  294. if(wsPages->uprofActive->ucGender == WeightScaleUserProfile::GENDER_FEMALE) // Gender
  295. this->labelGenderActive->Text = L"Female";
  296. if(wsPages->uprofActive->ucGender == WeightScaleUserProfile::GENDER_MALE)
  297. this->labelGenderActive->Text = L"Male";
  298. this->labelAgeActive->Text = System::Convert::ToString(wsPages->uprofActive->ucAge); // Age
  299. this->labelHeightActive->Text = System::Convert::ToString(wsPages->uprofActive->ucHeight); // Height
  300. this->labelDescriptionActive->Text = System::Convert::ToString(wsPages->uprofActive->ucDescription); // Description
  301. if (wsPages->uprofActive->bAthlete == TRUE) // Athlete bit
  302. this->labelLifestyle->Text = "Athlete";
  303. else
  304. this->labelLifestyle->Text = "Standard";
  305. // Update fields on custom tab
  306. this->numericUpDownActivityLevel->Value = wsPages->uprofActive->ucDescription; // Description
  307. this->numericUpDownAge->Value = wsPages->uprofActive->ucAge; // Age
  308. this->numericUpDownHeight->Value = wsPages->uprofActive->ucHeight; // Height
  309. if (wsPages->uprofActive->ucGender == WeightScaleUserProfile::GENDER_MALE) // Gender
  310. this->radioButtonMale->Checked = TRUE;
  311. else
  312. this->radioButtonFemale->Checked = TRUE;
  313. if (wsPages->uprofActive->usID <= WeightScaleUserProfile::PROFILE_SCALE_MAX) // ID
  314. this->numericUpDownProfile->Value = wsPages->uprofActive->usID;
  315. else
  316. this->numericUpDownProfile->Value = 0;
  317. if(wsPages->uprofActive->bAthlete == TRUE) // Athlete bit
  318. this->radioButtonLifetimeActivityTrue->Checked = TRUE;
  319. else
  320. this->radioButtonLifetimeActivityFalse->Checked = TRUE;
  321. }
  322. /**************************************************************************
  323. * WeightScaleSensor::UpdateDisplayCapabilities
  324. *
  325. * Updates display of capabilities (received from display)
  326. *
  327. * returns: N/A
  328. *
  329. **************************************************************************/
  330. void WeightScaleSensor::UpdateDisplayCapabilities()
  331. {
  332. // Show capabilities of display
  333. if(wsPages->capabDisplay->bScaleSet)
  334. this->labelProfileSetScale->Text = L"Yes";
  335. else
  336. this->labelProfileSetScale->Text = L"No";
  337. if(wsPages->capabDisplay->bScaleExchange)
  338. this->labelExchangeScale->Text = L"Yes";
  339. else
  340. this->labelExchangeScale->Text = L"No";
  341. if(wsPages->capabDisplay->bAntfs)
  342. this->labelAntfsRx->Text = L"Yes";
  343. else
  344. this->labelAntfsRx->Text = L"No";
  345. if(wsPages->capabDisplay->bDisplayExchange)
  346. this->labelExchangeDisplay->Text = L"Yes";
  347. else
  348. this->labelExchangeDisplay->Text = L"No";
  349. }
  350. /**************************************************************************
  351. * WeightScaleSensor::SelectPresetProfile
  352. *
  353. * Selects between preset user profiles
  354. * Application specific
  355. *
  356. * returns: N/A
  357. *
  358. **************************************************************************/
  359. void WeightScaleSensor::SelectPresetProfile()
  360. {
  361. if(this->radioButtonUser1->Checked) // Select among predefined profiles
  362. WeightScaleUserProfile::copyProfile(uprofU1, wsPages->uprofScale);
  363. if(this->radioButtonUser2->Checked)
  364. WeightScaleUserProfile::copyProfile(uprofU2, wsPages->uprofScale);
  365. if(this->radioButtonUser3->Checked)
  366. WeightScaleUserProfile::copyProfile(uprofU3, wsPages->uprofScale);
  367. if(this->radioButtonGuest->Checked)
  368. {
  369. // Enable Custom Profile
  370. this->numericUpDownProfile->Enabled = TRUE;
  371. this->numericUpDownAge->Enabled = TRUE;
  372. this->numericUpDownHeight->Enabled = TRUE;
  373. this->radioButtonFemale->Enabled = TRUE;
  374. this->radioButtonMale->Enabled = TRUE;
  375. this->numericUpDownActivityLevel->Enabled = TRUE;
  376. this->groupBoxLifetimeActivity->Enabled = TRUE;
  377. SelectCustomProfile();
  378. }
  379. else
  380. {
  381. // Disble Custom Profile
  382. this->numericUpDownProfile->Enabled = FALSE;
  383. this->numericUpDownAge->Enabled = FALSE;
  384. this->numericUpDownHeight->Enabled = FALSE;
  385. this->radioButtonFemale->Enabled = FALSE;
  386. this->radioButtonMale->Enabled = FALSE;
  387. this->numericUpDownActivityLevel->Enabled = FALSE;
  388. this->groupBoxLifetimeActivity->Enabled = FALSE;
  389. }
  390. // If there is no active profile, or current active profile was set on a scale, set scale profile as active
  391. if((wsPages->uprofActive->usID == WeightScaleUserProfile::PROFILE_UNDEF) || (wsPages->uprofActive->usID <= WeightScaleUserProfile::PROFILE_SCALE_MAX))
  392. {
  393. WeightScaleUserProfile::copyProfile(wsPages->uprofScale, wsPages->uprofActive);
  394. UpdateDisplayActiveProfile();
  395. }
  396. }
  397. /**************************************************************************
  398. * WeightScaleSensor::SelectCustomProfile
  399. *
  400. * Updates custom profile set on scale
  401. * Application specific
  402. *
  403. * returns: N/A
  404. *
  405. **************************************************************************/
  406. void WeightScaleSensor::SelectCustomProfile()
  407. {
  408. if(wsPages->capabScale->bScaleSet && this->radioButtonGuest->Checked) // User profile selected through interface and custom profile enabled
  409. {
  410. // Read user profile from GUI
  411. wsPages->uprofScale->usID = (USHORT) (this->numericUpDownProfile->Value); // ID
  412. wsPages->uprofScale->ucAge = (UCHAR) (this->numericUpDownAge->Value); // Age
  413. wsPages->uprofScale->ucHeight = (UCHAR) (this->numericUpDownHeight->Value); // Height
  414. wsPages->uprofScale->ucDescription = (UCHAR) (this->numericUpDownActivityLevel->Value); // Activity Level
  415. if(this->radioButtonFemale->Checked)
  416. wsPages->uprofScale->ucGender = WeightScaleUserProfile::GENDER_FEMALE; // Gender
  417. else if(this->radioButtonMale->Checked)
  418. wsPages->uprofScale->ucGender = WeightScaleUserProfile::GENDER_MALE;
  419. else
  420. wsPages->uprofScale->ucGender = WeightScaleUserProfile::GENDER_UNDEF;
  421. if (this->radioButtonLifetimeActivityTrue->Checked == TRUE)
  422. wsPages->uprofScale->bAthlete = TRUE; // Lifetime activity
  423. else
  424. wsPages->uprofScale->bAthlete = FALSE;
  425. }
  426. // Set scale profile as active
  427. // - if there is no active profile
  428. // - if updating current active profile (ID match)
  429. // - if current active profile was set on a scale
  430. if((wsPages->uprofActive->usID == WeightScaleUserProfile::PROFILE_UNDEF) || (wsPages->uprofActive->usID == wsPages->uprofScale->usID) || (wsPages->uprofActive->usID <= WeightScaleUserProfile::PROFILE_SCALE_MAX))
  431. {
  432. WeightScaleUserProfile::copyProfile(wsPages->uprofScale, wsPages->uprofActive);
  433. UpdateDisplayActiveProfile();
  434. }
  435. }
  436. /**************************************************************************
  437. * WeightScaleSensor::checkBoxProfileSet_CheckedChanged
  438. *
  439. * Selects user profile through the interface of the weight scale
  440. *
  441. * returns: N/A
  442. *
  443. **************************************************************************/
  444. System::Void WeightScaleSensor::checkBoxProfileSet_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
  445. {
  446. if(this->checkBoxProfileSet->Checked == TRUE) // Profile set
  447. {
  448. this->groupBox2->Enabled = TRUE;
  449. SelectPresetProfile(); // Use profile selected
  450. // The selected profile is only applied if there is no active profile
  451. wsPages->capabScale->bScaleSet = TRUE; // Set capabilities
  452. }
  453. else
  454. {
  455. this->groupBox2->Enabled = FALSE; // Profile not set
  456. WeightScaleUserProfile::copyProfile(uprofUndef, wsPages->uprofScale); // Invalid profile
  457. // Set the profile as active if current profile was set on the scale
  458. if(wsPages->uprofActive->usID <= WeightScaleUserProfile::PROFILE_SCALE_MAX)
  459. {
  460. WeightScaleUserProfile::copyProfile(wsPages->uprofScale, wsPages->uprofActive);
  461. UpdateDisplayActiveProfile();
  462. }
  463. wsPages->capabScale->bScaleSet = FALSE; // Set capabilities
  464. // This only affects the profile selected at the scale, it will not delete the current active profile
  465. }
  466. }
  467. /**************************************************************************
  468. * WeightScaleSensor::checkBoxExchange_CheckedChanged
  469. *
  470. * Enable/disable profile exchange
  471. *
  472. * returns: N/A
  473. *
  474. **************************************************************************/
  475. System::Void WeightScaleSensor::checkBoxExchange_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
  476. {
  477. if(this->checkBoxExchange->Checked)
  478. wsPages->capabScale->bScaleExchange = TRUE;
  479. else
  480. wsPages->capabScale->bScaleExchange = FALSE;
  481. }
  482. /**************************************************************************
  483. * WeightScaleSensor::checkBoxAntfs_CheckedChanged
  484. *
  485. * Enable/disable use of ANT-FS (future functionality)
  486. * ANT-FS usage on weight scale is not yet defined on the device profile
  487. *
  488. * returns: N/A
  489. *
  490. **************************************************************************/
  491. System::Void WeightScaleSensor::checkBoxAntfs_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
  492. {
  493. if(this->checkBoxAntfs->Checked)
  494. wsPages->capabScale->bAntfs = TRUE;
  495. else
  496. wsPages->capabScale->bAntfs = FALSE;
  497. }
  498. /**************************************************************************
  499. * WeightScaleSensor::SelectWeightStatus
  500. *
  501. * Sets weight as valid, invalid or computing
  502. *
  503. * returns: N/A
  504. *
  505. **************************************************************************/
  506. void WeightScaleSensor::SelectWeightStatus()
  507. {
  508. if (this->radioButtonWeightValid->Checked) // Valid weight
  509. {
  510. this->numericUpDownWeight->Enabled = TRUE;
  511. wsPages->usBodyWeight100 = (USHORT) (this->numericUpDownWeight->Value * 100);
  512. }
  513. else
  514. {
  515. this->numericUpDownWeight->Enabled = FALSE;
  516. this->label_Hydration->Text = "---";
  517. this->label_BodyFat->Text = "---";
  518. this->label_ActiveMetRate->Text = "---";
  519. this->label_BasalMetRate->Text = "---";
  520. if (this->radioButtonWieghtComputing->Checked == TRUE)
  521. {
  522. wsPages->usBodyWeight100 = WeightScale::WEIGHT_COMPUTING;
  523. }
  524. if (this->radioButtonWeightError->Checked == TRUE)
  525. {
  526. wsPages->usBodyWeight100 = WeightScale::WEIGHT_INVALID;
  527. }
  528. }
  529. }
  530. /**************************************************************************
  531. * WeightScaleSensor::SelectPages
  532. *
  533. * Selects advanced pages to transmit
  534. *
  535. * returns: N/A
  536. *
  537. **************************************************************************/
  538. void WeightScaleSensor::SelectPages()
  539. {
  540. bTxPage2 = (BOOL) (this->checkBox_TxPage2->Checked);
  541. bTxPage3 = (BOOL) (this->checkBox_TxPage3->Checked);
  542. bTxPage4 = (BOOL) (this->checkBox_TxPage4->Checked);
  543. }
  544. /**************************************************************************
  545. * WeightScaleSensor::buttonUpdateGlobal_Click
  546. *
  547. * Updates and validates global data
  548. *
  549. * returns: N/A
  550. *
  551. **************************************************************************/
  552. System::Void WeightScaleSensor::buttonUpdateGlobal_Click(System::Object^ sender, System::EventArgs^ e)
  553. {
  554. this->labelError->Visible = false;
  555. try
  556. {
  557. commonPages->usMfgID = System::Convert::ToUInt16(this->textboxMfgID->Text);
  558. commonPages->usModelNum = System::Convert::ToUInt16(this->textboxModelNum->Text);
  559. commonPages->ucHwVersion = System::Convert::ToByte(this->textboxHwVer->Text);
  560. commonPages->ucSwVersion = System::Convert::ToByte(this->textboxSwVer->Text);
  561. if(!this->checkBox_InvalidSerial->Checked)
  562. commonPages->ulSerialNum = System::Convert::ToUInt32(this->textboxSerialNum->Text);
  563. else
  564. commonPages->ulSerialNum = 0xFFFFFFFF;
  565. }
  566. catch(...)
  567. {
  568. this->labelError->Visible = true;
  569. this->labelError->Text = L"Invalid input";
  570. }
  571. }
  572. /**************************************************************************
  573. * WeightScaleSensor::buttonReset_Click
  574. *
  575. * Resets session, without changing user profiles
  576. *
  577. * returns: N/A
  578. *
  579. **************************************************************************/
  580. System::Void WeightScaleSensor::buttonReset_Click(System::Object^ sender, System::EventArgs^ e)
  581. {
  582. // Reset session
  583. bTxAdvanced = FALSE;
  584. bTxUserProfile = FALSE;
  585. // Set weight to calculating
  586. radioButtonWieghtComputing->Checked = TRUE;
  587. // Clear status
  588. this->labelStatusProfileMatch->Text= "---";
  589. this->labelStatusProfileNew->Text = "---";
  590. this->labelStatusProfileRx->Text = "---";
  591. this->labelStatusProfileSent->Text = "---";
  592. this->labelStatusProfileUpdate->Text = "---";
  593. }
  594. /**************************************************************************
  595. * WeightScaleSensor::AllowChangesProfile
  596. *
  597. * Enables/disables changes to user profile
  598. *
  599. * returns: N/A
  600. *
  601. **************************************************************************/
  602. void WeightScaleSensor::AllowChangesProfile(BOOL bNoSession_)
  603. {
  604. if(bNoSession_)
  605. {
  606. this->checkBoxProfileSet->Enabled = true;
  607. this->radioButtonUser1->Enabled = true;
  608. this->radioButtonUser2->Enabled = true;
  609. this->radioButtonGuest->Enabled = true;
  610. this->radioButtonGuest->Enabled = true;
  611. if(this->radioButtonGuest->Checked) // Enable custom profiles
  612. {
  613. this->numericUpDownProfile->Enabled = true;
  614. this->numericUpDownAge->Enabled = true;
  615. this->numericUpDownHeight->Enabled = true;
  616. this->radioButtonFemale->Enabled = true;
  617. this->radioButtonMale->Enabled = true;
  618. this->numericUpDownActivityLevel->Enabled = true;
  619. this->groupBoxLifetimeActivity->Enabled = true;
  620. }
  621. }
  622. else
  623. {
  624. this->checkBoxProfileSet->Enabled = false;
  625. this->radioButtonUser1->Enabled = false;
  626. this->radioButtonUser2->Enabled = false;
  627. this->radioButtonGuest->Enabled = false;
  628. this->radioButtonGuest->Enabled = false;
  629. this->numericUpDownProfile->Enabled = false;
  630. this->numericUpDownAge->Enabled = false;
  631. this->numericUpDownHeight->Enabled = false;
  632. this->radioButtonFemale->Enabled = false;
  633. this->radioButtonMale->Enabled = false;
  634. this->numericUpDownActivityLevel->Enabled = false;
  635. this->groupBoxLifetimeActivity->Enabled = false;
  636. }
  637. }
  638. /**************************************************************************
  639. * Functions to update input from numeric boxes:
  640. * Weight, Hydration, Body Fat, Active Metabolic Rate, Basal Metabolic Rate
  641. * Validation of input is done by the control
  642. *
  643. **************************************************************************/
  644. System::Void WeightScaleSensor::numericUpDownWeight_ValueChanged(System::Object^ sender, System::EventArgs^ e)
  645. {
  646. wsPages->usBodyWeight100 = (USHORT) (this->numericUpDownWeight->Value * 100); // Weight in 1/100 kg
  647. }
  648. System::Void WeightScaleSensor::numericUpDown_Hydration_ValueChanged(System::Object^ sender, System::EventArgs^ e)
  649. {
  650. wsPages->usHydrationP100 = (USHORT) (this->numericUpDown_Hydration->Value * 100); // Hydration in 0.01%
  651. }
  652. System::Void WeightScaleSensor::numericUpDown_BodyFat_ValueChanged(System::Object^ sender, System::EventArgs^ e)
  653. {
  654. wsPages->usBodyFatP100 = (USHORT) (this->numericUpDown_BodyFat->Value * 100); // Body fat in 0.01%
  655. }
  656. System::Void WeightScaleSensor::numericUpDown_ActiveMetRate_ValueChanged(System::Object^ sender, System::EventArgs^ e)
  657. {
  658. wsPages->usActiveMetRate4 = (USHORT) (this->numericUpDown_ActiveMetRate->Value * 4); // Active metabolic rate (1/4 kcal)
  659. }
  660. System::Void WeightScaleSensor::numericUpDown_BasalMetRate_ValueChanged(System::Object^ sender, System::EventArgs^ e)
  661. {
  662. wsPages->usBasalMetRate4 = (USHORT) (this->numericUpDown_BasalMetRate->Value * 4); // Basal metabolic rate (1/4 kcal)
  663. }
  664. System::Void WeightScaleSensor::numericUpDown_MuscleMass_ValueChanged(System::Object^ sender, System::EventArgs^ e)
  665. {
  666. wsPages->usMuscleMass100 = (USHORT) (this->numericUpDown_MuscleMass->Value * 100); // Muscle mass (1/100 kg)
  667. }
  668. System::Void WeightScaleSensor::numericUpDown_BoneMass_ValueChanged(System::Object^ sender, System::EventArgs^ e)
  669. {
  670. wsPages->ucBoneMass10 = (UCHAR) (this->numericUpDown_BoneMass->Value * 10); // Bone mass (1/10 kg)
  671. }
  672. System::Void WeightScaleSensor::checkBox_InvalidSerial_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
  673. {
  674. if(this->checkBox_InvalidSerial->Checked)
  675. this->textboxSerialNum->Enabled = false;
  676. else
  677. this->textboxSerialNum->Enabled = true;
  678. }