■nasneのAPIを知りたい!
今回の投稿は、nasneのAPIが返すデータを調べた結果です。前半は調べ方、後半はcurlを使って取得できるデータの説明です。
先日、気づかないうちにnasneのディスク使用率が100%に到達してしまい、いくつかの映像作品が録画できないという悲劇が発生しました。事前にディスク容量を把握していれば、この事象は避けられたに違いありません。しかし、私は週末にまとめてみる視聴スタイルのため、予定が入って見逃すと、容量が圧迫していても気づきづらかったのです。数値を取得できれば、きっとMuninやZabbixを使って監視が出来るはず。そう思い、調べることにしました。
■どうやって値を取得できるのか?
私が注目したのは、nasneの容量をブラウザから知る方法です。PS4を起動して確認する方法のほかに、nasneのIPアドレスをブラウザに入力してアクセス方法があります。これはPS4を起動することがなく、手元のPCやタブレットから手軽に参照できる便利な方法です。
nasuneのIPアドレスを知るには、nasuneのメニューから確認します。「セッテイ SETTINGS」→「nasne/「レコ×トルネ」設定」→「nasne設定」を辿ると、IPアドレスの情報が確認できます。
http://<IPアドレス>/ にアクセスすると、nasne HOME の URL、http://<IPアドレス>:64210/nasne_home/index.html にリダイレクトされます。この中のメニューにある「ハードディスク管理」をクリックすると、ディスク使用容量・空き容量が表示されています。ブラウザから参照できるということは、ブラウザとnasneが何らかの通信を行っていることがわかります。
ソースコードを確認して、簡単に確認可能かどうかを調べて見ます。上の画像にある容量を表示させている要素は、id=「hdd1_use」と「hdd1_free」と分かります。
<h3 id="labelUsageState">使用状態</h3> <table cellspacing="0"> <tr> <th id="internalHdd" width="237"> </th> <td width="339"><div> <div></div> <div id="usedHDD1"></div> </div> <p id="hdd1_use"></p> <p id="hdd1_free"></p></td> </tr> <tr> <th id="externalHDD"></th> <td id="externalHDD_data"></td> </tr> </table>
容量は動的に値をブラウザに反映させている模様なので、引き続きコードを確認します。HTMLを眺めていると、それらしそうなスクリプト「app.js」が読み込まれている箇所がありました。
<!-- ---------------------------------------------------------------------------------------- -->
<script src="lib/app.js?ver=250"></script>
<!-- <script src="lib/prototype_min.js?ver=250"></script> -->
<!-- <script src="lib/wordResource.js?ver=250"></script> -->
<!-- <script src="lib/appCtrl.js?ver=250"></script> -->
<!-- <script src="lib/appView.js?ver=250"></script> -->
<!-- ---------------------------------------------------------------------------------------- -->
あとは、この app.js をローカルにダウンロードし、「internalHdd」でgrepすると「app.res」という単語が頻出しています。
app.res.labelInternalHdd;document.getElementById("externalHDD")
今度は「app.res」で grep をかけると、ウェブ用のAPIの専用ポート番号が、WEB_API_PORTの「64210」だと分かります。
[zem@sion nasune]$ grep app.res * | more
app.js:
app.res=new WordResource;
RELEASE_MODE=1;
SERVER_ADDR="";
WEB_API_PORT="64210";
REMOTE_API_PORT="64220";
UPDATE_INFO_ADDR="http://ps-peripheral.dl.playstation.net/ps-peripheral/nasne/updateInfo.js";
INT_RECEIVE_WAITING_ERROR=1E3;
さらに app.res を詳しく読むと、「execGetWebApi」という、いかにもな名前と、URLに気づきます。
function(a){return null!=a&&0==a.errorcode?1==a.status?-1:a.complete Percent:null},this.defaultTimeoutMsec,a)};this.getHardwareVersion= function(a){return this.execGetWebApi("/status/hardwareVersionGet"
ここまで情報が揃ったら、あとは curl で nasne にアクセスすると・・・アタリでした。ここでは nasne の型番「CECH-ZNR2J」を確認できました。
[zem@sion nasune]$ curl -s http://192.168.21.10:64210/status/hardwareVersionGet | jq '.'
{
"productName": "CECH-ZNR2J",
"hardwareVersion": 2,
"errorcode": 0
}
コードを読み進めると「/status/」で検索すると、様々な情報が確認できることが分かりました。ここまで来ると、あとは簡単です。ディスク容量に関するものも特定できます。
this.getHDDInfo=function(a,c){return this.execGetWebApi
("/status/HDDInfoGet?id="+a,function(a){return null!=a&&app.js:0==
a.errorcode?a.HDD:null}
内蔵ディスクの場合は「id=0」で取得しています。curl を実行すると、次のように、合計容量、空き容量、使用中の容量、そしてシリアル番号が表示されることが分かります。
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/HDDInfoGet?id=0" | jq '.' { "HDD": { "totalVolumeSize": 998373937152, "freeVolumeSize": 330503405568, "usedVolumeSize": 667870531584, "serialNumber": "JA1000101XXXXX", "id": 0, "internalFlag": 0, "mountStatus": 1, "registerFlag": 1, "format": "xfs", "name": "hdd0", "vendorID": "ATA", "productID": "HGST HTS541010A9" }, "errorcode": 0 }
こうして容量が特定できました。app.js を参照すると、他にもブラウザで表示されている項目は、取得可能な事がわかります。
以降は、取得可能な情報をみていきます。
※nasuneのバージョンは「2.50」であり、古いバージョンや以降のバージョンとは仕様が変わる可能性があります。
■boxNameGet:nasne機器名称確認
複数台のnasneを持っている時の識別に役立ちます。
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/boxNameGet" | jq -M '.' { "name": "nasne", "errorcode": 0 }
■currDateGet:機器上の取得
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/currDateGet" | jq -M '.' { "type": 2, "currDate": "2014-12-06T23:53:42+09:00", "errorcode": 0 }
■HDDPowerSavingModeGet:省電力モード確認
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/HDDPowerSavingModeGet" | jq -M '.' { "mode": 0, "errorcode": 0 }
■areaInfoGet:都道府県・地域
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/areaInfoGet" | jq -M '.' { "zipCode": "0000000", "pref": 14, "areaIdentifierCode": 23, "errorcode": 0 }
■networkInfoGet:ネットワーク情報を表示
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/networkIfInfoGet" | jq -M '.' { "macAddr": "00:25:dc:59:0f:20", "gateway": "192.168.21.1", "secondaryDNS": "", "primaryDNS": "192.168.21.1", "subnetMask": "255.255.255.0", "ipv4Addr": "192.168.21.10", "enableDHCPFlag": 1, "errorcode": 0 }
■softwareVersionGet:ソフトウェアのバージョン情報を表示
結果が「0250」の場合、バージョン番号は「2.50」になります。
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/softwareVersionGet" | jq -M '.' { "backdatedVersion": "0000", "softwareVersion": "0250", "errorcode": 0 }
■NASInfoGet:ファイルサーバー(NAS)設定表示
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/NASInfoGet" | jq -M '.' { "shared": [ { "sharedName": "share1", "id": 0 } ], "number": 1, "nasName": "nasne-590f20", "workgroup": "WORKGROUP", "enable": 1,
■requestClientInfoGet:接続中のクライアント(ブラウザ)情報表示
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/requestClientInfoGet" | jq -M '.' { "client": { "lastAccessDate": "2014-11-30T17:32:23+09:00", "cn": "", "userAgent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0", "name": "", "registerFlag": 1, "macAddr": "8C:70:5A:80:3F:F8", "ipv4Addr": "192.168.21.14" }, "errorcode": 0 }
■DMPListGet:nasuneに接続したクライアント一覧を表示
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/DMPListGet" | jq -M '.' { "dmp": [ { "lastAccessDate": "2014-11-30T14:13:22+09:00", "cn": "Sony Computer Entertainment", "userAgent": "PVR_NETWORKMODULE libhttp/2.02 (PlayStation 4)", "name": "PlayStation 4", "registerFlag": 1, "macAddr": "70:9E:29:95:21:23" }, { "lastAccessDate": "2014-11-30T14:18:07+09:00", "cn": "Sony Computer Entertainment Inc.", "userAgent": "", "name": "PlayStation Vita", "registerFlag": 1, "macAddr": "F8:2F:A8:49:AA:82" }, (以降省略)
■remoteListGet:リモート接続中クライアントを表示
以下は該当無し。
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/remoteListGet" | jq -M '.' { "number": 0, "errorcode": 7000 }
■BCASInfoGet:BCASカード情報表示
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/BCASInfoGet" | jq -M '.' { "cardId": "0000320010406482XXXX", "info": "M002", "sw": 36864, "returnCode": 35073, "status": 1, "errorcode": 0 }
■bsPowerSupplyGet:BSアンテナ電源供給状況
1:有効
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/bsPowerSupplyGet" | jq -M '. ' { "enable": 1, "errorcode": 0 }
■downloadingPermissionGet:受信待機の有効・無効
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/downloadingPermissionGet" | jq -M '.' { "permission": 1, "errorcode": 0 }
■eventRealyInfoGet:イベントリレー機能(番組が別チャンネル移動時に追従)
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/eventRelayInfoGet" | jq -M '.' { "eventRelayInfo": 1, "errorcode": 0 }
■parentalRatingInfoGet:年齢視聴制限
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/parentalRatingInfoGet" | jq-M '.' { "parentalRatingInfo": 0, "errorcode": 0 }
■hardwareVersionGet:ハードウェアバージョンの表示
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/hardwareVersionGet" | jq -M '.' { "productName": "CECH-ZNR2J", "hardwareVersion": 2, "errorcode": 0 }
■mobileBitrateInfoGet:モバイル機器視聴設定
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/mobileBitrateInfoGet" | jq -M '.' { "bitrateInfo": 0, "errorcode": 0 }
■updateCheck2:更新の必要性
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/updateCheck2" | jq -M '.' { "existFlag": 0, "errorcode": 0 }
■最後に、録画・再生中のデータを取得できるかどうか。
さて、nasne HOMEにブラウザでアクセスすると、録画中・再生中のデータも確認できます。ここはソースコードを辿ろうとしましたが、面倒だったので、Wiresharkで辿ることにしました。再びindex.html の HTML を辿ると、録画や再生に関しては、次の範囲が該当します。
<div> <div> <h3 id="labelRecPlayStatus"></h3> <form name="recPlayForm"> <input name="change" type="button" value="" onclick="viewRecPlayStatus()"> </form> </div> <table cellspacing="0"> <tr> <th id="labelRec" width="204"></th> <td id="rec"></td> </tr> <tr> <th id="labelPlay" width="204" rowspan="2"></th> <td id="play1"></td> </tr> <tr> <td id="play2"></td> </tr> </table> </div>
この画面操作時のパケットを取得すると、「boxStatusListGet」が該当することが分かります。そして、録画中のデータは「tvTimeInfoStatus」に表示される「nowId」の数字が鍵になることが予測されます。これが番組情報を識別するIDです。また、serviceIdがテレビのチャンネルであり、transportStreamIdが地上波等の放送種別(?)のようです。
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/boxStatusListGet" | jq -M '.'
{
"dmsStreamStopReasonList": {
"generation": 9
(略)
"tvTimerInfoStatus": {
"nextId": "14123551310000000059",
"nowId": "14123551240000000058"
},
(略)
"tuningStatus": {
"serviceId": 23608,
"transportStreamId": 32391,
"networkId": 32391,
"status": 3
}
ここで得られた情報を元に、番組表情報を「channelInfoGet2」で取得すると、録画中の番組が何であるかが確認する事ができます。
[zem@sion ~]$ curl -s "http://192.168.21.10:64210/status/channelInfoGet2? networkId=32391&transportStreamId=32391&serviceId=23608&withDescriptionLong=0" | jq -M '.' { "channel": { "remoteInhibitFlag": 0, "EITFreeCAMode": 0, "parentalRating": 0, "audioInfo": [ { "componentType": 3, "componentTag": 16 } ], "audioInfoNumber": 1, "genre": [ { "type": 2, "id": 28927 } ], "genreNumber": 1, "description": "#22「旅路の果て」", "duration": 1800, "startDateTime": "2014-12-06T23:30:00+09:00", "title": "ソードアート・オンラインⅡ", "eventId": 50768, "EITFlag": 1, "tsName": "TOKYO MX", "remoteControlKeyId": 9, "networkName": "東京7", "serviceId": 23608, "transportStreamId": 32391, "networkId": 32391, "broadcastingType": 2, "EITScheduleFlag": 1, "EITPresentFollowingFlag": 1, "freeCAMode": 0, "channelNumber": 91, "branchNumber": 0, "service": { "serviceName": "TOKYO MX1", "serviceProviderName": "", "serviceType": 1 }, "freqChannelNo": "16", "eventValidityFlag": 1 }, "errorcode": 0 }
あとはこの情報を加工することで、twitterに自動ツイートする応用も考えられます。
さて、再生中の情報は録画中とは異なります。このとき「dhcpipClientListGet」を実行すると、クライアント側(ここではPS4)で表示されているコンテンツと「id」が表示されます。この情報は再生中だけ表示されるもので、再生を停止すると、表示されません。
[zem@sion nasune]$ curl -s "http://192.168.21.10:64210/status/dtcpipClientListGet" | jq -M '.' { "client": [ { "encryptType": 1, "content": { "id": "14171039270000000732" }, "purpose": 2, "name": "PlayStation 4", "ipAddr": "192.168.21.9", "macAddr": "70:9E:29:95:21:23", "id": 14 } ], "number": 1, "errorcode": 0 }
このIDはDLNA・UPnPでメディアにアクセスされた時に、コンテンツ、つまり個々の映像や音楽に割り当てられているIDのようです。あとは、何らかの方法でIDとコンテンツの情報を紐付けると、再生中の情報も把握出来そうです。ここから先は時間がかかりそうなので、調査をあきらめました。ご興味のある方は、色々調べてみてはいかがでしょうか。