2016년 3월 17일 목요일

Gear S2 로 문열기 - 4편 (시계 app 만들고 테스트하기)


별것도 아닌 것 같이 보이는 이 사진을 찍기 위해 하루를 날렸다 ㅡ,.ㅡ;;

그냥 윈도우 하나 만들고 버튼을 넣고 '문열어'를 labeling 하고 touch callback 을 걸어서 button 을 touch 하면 문여는 명령을 날리는 app 인데...

큰 시행착오가 있었는데 글의 분량을 줄이기 위해서 skip 하고 바로 본 게임으로 들어간다.
(시행착오는 Tizen IDE 를 ubuntu 에 설치 했던 것인데... 이것 때문에 반나절을 버렸다. 정신 건강을 위해 window 나 mac 에서 작업 하기를 강하게 권장한다. 많은 문제를 직접 해결하기를 즐기는 개발자라면 말리지는 않겠지만....)


1. Tizen SDK 를 다운로드하고 설치 해 준다.

 - 설치 과정은 공식 페이지를 참조

2. Basic UI template 을 하나 만들어 준다.

 - Menu > File > New > Tizen Native Project > Template > Basic UI
 - Project 이름은 적당히 작명을 하고 Finish 를 눌러 project 를 생성한다.

3. Basic UI 의 'Hello Tizen' Label 을 지우고 '문열어' 버튼을 넣고 callback 을 걸어 둔다.

 - 아래 코드만 수정해도 Emulator 에서 터치까지 잘 동작한다.
static void
_button_click_cb(void *data, Evas_Object *button, void *ev)
{
dlog_print(DLOG_INFO, LOG_TAG, "기다려 아직 안 만들었어 @@");
}
static void
create_base_gui(appdata_s *ad)
{
....
Evas_Object* button;
 ad->button = elm_button_add(ad->conform);
elm_object_text_set(ad->button, "문열어~");
evas_object_size_hint_weight_set(ad->button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(ad->button, EVAS_HINT_FILL, 0.5);
elm_object_content_set(ad->conform, ad->button);
evas_object_smart_callback_add(ad->button, "clicked", _button_click_cb, NULL);
}

4. Gear S2 에 설치 해 본다.

 여기서 부터 시간이 좀 걸렸는데 SDK 를 설치할 때 아무 생각없이 default 로만 설치 해서 Certificate (인증서) 관련된 것들은 어떻게 하는지 도무지 알 수가 없었다. 하고 나면 간단한 것들이 알기전에는 왜 그리 어려운지... 이럴 때는 가이드를 찾기 쉬운게 좋은 개발 환경인데 Tizen 은 아직 거기까지는 오지 않은 것 같다.

 - Gear S2 에 패키지를 설치 할 수 있게 설정한다.
  . Settings > Gear info > Debugging 을 켜 준다.
  . Bluetooth 를 끄고 Wifi 를 잡아준다.
  . Gear S2 와 PC 가 동일한 공유기에 물려 있어야 한다.

- IDE 에 Connection Explorer 에서 Remote Device Manager 를 통해 Gear S2 를 연결한다.

 - tizen-sdk/update-manager 에 있는 update-manager 를 실행해서 All Packages 의
  Certificate Extension 을 설치해 준다.
 - Certificate Extension 을 설치하면 IDE 에서 'Register Certificate' 라는 툴바 버튼이 생긴다.
 - 생성된 버튼을 누르면 4 Step 을 통해서 인증서를 생성할 수 있다. 이 과정에서 samsung account 가 필요하다. 
인증서가 정상적으로 만들어 졌을 때 화면


  setp 1. Device Type 을 선택한다.
   >> Gear S2 이기 때문에 Mobile/Wearable 을 선택해 준다.

  setp 2. Security Profile 을 만들어 준다.
   >> Profile 이름만 지어 주면 끝.

  setp 3. Author certificate 를 만든다.
   >> Request 를 눌러 주면 samsung account 에 sign in 하라고 창이 뜬다.

   >> sign in 을 하면 잠시 뒤 author.p12 파일이 생성된다.

  setp 4. Distibutor certificate 를 만든다.
   >> request 를 하면 아래 창이 뜨는데 연결해 둔 Gear S2의 UUID 가 우측에 자동으로 뜨는데 이것을 add 해 주고 password 를 넣어 주고 request 하면 끝. 
 - menu > Run > Debug 를 눌러서 빌드가 제대로 되는지, 패키지가 정상적으로 설치되는지 확인해 주고 앱이 뜨면 터치 해 본다.

5. Socket Client 코드를 넣어준다.

[수정 2016/03/18] socket 에서 curl 로 바꾸고 rest api 를 사용하게 했다.

 - 이제 팔부 능선은 넘어왔고 마지막으로 socket 을 사용해서 raspberry pi 에게 문열어 달라고 요청할 코드를 넣어 준다. SDK API 문서에서 열심히 socket api 를 찾았었는데 별도로 tizen api 가 존재 하지는 않고 legacy socket 을 그래도 사용할 수 있었다.
 - 한가지 주의할 점은 socket 을 쓰려면 privilege 를 추가해 줘야 한다.
  Tizen-manifest.xml 파일을 IDE 에서 선택하면 'Manifest Content' 항목에서 Privilieges 를 선택하고 필요한 권한을 추가해 준다. 나는 network/internet 관련된 것들을 모두 추가 해 줬더니 동작 했다.
 - 중요한 부분만 옮겨 왔고 자세한 코드는 Tizen 웹페이지 을 참조 하면 된다.
static void
_button_click_cb(void *data, Evas_Object *button, void *ev)
{
...
    if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
       dlog_print(DLOG_ERROR, LOG_TAG, "failed to create socket");
            return;
    }
...
    if(connect(socket_fd, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
       dlog_print(DLOG_ERROR, LOG_TAG, "failed to connect : %s", strerror(errno));
            close(s);
            return;
    }
    if ((count = write(socket_fd, user_msg, BUF_SIZE)) < 0) {
         dlog_print(DLOG_ERROR, LOG_TAG, "failed to write : %s", strerror(errno));
         close(s);
         return;
    }
    while((n = read(socket_fd, buf, BUF_SIZE)) > 0) {
            buf[n] = NULL;
            dlog_print(DLOG_ERROR, LOG_TAG, "%s", buf);
    }
    close(s);
...
}
역시 다 적어 놓고 보니까 그렇게 어렵지 않은데 익숙하지 않은 개발 환경에 적응하느라 하루를 보내고 나서야 동작하는 app 을 만들 수 있었다. 그럼 테스트를 해 볼까.

6. Raspberry pi 에서 간단한 socket server 를 만들어 주고 아두이노를 제어한다.

 - Gear S2 에서와 같은 방법으로 socket 을 만들어서 message 를 받아준다.
 - 테스트 코드로 1을 날렸는데 제대로 들어오면 TV 를 켜고 끄는 동작을 한다.
 - robot-server 는 rfcomm 으로 string 을 날려주는 간단한 툴이다. 블로그에 코드도 올려 놓은 것 같은데 오래 된 일이라서...
......
        client_fd = accept (server_fd, (struct sockaddr *)&client_addr, &len);
        if (client_fd < 0) {
                printf ("failed to accept \n");
                return;
        }
        inet_ntop (AF_INET, &address.sin_addr.s_addr, tmp, sizeof(tmp));
        printf ("%s client connected.\n", tmp);
        msg_size = read (client_fd, buffer, BUF_MAX);
        printf ("buffer : %s\n", buffer);
        if (atoi (buffer) == 1) {
                system ("./robot-server TV");
        }
......

7. Arduino 에 sketch code 를 다운로드 한다.

 - IRremote 예제 코드를 살짝 수정해 준다.
 - 블루투스 rfcomm 통신을 하기 때문에 Serial.read 를 사용해서 command 를 확인한다.
#include <IRremoteInt.h>
#include <IRremote.h>
int incoming = 0;
IRsend irsend;
int khz=38;
// samsung tv
unsigned int Signal_1_0[] = {4500, 4550, ...};
void setup()
{
Serial.begin(9600);
}
void loop()
{
    if (Serial.available() > 0) {
        incoming = Serial.read();
        Serial.println(incoming);
        Serial.flush();
        if (incoming == "TV") { /* TV On/Off */
            Serial.println("turn on the display");
            irsend.sendRaw(Signal_0_0, sizeof(Signal_0_0)/sizeof(int), khz);
        }
    }
   delay(100);
}

8. 시연

 - Gear S2 로 TV 를 켜고 끄는 테스트이고 이것을 홈패드 신호로 바꾸기만 하면 언제든지 문을 열고 들어 올 수 있다. Internet 으로 하는 것이기 때문에 멀리 있을 때 누가 문을 열어 달라고 해도 열어 줄 수 있다. 남자의 로망 완성!

댓글 3개:

양준철 :

작성자가 댓글을 삭제했습니다.

brian Park :

본문에 링크를 달아 드린 'https://developer.tizen.org/ko/development/tutorials/native-application/network/connection#init' 타이젠 공식 페이지가 정답일 듯 한데요. 중요한 것은 타이젠이라고 해서 socket 해 대해 특별히 다른 것이 있는 것이 아니라 기존 unix socket 을 해 보셨다면 동일한 방법으로 사용 가능합니다. 보통 동작이 잘 안된다고 할 때는 권한 문제일 경우가 많습니다. 댓글로 자세한 설명은 어려울 듯 하고 이메일로 좀 자세한 내용 주시면 답변 드리겠습니다.

양준철 :

네 답변 감사합니다 ㅎ ^^