안녕하세요, "생각의 웹"입니다.


앞서 아두이노 보드와 Node.js를 이용해 RESTful Web API와 JavaScript API를 제공하는 Do IoT Yourself 프로젝트를 소개한 바 있습니다.

문득 누군가 이와 유사한 프로젝트를 이미 하지 않을까 하는 생각이 들어 'arduino rest api'로 구글링해 보았습니다.

(친절한 구글 신은 자동 완성 기능을 통해 이런 프로젝트가 존재할 것이라는 제 예상에 힘을 실어 주었습니다.)


그 결과 발견한 프로젝트가 바로 aREST - arduino REST의 축약으로 보입니다. - 입니다.


http://arest.io/


상세 내용에 앞서 이 프로젝트를 통해 가능한 데모 영상 하나 보시죠. 




아직 사이트의 컨텐츠가 모두 완성되지 않은 상태로 보이나 (docs 메뉴에 가보면 under construction으로 되어 있습니다)
공개된 소스 코드의 README 파일이나 블로그에 포스팅 된 내용으로 보아 충분히 사용 가능한 수준으로 보입니다.

간략하게 정리하면 먼저 이 프로젝트는 다음과 같은 특성을 가지고 있습니다.



- REST API를 통한 아두이노 제어 가능

// 1. Connect a LED & resistor to pin number 8 of your Arduino board
GET 192.168.2.2/mode/8/o  // 2. Set the pin 8 as an output
GET 192.168.2.2/digital/8/1 // 3. Turn on LED

- 다양한 아두이노 보드 지원

  : Uno, Mega, Due, Yun and Teensy 3.x.

  

- 다양한 connectivity 지원

  : USB나 XBee를 통한 Serial 통신

  : CC3000 WiFi chip를 통한 HTTP 통신

  : Ethernet shield를 통한 HTTP 통신

  : nRF8001 chip를 통한 Bluetooth Low Energy 통신


- multicast DNS 프로토콜 지원으로 discovery 가능

  : Bonjour 서비스 필요


http://arest.io/ 를 보면 arduino library, Node.js module, JavaScript client 세 프로젝트로 구분되어 있는데 각각의

코드를 상세 검토(deep dive) 해 보면 다음과 같이 요약할 수 있습니다.


- arduino library: aREST의 핵심 모듈입니다. arduino IDE 프로젝트 파일 (*.ino)로 다양한 connectivity 하에서 

http server 기능을 C/C++로 구현하고 있습니다. 


- Node.js module: serial 통신을 통해 연결된 arduino 보드와의 gateway server 역할


- JavaScript client: aREST의 API를 호출하는 AJAX 코드


마무~으리로 이 프로젝트의 장/단점을 정리해 보겠습니다.  


- 장점

  : 다양한 connectivity를 지원합니다. 필요한 요구사항에 맞춰 가져다 쓸 수 있다는 점은 매우 매력적입니다.

  : 아두이노 보드(+ Ethernet or WiFi chip) 만으로도 독립된 인터넷 노드를 만들 수 있습니다.

  : 통신 시 전송량이 적은 JSON respresentation를 사용합니다.


- 단점

  : 보다 복잡한 기능을 추가하기 위해서는 arduino IDE를 통해 펌웨어를 업데이트해야 합니다.

    아두이노 펌웨어에 올릴 수 있는 코드 용량이 한정되어 있는 것으로 알고 있기에 제한을 받으리라 보입니다.

  : 제공하는 REST API의 성숙도 수준이 낮습니다. 

    상태를 변경시키는 unsafe 행위(e.g. LED를 켬)를 GET 명령으로 수행하고 있습니다.

    앞서 포스팅한 리처드슨 REST 성숙도 모델에 따르면 Level 1에 해당하며 클라이언트 프로그래밍 시 오류를

    야기시킬 수 있습니다.

  : 라이센스가 GPL입니다. 상업적인 목적으로 사용하시려는 분은 GPL이 모든 소스코드와 함께 빌드 방법까지 공개해야 하는 점을 유념하시기 바랍니다.  



이번 포스팅은 여기까지 입니다.

감사합니다.

안녕하세요,

"생각의 웹"입니다.


혹시 지난 "AppIN 세미나 - Do IoT Yourself" 강연에 참석하시고 꾸준히 이 블로그에 방문해 주시는 분들이 계신가요?

글을 시작하기 앞서 그 분들께 먼저 감사 말씀드립니다.


이번 포스팅에는 D.IoT.Y 두 번째 강연 시 대디스랩 송영광 대표님과 함께 만들었던 온도센서를 JavaScript로 구현해보고자 합니다.

이 강연은 다음 포스팅을 참조하시기 바랍니다.


Intuitive Understanding Arduino for IoT: Do IoT Yourself 2nd



여기서 실습한 온도 센서 만들기는  Sparkfun Starter Kit for RedBoard에 내장된 센서/엑추에이터로 한정해야 했기에 가격이 저렴한 서미스터 센서(Thermistor)로 기능을 구현하기 위해 arduino IDE에서 꽤 복잡한 코딩을 해야 했습니다. 


다음 코드는 실습 당시 복사/붙여넣기 했던 코드입니다.


#include <avr/pgmspace.h>

int led_state;
unsigned long time;

#define THERM_PIN   0  // 10k thermo & 10k resistor as divider.

/*
 *  Big lookup Table (approx 750 entries), 
 *  subtract 238 from ADC reading to start at 0*C. 
 *  Entries in 10ths of degree i.e. 242 = 24.2*C Covers 0*C to 150*C 
 *  For 10k resistor/10k thermistor voltage divider w/ therm on the + side.
 */
const int temps[] PROGMEM = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
    15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
	34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 
	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 
	69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 
	87, 88, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 
	102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 
	115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 124, 125, 126, 127, 
	128, 129, 130, 131, 132, 133, 134, 134, 135, 136, 137, 138, 139, 140, 
	141, 142, 143, 143, 144, 145, 146, 147, 148, 149, 150, 151, 151, 152, 
	153, 154, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 164, 165, 
	166, 167, 167, 168, 169, 170, 171, 172, 173, 174, 175, 175, 176, 177, 
	178, 179, 180, 181, 182, 182, 183, 184, 185, 186, 187, 188, 189, 190, 
	190, 191, 192, 193, 194, 195, 196, 197, 197, 198, 199, 200, 201, 202, 
	203, 204, 205, 205, 206, 207, 208, 209, 210, 211, 212, 212, 213, 214, 
	215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 225, 226, 227, 
	228, 228, 229, 230, 231, 232, 233, 234, 235, 235, 236, 237, 238, 239, 
	240, 241, 242, 243, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 
	252, 253, 254, 255, 256, 257, 258, 259, 260, 260, 261, 262, 263, 264, 
	265, 266, 267, 268, 269, 269, 270, 271, 272, 273, 274, 275, 276, 277, 
	278, 279, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 289, 
	290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 301, 302, 
	303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 315, 
	316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 
	330, 331, 332, 333, 334, 335, 335, 336, 337, 338, 339, 340, 341, 342, 
	343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 
	357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 
	371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 
	385, 386, 387, 388, 389, 390, 392, 393, 394, 395, 396, 397, 398, 399, 
	400, 401, 402, 403, 404, 405, 406, 407, 408, 410, 411, 412, 413, 414, 
	415, 416, 417, 418, 419, 420, 422, 423, 424, 425, 426, 427, 428, 429, 
	430, 432, 433, 434, 435, 436, 437, 438, 439, 441, 442, 443, 444, 445, 
	446, 448, 449, 450, 451, 452, 453, 455, 456, 457, 458, 459, 460, 462, 
	463, 464, 465, 466, 468, 469, 470, 471, 472, 474, 475, 476, 477, 479, 
	480, 481, 482, 484, 485, 486, 487, 489, 490, 491, 492, 494, 495, 496, 
	498, 499, 500, 501, 503, 504, 505, 507, 508, 509, 511, 512, 513, 515, 
	516, 517, 519, 520, 521, 523, 524, 525, 527, 528, 530, 531, 532, 534, 
	535, 537, 538, 539, 541, 542, 544, 545, 547, 548, 550, 551, 552, 554, 
	555, 557, 558, 560, 561, 563, 564, 566, 567, 569, 570, 572, 574, 575, 
	577, 578, 580, 581, 583, 585, 586, 588, 589, 591, 593, 594, 596, 598, 
	599, 601, 603, 604, 606, 608, 609, 611, 613, 614, 616, 618, 620, 621, 
	623, 625, 627, 628, 630, 632, 634, 636, 638, 639, 641, 643, 645, 647, 
	649, 651, 653, 654, 656, 658, 660, 662, 664, 666, 668, 670, 672, 674, 
	676, 678, 680, 683, 685, 687, 689, 691, 693, 695, 697, 700, 702, 704, 
	706, 708, 711, 713, 715, 718, 720, 722, 725, 727, 729, 732, 734, 737, 
	739, 741, 744, 746, 749, 752, 754, 757, 759, 762, 764, 767, 770, 773, 
	775, 778, 781, 784, 786, 789, 792, 795, 798, 801, 804, 807, 810, 813, 
	816, 819, 822, 825, 829, 832, 835, 838, 842, 845, 848, 852, 855, 859, 
	862, 866, 869, 873, 877, 881, 884, 888, 892, 896, 900, 904, 908, 912, 
	916, 920, 925, 929, 933, 938, 942, 947, 952, 956, 961, 966, 971, 976, 
	981, 986, 991, 997, 1002, 1007, 1013, 1019, 1024, 1030, 1036, 1042, 
	1049, 1055, 1061, 1068, 1075, 1082, 1088, 1096, 1103, 1110, 1118, 1126, 
	1134, 1142, 1150, 1159, 1168, 1177, 1186, 1196, 1206, 1216, 1226, 1237, 
	1248, 1260, 1272, 1284, 1297, 1310, 1324, 1338, 1353, 1369, 1385, 1402, 
	1420, 1439, 1459, 1480, 1502 
};


void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(19200);
  time=millis();
  //Serial.println("Ready");
}

void loop() { 

  int therm;   
  therm = analogRead(THERM_PIN) - 238;
  therm = pgm_read_word(&temps[therm]);
  
  //Serial.println(therm, DEC);
  float temp = (float)therm / 10.0;
  Serial.println(temp, 1);
  
  if (millis()-time > 1000) {   
    time = millis();
    digitalWrite(13,led_state);
    led_state =! led_state;
  }
  delay(2000);
}

약간 코딩 지식이 필요하기에 실습 시에는 많은 설명이 되지는 않았지만 여기서 조금 설명하자면
 look up table를 만들어 A0에서 읽어들인 값을 table에 있는 값에 대응해서 serial로 출력하는 logic이 되겠습니다.


보시듯, 여기서 이 프로그램의 logic의 핵심은 look up table을 어떻게 만들었는가이고 

이에 대한 답변은 table를 만들기 위해서는 서미스터 혹은 하드웨어 부품들에 대한 이해가 필요하다는 것입니다. 

즉 아래의 그림처럼 서미스터의 데이터 쉬트에서 table이 도출되었습니다. (송영광 대표님이 엑셀 신공을 사용하셨다고 하더군요. ^^a) 


서미스터는 회로 구성을 어떻게 했는가에 따라 (즉, 어떤 저항을 달았느냐)에 따라 다른 값을 내어 놓습니다. 

다시 말해 이 값은 위의 그래프에서 온도 X일때의 Y값과 같은 형태로 나옵니다.

하드웨어의 경우 물리의 세계에 닿아 있기에 재료의 특성과 환경에 따라 영향을 받기에 로직 만으로 이해하고자 하는 SW 쟁이는 이해하기 쉽지 않죠.  


따라서, 사실 원하는 동작을 얻기 위해서는 arduino 회로를 적절히 구성할 뿐 아니라
arduino IDE를 이용해 관련 로직을 구현한 후 해당 프로그램(속칭 펌웨어)을  

arduino 에서 전송해 테스트해 보는 일을 반복해야 합니다.


여기서 문제는 arduino에 이 동작 외에 추가로 기능을 구현해야 할 경우, 

반드시 arduino IDE로 펌웨어를 업드레이드해 주어야 합니다. 

이는 꽤 불편한 일이 아닐 수 없습니다. 


쓰다 보니 문제 제기로만으로도 꽤 길어졌는데 이에 대해 제가 제시하는 해결책은 다음과 같습니다.


1. arduino의 펌웨어에 호스트(host)의 명령을 처리해 동작을 수행하는 인터프리터(interpreter) 를 전송합니다.


2. 호스트는 arduino에 명령을 전송합니다. (e.g. A0 포트에서 아날로그 값을 읽어 오기)


3. 인터프리터는 명령을 받아 동작을 수행 후 결과를 호스트에 전송합니다.



혹시, 이 방식을 어디선가 본 듯한 느낌을 받은 분이 있나요? ;-)

앞서 소개한 바와 같이 이 방식으로 구현된 node.js 모듈이 바로 duino 입니다.   


관련 포스팅 : http://webofthink.tistory.com/13



이번에는 duino 모듈로 이 똑같은 동작을 수행해 보도록 하겠습니다. 


먼저, 아래 파일을 다운로드 받기 바랍니다.


duino.zip

(이 모듈은 현재 버전인 v0.0.9를 조금 수정해서 DHT11 센서 지원 및 윈도우즈에서 동작하도록 수정 확장한 버전입니다. 리눅스나 OS X는 기존 버전을 써도 무방합니다.)


이 파일의 압축을 풀어 src/du/du.ino 파일을 실행합니다. 

(먼저 Arduino IDE가 설치되어 있어야 합니다. 참고바랍니다.)


해당 arduino 펌웨어를 arduino 보드에 다운로드합니다.


정상적으로 전송되면 이제 node.js로 동일한 역할을 하는 코드를 구현해 봅니다.

코드를 다음과 같이 작성해 temp.js로 저장하고 콘솔에서 node temp 로 실행합니다.


var arduinoPort = 'COM7'; // only works in windows with patched duino module.
var pinName = '00'; // it means A0 pin

// look up table for resolving data to the appropriates temperature
var temps = [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
    15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
	34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 
	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 
	69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 
	87, 88, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 
	102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 
	115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 124, 125, 126, 127, 
	128, 129, 130, 131, 132, 133, 134, 134, 135, 136, 137, 138, 139, 140, 
	141, 142, 143, 143, 144, 145, 146, 147, 148, 149, 150, 151, 151, 152, 
	153, 154, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 164, 165, 
	166, 167, 167, 168, 169, 170, 171, 172, 173, 174, 175, 175, 176, 177, 
	178, 179, 180, 181, 182, 182, 183, 184, 185, 186, 187, 188, 189, 190, 
	190, 191, 192, 193, 194, 195, 196, 197, 197, 198, 199, 200, 201, 202, 
	203, 204, 205, 205, 206, 207, 208, 209, 210, 211, 212, 212, 213, 214, 
	215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 225, 226, 227, 
	228, 228, 229, 230, 231, 232, 233, 234, 235, 235, 236, 237, 238, 239, 
	240, 241, 242, 243, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 
	252, 253, 254, 255, 256, 257, 258, 259, 260, 260, 261, 262, 263, 264, 
	265, 266, 267, 268, 269, 269, 270, 271, 272, 273, 274, 275, 276, 277, 
	278, 279, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 289, 
	290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 301, 302, 
	303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 315, 
	316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 
	330, 331, 332, 333, 334, 335, 335, 336, 337, 338, 339, 340, 341, 342, 
	343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 
	357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 
	371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 
	385, 386, 387, 388, 389, 390, 392, 393, 394, 395, 396, 397, 398, 399, 
	400, 401, 402, 403, 404, 405, 406, 407, 408, 410, 411, 412, 413, 414, 
	415, 416, 417, 418, 419, 420, 422, 423, 424, 425, 426, 427, 428, 429, 
	430, 432, 433, 434, 435, 436, 437, 438, 439, 441, 442, 443, 444, 445, 
	446, 448, 449, 450, 451, 452, 453, 455, 456, 457, 458, 459, 460, 462, 
	463, 464, 465, 466, 468, 469, 470, 471, 472, 474, 475, 476, 477, 479, 
	480, 481, 482, 484, 485, 486, 487, 489, 490, 491, 492, 494, 495, 496, 
	498, 499, 500, 501, 503, 504, 505, 507, 508, 509, 511, 512, 513, 515, 
	516, 517, 519, 520, 521, 523, 524, 525, 527, 528, 530, 531, 532, 534, 
	535, 537, 538, 539, 541, 542, 544, 545, 547, 548, 550, 551, 552, 554, 
	555, 557, 558, 560, 561, 563, 564, 566, 567, 569, 570, 572, 574, 575, 
	577, 578, 580, 581, 583, 585, 586, 588, 589, 591, 593, 594, 596, 598, 
	599, 601, 603, 604, 606, 608, 609, 611, 613, 614, 616, 618, 620, 621, 
	623, 625, 627, 628, 630, 632, 634, 636, 638, 639, 641, 643, 645, 647, 
	649, 651, 653, 654, 656, 658, 660, 662, 664, 666, 668, 670, 672, 674, 
	676, 678, 680, 683, 685, 687, 689, 691, 693, 695, 697, 700, 702, 704, 
	706, 708, 711, 713, 715, 718, 720, 722, 725, 727, 729, 732, 734, 737, 
	739, 741, 744, 746, 749, 752, 754, 757, 759, 762, 764, 767, 770, 773, 
	775, 778, 781, 784, 786, 789, 792, 795, 798, 801, 804, 807, 810, 813, 
	816, 819, 822, 825, 829, 832, 835, 838, 842, 845, 848, 852, 855, 859, 
	862, 866, 869, 873, 877, 881, 884, 888, 892, 896, 900, 904, 908, 912, 
	916, 920, 925, 929, 933, 938, 942, 947, 952, 956, 961, 966, 971, 976, 
	981, 986, 991, 997, 1002, 1007, 1013, 1019, 1024, 1030, 1036, 1042, 
	1049, 1055, 1061, 1068, 1075, 1082, 1088, 1096, 1103, 1110, 1118, 1126, 
	1134, 1142, 1150, 1159, 1168, 1177, 1186, 1196, 1206, 1216, 1226, 1237, 
	1248, 1260, 1272, 1284, 1297, 1310, 1324, 1338, 1353, 1369, 1385, 1402, 
	1420, 1439, 1459, 1480, 1502
];


var arduino = require('duino');
var board = new arduino.Board({
    device: 'COM7',
    debug: false //true
});



board.on('ready', function () {
    console.log("arduino board is ready to serve.");
    board.pinMode(pinName, 'in');
    
    setInterval(function () {
        console.log('request to get an analog value from ' + pinName);
        board.analogRead(pinName);
    }, 1000);
});

board.on('data', function (message) {
    // message looks like {pin}::{data}. so it will be disassembled properly.
    var m = message.slice(0, -1).split('::'),
        err = null,
        pin, data;
    
    if (!m.length) {
        return;
    }
    
    pin = m[0];
    data = m.length === 2 ? m[1] : null;

    console.log('reading value from pin' + pin + ': ' + data );
    if (pin === pinName) {        
        var converted = temps[parseInt(data) - 238] / 10.0;
        console.log('current temperature is ' + converted + ' degree of celsius');
    }
});


C:\tests>node temp.js
arduino board is ready to serve.
request to get an analog value from 00
reading value from pin00: 489
current temperature is 23.5 degree of celsius
request to get an analog value from 00
reading value from pin00: 489
current temperature is 23.5 degree of celsius
request to get an analog value from 00
reading value from pin00: 489
current temperature is 23.5 degree of celsius
^C
C:\tests>


단순히 보면 위의 코드가 앞서 arduino 펌웨어의 코드보다 더 간략해 보이지 않지만, 

이 코드는 세번 째 강연으로 진행했던 사물 간의 연결을 위한 Open API에서
다루었던 serialport 모듈의 기능을 포함하고 있습니다.

(즉 비슷한 코딩 량으로 두 가지 일을 한번에 한 것입니다.)


이외에도 앞서 문제로 제기했던 것들의 해결책으로써 

호스트에서 arduino 원격 제어와 펌웨어 업데이트 없이 추가 기능 구현이 가능해 졌습니다. 


더 나아가 이를 RESTful Web API와 JavaScript API 형태인 Open API로 재 설계한다면
웹을 통해서 아두이노를 원격 제어하는 게 가능해 집니다.


마지막으로 사족을 붙여 보겠습니다.


아래 포스팅을 통해 사물과 사물 간의 대화를 위해서는 수 많은 기술적 제약들이 현재 존재함을 말씀드린 바 있습니다.


- 사물 인터넷을 지탱하는 것 

- 사물 인터넷은 어떻게 생각하게 될까?


저는 이 장벽을 푸는 첫 번째 기술적 열쇠로 자바스크립트 언어를 바라보고 있습니다. 

이 언어를 사용하는 많은 개발자들이 존재하면서도 지적 재산권(IP) 문제에 자유롭고 계속적으로 기능이 향상되고 있기 때문입니다.


최근 뉴스에 등장한 오라클과 구글의 안드로이드에서의 자바 언어 사용 관련 특허 분쟁은 사물인터넷 시대를 맞이 할 우리에게 시사하는 점이 많습니다.

처음 기술을 개발한 세력이 개방과 공유를 빙자해 전파하더라도 나중에 가서는 그것을 사유화하려고 할 것이기 때문입니다. 


그러나 우리는 지난 사반세기 동안 이런 사유화를 막고 지구적 공동체를 만들어낸 훌륭한 사례를 본 적이 있습니다. 

따라서 웹과 arduino가 그러했듯이 오픈 소스 소프트웨어오픈소스 하드웨어가 초연결 사회로 나아가는 축으로 자리 잡길 기대합니다.


감사합니다.  


안녕하세요,

"생각의 웹"입니다.


AllJoyn Framework (이하 올조인)은 퀄컴에서 개발한 P2P 기술을 오픈 소스로 공개 후 AllSeen Alliance (이하 올신) 주관으로 리눅스 재단의 프로젝트로 진행하는 만물 인터넷 (사물 인터넷보다 한단계 더 나아간 개념입니다만 저는 아직까지는 동의어 혹은 파생어로 봅니다.  ) 프레임 워크입니다.


이 기술을 공개된 지도 일 년이 지난 것으로 기억하는데 가장 최근인 올 해 7월 IFA 2014에서 공개한 데모에 대해 정리한 포스팅이 있어 올조인에 대해 아직 문외한인 분들은 읽어 보면 좋을 것 같아 링크 공유합니다.


퀄컴 올조인으로 물꼬튼 올신의 현재 (칫솔 - 초이의 IT 휴게실)  



올조인의 가장 긍정적인 면은 처음부터 누구나 소스 코드를 사용할 수 있도록 공개하고도 더불어 다양한 플랫폼 개발자들을 위해 여러 프로그래밍 언어의 API 문서와 프로그래밍 가이드를 잘 정리해 두었다는 점입니다.


튜토리얼: https://allseenalliance.org/alljoyn-framework-tutorial



오픈소스의 영향으로 인지는 모르겠지만 간단한 검색어를 통한 구글링으로도 꽤 많은 관련 포스팅이 눈에 띄는데 아래 '바쁜척쟁이 개발자의 블로그'에 기능 별로 잘 정리되어 있는 것 같아 살펴 보시길 추천합니다.


http://busydeveloper.tistory.com/category/Alljoyn



개인적으로 아쉬운 점이자 이 포스팅을 쓰게 된 동기는  official site의 가이드에는 JavaScript API가 준비되지 않았다는 점입니다.

개발 이력을 살펴 보니 NPAPI를 이용해 browser에서 사용 가능한 API를 만들려는 시도가 있었다가 실패한 듯 하고 (github에서 관련 프로젝트가 없어졌더군요.) 
대신 아래 경로처럼  node.js를 위한 npm 모듈이 존재하는 것을 확인했습니다.


https://github.com/octoblu/alljoyn


따라서, 현재 클라이언트의 주변에서는 올조인 기기들을 찾을 수 없겠지만 node.js를 탑재한 모바일 기기나 
클라이언트와 node.js 서버가 같은 네트워크 상에 있다는 가정 하에서는 Open API를 통해 기기 간 통신이 가능할 것으로 보입니다.


각론으로 들어가면 사실 올조인의 API는 P2P 개념이 부족한 분들에게는 조금 생소할 수도 있습니다.

하는 역할인 기기 간 통신에 비해 복잡해 보이기도 하고요. 

각 인터페이스들의 역할과 상호 작용의 개념을 명확히 이해하기 위해 먼저 위의 튜토리얼을 읽어 보실 것을 권합니다.

어느 정도 동작 방식에 대해 이해 하셨나요? 아래 코드는 위의 깃허브의 샘플 코드에서 유추해서 Web IDL 형태로 간단히 정리해 본 JavaScript API 입니다.

 


typedef DOMString AllJoynAppName; 

callback SignalMessageCallback = void (DOMString message, DOMString info);
[Constructor (DOMString appName)]
interface BusAttachment {

    void createInterface(AllJoynAppName name, InterfaceDescription description);

    void registerBusListener(BusListener listener);

    void start();

    void connect();

    void findAdvertisedName(AllJoynAppName name);

   void registerSignalHandler(BusObject bus, 
       SignalMessageCallback  smcb,
       InterfaceDescription description, 
       DOMString signalType);
};

[Constructor ()]
interface InterfaceDescription {

    void addSignal(DOMString target, 
        DOMString messageType,
        DOMString message);
};

callback FoundAdvertisedCallback = void (DOMString name);
callback LostAdvertisedCallback = void (DOMString name);
callback NameOwnerChangedCallback = void (DOMString name);

[Constructor (FoundAdvertisedCallback facb, 
    LostAdvertisedCallback lacb, 
    NameOwnerChangedCallback nocb)]
interface BusListener {
};

[Constructor (DOMString busName)]
interface BusObject {

    void addInterface(InterfaceDescription description);
};

callback AcceptSessionJoinerCallback = void (unsigned short port, AllJoynAppName joiner);
callback SessionJoinedCallback = void (unsigned short port, DOMString sessionId, AllJoynAppName joiner);

[Constructor (AcceptSessionJoinerCallback asjcb, SessionJoinedCallback sjcb)]
interface SessionPortListener {
};

문서화 수준과 지원하는 OS (유닉스 계열 - OS X, linux 만 지원)이 부족한 것으로 보아 아직 신뢰할 만한 수준이 아닌 것으로 보입니다.
즉 이 모듈을 사용할 때 각자가 해야 할 삽질이 정해져 있다는 것을 의미합니다. -_-;; 


어쨌든 올신에는 꽤 많은 기기 제작업체가 가입해 있고 슬슬 호환 기기들도 출시를 앞두고 있은 것 같아 기존 레거시 시스템들과 혹은 올신에 가입하지 않는 업체들의 기기와의 대화를 위해 인터프리터 역할을 할 노드가 필요하리라고 예측합니다.

추후 좀 더 구체화된 내용이 있으면 포스팅하도록 하겠습니다.


감사합니다.


행복한 하루 되시길! 

+ Recent posts