Help us understand the problem. What is going on with this article?

VIERAを操作する方法

More than 3 years have passed since last update.

はじめに

パナソニックのテレビ「VIERA」を操作する方法を紹介します。
パナソニックは、「TV Remote」というテレビの操作やスマートフォンなどの動画や写真を表示したり共有するためのスマートフォンアプリを提供しています。
このスマートフォンアプリを使えば、同一LANにあるVIERAを発見、操作することが可能です。
また、このスマートフォンアプリに対応しているVIERAは、内部でHTTPサーバが起動しており、XMLをVIERAに送信することで操作が可能です。

機器を発見する

「TV Remote」には、同一LANにあるVIERAを発見する機能があります。
UPnPで規定されたSSDPを利用して機器を発見します。
UPnPは機器をネットワークに接続すると複雑な設定作業を行わなくても他の機器と通信したり利用できるようにするプロトコルです。
またSSDPは、UPnPで用いられるプロトコルの1つで機器の発見や応答を行うためのものです。

サンプルコードをSwift(バージョンは1.2)で記述します。

はじめにヘッダファイルをインポートします。

Bridging_Header.h
#import "AsyncUdpSocket.h"

次に以下のテキストを239.255.255.250:1900に送信します。

M-SEARCH * HTTP/1.1'
ST: urn:panasonic-com:device:p00RemoteController:1
MX: 1
MAN: \"ssdp:discover\"
HOST: 239.255.255.250:1900

sample1.swift
let data = "M-SEARCH * HTTP/1.1'\r\nST: urn:panasonic-com:device:p00RemoteController:1\r\nMX: 1\r\nMAN: \"ssdp:discover\"\r\nHOST: 239.255.255.250:1900\r\n\r\n\r\n" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!

let sock:AsyncUdpSocket = AsyncUdpSocket(delegate: self)
sock.enableBroadcast(true, error: nil)
sock.bindToPort(0, error: nil)
sock.joinMulticastGroup(239.255.255.250, error: nil)
sock.sendData(data, toHost: 239.255.255.250, port: 1900, withTimeout: -1, tag: 1)
sock.receiveWithTimeout(-1, tag: 1)

VIERAが見つかると以下の関数が呼ばれます。hostがVIERAのIPアドレスです。

sample2.swift
func onUdpSocket(sock: AsyncUdpSocket!, didReceiveData data: NSData!, withTag tag: Int, fromHost host: String!, port: UInt16) -> Bool {

  println(host) // IPアドレス

  return true
}

リモコンキーの送信

発見したVIERAにリモコンキーを送信します。
リモコンキーはリモコンのキー一つ一つに割り当てられたキーのことです。

例えば、次のようなキーがあります。
「NRC_CH_UP-ONOFF」はチャンネルを1つ進めます。
「NRC_VOLUP-ONOFF」はボリュームを1つ高くします。
「NRC_TV-ONOFF」はテレビの電源を切ります。機器によっては内部のHTTPサーバも停止してしまうため再度電源を入れるにはリモコンを使うか、直接電源ボタンを押さなければなりません。
「NRC_RED-ONOFF」はデータ放送の赤ボタンです。

リモコンキーはtomokas/pyvieraを参考にしました。

リモコンキーのXMLは以下のフォーマットです。

sample.xml
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:X_SendKey xmlns:u="urn:panasonic-com:service:p00NetworkControl:1">
      <X_KeyEvent>NRC_TV-ONOFF</X_KeyEvent>
    </u:X_SendKey>
  </s:Body>
</s:Envelope>

リモコンキー送信時にヘッダが必要です。

SOAPACTION: "urn:panasonic-com:service:p00NetworkControl:1#X_SendKey"

これをhttp://<IP Address>:55000/nrc/control_0に送信します。

具体的には以下のようなコードになります。
NSMutableURLRequestを組み立て、NSURLConnectionを使ってリモコンキーを送信します。

sample4.swif
    /**
    URLリクエストを返します。

    :param: host   IPアドレス
    :param: code   リモコンキー
    :returns: URLリクエスト
    */
    private func commonURLRequest(host: String, code: String) -> NSMutableURLRequest {
        let action = "X_SendKey"
        let option = "<X_KeyEvent>" + code + "</X_KeyEvent>
        let xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:%@ xmlns:u=\"urn:panasonic-com:service:p00NetworkControl:1\">%@</u:%@></s:Body></s:Envelope>"
        let header = NSString(format: "\"urn:panasonic-com:service:p00NetworkControl:1#%@\"", action)
        let input = NSString(format: xml, action, option, action)
        let url = "http://" + host + ":55000/nrc/control_0"
        let request = NSMutableURLRequest(URL: NSURL(string: url)!)
        request.HTTPMethod = "POST"
        request.HTTPBody = input.dataUsingEncoding(NSUTF8StringEncoding)
        request.addValue(header as String, forHTTPHeaderField: "SOAPACTION")

        return request
    }

最後に

今回の内容をまとめたライブラリをGitHubで公開しています。

arthur87
iwate-pu
岩手県滝沢市にある公立大学です。Qiitaではソフトウェア情報学部生や出身の人が多いです。
https://www.iwate-pu.ac.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした