1. はじめに
IoT組み込みエンジンNEQTOをご契約の方は、NEQTOで提供しているNEQTO APIを使ってノードに関する情報を閲覧・管理するUIを独自で作成できます。例えば、NEQTOに接続しているエアコンをお持ちの場合、管理しているエアコンの一覧を表示したり、機械や機器に対して遠隔操作を行えるDynamic APIを使用して各エアコンの設定温度を操作したりするような、特定のデバイスに特化したダッシュボードを作成できます。
そこで今回は、そういったUIを作る方の参考になるよう、Reactをベースにノードのイベント一覧を表示するUIを作る方法をご紹介します。
2. Reactでプロジェクトを作る
まず、React公式の手順に従い、以下のコマンドを実行してプロジェクトを作成します。
$ npx create-react-app neqto-custom-ui
$ cd neqto-custom-ui</pre>
ファイル構造はこのようになっています。
.
├── README.md
├── node_modules/
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
├── reportWebVitals.js
└── setupTests.js</pre>
UIを作成する際に必要のないコードは削除します。
src/App.js
src/App.js
import './App.css';
function App() {
return (
<div className='App'>
{/* something */}
</div>
);
}
export default App;
また、useEffectで指定した関数が2回実行される問題を防ぐため、index.jsのReact.StrictModeを外します。本番モードでは機能しないため、外していてもそれほど影響はありません。
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
// - root.render(
// - <React.StrictMode>
// - <App />
// - </React.StrictMode>
// - );
root.render(
<App />
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
そして、以下のコマンドを実行して開発モードで起動できます。
$ npm start
3. ログイン部分を作る
NEQTO APIに関する情報はNEQTOの公式ドキュメントの「APIの利用」のページに記載しています。
ログイン情報は同ページの「認証情報取得」の項目を参照すると、以下のパラメーターとボディでリクエストを行うことができます。
パラメーター | |
---|---|
URL | https://auth.neqto.com/account/api-token-auth |
method | POST |
Content-Type | application/json |
body
{
"company_code": "your company code",
"email": "your login user",
"password": "your user's login password"
}
これらを踏まえて書いたコードがこちらです。
src/App.js
import { useState } from 'react';
import './App.css';
function login(password) {
return fetch('https://auth.neqto.com/account/api-token-auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
company_code: 'your-company-code',
email: '■■■■@▲▲▲.com',
password: password
})
}).then(res => res.json());
}
function App() {
const [accessToken, setAccessToken] = useState();
const onSubmit = (e) => {
e.preventDefault();
const password = e.target.querySelector('input[type="password"]').value;
login(password)
.then(data => setAccessToken(data.token));
}
return (
<div className='App'>
<form onSubmit={onSubmit}>
<label htmlFor='password-input'>パスワードを入力してください</label>
<br />
<input type='password' id='password-input' />
<button type='submit'>ログイン</button>
</form>
{accessToken &&
<>
<p>ログインに成功しました</p>
{accessToken}
</>
}
</div>
);
}
export default App;
ログインにはパスワードの他に、company codeとemailが必要ですが、今回は一つのノードにのみ対象にするUIを作成するため、この二つの情報はハードコーディングしています。
開発モードでアプリを起動後、localhost:3000にアクセスすると、以下のようにパスワードを入力するフォームが表示されます。
入力を終えボタンをクリックすると、認証APIにリクエストされます。 ログインが成功すると以下のように表示され、アクセストークンを正常に得られたことが確認できます。
4. イベント履歴を取得する
特定のノードのイベントを取得するにはリージョンAPIを使用します。 NEQTOの公式ドキュメントの「APIの利用」のエンドポイントの表にも記載されていますが、リージョンAPIには2種類あるので、対象のデバイスに近いリージョンをお使いください。 APIリファレンスの「groups_nodes_events」のAPIで特定のノードのイベント履歴を取得できます。
また、認証APIで取得したアクセストークンはAuthorizationリクエストヘッダーにjwt <access token>という形でセットすることで使用できます。
次に、実際にコーディングをしますが、App.jsと同じディレクトリにEventTable.jsというファイルを新規作成し、そのファイルにイベント一覧を表示するテーブルをもつコンポーネントを書きます。 グループIDとノードIDを使用するため、定数”GROUP_ID”と”NODE_ID”を適宜書き換えてください。
グループIDとノードIDについては、ブログ「NEQTO リージョンAPIを使って、コマンドラインからスクリプトの操作をする方法」を参照してください。
src/EventTable.js
import { useEffect, useState } from 'react';
const GROUP_ID = 'your-group-id';
const NODE_ID = 'your-node-id';
function listEvents(accessToken) {
const url = `https://asia-pacific-1.neqto.com/groups/${GROUP_ID}/nodes/${NODE_ID}/events`
+ `?from_time=${Date.now() - 70 * 24 * 60 * 60 * 1000}`
+ `&to_time=${Date.now()}`
+ '&limit=10'
return fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'jwt ' + accessToken,
}
}).then(res => res.json());
}
function formatTime(unixtime) {
return new Date(unixtime).toISOString()
.replace('T',' ')
.replace(/\..*/, '')
}
export default function EventTable({ accessToken }) {
const [events, setEvents] = useState();
useEffect(() => {
listEvents(accessToken)
.then(data => {
setEvents(data.results);
});
}, [accessToken]);
return (
<div className='table-wrapper'>
<table>
<thead>
<tr>
<th>種類</th>
<th>レベル</th>
<th>メッセージ</th>
<th>発生時間(サーバー)</th>
<th>発生時間(デバイス)</th>
</tr>
</thead>
{events ?
events.map(event => (
<tr>
<td>{event.event_type}</td>
<td>{event.event_level}</td>
<td>{event.message}</td>
<td>{formatTime(event.timestamp)}</td>
<td>{formatTime(event.occurred_at)}</td>
</tr>
))
:
<span>
loading...
</span>
}
<tbody>
</tbody>
</table>
</div>
)
}
そして、App.jsからこのコンポーネントを呼び出します。
src/App.js
import { useState } from 'react';
import './App.css';
import EventTable from './EventTable';
function login(password) {
return fetch('https://auth.neqto.com/account/api-token-auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
company_code: 'your-company-code',
email: '■■■■@▲▲▲.com',
password: password
})
}).then(res => res.json());
}
function App() {
const [accessToken, setAccessToken] = useState();
const onSubmit = (e) => {
e.preventDefault();
const password = e.target.querySelector('input[type="password"]').value;
login(password)
.then(data => setAccessToken(data.token));
}
return (
<div className='App'>
<form onSubmit={onSubmit}>
<label htmlFor='password-input'>パスワードを入力してください</label>
<br />
<input type='password' id='password-input' />
<button type='submit'>ログイン</button>
</form>
<h1>イベント一覧</h1>
{accessToken ?
<EventTable accessToken={accessToken} />
:
'Loading...'
}
</div>
);
}
export default App;
EventTableコンポーネントでは、リージョンAPIを使ってイベント一覧を取得し、eventsというステートにセットし、テーブルとして表示しています。
以下が実際に作成したUIです。(CSSは別途設定しています。)
5. まとめ
今記事では、NEQTO APIを使用して特定のノードの情報を取得するUIを作成する方法をご紹介しました。
簡単のため、API呼び出しのエラーハンドリングの実装や煩雑な処理の抽象化を省いていますが、NEQTO APIを用いたUIを実装する際の参考になれば幸いです。