
- 전체 시습템 설계
- 조명제어
- 스마트 가습기
- 수면 패턴 분석
- 시스템 연동
Enact webapplication 개발하기
1. Enact 기본 앱 만들기
Enact webapplication의 설치 및 Enact App개발 시작에 관한 것은 기존 게시글을 참고해주세요.
2. wepappication의 UI 디자인 & 기능

코드
1. MainPanel.js 전체 코드
import imgHumidOn from '../../../resources/humidOn.png';
import imgHumidOff from '../../../resources/humidOff.png';
import './HumidityPanel.style.css';
import Switch from '@enact/sandstone/Switch';
import Dropdown from '@enact/sandstone/Dropdown';
import {useState} from 'react';
import Image from '@enact/sandstone/Image';
import BodyText from '@enact/sandstone/BodyText';
import Button from '@enact/sandstone/Button';
import LS2Request from '@enact/webos/LS2Request';
import ReactInterval from 'react-interval';
const bridge = new LS2Request();
const serviceUrl = 'luna://com.cosmos.project.service';
const lsSetTargetHum = (value) => {
let request = {
service: serviceUrl,
method: 'setTargetHum',
parameters: {value:value},
onSuccess: (msg) => {console.log(msg);},
onFailure: (msg) => {console.log(msg);},
};
bridge.send(request);
};
const lsSetIsHumdOn = (value) => {
let request = {
service: serviceUrl,
method: 'setHumdOn',
parameters: {value:value},
onSuccess: (msg) => {console.log(msg);},
onFailure: (msg) => {console.log(msg);},
};
bridge.send(request);
};
const startServer = () => {
const onSocketOnSuccess = (msg) => {console.log(msg)};
const onSocketOnFailure = (msg) => {console.log(msg)};
let request = {
service: serviceUrl,
method: 'startServer',
parameters: {},
onSuccess: onSocketOnSuccess,
onFailure: onSocketOnFailure,
};
bridge.send(request);
};
const WhichText = function(props) {
if(props.isSwitchOn) {
if(props.isHumdOn) {
return (<span> [자동모드 On] 가습기 동작 중입니다.</span>);
}
else {
return (<span> [자동모드 On] 목표습도에 도달하였습니다.</span>);
}
}
else {
return (<span> [자동모드 Off] 가습기가 꺼져있습니다. </span>);
}
};
const getIndexFromHumdValue = (value) => {
let index = 0;
switch (value) {
case 45: index = 0; break;
case 50: index = 1; break;
case 55: index = 2; break;
case 60: index = 3; break;
}
return index;
};
const getHumdValueFromIndex = (index) => {
let value = 0;
switch (index) {
case 0: value = 45; break;
case 1: value = 50; break;
case 2: value = 55; break;
case 3: value = 60; break;
}
return value;
};
const HumidImage = (props) => {
return (
<>
<Image
src={props.isOnOff ? imgHumidOn : imgHumidOff}
sizing={'fill'}
onLoad={console.log('image onLoad')}
style={{
border: '#ffa500 dashed 0px'
}}
></Image>
</>
);
};
const HumidityPanel = () => {
// 현재 온도
let [currentTemp, setCurrentTemp] = useState(18);
// 현재 습도
let [currentHum, setCurrentHum] = useState(45);
// 가습기 동작 중인지 아닌지
let [isHumdOn, setIsHumdOn] = useState(false);
// 토글버튼 on인지 off인지
let [isSwitchOn, setIsSwitchOn] = useState(false);
// 목표 습도
let [targetHum, setTargetHum] = useState(45);
const handleHumdControlData = (data) => {
setCurrentTemp(data.currentTemp);
setCurrentHum(data.currentHum);
setIsHumdOn(data.isHumdOn);
setTargetHum(data.targetHum);
};
let request = {
service: serviceUrl,
method: 'getHumdControlData',
parameters: {},
onSuccess: (msg) => {handleHumdControlData(msg.data);},
onFailure: (msg) => {console.log('getHumdControlDataFailure', msg);},
};
bridge.send(request);
return (
<>
<div className="my-container">
<div className="imgtop">
<HumidImage isOnOff={isHumdOn}></HumidImage>
</div>
<div className="drop">
<Dropdown
className = "down"
defaultSelected={getIndexFromHumdValue(targetHum)}
onSelect={(e)=>{targetHum = getHumdValueFromIndex(e.selected); lsSetTargetHum(targetHum);}}
inline
title="목표 습도를 선택하세요(Humidifier)">
{['45%(겨울)', '50%(봄, 가을)', '55%(여름)','60%(기본 값)']}
</Dropdown>
</div>
<div className="texttop">
<BodyText>
------------------ 현재습도 ------------------
</BodyText>
<BodyText>
현재 이 곳은 온도 {currentTemp}도, 습도는 {currentHum}%입니다.
</BodyText>
</div>
<div className="textmid">
<BodyText>
--------------- 가습기 ON/OFF ---------------
</BodyText>
<div>
<span><Switch onToggle={ (e)=>{setIsSwitchOn(e.selected); setIsHumdOn(e.selected); lsSetIsHumdOn(e.selected);}}/></span>
<WhichText isHumdOn={isHumdOn} isSwitchOn={isSwitchOn}></WhichText>
</div>
<Button onClick={startServer}>server 켜기</Button>
</div>
<ReactInterval timeout={1000} enabled={true}
callback={() => {bridge.send(request);}} />
</div>
</>
);
};
export default HumidityPanel;
2. MainPanel.js 코드 설명
- 필요한 기능을 import
import Switch from '@enact/sandstone/Switch';
import Dropdown from '@enact/sandstone/Dropdown';
import {useState} from 'react';
import Image from '@enact/sandstone/Image';
import BodyText from '@enact/sandstone/BodyText';
import Button from '@enact/sandstone/Button';
import LS2Request from '@enact/webos/LS2Request';
import ReactInterval from 'react-interval';
ui 디자인에 있는 이미지도 같이 import 해줍니다.
import imgHumidOn from '../../../resources/humidOn.png';
import imgHumidOff from '../../../resources/humidOff.png';
import './HumidityPanel.style.css';
- 서비스 구현
1. 서버를 여는 service
'server' 버튼을 누르면 서버 여는 서비스를 실행하는 함수를 구현합니다.
Enact에서 LS2 API(Luna Service API) 사용하기에 대해 <Enact LS2 API 호출하기>에 자세하게 설명되어 있으니 참고바랍니다.
const startServer = () => {
const onSocketOnSuccess = (msg) => {console.log(msg)};
const onSocketOnFailure = (msg) => {console.log(msg)};
let request = {
service: serviceUrl,
method: 'startServer',
parameters: {},
onSuccess: onSocketOnSuccess,
onFailure: onSocketOnFailure,
};
bridge.send(request);
};
2. Enact app에서 service로 value 값 전달
목표습도의 value값과 가습기가 on/off 상태를 service로 보냅니다.
값이 잘 전달되었는지 log를 통해 확인합니다.
const lsSetTargetHum = (value) => {
let request = {
service: serviceUrl,
method: 'setTargetHum',
parameters: {value:value},
onSuccess: (msg) => {console.log(msg);},
onFailure: (msg) => {console.log(msg);},
};
bridge.send(request);
};
const lsSetIsHumdOn = (value) => {
let request = {
service: serviceUrl,
method: 'setHumdOn',
parameters: {value:value},
onSuccess: (msg) => {console.log(msg);},
onFailure: (msg) => {console.log(msg);},
};
bridge.send(request);
};
3. 가습기 on/off상태와 습도에 따라 문구를 설정
가습기가 켜져있고, 목표 습도에 아직 도달하지 않았을 경우 -> "가습기가 동작 중입니다."
가습기가 켜져있고, 목표 습도에 도달한 경우 -> "목표습도에 도달하였습니다."
가습기가 꺼져있는 경우 -> "가습기가 꺼져있습니다."
const WhichText = function(props) {
if(props.isSwitchOn) {
if(props.isHumdOn) {
return (<span> [자동모드 On] 가습기 동작 중입니다.</span>);
}
else {
return (<span> [자동모드 On] 목표습도에 도달하였습니다.</span>);
}
}
else {
return (<span> [자동모드 Off] 가습기가 꺼져있습니다. </span>);
}
};
4. 목표 습도에 따라 case를 분류해줍니다.
const getIndexFromHumdValue = (value) => {
let index = 0;
switch (value) {
case 45: index = 0; break;
case 50: index = 1; break;
case 55: index = 2; break;
case 60: index = 3; break;
}
return index;
};
const getHumdValueFromIndex = (index) => {
let value = 0;
switch (index) {
case 0: value = 45; break;
case 1: value = 50; break;
case 2: value = 55; break;
case 3: value = 60; break;
}
return value;
};
5. 현재 온도, 습도와 토글버튼과 가습기 on/off 여부를 service로 보내줍니다.
useState를 이용하여 현재 온도는 18도, 현재 습도는 45%로 초기 값을 설정해줍니다.
가습기의 동작 여부와 토글 버튼의 상태는 false 변수로 저장합니다.
const HumidityPanel = () => {
// 현재 온도
let [currentTemp, setCurrentTemp] = useState(18);
// 현재 습도
let [currentHum, setCurrentHum] = useState(45);
// 가습기 동작 중인지 아닌지
let [isHumdOn, setIsHumdOn] = useState(false);
// 토글버튼 on인지 off인지
let [isSwitchOn, setIsSwitchOn] = useState(false);
// 목표 습도
let [targetHum, setTargetHum] = useState(45);
const handleHumdControlData = (data) => {
setCurrentTemp(data.currentTemp);
setCurrentHum(data.currentHum);
setIsHumdOn(data.isHumdOn);
setTargetHum(data.targetHum);
};
let request = {
service: serviceUrl,
method: 'getHumdControlData',
parameters: {},
onSuccess: (msg) => {handleHumdControlData(msg.data);},
onFailure: (msg) => {console.log('getHumdControlDataFailure', msg);},
};
bridge.send(request);
6. Enact 기능
목표 습도를 선택하는 드롭다운과 가습기 on/off를 제어하는 토글버튼을 구현해줍니다.
또한, 현재 온도와 습도 값을 받아와 화면에 표시되도록 코딩하였습니다.
<div className="my-container">
<div className="imgtop">
<HumidImage isOnOff={isHumdOn}></HumidImage>
</div>
<div className="drop">
<Dropdown
className = "down"
defaultSelected={getIndexFromHumdValue(targetHum)}
onSelect={(e)=>{targetHum = getHumdValueFromIndex(e.selected); lsSetTargetHum(targetHum);}}
inline
title="목표 습도를 선택하세요(Humidifier)">
{['45%(겨울)', '50%(봄, 가을)', '55%(여름)','60%(기본 값)']}
</Dropdown>
</div>
<div className="texttop">
<BodyText>
------------------ 현재습도 ------------------
</BodyText>
<BodyText>
현재 이 곳은 온도 {currentTemp}도, 습도는 {currentHum}%입니다.
</BodyText>
</div>
<div className="textmid">
<BodyText>
--------------- 가습기 ON/OFF ---------------
</BodyText>
<div>
<span><Switch onToggle={ (e)=>{setIsSwitchOn(e.selected); setIsHumdOn(e.selected); lsSetIsHumdOn(e.selected);}}/></span>
<WhichText isHumdOn={isHumdOn} isSwitchOn={isSwitchOn}></WhichText>
</div>
<Button onClick={startServer}>server 켜기</Button>
</div>
<ReactInterval timeout={1000} enabled={true}
callback={() => {bridge.send(request);}} />
</div>
</>
);
};
결과

'webOS 프로젝트' 카테고리의 다른 글
webOS를 활용한 HomeIoT : 수면패턴분석1 - 디바이스 (0) | 2021.11.27 |
---|---|
webOS를 활용한 HomeIoT : 스마트 가습기3 - 서비스 (0) | 2021.11.27 |
webOS를 활용한 HomeIoT : 스마트 가습기1 - 디바이스 (0) | 2021.11.27 |
webOS를 활용한 HomeIoT : 조명제어3 - 서비스 (0) | 2021.11.27 |
webOS를 활용한 HomeIoT : 조명제어2 - Enact App (0) | 2021.11.27 |