Skip to main content
Samsung Developer Program

Heart Rate Monitor (HRM) Sample App Guide

How to build and run a heart rate monitor Web app for a Gear device

 

This workshop guide describes how to build a sample Web application that runs on Gear devices and monitors the user's heart rate.

NOTE:  You can also view and download a PDF version of the Heart Rate Monitor Sample App Guide.

 

To build and run a Heart Rate Monitor app for a Gear Device:

  1. Develop a Heart Rate Monitor App
  2. Connect a Gear Device via Wi-Fi
  3. Create Author and Distributor Certificates and "permit install applications"
  4. Side-Load the App to a Gear Device
  5. Run the App on the Emulator
  6. Debug the App with the Web Inspector Tool

 

1.    Develop a Heart Rate Monitor App

Build your Web app for a Gear device to monitor and display the user's heart rate.

 

Pre-Requisites:

  • Either a Gear S2 device or Gear S3 device is available to run the Web app.
  • Tizen Wearables SDK is installed.

 

1.a.    Create a new Tizen Web project:

1.a.i.    Click File > New >Tizen Project

            HRM_Step1ai.png

1.a.ii.    In the New Tizen Project wizard, select Template, and click Next

            HRM_Step1aii.png

1.a.iii.    Select the Profile & Version as Wearable and Wearable v2.3.1, and click Next

            HRM_Step1aiii.png

1.a.iv.    Select the Application Type as Web application, and click Next

             HRM_Step1aiv.png   

1.a.v.    Select the Template as TAU Basic and click Next

            HRM_Step1av.png

1.a.vi.    Enter the Project name and click Finish

             HRM_Step1avi.png

 

You can see the created project in the Project Explorer View.  The most important files and folders are:

  css Folder for CSS files used by the application to style its content
  js Folder for JavaScript files used by the application to implement its functional logic
  config.xml Application configuration file used by the platform to install and launch the application
  icon.png Application icon file used by the platform to represent the application
  index.html Main HTML file for the layout of the application screen

 

Privileges

 
  • To effectively protect the device system and user private data, the Tizen security architecture is based on privileges and application signing of the Linux basic security model, which includes process isolation and mandatory access control.
 
  • Tizen provides API-level access control for security-sensitive operations.  If this is not used correctly, it can harm user privacy and system stability. Therefore, applications that use such sensitive APIs must declare the required privileges in the config.xml file.
 
  • To access Heart Rate Sensor, declare the following privilege in config.xml file:   

http://tizen.org/privilege/healthinfo

 

1.b.    Add required privileges in order to access heart rate sensor data:

1.b.i.    In the Project Explorer window, select config.xml

     HRM_Step1bi.png


1.b.ii.    Click the  privileges tab and add a new privilege:

    http://tizen.org/privilege/healthinfo

HRM_Step1bii.png

 

1.c.    Add image resources:

1.c.i.    In your project, create a new folder titled images

1.c.ii.   Click to download the heart.png file

1.c.iii.  Copy the heart.png file to the folder.  
       

   HRM_Step1cii_heart.png        HRM_Step1ciii.png        

 

1.d.    Define the application layout by opening index.html and adding HTML code:

a.    Define init() in the 'onload' of the document in order to execute init() immediately after the page has been loaded.

b.    Change the title of the application.

c.    Define the UI to show the Heart Rate value.

d.    Define the UI to show the heart image.

e.    Define the UI to display the measuring status.

f.    Create a UI button to control the sensor operation.

 

<body onload="init()"> ⓐ
    <div class="ui-page ui-page-active" id="main">
        <div class="ui-header">
            <h2 class="ui-title">Heart Rate Monitor</h2> ⓑ
        </div>  
        <div class="ui-content">
            <div id="heart-rate-value"></div> ⓒ
            <div id="heart">
                <div id="heart-img"></div> ⓓ
            </div>
            <div id="measuring-info" class="hide"> ⓔ
                Measuring...
            </div>
        </div>
        <footer class="ui-footer ui-bottom-button">
            <a id="hrm-control-btn" class="ui-btn">Start</a> ⓕ
        </footer>
</div>

 

 

g.    Create a TAU UI component “ui-page” to create a second page that displays information to the user when the sensor is not working.  

h.    Create TAU UI component – Bottom Button  (“ui-bottom-button”) which displays “Back” text  

i.    Create a title for the second page by using a "ui-title" TAU UI component  

ii.   Create a UI to display information text  

 

<div class="ui-page" id="info"> ⓖ
    <div class="ui-header">
        <h2 class="ui-title">HRM Info</h2> ⓧ
    </div>
    <div class="ui-content">
        <div class="info-text"> ⓨ
            Try again. Clean the sensor, wear the watch properly.
        </div>
    </div>
    <footer class="ui-footer ui-bottom-button">
        <a id="info-back-btn" class="ui-btn">Back</a> ⓗ
    </footer>
</div>

 

 

i.    TAU Theme: tau.circle.(min).css OR tau/wearable/js/tau.min.js 
        It is mandatory for wearable devices, as it imports themes for wearables.

j.    Circle-helper.js contains TAU helper modules for displaying circular UI components.

k.    Load your java script file

l.    lowBatteryCheck.js is a default JS file that is available with the TAU template.
        If the device battery level reaches below a threshold, it closes the app. Usually, the platform closes the app when the device is in low power and turns off the device. If your app         wants to implement some logic (save the status of the app or data, etc), you can use this file to implement the logic.

 

    <script type="text/javascript" src="lib/tau/wearable/js/tau.min.js"></script> Ⓘ
    <script type="text/javascript" src="js/circle-helper.js"></script> ⓙ
    <script src="./js/app.js"></script> ⓚ
    <script src="lowBatteryCheck.js"></script> ⓛ
</body>
</html>

 

 

1.e.    Add styles to HTML elements to manage the styles and positioning of UI elements:

Cascading Style Sheets (CSS) specify the layout and the styling of the Web application.

  # is an “id selector” Used to select a single specific element with a unique ID.
  . is a “class selector” Used to target multiple elements with a particular class name.

 

 

1.e.i.    In the Project Explorer, open the styles.css file and add the following code:

 

@keyframes 

The @keyframes rule specifies the animation code. Specify when a style change will happen in percent  (from 0% to 100%).  

The sample Web app specifies the image size at 0%, 50%, 100% and changes the image to a smaller size of 25% and 75%.

 

@Media queries

Media queries allow you to apply the CSS differently according to the type of device.  To define media queries for a circular Tizen device in the CSS, use the format:
“@media screen and (-tizen-geometric-shape: circle) {<styles>}”

 

.ui-title {
    font-size: 25px !important;
}

.ui-content {
    font-size: 20px;
}

#heart-rate-value {
    position: absolute;
    text-align: center;
    width: 100%;
    height: 20%;
    font-size: 17vh;
    font-weight: bold;
    z-index: 100;
    margin-top: 15%;
    color: #ffffff;
}

#heart {
    position: absolute;
    width: 100%;
    height: 85%;
}

#heart-img {
    margin: 5% auto;
    background-image: url(../images/heart.png);
    background-position: center;
    background-size: cover;
    width: 60%;
    height: 60%;
}

#measuring-info {
    position: absolute;
    float: left;
    margin-left: 1%;
    color: white;
    font-size: 20px;
}

.show {
    display: inline-block;
}

.hide {
    display: none;
}

.ui-footer {
    background-color: transparent;
}

.info-text {
    text-align: left;
    color: #ffffff;
    font-size: 24px;
}

@-webkit-keyframes heartMove360 {  ⓐ
    0%, 50%, 100% {
        width: 35%;
        height: 35%;
    }
    25%, 75% {
        width: 45%;
        height: 45%;
    }
}

@media screen and (-tizen-geometric-shape: circle) {  ⓑ
    .ui-header {
        height: 90px;
    }
    
    #measuring-info {
        position: relative;
        margin-left: 7%;
    }
    
    #heart-img {
        width: 45%;
        height: 45%;
    }
    
    .animate {
        -webkit-animation: heartMove360 1.5s infinite;
    }
    
    .ui-footer {
        height: 20%;
    }
    
    .info-text {
        text-align: center;
        margin-left: 5%;
        margin-right: 5%;
    }
}

 

 

1.f.    Implement the app’s functional logic by opening the app.js file in Project Explorer and by adding JavaScript code to define the variables for measuring HR:

  INFO_SETTIMEOUT_DELAY After starting the HRM sensor, it takes couple of seconds to get the Heart Rate data.  A timer is stated when the sensor is started, but we do not get any data yet and also display contextual text “Measuring…” to the user
  INFO_SHOW_DELAY A timer is started when “info” page is shown. After the specified time interval (milliseconds), it is redirected to “Main” page.
  TEXT_STOP To set the value of the bottom button to “Stop”
  TEXT_START To set the value of the bottom button to “Start”
  heartRateEl Variable that has the HR sensor value and updates the value of <div> heart-rate-value
  heartImg Variable to add animation to the heart image.
  infoBackBtn Variable for <div>info-back-btn
  hrmControlBtn Variable for <div> hrm-control-btn
  measuringText Variable to change the label of <div> measuring-info
  sensorStarted Boolean variable to toggle the value between “started” and “stopped”

      

/*global tau*/
/*exported init*/

var INFO_SETTIMEOUT_DELAY = 10000;  ⓐ
var INFO_SHOW_DELAY = 10000;  ⓑ
var TEXT_STOP = 'Stop';  ⓒ
var TEXT_START = 'Start';  ⓓ

var heartRateEl;  ⓔ
var heartImg;  ⓕ
var infoBackBtn;  ⓖ
var hrmControlBtn;  ⓗ
var measuringText;  Ⓘ

var infoTimeoutEnd = 0;
var infoTimeout = 0;

var sensorStarted = false;  ⓙ

/*
 * Function invoked on onload event
 */
function init() 
{
    console.log("init() called...");
    heartRateEl = document.getElementById('heart-rate-value');
    heartImg = document.getElementById('heart-img');
    infoBackBtn = document.getElementById('info-back-btn');
    hrmControlBtn= document.getElementById('hrm-control-btn');
    measuringText = document.getElementById('measuring-info');
    
    //Registering click event handler for buttons.
    infoBackBtn.addEventListener('click', onInfoBackBtnClick);
    hrmControlBtn.addEventListener('click', onhrmControlBtnClick);
}

/*
 * Click event handler for HRM sensor Start/Stop
 * Toggles the sensor state.
 */
function onhrmControlBtnClick() {
    console.log("onhrmControlBtnClick() called...");
    
    if (hrmControlBtn.innerHTML === TEXT_START){
        console.log("info on button = start");
        startSensor();
    } else {
        console.log("info on button = stop");
        stopSensor();
    }
}

/*
 * Starts the HRM sensor and registers a change listener.
 * Update the UI: Shows measuring text, and change button text to Stop.
 */    
function startSensor() {
    console.log("start sensor() called...");
    sensorStarted = true;
    clearTimers();
    measuringText.classList.remove('hide');
    measuringText.classList.add('show');
    hrmControlBtn.innerHTML = TEXT_STOP;
    
    tizen.humanactivitymonitor.start('HRM', onHeartRateDataChange, onerrorCB);
}

/*
 * Clear the timers if running for handling the information popup.
 */
function clearTimers() {
    console.log("Clear timers() called");
    window.clearTimeout(infoTimeout);
    window.clearTimeout(infoTimeoutEnd);
    infoTimeout = 0;
    infoTimeoutEnd = 0;
}

/*
 * Callback function Handles change event on current heart rate.
 * 
 */
function onHeartRateDataChange(heartRateInfo) {
    console.log("onHeartRateDataChange() called...");
    if (!sensorStarted){
        return;
    }
    
    var rate = heartRateInfo.heartRate;
    var activePage = document.getElementsByClassName('ui-page-active')[0];
    var activePageId = activePage ? activePage.id : '';

    /*
     * If heart rate value is invalid-
     * Remove heart image animation, 
     * Displays measuring text and start a timer to show the information popup after 10 seconds. 
     */
     
    if (rate < 1) {
        console.log("Heart rate value < 1");
        rate = 0;
        heartRateEl.innerHTML = '';
        heartImg.classList.remove('animate');
        measuringText.classList.remove('hide');
        measuringText.classList.add('show');

        /* Start a timer when sensor is started but not able to measure the heart rate
         * showMeasuringInfo() function will be execute after 10 sec and will show a info popup.
         */
         
        if (activePageId === 'main' && infoTimeout === 0) {
            infoTimeout = window.setTimeout(showMeasuringInfo, INFO_SETTIMEOUT_DELAY);
        }
    } else {
        /*
         * If heart rate value is valid
         * Clear all the timers to  handle info popup
         * Hides measuring text
         * Start the animation on heart image
         * and displays the heart rate value.
         */
        clearTimers();
        hideMeasuringInfo();
        console.log("heartRateEl is valid information...");
        if (!heartImg.classList.contains('animate')) {
            heartImg.classList.add('animate');
            measuringText.classList.remove('show');
            measuringText.classList.add('hide');
        }
        heartRateEl.innerHTML = rate;
    }
}

/* 
 * Call back when an error occurs */
 
function onerrorCB(error) {
    console.log("Error name:"+error.name + ", message: "+error.message);
}

/*
 * Displays information popup.
 */
function showMeasuringInfo() {
    console.log("showMeasuringInfo() called..");
    infoTimeout = 0;
    tau.changePage('#info');
    
    /* Start a timer when info popup is shown
     * hideMeasuringInfo() function will be execute after 10 sec and which will redirect to main page.
     */
    infoTimeoutEnd = window.setTimeout(hideMeasuringInfo, INFO_SHOW_DELAY);
}

/*
 * Hides information popup, redirects to main page.
 */
function hideMeasuringInfo() {
    console.log("hideMeasuringInfo() called..");
    tau.changePage('#main');
    infoTimeoutEnd = 0;
}

/*
 * Stops the sensor
 * Clears timers (to handle info popup)
 * Update the UI: Hides measuring text, stop animation on heart image and change button text to Start.
 */    
function stopSensor() {
    console.log("stopSensor() called...");
    sensorStarted = false;
    heartImg.classList.remove('animate');
    measuringText.classList.remove('show');
    measuringText.classList.add('hide');
    
    clearTimers();    
    
    tizen.humanactivitymonitor.stop("HRM");
    hrmControlBtn.innerHTML = TEXT_START;
}

/*
 * Click event handler for back button on info page
 * Hides the information popup and redirects to main page.
 */
function onInfoBackBtnClick() {
    console.log("onInfoBackBtnClick() called...");
    window.clearTimeout(infoTimeoutEnd);
    infoTimeoutEnd = 0;
    tau.changePage('#main');
}

( function () {
    
    window.addEventListener( 'tizenhwkey', function( ev ) {
        if( ev.keyName === "back" ) {
        var page = document.getElementsByClassName( 'ui-page-active' )[0], pageid = page ? page.id : "";
            if( pageid === "main" ) {
                try {
                    tizen.humanactivitymonitor.stop("HRM");
                    tizen.application.getCurrentApplication().exit();
                } catch (ignore) {
                }
            } else {
                window.history.back();
            }
        }
    } );
    
} () );

 

 

 

 

2.    Connect a Gear Device via Wi-Fi

To connect a Gear S2 or S3 device to a host PC, a wireless access point is needed (Wi-Fi with no firewalls). Both the Gear device and the host PC must be connected to the same Wi-Fi.

  • Set up the connection.
  • Connect the Gear device using Tizen Studio or a terminal command.
  • Accept the RSA key.
     

2.a.    In the Gear device, set up the connection:

2.a.i.    Go to Settings > Connections and turn on Wi-Fi.

2.a.ii.    Go to Settings > Gear Info and turn on Debugging.

2.a.iii.    Reboot the Gear device.
 

2.b.    Connect the Gear device to the Wireless Access Point:

2.b.i.    In the Gear device:

2.b.i.1.a.    In the Wi-Fi menu, find the Wireless Access Point and connect to it.

2.b.i.1.b.    Turn off Bluetooth by going to Settings > Connections > Bluetooth

2.b.i.1.c.    After the Gear device UI indicates it is connected, find the IP address assigned to  the Gear device by the Access Point via DHCP by going to                     Settings>Connections> Wi-Fi>Wi-Fi Networks > Select the Wi-Fi you are connected > IP Address        

HRM_Step2bi1c.png

2.b.i.1.d.    Note the IP address of the Gear device.

 

2.b.ii.    Connect to the Gear device:
                NOTE:  You can use either of 2 ways to connect:

  • Via a command line
  • From within Tizen Studio

2.b.i.2.a.    Connect to the Gear device by using a terminal and the following command:

 

$ sdb connect [WiFi network IP address]:26101

For example:

$sdb connect 192.168.0.130:26101

 

2.b.i.2.b.    Connect to the Gear device in Tizen Studio:

2.b.i.2.b.i.    Go to Window > Show View > Connection Explorer
                    This will make the Connection Explorer view visible in the right panel of Tizen Studio.

2.b.i.2.b.ii.    In the Connection Explorer view toolbar, click the [Remote Device Manager icon]

HRM_Step2bi2biiA.png
 

HRM_Step2bi2biiB.png

  The Remote Device Manager lists all remote devices on the host system's subnet.  If the IP address of the Gear device is not listed, verify that you have performed all previous steps correctly.

 

2.b.i.2.b.iii.    In the Remote Device Manager:

2.b.i.2.b.iii.1.    Select the listed remote device with the IP address assigned to the Gear device.

2.b.i.2.b.iii.2.    Click Connect

 

NOTE:  Later, you can add remote devices and change remote device information in the Remote Device Manager window:

  • To add remote device information: click New, and enter the Name, IP and Port field entries of the new remote device.
  • To modify remote device information: select the device, click Edit, and modify the Name, IP, and/or Port field entries.

 

2.b.iii.    In the Gear device, a popup notice will be displayed.  Accept the RSA key.

 

 

3.    Create Author and Distributor Certificates and "permit install         applications"

To run a Web application on a commercial device, you must create a Tizen author and distributor certificates from the Samsung certificate center.
 

3.a.   Generate a certificate profile:

3.a.i.     In Tizen Studio, select Tools > Certificate Manager

            HRM_Step3ai.png

3.a.ii.    Click the [Plus icon]

3.a.iii.   Click [Type of certificate profile]

            HRM_Step3aiii.png
            

3.a.iv.    Click Close

            HRM_Step3aiv.png

3a.v.    Select Mobile / Wearable type of device.

3.a.vi.    Click Next
             
 

3.b.    Create a certificate profile:

            HRM_Step3b.png

3.b.i.    Select Create a new certificate profile

3.b.ii.    Enter the name of the profile.

3.b.iii.   Click Next

             

3.c.    Create an author certificate:

            HRM_Step3c.png

3.c.i.    Select Create a new author certificate

3.c.ii.    Click Next

            HRM_Step3cii.png

3.c.iii.    Enter the author and password information.

3.c.iv.    Optional   Checkmark Apply the same password for the distributor certificate

3.c.v.    Click Next

3.c.vi.   If you are not logged in, log in to your Samsung account.

            HRM_Step3cvi.png

3.c.vii.    When the Congratulations! window is displayed, author certificate generation is complete.  

                HRM_Step3cvii.png

3.c.viii.    Click Next
 

3d.    Create a distributor certificate:

            HRM_Step3d.png

3.d.i.    Select Create a new distributor certificate

3.d.ii.   Click Next

             HRM_Step3dii.png

3.d.iii.    Enter the privilege level, password, and device unique ID (DUID) information.

3.d.iv.    Click Next

3.d.v.    Verify that the DUIDs of connected devices are in the Add individual DUIDs list.

3.d.vi.   When the Congratulations! window is displayed, distributor certificate generation is complete.  Click Finish

             HRM_Step3dvi.png

3.d.vii.   When the Create Certificate Profile popup window is displayed, profile generation is complete.  Click OK

              HRM_Step3dvii.png

3.d.viii.    In the Certification Manager, review the certificate profile name and certificate information.  Click Close

     
 

3.d.ix.   In the Connection Explorer, right-click your Gear device and select Permit to install applications

    

  This transfers the certificate info to the device (from device-profile.xml to the /home/developer folder of device).

 

3.d.x.    When the upload success popup is displayed, click OK

            

 

\

4.    Side-Load the App to a Gear Device

Side-load install the Web app to a Gear device by using EITHER the Project Explorer or a terminal command.

4.a.    Via Project Explorer:

4.a.i.    In Tizen Studio, go to the Project Explorer.

4.a.ii.    Right click on your project and select Run as > Tizen Web Application
Your application will be installed on your Gear device.
 

4.b.    Via a terminal and the following command:

  $ sdb install <pkg-file> 

 

 

 

5.    Run the App on the Emulator

Tizen Studio provides an emulator to run your Gear app.

5.a.    Create and launch an emulator instance:

5.a.i.    In the Connection Explorer view, launch the Emulator Manager by clicking the [Emulator Manager icon]

            

5.a.ii.    In the Emulator Manager window, click  + Create

            

5.a.iii.   In the Emulator Configuration window:

             

5.a.iii.1.    Select wearable-2.3.2-circle (basic),  and click Next

5.a.iii.2.    Select the [Device definition for the platform version], and click Next

                

5.a.iii.3.    Specify the emulator properties.
                    You can leave the options set to their default values.

                

5.a.iii.4.    Click Finish
 

5.a.iv.    In the Emulator Manager, launch the emulator instance:

   

 

5.a.iv.1.    Select the emulator.

5.a.iv.2.    Click Launch

  The emulator is launched in its own window. You can also see the new emulator instance in the Connection Explorer view. To view the emulator folder structure, click the arrow next to the emulator instance.

 

5.b.    In the Project Explorer, launch your app:

          

5.b.i.    Right-click on your project and select Run as > Tizen Web Application
            Your application will be installed and run in the emulator

 

 

 

 

6.    Debug your Gear App with the Web Inspector Tool

Debugging a Web application on the target device enables you to understand its flow of control.
You can debug your Web Gear application by running it on the target device and debugging its JavaScript code. JavaScript code debugging uses the Web Inspector tool.
 

6.a.    Connect the target device to your computer.

6.b.    Open the Debug Configurations window by EITHER of the following:

  • In the Project Explorer view, right-click the project and select Debug As > Debug Configurations
  • In the Tizen Studio menu, go to Run > Debug Configurations
     

6.c.    In the Debug Configurations window, click New Launch Configuration

6.d.    Set the timeout using the Timeout value slider.

The timeout value represents the waiting time for the application launch operation. If you are using a lower configuration system, set a higher timeout value to avoid application launch failure errors.

6.e.    Enable debugging by clicking Debug
            NOTE:   You must enable debugging before debugging JavaScript code.

The Web Inspector tool is displayed in a new Chrome browser window. You can perform the following debugging tasks using the Web Inspector:

  • Inspect styles
  • Inspect the DOM
  • Inspect resources
  • Debug JavaScript code

 

NOTE:   The Web Inspector always opens in a new window. Life-cycle synchronization between the application to be debugged and the Web Inspector browser is not supported. Installing Google Chrome on the device is mandatory for the Web Inspector to work. When Google Chrome is installed, the Tizen Studio automatically detects it.

To select the browser path, go to Window > Preferences > Tizen Studio > Web > Chrome

 

6.f.    In the Web Inspector menu , click Sources

You can set a break point in the code by: right-clicking in the marker bar area on the left side of the editor, and selecting Toggle Breakpoint.   After the break points have been set, you can watch variables, expressions, and the current call stack.

You can control the debugging by using the following control buttons:

  HRM_Step6fA.png Resumes the current execution.
  Steps over the highlighted statement.
Executes the current line, and if the line contains a method, executes the method without entering it.
  Steps into the highlighted statement.
Executes the current line, and if the line contains a method, steps into the method.
  Steps out of the current method.
  Deactivates all break points.

 

If the Web app successfully launches on the target device, the JavaScript Log Console View is automatically launched in Tizen Studio. The JavaScript Log Console view displays Web app JavaScript logs.

  • Was this article helpful?