MESH SDK上で簡単な設定とJavaScriptのプログラミングを行うことで、以下の例のような独自のソフトウェアタグを作成することができます。
外部サービスが公開している機能(Web API)にアクセスするソフトウェアタグ
WiFi搭載機器が公開している機能(Web API)にアクセスするソフトウェアタグ
複雑な手続きや演算、Canvas上での経路制御を実行するソフトウェアタグ
タグを作成するために主にやるべきことは以下の3点です。
以下に詳細手順を示します。
Step 1. MESH SDK Topページへアクセス
ブラウザの検索窓に「http://meshprj.com/sdk/」を入力して、検索します。または、こちらのリンク「SDK TOPページ」をクリックします。
Step 2. サインイン画面へアクセス
Step 3. アカウント登録画面へアクセス
Step 4. アカウント情報を入力
Step 5. アカウント情報の確認と登録
Step 6. アカウント申し込み完了
Step 7. アカウントの有効化
Step 8. SDKへのアクセス
Step 1. タグを新規作成
Step 2. 外部仕様の関連項目を設定
アイコン、タグの名前、タグの説明、機能、機能の名前などの外部仕様関連項目を追加、入力します。
項目ごとの詳細については、「設定項目について」を参照してください。また、「▶ / ▼」をクリックすることで、項目の表示/非表示を切り替えることができます。
Step 3. SDK上で機能ごとにJavaScriptでコードを記述
「Initialize」、「Receive」、「Execute」、「Result」のうち、必要な部分にJavascriptのコードを記述します。各ラベルをクリックすることで、タブ切り替えが可能です。コードの記述に関する詳細については、「コードについて」を参照してください。
タグをタブレットのMESHアプリケーション上に追加するためにやるべきことは以下の2点です。
以下に詳細手順を示します。
タグをタブレットのMESHアプリケーション上で実行&デバッグするためにやるべきことは以下の3点です。
以下に詳細手順を示します。
Step 1. ログダイアログを開く
Step 2. ログを確認する
エラーや、logコマンドによるメッセージがリアルタイムで出力されます。logコマンドについての詳細は、「ログ出力」を参照してください。
バグが見つかった場合や、機能を変更したい際にはSDK上で作成したタグを再編集する必要があります。また、再編集した場合は、アプリケーション上でも編集内容を反映(アップデート)させる必要があります。
Step 1. SDK上で再編集する
Step 2. タグ詳細ダイアログを開く
Step 3. アップデートを確認する
Step 4. アップデートを実行する
Tagが持つ各Functionの動作を定義するために、Functionが持つ4つのメソッド {Initialize, Receive, Execute, Result} を実装します。
4つのメソッドの概要は以下の通りです。
メソッド | 概要 |
---|---|
Initialize | Functionの初期化時に呼ばれます。 内部変数の確保やスケジューラーの設定といった、初期化処理が必要な場合に実装します。 |
Receive | 入力コネクタからメッセージを受け取った際に呼ばれます。入力コネクタが複数あり、どれから受け取ったか区別したい場合に実装します。 |
Execute | Function実行時に呼ばれます。 通常、手続きはこのメソッドに記述します。 |
Result | Executeメソッドが完了し、出力コネクタから次のタグにメッセージを送信する際に呼ばれます。 出力コネクタが複数あり、どのコネクタからメッセージを出力するかを選びたい場合に実装します。 デフォルトでは全ての出力コネクタから出力されます。 |
また、ソフトウェアタグ開発で利用可能な共通の仕組みとして、
– 処理制御
– コネクタ制御
– 変数・定数
– ライブラリ
が用意されています。
各メソッドの戻り値により、処理を中断するか継続するか(次のメソッドを呼ぶかどうか)を制御することができます。
例えば下記ソースコードの場合は、処理が継続し、次のメソッドが実行されます。
1 | return { resultType : "continue" } |
制御は戻り値の”resultType”の値によって行います。”resultType”の値には以下の3つのパターンがあります。
resultType | 処理制御 |
---|---|
“continue” | 次のメソッドを呼ぶ。 “resultType”が明示的に指定されなかった場合には、デフォルト値として”continue”が指定されたとみなされます。 |
“stop” | 次のメソッドを呼びません。 |
“pause” | 次のメソッドを呼びません。 Web APIなどの非同期のレスポンスが返ってくるのを待つなど、特定の条件が満たされるのを待つ場合に利用します。 |
Functionの入力コネクタが複数ある場合、どのコネクタから入力されたかを区別して処理を変えることができます。どの入力コネクタでメッセージを受け取ったかは、”Receive”メソッド内で参照可能な定数 “index” に格納されています。
入力コネクタIDを参照するサンプルソースコードは以下の通りです。
1 2 3 | if ( index == 0 ) { //1番目のコネクタから入力 log( "message from #0" ); } |
Functionの出力コネクタが複数ある場合、通常、Functionの実行完了後は全ての出力コネクタからメッセージが出力されますが、出力するコネクタを選択することもできます。設定は、”Result”メソッド内で戻り値に”indexes”としてコネクタID配列を指定します。
出力コネクタIDを設定するサンプルソースコードは以下の通りです。
1 2 3 4 | return { indexes : [0, 1], //1番目, 2番目のコネクタから出力 resultType : "continue" } |
タスクスケジューラを設定するとFunctionをタイマー実行させることができます。
設定は、Initializeメソッドの戻り値に”taskConfig”オブジェクトを指定することで行います。下記の場合は、100秒間隔でFunctionが実行されます。
1 2 3 4 5 6 7 | return { resultType : "pause" , taskConfig : { mode : "interval" , seconds : 100 } } |
“taskConfig”の設定パターンは下記の通りです。
設定パターン | 例 |
---|---|
一定間隔で実行 |
taskConfig : { //10秒ごとに実行 mode : "interval", seconds : 10 } |
毎日、指定した時間に実行 |
taskConfig : { //毎日12時29分に実行 mode : "every_day", hours : 12, minutes : 29 } |
指定した日時に実行 |
taskConfig : { //2015年7月31日 17時27分00秒に実行 mode : "date", year : 2015, month : 7, day : 31, hours : 17, minutes : 27, seconds : 00 } |
Function内のメソッドから共通にアクセスできる定数・変数が用意されています。定数・変数には下記の種類があります。
Functionの入力コネクタが複数ある場合、何番目のコネクタで受け取ったかを示す値です。
参照は下記のように行います。
1 2 3 | if ( index == 0 ) { //1番目のコネクタから入力 log( "message from #0" ); } |
同一Function内のメソッド間で共有できる変数です。主にFunctionの状態変数としての利用を想定しています。
変数の初期化は”Initialize”メソッド内で行います。下記のように戻り値にruntimeValuesオブジェクトとして指定します。
1 2 3 | return { runtimeValues : { count : 0 } //"count"という変数を定義して初期化する } |
変数へのアクセスは、各メソッド内でruntimeValuesオブジェクトを参照・更新して行います。ただし、更新を行った場合は、メソッドの戻り値として、runtimeValuesオブジェクトを必ず指定してください。忘れると、更新が反映されません。
1 2 3 4 5 6 7 8 9 10 11 12 13 | runtimeValues.count++; if ( runtimeValues.count == properties.Limit ) { runtimeValues.count = 0; return { resultType : "continue" , //処理を継続 runtimeValues : runtimeValues //runtimeValuesとして返す }; } else { return { resultType : "pause" , //処理を停止 runtimeValues : runtimeValues //runtimeValuesとして返す } } |
タグ間でデータを受け渡すための変数です。Canvas上の接続元から接続先に送られるメッセージのデータを参照・更新できます。
変数へのアクセスは、各メソッド内でmessageValuesオブジェクトを参照・更新して行います。ただし、更新を行った場合は、メソッドの戻り値として、messageValuesオブジェクトを必ず指定してください。指定を忘れると、更新が反映されません。
メッセージ送信側タグのソースコード例は下記の通りです。
1 2 3 4 5 6 7 | var msgVal = {}; msgVal.date = new Date(); //メッセージに情報(e.g. 実行日時)を追加 return { messageValues : msgVal, //messageValuesとして返す resultType : "continue" } |
メッセージ受信側タグのソースコード例は下記の通りです。
1 | var date = messageValues.date; |
SDKではソフトウェアタグ開発で共通利用可能な関数の整備を進めています。
現状、下記2つの関数を用意しています。
非同期HTTP通信機能です。
指定可能な主なパラメータは下記の通りで、基本的にはjQueryのajaxメソッドに準拠しております。
パラメータ | 説明 |
---|---|
url | アクセスしたいURL |
data | URLに送信したいデータオブジェクト |
type | HTTP通信の種類 {GET / POST} |
contentType | サーバにデータを送信する際に用いるcontent-typeヘッダの値 |
dataType | サーバから返されるデータの型 {xml / html / script / json / jsonp / text} |
timeout | タイムアウト時間(ミリ秒) |
beforeSend | リクエスト送信前にコールバックされるイベントハンドラ |
success | 通信が成功した場合にコールバックされるイベントハンドラ |
error | 通信が失敗した場合にコールバックされるイベントハンドラ |
Ajaxは非同期通信のため、応答を待ちたい場合はメソッドの戻り値に resultType: “pause”を指定してください。
天気予報Webサービス(OpenWeatherMap service)を利用した天気チェック(詳細は「天気予報タグ」を参照してください)のサンプルソースコードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 | //デイリーの天気予報を取得するAPI var apiURL = "http://api.openweathermap.org/data/2.5/forecast/daily" ; //APIを叩く際のパラメータ //プロパティの値を渡す var data = { "q" : properties.location, "cnt" : 1, "APPID" : '1111111111' //取得したAPP Keyに置き換えてください }; ajax ({ url : apiURL, data : data, type : "get" , timeout : 5000, success : function ( contents ) { //正しいデータが取れているかチェック if ( !contents.list || !contents.list[ 0 ] || !contents.list[ 0 ].weather || !contents.list[ 0 ].weather[ 0 ] || !contents.list[ 0 ].weather[ 0 ].id ) { log( "Weather : Invalid data" ); runtimeValues.outputIndex = -1; callbackSuccess( { resultType : "continue" , runtimeValues : runtimeValues } ); } //天気を示すID部分を抜き出し、数値に変換する var idNum = contents.list[ 0 ].weather[ 0 ].id + 0; //天気に応じて outputIndex の値を変更する if ( ( 200 <= idNum && idNum <= 531 ) || ( 600 <= idNum && idNum <= 622 ) ) { //「雨」なら runtimeValues.outputIndex = 2; } else if ( 701 <= idNum && idNum <= 781 ) { //「くもり」なら runtimeValues.outputIndex = 1; } else if ( 800 <= idNum && idNum <= 802 ) { //「晴れ」なら runtimeValues.outputIndex = 0; } else { //それ以外なら「くもり」 runtimeValues.outputIndex = 1; } callbackSuccess( { resultType : "continue" , runtimeValues : runtimeValues } ); }, error : function ( request, errorMessage ) { log( "Weather : Network error" ); runtimeValues.outputIndex = -1; callbackSuccess( { resultType : "continue" , runtimeValues : runtimeValues } ); } }); return { resultType : "pause" }; |
カメラタグは、Sony Camera Remote API betaを利用して、対応するカメラをMESHからコントロールするためのソフトウェアタグです。今回の例では、シンプルに写真を撮影する、"TakePicture" Functionを備えたタグを実装します。
このタグを利用する際には、Camera Remote API betaに対応したカメラとiPadがネットワーク接続された状態で利用してください。また、Propertyとして、ActionListURL(e.g. http://192.168.122.1:10000/sony)を指定する必要があります。対応カメラのActionListURLを調べた上で利用してください。
"TakePicture" Functionのソースコードは以下の通りです。
1 | /*** No Initialize Codes ***/ |
1 | /*** No Receive Codes ***/ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 | //The endpoint URL of Remote API var endPointURL = properties.actionListURL + "/camera" ; //The JSON data which puts the camera into "Shooting mode" var setShootModeJSONData = { method : "setShootMode" , params : [ "still" ], id : 1, version : "1.0" }; //The JSON data which makes the camera take picture var takePictureJSONData = { method : "actTakePicture" , params : [], id : 1, version : "1.0" }; //Puts the camera into "Shooting mode" ajax ({ url : endPointURL, type : "post" , data : JSON.stringify( setShootModeJSONData ), contentType : "application/json" , dataType : "json" , timeout : 5000, success : function ( contents ) { //Makes the camera take picture ajax({ url : endPointURL, type : "post" , data : JSON.stringify( takePictureJSONData ), contentType : "application/json" , dataType : "json" , timeout : 5000, success : function ( contents ) { callbackSuccess( { resultType : "continue" } ); }, error : function ( request, errorMessage ) { log( "Camera : Network error" ); callbackSuccess( { resultType : "continue" } ); } }); }, error : function ( request, errorMessage ) { log( "Camera : Network error" ); callbackSuccess( { resultType : "continue" } ); } }); return { resultType : "pause" }; |
1 | /*** No Result Codes ***/ |
以下にImport用のJSONデータを記載します。「Import機能」を参考にJSONデータをImportすることで、SDK上でタグの作成、設定項目、コードの確認、編集が可能です。
1 | { "formatVersion" : "1.0" , "tagData" :{ "name" : "Camera" , "icon" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAA8BJREFUeAHtnE9rIkEQxceoIIpelOTmKZDv/2E8efDkRVBRRBMjcamFXhrsP5Opnn4z7hOCw3RPv6r365pp3bU7i8XiXvAFc+AFpkzhvw4QAHgiEAABgB0Ay7MCCADsAFieFUAAYAfA8qwAAgA7AJZnBYAB9DT693v8a6ROp6ORaMy1sVyr5qkC8Pr6GjVou90WPz8/0X5N7jAcDovRaBQM8evrqzgej8E+rkYVgOl0WrjIyzkzY/b7fasBSB4CYDabPfhn53k6nYrD4eD04+FC64QKgIzjAmCfNyAszdYeunI156rmyYcweDoQQEkAZqaX7F66GwGUtKrqLSY2vPoZEBMItUtSk8mkeHlpzjyQ1czn52co7KRttQIoM2vG43HR7XaTJqUZTJaSl8vlYXFR1y2oVgBiRChwaVuv1xq/arnWFbNMJtd5CSDUFgtQBUDWvrFX7EOYL6nYuLnaJb7r9VpIrr6Klj7n87lSSB3Nf0vxBWRH0nSD7VhDx3XlqqqAZzE3ZLxpqyvX5iw/TKb/2TsBgIETwLMAkIeUfGVb5mEFzjmJfK/XKwaDgXqsZBUgxs/nc3VAbRlAvqJ+e3tTT7hkANpiXNPiJAAwEQIgALADYHlWAAGAHQDLswIIAOwAWJ4VQABgB8DyrAACADsAlmcFEADYAbA8K4AAwA6A5VkBBAB2ACzPCiAAsANgeVYAAYAdAMuzAggA7ABYnhVAAGAHwPKsAAIAOwCWZwUQANgBsDwrgADADoDlWQEEAHaggrz8ZFX+UuxxofqhdoXYn+oS+VmW9vfDvAUppoTWfJEmAAWAFJcSQAoXFWMQgMK8FJcSQAoXFWMQgMK8FJcSQAoXFWOo9gt6f3//tw6WJZnZJ8I+Xq1Wxe12U4SIvVRykh2C7Z1z7fW/OZYdtWT7td8uTVUAZMOK0KdBCU7+2v6SHGVjwZC5IR9C+fMWFHLHaguZb3X79aGqAmJqZYKObeoX00jdLjG74ja3mtR6tQKIBStJfXx8BG9jsTFSt+92u2Kz2TxAcEFJoQ0FIEktl8sUeSQdw2V2XRXAZ0ACdJqFRq0ANIEl8CXpEK6qMAKhNtPH966+BblMloBc531BtOG8Kx87z6oQVP8g0+/3o959f39H+zS9g/kcEIpTAFX5wKmqgGcwN2SqaZOlcl3L5VqfASYBvvsdIAC/N1laCCCLzX4RAvB7k6WFALLY7BchAL83WVoIIIvNfhEC8HuTpYUAstjsFyEAvzdZWgggi81+EQLwe5OlhQCy2OwX+QM87NrMcdrt8wAAAABJRU5ErkJggg==" , "description" : "This is a sample Software Tag using \"Camera Remote API\"." , "functions" :[{ "id" : "function_0" , "name" : "TakePicture" , "connector" :{ "inputs" :[{ "label" : "" }], "outputs" :[{ "label" : "" }]}, "properties" :[{ "name" : "ActionListURL" , "referenceName" : "actionListURL" , "type" : "string" , "defaultValue" : "http://192.168.0.100:10000/sony" }], "extension" :{ "initialize" : "/*** No Initialize Codes ***/" , "receive" : "/*** No Receive Codes ***/" , "execute" : "//The endpoint URL of Remote API\nvar endPointURL = properties.actionListURL + \"/camera\";\n\n//The JSON data which puts the camera into \"Shooting mode\"\nvar setShootModeJSONData = {\n \tmethod : \"setShootMode\",\n\tparams : [\"still\"],\n\tid : 1,\n\tversion : \"1.0\"\n};\n\n//The JSON data which makes the camera take picture\nvar takePictureJSONData = {\n\tmethod : \"actTakePicture\",\n\tparams : [],\n\tid : 1,\n\tversion : \"1.0\"\n};\n\n//Puts the camera into \"Shooting mode\"\najax ({\n\turl : endPointURL,\n\ttype : \"post\",\n\tdata : JSON.stringify( setShootModeJSONData ),\n\tcontentType : \"application/json\",\n\tdataType : \"json\",\n\ttimeout : 5000,\n\tsuccess : function ( contents ) {\n\t\t//Makes the camera take picture\n\t\tajax({\n\t\t\turl : endPointURL,\n\t\t\ttype : \"post\",\n\t\t\tdata : JSON.stringify( takePictureJSONData ),\n\t\t\tcontentType : \"application/json\",\n\t\t\tdataType : \"json\",\n\t\t\ttimeout : 5000,\n\t\t\tsuccess : function ( contents ) {\n\t\t\t\tcallbackSuccess( {\n\t\t\t\t\tresultType : \"continue\"\n\t\t\t\t} );\n\t\t\t},\n\t\t\terror : function ( request, errorMessage ) {\n\t\t\t\tlog(\"Camera : Network error\");\n\t\t\t\tcallbackSuccess( {\n\t\t\t\t\tresultType : \"continue\"\n\t\t\t\t} );\n\t\t\t}\n\t\t});\n\t\t\n\t},\n\terror : function ( request, errorMessage ) {\n\t\tlog(\"Camera : Network error\");\n\t\tcallbackSuccess( {\n\t\t\tresultType : \"continue\"\n\t\t} );\n\t}\n});\n\nreturn {\n\tresultType : \"pause\"\n};" , "result" : "/*** No Result Codes ***/" }}]}} |
天気予報タグは、OpenWeatherMap serviceが提供するWeather APIを利用して、現在の天気に応じて反応が変わるソフトウェアタグです。今回の例では、入力コネクタから入力があった時に、特定の場所(Tokyoなど文字列で指定)の晴れ、雨、曇りの天気を判別して、複数のアウトプットに出力しわけるタグを実装します。
"Check" Functionのソースコードは以下の通りです。"Execute"のソースコードの一部にAPI Keyを記述する行があります。このタグを利用する際には、ご自身でOpenWeatherMap serviceでアカウント作成、API Keyを取得していただき、該当行を取得したAPI Keyに置き換えた上で利用してください。
1 2 3 4 5 6 7 | //Initialize "outputIndex" return { runtimeValues : { outputIndex : 0 }, resultType : "continue" }; |
1 | /*** No Receive Codes ***/ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 | //The API which gets daily weather forecast var apiURL = "http://api.openweathermap.org/data/2.5/forecast/daily" ; //The parameter of the API //Pass the value of the property var data = { "q" : properties.location, "cnt" : 1, "APPID" : '1111111111' //Please replace it with the App ID you get }; ajax ({ url : apiURL, data : data, type : "get" , timeout : 5000, success : function ( contents ) { //Validate the contents if ( !contents.list || !contents.list[ 0 ] || !contents.list[ 0 ].weather || !contents.list[ 0 ].weather[ 0 ] || !contents.list[ 0 ].weather[ 0 ].id ) { log( "Weather : Invalid data" ); runtimeValues.outputIndex = -1; callbackSuccess( { resultType : "continue" , runtimeValues : runtimeValues } ); } //Extract the ID part indicating the weather and convert it to the number value var idNum = contents.list[ 0 ].weather[ 0 ].id + 0; //Change the value of "outputIndex" depending on the weather if ( ( 200 <= idNum && idNum <= 531 ) || ( 600 <= idNum && idNum <= 622 ) ) { //Rainy runtimeValues.outputIndex = 2; } else if ( 701 <= idNum && idNum <= 781 ) { //Cloudy runtimeValues.outputIndex = 1; } else if ( 800 <= idNum && idNum <= 802 ) { //Sunny runtimeValues.outputIndex = 0; } else { runtimeValues.outputIndex = 1; } callbackSuccess( { resultType : "continue" , runtimeValues : runtimeValues } ); }, error : function ( request, errorMessage ) { log( "Weather : Network error" ); runtimeValues.outputIndex = -1; callbackSuccess( { resultType : "continue" , runtimeValues : runtimeValues } ); } }); return { resultType : "pause" }; |
1 2 3 4 5 | //Select an output connector depending on the "outputIndex" value updated in "Execute" return { indexes : [ runtimeValues.outputIndex ], resultType : "continue" }; |
以下にImport用のJSONデータを記載します。「Import機能」を参考にJSONデータをImportすることで、SDK上でタグの作成、設定項目、コードの確認、編集が可能です。
1 | { "formatVersion" : "1.0" , "tagData" :{ "name" : "Weather" , "icon" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAqFJREFUeAHtnUtrwkAYRRNRBHUjoks3guD//y2CG1fuRBTBhYiPMl3MqiY0k+ZoPYHCkJi5892TO6N9TPPlcvnIPDAHWpiywt8OCAB+EAQgANgBWN4ECAB2AJY3AQKAHYDlTYAAYAdgeRMgANgBWL6doj8ej0tv3+122ePx3t/v6/V6Wb/fL6z1crlkx+Ox8DU/XWwEwE/C73QuACh72E6nUyUArgHwkyAAAcAOwPImAAaQtAjXMfbBYFBHN7X1Ed7NhK+mDhzAcDjMWq3XCeLhcPgsAJvNpqmH7SV1khIQ3vt+whGmpLJaz+dzJStyfy2lkm+13fQ6k29tJb1XRwKAeQlAALADsHytCeh2u3A5zcmHzy6dTidZsFYAs9ksy/M8eVDv0EH4BD+dTpOHWiuA5NF8YAcCgKELQACwA7C8CRAA7AAsbwIEADsAy5sAAcAOwPImQACwA7C8CRAA7AAsbwIEADsAy5sAAcAOwPImQACwA7C8CRAA7AAsbwIEADsAy5sAAcAOwPImQACwA7C8CRAA7AAsbwIEADsAy5sAAcAOwPL+oTYMwClIALADsLwJEADsACxvAgQAOwDLmwAYQNKOWYvFonT4q9Xq7bcuHo1G2WQyKaw17KhVZfu1JACfsi9EqLOs1rLrz+g5BT1zpqHzAmjI6GcySVPQs05/c34+n7/UvqHb7Tbb7/e/KSHptTiA9XqdVEDdN9/v97q7LOwPB3C73QoH+N8vugbAhAUAA0j6gUy7XT6DXa9XuMR0+bBBX9kG4+H/5FSZTssdLBj/fzC3oLx4KSzMf7U4OwVFm5mGABjfo6oAohVMQwCM71FVANEKpiEAxveoKoBoBdMQAON7VBVAtIJpCIDxPaoKIFrBNATA+B5VBRCtYBpfYS9rl/NlrzIAAAAASUVORK5CYII=" , "description" : "This is a sample software tag using \"Open Weather Map : Weather API\"." , "functions" :[{ "id" : "function_0" , "name" : "Check" , "connector" :{ "inputs" :[{ "label" : "" }], "outputs" :[{ "label" : "Sunny" },{ "label" : "Cloudy" },{ "label" : "Rainy" }]}, "properties" :[{ "name" : "Location" , "referenceName" : "location" , "type" : "string" , "defaultValue" : "Tokyo" }], "extension" :{ "initialize" : "//Initialize \"outputIndex\"\nreturn {\n\truntimeValues : {\n\t\toutputIndex : 0\n\t},\n\tresultType : \"continue\"\n};" , "receive" : "/*** No Receive Codes ***/" , "execute" : "//The API which gets daily weather forecast\nvar apiURL = \"http://api.openweathermap.org/data/2.5/forecast/daily\";\n\n//The parameter of the API\n//Pass the value of the property\nvar data = {\n\t\"q\" : properties.location,\n\t\"cnt\" : 1,\n\t\"APPID\" : '1111111111' //Please replace it with the App ID you get\n};\n\najax ({\n\turl : apiURL,\n\tdata : data,\n\ttype : \"get\",\n\ttimeout : 5000,\n\tsuccess : function ( contents ) {\n\t\t//Validate the contents\n\t\tif ( !contents.list || !contents.list[ 0 ] || !contents.list[ 0 ].weather || !contents.list[ 0 ].weather[ 0 ] || !contents.list[ 0 ].weather[ 0 ].id ) {\n\t\t\tlog(\"Weather : Invalid data\");\n\t\t\truntimeValues.outputIndex = -1;\n\t\t\tcallbackSuccess( {\n\t\t\t\tresultType : \"continue\",\n\t\t\t\truntimeValues : runtimeValues\n\t\t\t} );\n\t\t}\n\n\t\t//Extract the ID part indicating the weather and convert it to the number value\n\t\tvar idNum = contents.list[ 0 ].weather[ 0 ].id + 0;\n\n\t\t//Change the value of \"outputIndex\" depending on the weather\n\t\tif ( ( 200 <= idNum && idNum <= 531 ) || ( 600 <= idNum && idNum <= 622 ) ) { //Rainy\n\t\t\truntimeValues.outputIndex = 2;\n\t\t} else if ( 701 <= idNum && idNum <= 781 ) { //Cloudy\n\t\t\truntimeValues.outputIndex = 1;\n\t\t} else if ( 800 <= idNum && idNum <= 802 ) { //Sunny\n\t\t\truntimeValues.outputIndex = 0;\n\t\t} else {\n\t\t\truntimeValues.outputIndex = 1;\n\t\t}\n\t\t\n\t\tcallbackSuccess( {\n\t\t\tresultType : \"continue\",\n\t\t\truntimeValues : runtimeValues\n\t\t} );\n\t},\n\terror : function ( request, errorMessage ) {\n\t\tlog(\"Weather : Network error\");\n\t\truntimeValues.outputIndex = -1;\n\t\tcallbackSuccess( {\n\t\t\tresultType : \"continue\",\n\t\t\truntimeValues : runtimeValues\n\t\t} );\n\t}\n});\n\nreturn {\n\tresultType : \"pause\"\n};" , "result" : "//Select an output connector depending on the \"outputIndex\" value updated in \"Execute\"\nreturn {\n\tindexes : [ runtimeValues.outputIndex ],\n\tresultType : \"continue\"\n};" }}]}} |
ランダムタグは入力コネクタにメッセージが入るたびに、複数の出力コネクタのうちランダムに1つを選びメッセージを出力するソフトウェアタグです。今回の例では、6つの出力コネクタの中からランダムに1つを選び出力するようにします。
"RandomOut" Functionのソースコードは以下の通りです。
1 | /*** No Initialize Codes ***/ |
1 | /*** No Receive Codes ***/ |
1 | /*** No Execute Codes ***/ |
1 2 3 4 5 6 7 | //Select a output connector out of 6 connectors randomly var outputIndex = Math.floor( Math.random() * 6 ); return { indexes : [ outputIndex ], resultType : "continue" } |
以下にImport用のJSONデータを記載します。「Import機能」を参考にJSONデータをImportすることで、SDK上でタグの作成、設定項目、コードの確認、編集が可能です。
1 | { "formatVersion" : "1.0" , "tagData" :{ "name" : "Random" , "icon" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAA8BJREFUeAHtnE9rIkEQxceoIIpelOTmKZDv/2E8efDkRVBRRBMjcamFXhrsP5Opnn4z7hOCw3RPv6r365pp3bU7i8XiXvAFc+AFpkzhvw4QAHgiEAABgB0Ay7MCCADsAFieFUAAYAfA8qwAAgA7AJZnBYAB9DT693v8a6ROp6ORaMy1sVyr5qkC8Pr6GjVou90WPz8/0X5N7jAcDovRaBQM8evrqzgej8E+rkYVgOl0WrjIyzkzY/b7fasBSB4CYDabPfhn53k6nYrD4eD04+FC64QKgIzjAmCfNyAszdYeunI156rmyYcweDoQQEkAZqaX7F66GwGUtKrqLSY2vPoZEBMItUtSk8mkeHlpzjyQ1czn52co7KRttQIoM2vG43HR7XaTJqUZTJaSl8vlYXFR1y2oVgBiRChwaVuv1xq/arnWFbNMJtd5CSDUFgtQBUDWvrFX7EOYL6nYuLnaJb7r9VpIrr6Klj7n87lSSB3Nf0vxBWRH0nSD7VhDx3XlqqqAZzE3ZLxpqyvX5iw/TKb/2TsBgIETwLMAkIeUfGVb5mEFzjmJfK/XKwaDgXqsZBUgxs/nc3VAbRlAvqJ+e3tTT7hkANpiXNPiJAAwEQIgALADYHlWAAGAHQDLswIIAOwAWJ4VQABgB8DyrAACADsAlmcFEADYAbA8K4AAwA6A5VkBBAB2ACzPCiAAsANgeVYAAYAdAMuzAggA7ABYnhVAAGAHwPKsAAIAOwCWZwUQANgBsDwrgADADoDlWQEEAHaggrz8ZFX+UuxxofqhdoXYn+oS+VmW9vfDvAUppoTWfJEmAAWAFJcSQAoXFWMQgMK8FJcSQAoXFWMQgMK8FJcSQAoXFWOo9gt6f3//tw6WJZnZJ8I+Xq1Wxe12U4SIvVRykh2C7Z1z7fW/OZYdtWT7td8uTVUAZMOK0KdBCU7+2v6SHGVjwZC5IR9C+fMWFHLHaguZb3X79aGqAmJqZYKObeoX00jdLjG74ja3mtR6tQKIBStJfXx8BG9jsTFSt+92u2Kz2TxAcEFJoQ0FIEktl8sUeSQdw2V2XRXAZ0ACdJqFRq0ANIEl8CXpEK6qMAKhNtPH966+BblMloBc531BtOG8Kx87z6oQVP8g0+/3o959f39H+zS9g/kcEIpTAFX5wKmqgGcwN2SqaZOlcl3L5VqfASYBvvsdIAC/N1laCCCLzX4RAvB7k6WFALLY7BchAL83WVoIIIvNfhEC8HuTpYUAstjsFyEAvzdZWgggi81+EQLwe5OlhQCy2OwX+QM87NrMcdrt8wAAAABJRU5ErkJggg==" , "description" : "This is a sample software tag." , "functions" :[{ "id" : "function_0" , "name" : "RandomOut" , "connector" :{ "inputs" :[{ "label" : "" }], "outputs" :[{ "label" : "out1" },{ "label" : "out2" },{ "label" : "out3" },{ "label" : "out4" },{ "label" : "out5" },{ "label" : "out6" }]}, "properties" :[], "extension" :{ "initialize" : "/*** No Initialize Codes ***/" , "receive" : "/*** No Receive Codes ***/" , "execute" : "/*** No Execute Codes ***/" , "result" : "//Select a output connector out of 6 connectors randomly\nvar outputIndex = Math.floor( Math.random() * 6 );\n\nreturn {\n\tindexes : [ outputIndex ],\n\tresultType : \"continue\"\n}\n" }}]}} |