"기술"에 해당하는 글들
페이지:«1234567...19»

장마대비 코드 수정

2016-07-05   //   alexken작성   //   기술  //  No Comments

가장 최근 게시글이 2014년 4월 글이다.
그래 뭐라도 좀 쓰자.

심각한 결정장애자로 구성된 팀원들이 매일 점심마다 엘리베이터타고 지하 1층까지 내려와서는 서로의 눈치만 살필뿐 어디가자 말하는 사람이 없이 한동안 멍하니 서있기만 한 상황이 싫어서 만든 웹앱이 “오늘의 밥집”이다.

상암동 누리꿈스퀘어 근무자만 사용가능한 앱이다.

img_1104

오늘같이 비가 퍼붓는 날은 건물 밖에 나갈 수 없으니 날씨에 따라 추천 밥집을 유동적으로 할 필요가 있겠다 싶어 현재 날씨 관련 OPEN API를 찾아서 적용하였다.

기준은 가장 쉬어 보이는 놈으로 해서 openweathermap.org 꺼로 정했다.

http://api.openweathermap.org/data/2.5/weather?q=Seoul,uk&appid=3427...

HTTP GET 메소드로 요청하면 JSON으로 반환해준다.

{
  "coord": {
    "lon": 127,
    "lat": 37.52
  },
  "weather": [
    {
      "id": 301,
      "main": "Drizzle",
      "description": "drizzle",
      "icon": "09n"
    },

    {
      "id": 701,
      "main": "Mist",
      "description": "mist",
      "icon": "50n"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 292.66,
    "pressure": 1012,
    "humidity": 88,
    "temp_min": 290.15,
    "temp_max": 296.15
  },
  "visibility": 10000,
  "wind": {
    "speed": 1.5,
    "deg": 320
  },
  "clouds": {
    "all": 90
  },
  "dt": 1467724800,
  "sys": {
    "type": 1,
    "id": 8519,
    "message": 0.0104,
    "country": "KR",
    "sunrise": 1467663409,
    "sunset": 1467716182
  },
  "id": 1846735,
  "name": "Chamsil",
  "cod": 200
}

여기서 weather[0] –> main 에 해당하는 문자열만 끄집어 내서 Rain, Storm … 이면 건물 밖 밥집은 제외토록 하였다.

function currWeather(){
  var xhr = new XMLHttpRequest();
  var curr = "Clear";
  xhr.onreadystatechange=function() {
    if(xhr.status == 200 && xhr.readyState==4)
      curr = JSON.parse(xhr.responseText).weather[0].main;
  }

  xhr.open('GET', 'http://api.openweathermap.org/data/2.5/weather?" +
        "q=Seoul&appid=3427...'
,false);
  xhr.send();
  return curr;
}

짜증나는 KT의 실시간 사용량 알림 서비스

2014-04-07   //   alexken작성   //   기술  //  No Comments

4월3일 15~16시경 사용했던 원격접속이 Wifi에 붙지않고, 3G 데이터로 연결되었던 모양이다.
Wifi 접속 여부를 제대로 확인하지 않은 나의 불찰도 있지만, 데이터 사용량에 따라 실시간으로 시스템에서 알려주는 사용량 고지 서비스를 너무 믿었나 보다.

처음엔 3G 데이터를 사용했는지 모르고 있었는데, 사용 후 3시간이 훨씬 지난 후에야 짜증나는 문자가 하나 둘씩 도착하기 시작했다. 월초라 잔여 데이터도 넉넉했고, 실시간 사용량 고지 서비스도 있으니 별로 걱정안했는데, 8시 42분에 무료데이터 소진 안내 문자를 받고선 아예 3G Data 자체를 차단하고, 앞으로 한달간 데이터 없이 살아야 할껄 생각하니 짜증이 나기 시작했다.

그러더니 여기서 끝이 아니고 9시12분, 44분에도 계속 1만원 초과, 2만원 초과란 문자가 사용후 6시간이 지난 후에도 계속 날라왔다.

다음날 KT에 전화해서 과다한 데이터 사용을 실시간으로 알려서 사용자가 사용을 멈출수 있게 해야할 사용량 고지 서비스가 6시간이나 지난 시점에 날라오면 어떻하냐고 따지니, 고객님의 불편은 충분히 죄송하게 생각하고 자신들도 이러한 사실을 충분히 인지하고 있지만, 기술적 한계로 다소(??) 지연이 발생할 수 밖에 없는 점을 양해해 달란다.

100ms 이내의 실시간성을 요구한것도 아니고, 문자가 아닌 email로 알려줘도 5분이면 될 것을 최대 6시간이나 뒤에 알려주는 사용량 고지 서비스면 이건 장애 수준이지 KT의 기술적 한계라고?

결론은 KT의 3G 데이터는 차단 서비스도 제공하지 않으니 데이터 무제한 사용자가 아니면 함부로 써서는 안된다는 결론이다. 특히 사용중 알려주는 실시간 고지 서비스 따윈 절대 믿어서는 안된다고…
더 보기 >>

[Sony PHA-1] Windows8.1 드라이버 오류 문제

2014-03-18   //   alexken작성   //   기술  //  2 Comments

헤드폰 앰프로는 그람슬리 솔로가 있고, 이준화 교수님이 만들어주신 앰프도 있으면서 Sony PHA-2가 나오면서 20만원 초반으로 떨어진 PHA-1을 계륵인지 알면서 낼름 구매해버림.

주로 Macbook air나 iPhone에 연결해서 들어서 몰랐는데, Windows8.1에 연결하면 디바이스 드라이버 오류가 난다고 해서 해보니 정말 재현되었고, 그래서 해결책을 찾아 봤음.

소니 공식 Q&A

pha-1
소니 Q&A 사이트의 해결 방법을 간략히 정리

0. 뭔가를 느끼고 있는 “Sony Device”를 선택하고 오른쪽 마우스 클릭
1. “드라이버 소프트웨어 업데이트” 선택
2. “컴퓨터에서 드라이버 소프트웨어 찾아보기” 선택
3. “컴퓨터의 장치 드라이버 목록에서 직접 선택” 선택
4. “호환 가능한 하드웨어 표시” 선택 해제
5. “제조업체” 에서 (표준 USB 호스트 컨트롤러) 선택
6. “모델”에서 “USB Composite Device” 선택
7. 끝.

[ruby2] (‘가’..’힣’).each{|x| print x}

2013-10-24   //   alexken작성   //   기술  //  No Comments

ruby라는 언어를 안건 1999년 이었지만, 줄곳 잊고 살다가 흥미를 가지고 배운것은 2008년 5월 이었다.

ruby 공부를 시작한지 2틀째 썼던 글인 [ruby] (‘가’..’힣’).each{|x| print x}는 ruby 1.8 시절에 내부 문자열 소팅을 unicode 순이 아닌 utf-8로 인코딩된째 소팅한다고 푸념하는 글이었다.

그때 막연한 희망으로 ruby 2.0에서는 unicode 순으로 해줬으면 좋겠다고 썼던적이 있다.

ruby 2.0이 나왔는 지 알게된 계기도, 오늘 쓴 ruby 2.0.0에서 iconv 사용 불가에서 썼듯이 우연히 MacOSX 를 Mavericks로 바꾸면서 알게 되었다.
혹시나 하는 맘에 ruby 2.0에서 문자열 소팅이 개선되었는지 확인해 보니 정말 바뀌어 있었다.

5년전에 생각했던,
‘가’에서 ‘힣’까지 출력하는 ruby code는

('가'..'힣').each{|x| print x}

한줄이면 된다.

더이상 utf-8을 unicode로 디코딩해서 소팅하고, 다시 utf-8로 인코딩 안해도 되게 되었다.
혹시나 하고 찾아 보니 이런 글 이 있네.

ruby 2.0.0에서 iconv 사용 불가

2013-10-24   //   alexken작성   //   기술  //  1 Comment

이전에 만들어 두었던 나만을 위한 EPG가 동작을 하고 있지 않았다.

/System/Library/Frameworks/Ruby.framework/... /kernel_require.rb:45:in `require'
    : cannot load such file -- iconv (LoadError)

이유를 살펴 보니, 날마다 EPG 데이터에서 HTML페이지를 생성하는 ruby 코드 내에서 사용한 iconv 때문에 requre 문에서 부터 오류가 발생했다. 문제를 추적해 가보니, 근원은 MacOSX를 “Mavericks”로 업그레이드 해서 발생한 문제였다.

  • MacOSX 10.8(“Mountain Lion”)에 기본으로 설치된 ruby 버전은 1.8.7이었다.
  • 반면 MacOSX 10.9(“Mavericks”)에서 2.0.0으로 판올림 되었다.
  • 그 과정에서 iconv가 deprecated 되었다가 1.9.3부터는 아예 빠져 버렸다고 한다. 해결책은 iconv를 추가로 까는 방법도 있겠지만, deprecated한 취지 대로, string의 encode로 바꾸었다.

기존 iconv 사용 코드

requrie 'iconv'
conv = Iconv.new('UTF-8//IGNORE','KS_C_5601-1987')
utf8_str = conv.iconv(ksc5601_str)

string.encode로 변경한 새 코드

utf8_str = ksc5601_str.encode("UTF-8", "KS_C_5601-1987")

이취임식

2013-09-13   //   alexken작성   //   기술, 인생  //  1 Comment

그동안 사용하던
메인 : iPhone 4S, 서브 : Blackberry 9900 조합에서
메인 : XPeria Z Ultra, 서브 : iPhone 4S 로 변경하게 되었다.

XPeria Z Ultra는 바다건너 홍콩에서 수요일날 도착했고, 하필 그날은 온통 iPhone 5S/5C 얘기만 하던날.
혼자서 “크고 아름다운” Z Ultra 에 하악하악.

외도는 이번 한번만.

Sony Bravia TV의 웹 EPG 만들기 (두번째)
XMLHttpRequest로 SOAP 메시지 보내기

2013-04-28   //   alexken작성   //   기술  //  No Comments

이전글에 이어서,

이전 방식(Ruby + Server)의 단점은 집에 웹서버를 운영해야 한다는 점이다.
NAS도 어엿한 웹서버이므로 크게 문제될 것은 없지만, 그냥 단말기에서 동작하도록, 즉 HTML측에서 동작하도록 javascript를 이용해 XMLHttpRequest로 soap메시지를 전달하도록 전부 재 작성하였다.

단순 웹페이지라, 브라우저만 있는 기기라면, 스마트폰/태블릿/PC 어디서나, iOS/Android/WP7.5/Windows/MacOSX 무관하게 동작할 것이나, 현재 하늘이 핸드폰인 Lumia 710(WP7.5)의 IE에서만 동작하지 않았고, 나머지 기기에서는 완벽 동작한다.
사용하기 정말 편하며, 만들어 놓고 아주 뿌듯해 하고 있다.

그럼 본문

ircc Command 목록을 조회하는 코드는 다음과 같다.
중요한 점은 “X-CERS-DEVICE-ID”라는 헤더에 TV에 페어링을 통해 등록된 Mac주소를 함께 전송해야 한다. 없으면 403을 반환한다.

var tv_ip = 'XXX.XXX.XXX.XXX';
var client_mac_addr = 'XX-XX-XX-XX-XX-XX';

function getRemoteCommandList(){
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'http://' + tv_ip + '/cers/api/getRemoteCommandList',true);
  xhr.setRequestHeader("X-CERS-DEVICE-ID", 'MediaRemote:' + client_mac_addr);
  xhr.onreadystatechange=function() {
    if(xhr.status == 200){
      if (xhr.readyState==4) {
        alert(xhr.responseText);
      }
    }else{
      alert(xhr.status);
    }
  }
  xhr.send(null);
}

getRemoteCommandList를 호출하면 TV는 아래와 같은 xml 형태로 리모콘 값에 해당하는 값의 Base64로 인코딩된 값을 반환한다.
전체 커맨드 목록은 이 글 맨 아래에 정리하였다.

< ?xml version="1.0"?>
<remotecommandlist>
 <command name="Confirm" type="ircc" value="AAAAAQAAAAEAAABlAw==" />
 <command name="Up" type="ircc" value="AAAAAQAAAAEAAAB0Aw==" />
 <command name="Down" type="ircc" value="AAAAAQAAAAEAAAB1Aw==" />
  ...
 <command name="OneTouchRecStop" type="ircc" value="AAAAAgAAABoAAABjAw==" />
 <command name="MuteOn" type="url" value="http://_:80/cers/command/MuteOn"/>
 <command name="MuteOff" type="url" value="http://_:80/cers/command/MuteOff"/>    
</remotecommandlist>

마지막 줄에 type이 “ircc”가 아닌 “url”인 MuteOn과 MuteOff가 있는데, 이 url 유형의 command는 soap으로 보내지 않고, 해당 url에 GET만 수행해도 동작하며, 요청 기기의 MAC주소도 확인하지 않는다.
즉 코딩할 필요 없이 웹브라우저에서 해당주소를 입력하고 Enter만 쳐도 동작한다는 얘기다.
특이점은 command는 MuteOn과 MuteOff가 있지만 MuteOff는 동작하지 않고, MuteOn만 토글 형태로 동작한다.
물리적인 리모콘 버튼에서도 [조용히] 하나만 있기 때문에 일맥상통한다.

[조용히]/[조용히 해제]에 해당하는 코드는 아래와 같다.
getRemoteCommandList함수와의 차이점은 커스텀 헤더인 “X-CERS-DEVICE-ID”는 필요치 않다.

function muteOnOff(){          
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'http://' + tv_ip + '/cers/command/MuteOn',false);
  xhr.send(null);
}

위에서 작성한 getRemoteCommandList()를 통해서 얻은 ircc code를 가지고 직접 리모콘 키를 누르는 것과 동일한 효과를 내는 함수는 다음과 같다. sendIrccCommand에 ircc 코드를 보낼때 마다 리모콘 키 하나를 누르는 행위와 일치한다.

function sendIrccCommand(ircc){
  var body =
    '< ?xml version="1.0"?>'+
    '<s:envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" '+
    ' s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'+
    '  <s:body>'+
    '    <u:x_sendircc xmlns:u="urn:schemas-sony-com:service:IRCC:1">'+
    '      <ircccode>' + ircc + '</ircccode>'+
    '    </u:x_sendircc>'+
    '  </s:body>'+
    '</s:envelope>';
  var xhr = new XMLHttpRequest();
  xhr.open('POST', 'http://' + tv_ip + '/IRCC',false);
  xhr.setRequestHeader('X-CERS-DEVICE-ID', 'MediaRemote:' + client_mac_addr);
  xhr.setRequestHeader('SOAPAction',     
                        '"urn:schemas-sony-com:service:IRCC:1#X_SendIRCC"');
  xhr.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
  xhr.send(body);
}

하지만 SBS를 튜닝하기 위해서는 디지털인 경우에 ‘6’, ‘.’, ‘1’과 같이 연속으로 3개의 키를 입력해야 한다.
sendIrccCommand를 좀더 추상화한 setChannel은 아래와 같고, 입력은 ‘6.1’, ‘10.1’ 과 같은 키 시퀀스에 해당하는 문자열을 입력으로 받는다.

function setChannel(ch){

  var num = [
            "AAAAAQAAAAEAAAAJAw==", //0
            "AAAAAQAAAAEAAAAAAw==", //1
            "AAAAAQAAAAEAAAABAw==", //2
            "AAAAAQAAAAEAAAACAw==", //3
            "AAAAAQAAAAEAAAADAw==", //4
            "AAAAAQAAAAEAAAAEAw==", //5
            "AAAAAQAAAAEAAAAFAw==", //6
            "AAAAAQAAAAEAAAAGAw==", //7
            "AAAAAQAAAAEAAAAHAw==", //8
            "AAAAAQAAAAEAAAAIAw=="  //9
  ];
  var dot = "AAAAAgAAAJcAAAAdAw=="  //.

  var c = ch.split("");
  for( var i in c ){
    switch(c[i]){
      case '.' :
        sendIrccCommand( dot );
        break;
      default:
        sendIrccCommand( num[ch[i]] );
        break;
    }
  }
}

더 보기 >>

Sony Bravia TV의 웹 EPG 만들기 (첫번째)
Ruby+Server 버전

2013-04-27   //   alexken작성   //   기술  //  3 Comments

집에 TV는 2년전 구입한 nx720이라는 Sony사 제품이다.
스마트폰에서 제어할 수 있도록 Media Remote라는 앱을 iOS용과 Android용으로 제공하고 있다.

그런데 Android용으로 TV SideView라는 새로운 앱을 제공하기 시작했다.
Media Remote가 리모콘의 단순 대체라면, TV SideView는 음성 컨트롤, EPG를 통한 채널 선택, 저장된 미디어 재생(PVR 모델의 경우)와 같은 새로운 UX를 제공하고, 이중에서 EPG를 통한 채널선택은 TV 사용에 있어 가장 자연스런 UX인거 같다.

그런데, 국가가 [일본/미국]인 경우에는 EPG를 보여주고 해당 채널을 선택할 수 있는 반면, 국가를 [한국]으로 설정해면 EPG 기능이 비활성화 되는 것에 광분하여 자체적으로 만들게 되었다.

조사해본 결과

Sony TV의 경우 IRCC라는 웹서비스를 제공한다.
리모콘 키의 IR 신호에 해당하는 ircc 코드를 HTTP 프로토콜로 SOAP 메시지로 전달하면 리모콘 키를 누른 것과 동일하게 동작한다.
IRCC의 경우에 범용적으로 표준화된 것은 아니고, Sony가 개발한 Sony의 Bravia 브랜드를 사용하는 TV, Blue-lay, PVR 기기에서만 활용되는, 그다지 범용적인 기술 표준은 아니었다.

적당히 EPG 정보를 대충 가져와 그냥 html로 알아서 아래와 같이 변환 후 화면을 터치하면, 해당 프로그램의 채널로 TV가 튜닝하도록 하였다.

ircc command를 soap으로 전송하는 가장 손쉬운 방법은 ruby cers_remote 라이브러리를 이용하면 되고, 웹 서버측 php에서 ruby를 통해 TV로 soap 메시지를 보내게 된다.

ircc가 동작 제한 조건으로

  • ircc의 soap 메시지 header에 TV에 기 등록된 기기의 MAC주소를 보낼 것
  • ircc 전송측과 TV가 동일 네트워크에 있을 것

이 중 MAC 주소는 기존에 Media Remote를 설치해서 TV와 패어링된 스마트폰/태블릿의 MAC 주소여야 하고,송신측이 TV와 동일 네트워크에 있어야 하려면, 웹버서를 집내에서 운영해야 한다.

#!/usr/bin/env ruby

require "cers_device"
tv_ip = "XXX.XXX.XXX.XXX"
paired_device_mac = "XX-XX-XX-XX-XX-XX"

command =
"1"=>"AAAAAQAAAAEAAAAAAw==",
"2"=>"AAAAAQAAAAEAAAABAw==",
"3"=>"AAAAAQAAAAEAAAACAw==",
"4"=>"AAAAAQAAAAEAAAADAw==",
"5"=>"AAAAAQAAAAEAAAAEAw==",
"6"=>"AAAAAQAAAAEAAAAFAw==",
"7"=>"AAAAAQAAAAEAAAAGAw==",
"8"=>"AAAAAQAAAAEAAAAHAw==",
"9"=>"AAAAAQAAAAEAAAAIAw==",
"0"=>"AAAAAQAAAAEAAAAJAw==",
"."=>"AAAAAgAAAJcAAAAdAw=="
}

device = CersDevice.new(tv_ip,paired_device_mac)

if __FILE__ == $0
  ARGV[0].split(//).each{|x|
    device.send_ircc(command[x])
    sleep 1
  }
end

위 파일을 setch 라고 저장하였다면 터미널에서

$setch 11.1

로 채널전환 가능하며, 이를 서버측에서 불러주면됨

페이지:«1234567...19»