【MESH カスタムタグ】出力制御(誤動作防止)をするタグの実装方法

#できること
MESH*アプリ上で、このタグをトリガータグ(トリガーとなるタグ)とアクションタグ(アクションとなるタグ)の間に挟むと、指定した時間内での意図しないアクションタグの複数回実行を防ぐことができます。トリガータグが意図せず反応し、複数回アクションが実行されて『うーん...』って思う事がこれで少なくなります。


*MESHとは、小さな便利を形にできる、ブロック形状の電子タグです。
- [MESH：小さな便利を形にできる、ブロック形状の電子タグ](http://meshprj.com/jp/)


<img src="https://qiita-image-store.s3.amazonaws.com/0/159447/41d51421-a887-aecd-9eb2-342bd9e77d52.gif" width=100%>
言葉だと伝わりにくいと思うので、上記のgif画像を見て頂くと今回のタグ(盾マークのアイコン)の挙動が伝わると思います。3000ミリ秒を設定しているので、一度目の入力に対しては出力信号を出しますが、その後3000ミリ秒間は入力が来ても出力信号を出さない状態になります。
<br>

<img src="https://qiita-image-store.s3.amazonaws.com/0/159447/1197eb33-e617-3792-5ac1-a9c8115b0214.jpeg" width=100%>
動作の挙動としては、動きタグなどで設定できる**間隔(秒)**に近い動作になります。この項目を設定できるタグではこのタグを利用する必要はないのですが、それが出来ないタグの場合は活用する事ができます。



#実装
前に実装した[【MESH カスタムタグ】ミリ秒単位で処理をsleepさせる方法](https://qiita.com/glory/items/5bdb7b96c4a502e6efc7)を少し改良して実装しました。

###Initialize

```Initialize.js
return {
    runtimeValues : { 
		ignoreSignal:false
	} 
}
```

###Receive
特に書くことはありません。

###Execute


```Execute_success.js
w
wait().then((v) => {
    log(runtimeValues.ignoreSignal);
});

function sleep() {
	return new Promise(resolve => setTimeout(resolve,properties.millisecond));
}

async function wait() {
	//1回目の入力信号は、出力信号を送る
	if(!runtimeValues.ignoreSignal){

		runtimeValues.ignoreSignal = true;
		callbackSuccess( {
			resultType : "continue"
		} );
		
		//非同期処理が完了するまで待機
		await sleep();
		
		runtimeValues.ignoreSignal = false;		
	}
	//入力信号があってから指定時間以内は、出力信号を送らない
	else{
		callbackSuccess( {
			resultType : "stop"
		} );

	}
	return properties.millisecond.toString();
}

return {
	resultType : "pause"
};
```

###Result

```Result.js
return {
	indexes : 0,
	resultType : "continue"
};
```

###importファイル
[MESH SDKログインページ](https://meshprj.com/signin/)からID等を入力してログインし、「Create New Tag」から新しいカスタムタグを作ってください。その後、import」を開き、下記のjosnデータをコピペして「Load JSON」を押して読み込んでください。

```output_control.json
{"formatVersion":"1.0","tagData":{"name":"出力制御(誤動作防止)","icon":"data:image/png;base64,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","description":"一度入力・出力されてから、指定時間経過するまで入力を無視するタグです。\n(誤動作で複数回信号が送信される可能性がある場合、このタグを間に挟む事で指定時間内の出力を1回だけすることができます。)","functions":[{"id":"function_0","name":"時間内の複数入力を1出力とする","connector":{"inputs":[{"label":"入力"}],"outputs":[{"label":"出力"}]},"properties":[{"name":"時間(ミリ秒)","referenceName":"millisecond","type":"string","defaultValue":"1000"}],"extension":{"initialize":"return {\n    runtimeValues : { \n\t\tignoreSignal:false\n\t} \n}","receive":"","execute":"\nwait().then((v) => {\n    log(runtimeValues.ignoreSignal);\n});\n\nfunction sleep() {\n\treturn new Promise(resolve => setTimeout(resolve,properties.millisecond));\n}\n\nasync function wait() {\n\t//1回目の入力信号は、出力信号を送る\n\tif(!runtimeValues.ignoreSignal){\n\n\t\truntimeValues.ignoreSignal = true;\n\t\tcallbackSuccess( {\n\t\t\tresultType : \"continue\"\n\t\t} );\n\t\t\n\t\t//非同期処理が完了するまで待機\n\t\tawait sleep();\n\t\t\n\t\truntimeValues.ignoreSignal = false;\t\t\n\t}\n\t//入力信号があってから指定時間以内は、出力信号を送らない\n\telse{\n\t\tcallbackSuccess( {\n\t\t\tresultType : \"stop\"\n\t\t} );\n\n\t}\n\treturn properties.millisecond.toString();\n}\n\nreturn {\n\tresultType : \"pause\"\n};\n","result":"return {\n\tindexes : 0,\n\tresultType : \"continue\"\n};"}}]}}
```

#感想
意図しないアクションの複数回連続動作に悩まされていたので、これで解決する事ができました！