webOS 프로젝트

webOS를 활용한 HomeIoT : 수면패턴분석2 - Enact App

하이하정 2021. 11. 27. 13:42

  • 전체 시습템 설계
  • 조명제어
  • 스마트 가습기
  • 수면 패턴 분석
  • 시스템 연동

 

Enact webapplication 개발하기


1. Enact 기본 앱 만들기

Enact webapplication의 설치 및 Enact App 개발 시작에 관한 설명은 <Enact 사용하기>를 참고해주세요.

 

2. webapplication의 ui 디자인 & 기능

침대에 압력이 가해졌을 때의 UI

침대에 압력이 가해지면 연결된 디바이스로부터 측정된 압력값을 서비스에서 알맞게 처리하여, 차트로 도식화합니다. 

X축은 시간 단위로, 취침 측정을 시작한 이후부터 표시됩니다. 위 예시에선 19시에 측정이 시작된 것을 볼 수 있습니다.

Y축은 압력의 크기로, 1시간 단위로 압력 변화(이전 압력과 현재 압력의 차이)를 누적한 값을 나타냅니다.

즉, 차트의 높이가 높을수록 침대에 가해지는 압력 변동이 심하다는 것이므로 사용자가 많이 뒤척였다는 사실을 알 수 있습니다.

 

코드


1. MainPanel.js  코드 기능별 설명

앱의 UI를 구현하고, 서비스를 호출하는 코드를 천천히 살펴봅니다.

 

  • 필요한 기능을 import
import React, { useState } from 'react';
import { Bar } from 'react-chartjs-2';
import LS2Request from '@enact/webos/LS2Request';
import './SleepPanel.style.css';
import ReactInterval from 'react-interval';
  • 필요한 서비스 구현

먼저, WebOSServiceBridge Object를 사용하기 위해 아래와 같이 object로 변수를 선언합니다.

사용할 service도 불러옵니다.

var webOSBridge = new LS2Request();
const serviceUrl = 'luna://com.cosmos.project.service';

1. 초기 설정

차트에 대한 option값입니다.

Chart.js는 차트에 애니메이션 효과가 기본으로 들어가있습니다. 애니메이션을 끄기 위해 false값을 줍니다.

responsive 옵션을 true 값을 주면 창의 사이즈에 따라 비율에 맞게 차트 크기가 자동으로 변합니다. 만약 차트를 원하는 사이즈로 고정하는 등의 작업이 필요하다면, false 값을 줍니다.

차트의 bar 두께, x축, y축 등 scale 조절 가능합니다.

const options = {
    animation: false,
    responsive: true,
    scales: {
       yAxes: [{
          ticks: {
             beginAtZero: true,
          },
          barPercentage: 0.1,
          maxBarThickness: 100,
          barThickness: 80
       },],
       xAxes: [{
          barPercentage: 0.1,
          maxBarThickness: 100,
          barThickness: 80
       }],
    },
 };

 

차트에 필요한 변수들과 차트에 나타낼 데이터에 대한 정보를 설정합니다.

차트의 label은 times, data는 values로 나타냅니다. 이 times와 values는 service를 통해 불러옵니다.

  let [values, setValues] = useState([]);
  let [times, setTimes] = useState([]);

  let data = {
     labels: times,
     datasets: [{
        label: 'Bed',
        data: values,
        backgroundColor: [
           'rgba(255, 159, 64, 0.4)',
        ],
        borderColor: [
           'rgb(255, 159, 64)',
        ],
        borderWidth: 1
     }]
  };

 

2. 데이터를 가져오는 서비스 구현

service와 연결이 정상적으로 되었다면 times와 values를 service로부터 받아옵니다.

function getData() {
        const onGetDataSuccess = (msg) => {
            console.log('onGetDataSuccess', msg);
            // console.log('Debugging-before', values, times);
            setTimes(msg.data.times);
            setValues(msg.data.values);
            // console.log('Debugging-after', values, times);
        }
       
        const onGetDataFailure = (msg) => {
            console.log('onGetDataFailure', msg);
        }
       
        var lsRequest ={
            "service":serviceUrl,
            "method": "getSleepData",
            "parameters":{"deviceID":"Sleep00"},
            "onSuccess": onGetDataSuccess,
            "onFailure": onGetDataFailure
        };
 
        console.log("call my getData service");
        webOSBridge.send(lsRequest);
    }

 

3. 차트 나타내기

차트는 Bar 태그로 나타냅니다. 위에서 설정한 data와 options을 넣어줍니다.

  return (
      <>
      <div id='bar-section'>
          <Bar type="bar" data={data} options={options}/>
      </div>
      <ReactInterval timeout={1000} enabled={true} callback={()=>{getData();}}/>
      </>
  );

 

 

2. MainPanel.js  전체 코드

앱을 구성하는 Mainpanel의 전체 코드는 더보기를 통해 확인할 수 있습니다.

더보기
import React, { useState } from 'react';
import { Bar } from 'react-chartjs-2';
import LS2Request from '@enact/webos/LS2Request';
import './SleepPanel.style.css';
import ReactInterval from 'react-interval';

var webOSBridge = new LS2Request();
const serviceUrl = 'luna://com.cosmos.project.service';

const options = {
    animation: false,
    responsive: true,
    scales: {
       yAxes: [{
          ticks: {
             beginAtZero: true,
          },
          barPercentage: 0.1,
          maxBarThickness: 100,
          barThickness: 80
       },],
       xAxes: [{
          barPercentage: 0.1,
          maxBarThickness: 100,
          barThickness: 80
       }],
    },
 };

const SleepPanel = () => {
    let [values, setValues] = useState([]);
    let [times, setTimes] = useState([]);
 
    let data = {
       labels: times,
       datasets: [{
          label: 'Bed',
          data: values,
          backgroundColor: [
             'rgba(255, 159, 64, 0.4)',
          ],
          borderColor: [
             'rgb(255, 159, 64)',
          ],
          borderWidth: 1
       }]
    };

    function getData() {
        const onGetDataSuccess = (msg) => {
            console.log('onGetDataSuccess', msg);
            // console.log('Debugging-before', values, times);
            setTimes(msg.data.times);
            setValues(msg.data.values);
            // console.log('Debugging-after', values, times);
        }
       
        const onGetDataFailure = (msg) => {
            console.log('onGetDataFailure', msg);
        }
       
        var lsRequest ={
            "service":serviceUrl,
            "method": "getSleepData",
            "parameters":{"deviceID":"Sleep00"},
            "onSuccess": onGetDataSuccess,
            "onFailure": onGetDataFailure
        };
 
        console.log("call my getData service");
        webOSBridge.send(lsRequest);
    }
 
    return (
        <>
        <div id='bar-section'>
            <Bar type="bar" data={data} options={options}/>
        </div>
        <ReactInterval timeout={1000} enabled={true} callback={()=>{getData();}}/>
        </>
    );
};

export default SleepPanel;

결과


1. 초기 화면

초기에는 데이터가 없기 때문에 차트는 존재하지만 아무것도 뜨지 않습니다.

초기 UI 화면

2. 데이터를 차트로 띄우기

데이터가 들어오면 1시간마다 누적된 값을 차트로 업데이트시켜줍니다.

아래 차트 예시는 23시에 매우 뒤척였다고 판단할 수 있습니다.

침대에 압력이 가해졌을 때의 UI