【Nature Remo】Local APIでブラウザから家電リモコンを操作する方法

スマートリモコン『Nature Remo』では、赤外線送信などの操作ができるCloud APIとLocal APIが公開されています。

今回は、そのNature RemoのLocal APIを利用して、以下のような簡単なページを作成しブラウザから家電操作を行う例となります。

また、リモコン機能のない照明や家電などに、リモコン機能を簡単に取り付ける機器もあります。詳しくは以下のリンク先を参考にしてみてください。

【Nature Remo】ローカルAPIでブラウザから家電リモコンを操作する方法

ローカルAPIをブラウザから利用する場合

ブラウザ(クライアント側)からNature RemoのローカルAPIを利用しようとすると、CORS(Cross-Origin Resource Sharing)エラーにより、利用できませんでした。

そのため、今回の例ではローカルサーバーを構築して、サーバー側からNature RemoのローカルAPIを送信して、Nature Remoを操作します。

サーバーの構築にはWebアプリケーションなどを作成できるNode.jsモジュールの「Express」を利用するため、Node.jsを利用できる環境が用意されている前提としています。

Node.jsをMacでインストールする方法については、以下のリンク先を参考にしてみてください。

また、クラウドAPIの場合はブラウザ(クライアント側)から利用できたため、サーバー側を実装しなくてもNature Remoを操作するページを作成できます。詳しくは以下のリンク先を参考にしてみてください。

Node.jsのプロジェクトを準備

まずは、以下の手順でNode.jsのプロジェクトを準備します。

任意の場所にプロジェクトフォルダを作成し、そのディレクトリに移動して以下のコマンドを実行します。

npm init -y

そして、今回のプロジェクトで利用するnpmパッケージのexpressとnode-fetchを以下のコマンドでインストールします。

node-fetchはNode.jsでJavaScriptのfetchを利用できるモジュールとなります。 

npm install express node-fetch

また、今回の例ではパッケージのバージョンは、それぞれ以下となります。

  • express@4.17.1
  • node-fetch@2.6.1

サーバー側のスクリプトを作成

プロジェクトのルートディレクトリ直下にindex.js が作成されているので、そのファイル内に以下のサーバー側のコードを記述します。

また、コード22行目のXXX.XXX.XX.XXの箇所には、Nature RemoのIPアドレスを指定します。Nature RemoのIPを確認する方法については、以下のリンク先を参考にしてみてください。

const express = require('express')
const app = express()
const fetch = require('node-fetch')
// 利用するlocalhostのポート番号を指定
const port = 3000

// クライアントから受け取るデータを解析して扱えるようにする設定
app.use(express.json())
app.use(express.urlencoded({extended: true}))

// クライアント側で処理をする静的ファイルをロードできるディレクトリを指定
app.use(express.static(__dirname + '/public'))

// クライアントからのPOSTリクエストを処理するルーティング
app.post('/ir-send', (req, res) => {

  const headers = new fetch.Headers({
    'X-Requested-With': 'fetch',
    'Content-Type': 'application/json'
  })

  fetch('http://XXX.XXX.XX.XX/messages', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(req.body)
  })
  .then((response) => {
    if(response.ok) {
      res.send('OK')
      return
    }
    throw new Error('Network response was not ok.')
  })
  .catch((error) => {
    console.error('Error:', error)
  })
})

// ローカルサーバーを起動
app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

上記サーバー側のコードでは、主に次の処理を行っています。

クライアントから受け取った赤外線信号のJSONデータを、node-fetchでローカルAPIのリクエストを行いNature Remoに送信します。それによりNature Remoを操作しています。

クライアント側で処理をする静的ファイルを作成

今回の例では、クライアント側で処理をする静的ファイルを以下のように配置します。

プロジェクトのルートディレクトリ直下にpublicフォルダを作成して、その中に次の3つのファイルを配置。

  • index.html
  • index.js
  • style.css

それぞれのファイルの内容は以下となります。

index.html

リモコンを操作するページは、button要素をクリックすると、Nature Remoからリモコン送信を行えるようにします。

また、button要素はJavaScriptで操作するため、nameの値にはir、valueの値はボタンを識別するため一意の値を指定します。

以下、index.htmlの例となります。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Remote</title>
  <link rel="stylesheet" type="text/css" media="screen,print" href="style.css">
  <script type="text/javascript" src="index.js"></script>
</head>

<body>
  <div class="container">

    <div class="light_box"></div>
    
    <section class="tv">
      <h1>TV</h1>
      <div class="tv_onoff col_1">
        <div><button type="button" name="ir" value="tv_on_off">ON/OFF</button></div>
      </div>
    </section>

    <section class="light">
      <h1>Light</h1>
      <div class="col_2">
        <div><button type="button" name="ir" value="light_on">ON</button></div>
        <div><button type="button" name="ir" value="light_off">OFF</button></div>
      </div>
    </section> 
  </div>

</body>
</html>

index.js

以下はindex.jsの例となります。

コード行6目からのオブジェクトは、上記HTMLで指定したbutton要素のvalueの値と、そのボタンで操作したい赤外線信号のデータをペアとします。

Nature Remoで利用する赤外線信号を取得する方法については以下のリンク先を参考にしてみてください。

 document.addEventListener('DOMContentLoaded', function(){

  // クリックした際に実行する関数
  function irSend(key){

    const irObj = {
      tv_on_off: {"format":"us","freq":XX,"data":[XXXXXXXX]},
      light_on: {"format":"us","freq":XX,"data":[XXXXXXXX]},
      light_off: {"format":"us","freq":XX,"data":[XXXXXXXX]},
    };
		
    const headers = new Headers({
      'Content-Type': 'application/json',
    });

    fetch('http://localhost:3000/ir-send', {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(irObj[key])
    })
    .then(function(response) {
      if(response.ok) {
        document.getElementsByClassName('light_box')[0].classList.add('flash');
        setTimeout(function(){
          document.getElementsByClassName('light_box')[0].classList.remove('flash');
        }, 1000);
        return ;
      }
      throw new Error('Network response was not ok.');
    })
    .catch(function(error) {
      console.error('Error:', error);
    });
  }

  // 指定したHTML要素にクリックイベントを実装
  const irButton = document.getElementsByName('ir');
  for(let i = 0; i < irButton.length; i++){
    irButton[i].addEventListener('click', function(){
      let irValue = irButton[i].value;
      irSend(irValue);
    });
  }
});

上記のJavaScriptコードでは、ページ上のbutton要素をクリックした際に、JavaScriptのfetchを利用して、ローカルサーバーに赤外線信号のJSONデータを送信しています。

style.css

以下はstyle.cssの例となります。

body{
	background-color:#fff;
	font-size:1.1rem;
	line-height: 1.0rem;
}
.container{
	width: 90%;
	margin: 2rem auto;
}
section{
	margin-bottom: 2rem;
	padding-bottom: 1rem;
	border: solid 1px #ddd;
	border-radius: 0.5rem;
}

.col_1, .col_2, .col_3, .col_auto{
	width: 80%;
	margin: 0 auto 1.5rem;
	grid-gap: 1.0rem;
}
.col_2{
	display: grid;
	grid-template-columns: repeat(2,1fr);
}
.col_3{
	display: grid;
	grid-template-columns: repeat(3,1fr);
}
.col_auto{
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

h1{
	padding:1.3rem 0;
	text-align:center;
	color:#111;
	font-weight:normal;
	font-size:1.2rem;
}

button{
	display:block;
	width: 100%;
	padding: 1.0rem;
	background-color: #f0f0f0;
	border: none;
	color:#111;
	font-size:1.1rem;
	text-align: center;
	text-decoration: none;
}
button:hover{
	background-color:#ddd;
}

.light_box{
	position: fixed;
	width: 1rem;
	height: 3rem;
	margin-left: -1.0rem;
	border: solid 1px #ddd;
	border-radius: 3.0rem;
}
.flash{
	animation: flash 0.5s 2 linear;
}
@keyframes flash {
	0%{
		opacity: 0;
	}
  
	50% {
		opacity: 1;
		background-color:#6cf;
	}
}

@media screen and (min-width: 768px) {
	.container{
		width: 45%;
	}
	.light_box{
		margin-left: -2.0rem;
	}
}

リモコン送信が成功した際には、ページ左上にある固定された箇所をCSSで点滅させています。

CSSで要素を点滅させる方法については以下のリンク先を参考にしてみてください。

作成したアプリケーションを実行

以下のコマンドを実行するとローカルサーバーが起動し、アプリケーションを利用できます。

node index.js

今回の例では、http://localhost:3000 にアクセスすると、サイトが表示され、サイト内のボタンをクリックすると、Nature Remoからリモコンを操作できます。

参考サイトなど

コメント投稿コメント投稿欄を開く

コメントは項目欄(*は必須項目)を入力し、「コメントを送信」ボタンをクリックしてください。 (メールアドレスは公開されることはありません。コメントの公開は承認制となります。)

また、多忙によりコメントには返信できない場合があります。

Twitterで返信する場合はこちらから。