---
title: Web×IoTメイカーズチャレンジ2019-20 ハンズオン講習会2:04 IoT試作
tags: Web×IoTメイカーズチャレンジ
slideOptions:
theme: white
slideNumber: 'c/t'
center: false
transition: 'none'
keyboard: true
width: '93%'
height: '100%'
---
<style>
/* basic design */
.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6,
.reveal section, .reveal table, .reveal li, .reveal blockquote, .reveal th, .reveal td, .reveal p {
font-family: 'Meiryo UI', 'Source Sans Pro', Helvetica, sans-serif, 'Helvetica Neue', 'Helvetica', 'Arial', 'Hiragino Sans', 'ヒラギノ角ゴシック', YuGothic, 'Yu Gothic';
text-align: left;
line-height: 1.8;
letter-spacing: normal;
text-shadow: none;
word-wrap: break-word;
color: #444;
}
.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {font-weight: bold;}
.reveal h1, .reveal h2, .reveal h3 {color: #2980b9;}
.reveal th {background: #DDD;}
.reveal section img {background:none; border:none; box-shadow:none; max-width: 95%; max-height: 95%;}
.reveal blockquote {width: 90%; padding: 0.5vw 3.0vw;}
.reveal table {margin: 1.0vw auto;}
.reveal code {line-height: 1.2;}
.reveal p, .reveal li {padding: 0vw; margin: 0vw;}
.reveal .box {margin: -0.5vw 1.5vw 2.0vw -1.5vw; padding: 0.5vw 1.5vw 0.5vw 1.5vw; background: #EEE; border-radius: 1.5vw;}
/* table design */
.reveal table {background: #f5f5f5;}
.reveal th {background: #444; color: #fff;}
.reveal td {position: relative; transition: all 300ms;}
.reveal tbody:hover td { color: transparent; text-shadow: 0 0 3px #aaa;}
.reveal tbody:hover tr:hover td {color: #444; text-shadow: 0 1px 0 #fff;}
/* blockquote design */
.reveal blockquote {
width: 90%;
padding: 0.5vw 0 0.5vw 6.0vw;
font-style: italic;
background: #f5f5f5;
}
.reveal blockquote:before{
position: absolute;
top: 0.1vw;
left: 1vw;
content: "\f10d";
font-family: FontAwesome;
color: #2980b9;
font-size: 3.0vw;
}
/* font size */
.reveal h1 {font-size: 5.0vw;}
.reveal h2 {font-size: 4.0vw;}
.reveal h3 {font-size: 2.8vw;}
.reveal h4 {font-size: 2.6vw;}
.reveal h5 {font-size: 2.4vw;}
.reveal h6 {font-size: 2.2vw;}
.reveal section, .reveal table, .reveal li, .reveal blockquote, .reveal th, .reveal td, .reveal p {font-size: 2.2vw;}
.reveal code {font-size: 1.6vw;}
/* new color */
.red {color: #EE6557;}
.blue {color: #16A6B6;}
/* split slide */
#right {left: -18.33%; text-align: left; float: left; width: 50%; z-index: -10;}
#left {left: 31.25%; text-align: left; float: left; width: 50%; z-index: -10;}
</style>
<style>
/* specific design */
.reveal h1 {
margin: 0% -100%;
padding: 2% 100% 4% 100%;
color: #fff;
background: #c2e59c; /* fallback for old browsers */
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 200% 200%;
animation: Gradient 60s ease infinite;
}
@keyframes Gradient {
0% {background-position: 0% 50%}
50% {background-position: 100% 50%}
100% {background-position: 0% 50%}
}
.reveal h2 {
text-align: center;
margin: -5% -50% 2% -50%;
padding: 4% 10% 1% 10%;
color: #fff;
background: #c2e59c; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #64b3f4, #c2e59c); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #64b3f4, #c2e59c); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
</style>
<!-- --------------------------------------------------------------------------------------- -->
#### Web×IoTメイカーズチャレンジ2019-2020
# FIWAREを使ったIoTの試作
<br>
<br>
#### 2019.11.3
### 講師:香川大学 米谷雄介
---
## 目次
1. IoTの基本要素の確認と学習方法
2. 学習の準備
3. FIWAREを使ったIoTの試作
-- Step6. FIWAREへの登録(プッシュスイッチ)
-- Step7. FIWAREへの登録(温度センサー)
-- Step8. IoTシステム(プッシュスイッチ→Lチカ)
-- Step9. IoTシステム(温度→モーター)
-- Step10. GPSセンサーの利用
-- Step11. GPSロガーを試作する
-- Step12. 移動型温度センサーを試作する
---
## 1. IoTの基本要素の確認と学習方法
### IoTの基本要素
1. センサー
-- タクトスイッチ
-- 温湿度センサ
-- GPSセンサ
2. IoTプラットフォーム
-- FIWARE
3. アクチュエータ
-- LED(発光ダイオード)
-- サーボモータ
-- Webブラウザ
---
## 1. IoTの基本要素の確認と学習方法
### 学習の基本的な流れ
1. アクチュエータを動かします。
2. センサーでデータを取ります。
3. IoTプラットフォームを介してセンサーとアクチュエータを連携させます。
---
## Step0:学習の準備
### 作業用のフォルダをデスクトップに作りましょう
- 説明の都合上「web-iot」という名前のフォルダを作ってください。
- この中にプログラムを入れていきます。
---
## Step0:学習の準備
### プログラムを作成するエディタを開きます。
- 左上のラズベリーマークをクリックし、「プログラム」をクリック、「Geany」をクリックしてください。
- このエディタでプログラムを作っていきます。
---
## Step0:学習の準備
### プログラムを実行するターミナルを開きます。
- 上部のメニューバー一覧の中から黒いアイコン(LXTerninal)を開いておいてください。
---
## Step0:学習の準備
### 以下のような状態で作業を進めていきます。
- Geany:プログラムを作成
- Chromium:教材確認&アクチュエータプログラムを実行
- LXTerminal:センサープログラムを実行
- ファイルマネージャ:作業フォルダを見えるように

#### ウィンドウ配置はご自身が作業しやすいように工夫してください。
---
## Step0:学習の準備
### IoTプラットフォームの利用を助けるツール
- 以下からダウンロードして解凍してください。(パスワード付)
- fiware-api.zip
https://drive.google.com/file/d/1skDLZNIumLGxQtT1U0CcX2UkNW3GpN5w/view?usp=sharing
- 解凍した「fiware-api」フォルダを作業用フォルダ「web-iot」に入れてください。
---
## Step6 FIWAREへの登録(プッシュスイッチ)
### 配線図
Step2と同じです。

---
## Step6 FIWAREへの登録(プッシュスイッチ)
### プログラム
#### スイッチ状態送信プログラムを実行するWebアプリ(step6.html という名前で保存)
```html=
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width" name="viewport">
<title>Sync-Switch</title>
</head>
<body>
<!-- ブラウザによる動作の違いを吸収する -->
<script src="https://r.chirimen.org/polyfill.js"></script>
<!-- 基本ライブラリを読み込む -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<!-- FIWAREのライブラリを読み込む -->
<script src="fiware-api/ngsi.js"></script>
<script src="fiware-api/orion.js"></script>
<script src="fiware-api/config.js"></script>
<!-- プッシュスイッチON/OFFプログラムを読み込む -->
<script src="step6.js"></script>
</body>
</html>
```
---
## Step6 FIWAREへの登録(プッシュスイッチ)
### プログラム
#### スイッチ状態送信プログラムの本体(step6.js という名前で保存)
```javascript=
main();
async function main() {
var gpioAccess = await navigator.requestGPIOAccess();
var switchPort = gpioAccess.ports.get(5); // タクトスイッチの付いているポート
await switchPort.export("in");
switchPort.onchange = function(val) {
// タクトスイッチをデータとして表現する
var tactSwitch = {
id: "jp.kagawa.takamatsu.e-topia.tactSwitch.0001",
type: "TactSwitch",
location: {type: "geo:point", value: "34.353837,134.046586", metadata: {}},
name: { type: "Text", value: "Switch001", metadata: {} },
status: { type: "Number", value: val, metadata: {} }
};
// ルールに従い送信データを整形する
var ngsiContext = {
"entities":[ tactSwitch ],
"actionType" : "APPEND"
};
// Orionにデータを送る
orion.batchUpdate( ngsiContext , function (data, status) {
console.log("STATUS : " + status + "\n");
});
};
}
```
---
## Step6 FIWAREへの登録(プッシュスイッチ)
### 補足:データによるヒト・モノ・コトの表現の仕方
#### FIWAREで扱えるデータの構造(Key-Value形式)
- 必須属性
- id:データ化されたヒト・モノ・コトを識別するための番号(他と衝突しないよう注意)
- type: ヒト・モノ・コトの分類(例:ヒト=Personと表記など;国で標準化が進められている)
- オプション属性:各属性にtype, value, metadataを指定
- location
- type
- value
- metadata
- name
- type
- value
- metadata
- status
- type
- value
- metadata
---
## Step6 FIWAREへの登録(プッシュスイッチ)
### 補足:データによるヒト・モノ・コトの表現の仕方
#### FIWAREで扱えるデータの構造(Key-Value形式)
- オプション属性のtype
- Text(文字列)
- Number(数値)
- ロケーションフォーマット
- 点: geo:location(形式:緯度,経度)
- 線: geo:line(形式:"緯度,経度","緯度,経度","緯度,経度",・・・)
- 長方形: geo:box(形式:"緯度,経度","緯度,経度";左上と右下を指定)
- 多角形: geo:polygon(形式:"緯度,経度","緯度,経度","緯度,経度",・・・;最初と最後が一致)
- 複数の多角形: geo:json(複数のgeo:polygonを合わせて書く)
- DateTime
- Boolean(0か1か)
- StructuredValue(配列)
- その他
---
## Step6 FIWAREへの登録(プッシュスイッチ)
### 補足:データによるヒト・モノ・コトの表現の仕方
#### JavaScriptにおける表現
- id:jp.kagawa.takamatsu.e-topia.tactSwitch.0001
- type: TactSwitch
- location: 固定値にする or GPSセンサーの値を指定する(lat,lon)
- name
- type: 文字列
- value: "tempSensor001"
- metadata: なし
- status
- type: 数値
- value: 温度センサーの値を指定する
- metadata: なし
```javascript=
var tactSwitch = {
id: "jp.kagawa.takamatsu.e-topia.tactSwitch.0001",
type: "TactSwitch",
location: {type: "geo:point", value: "34.353837,134.046586", metadata: {}},
name: { type: "Text", value: "Switch001", metadata: {} },
status: { type: "Number", value: val, metadata: {} }
};
```
---
## Step6 FIWAREへの登録(プッシュスイッチ)
### データ連携のイメージ

---
## Step7 FIWAREへの登録(温度センサー)
### 配線図
Step3と同じです。

---
## Step7 FIWAREへの登録(温度センサー)
### プログラム
#### 温度状態送信プログラムを実行するWebアプリ(step7.html という名前で保存)
```html=
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width" name="viewport">
<title>Sync-Temp</title>
</head>
<body>
<p id="head">TEST</p>
<!-- ブラウザによる動作の違いを吸収する -->
<script src="https://r.chirimen.org/polyfill.js"></script>
<script src="i2c-ADT7410.js"></script>
<!-- 基本ライブラリを読み込む -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<!-- FIWAREのライブラリを読み込む -->
<script src="fiware-api/ngsi.js"></script>
<script src="fiware-api/orion.js"></script>
<script src="fiware-api/config.js"></script>
<!-- プッシュスイッチON/OFFプログラムを読み込む -->
<script src="step7.js"></script>
</body>
</html>
```
---
## Step7 FIWAREへの登録(温度センサー)
### プログラム
#### スイッチ状態送信プログラムの本体(step7.js という名前で保存)
```javascript=
main();
async function main() {
var head = document.getElementById("head");
var i2cAccess = await navigator.requestI2CAccess(); // i2cAccessを非同期で取得
var port = i2cAccess.ports.get(1); // I2C I/Fの1番ポートを取得
var adt7410 = new ADT7410(port, 0x48); // 取得したポートの0x48アドレスをADT7410ドライバで受信する
await adt7410.init();
for (;;) { // 無限ループ
var value = await adt7410.read();
head.innerHTML = value ? `${value} degree` : "Measurement failure";
console.log(value + ' degree');
// 温度センサをデータとして表現する
var tempSensor = {
id: "jp.kagawa.takamatsu.e-topia.tempSensor.0001",
type: "TempSensor",
location: {type: "geo:point", value: "34.353837,134.046586", metadata: {}},
name: { type: "Text", value: "TempSensor001", metadata: {} },
status: { type: "Number", value: value, metadata: {} }
};
// ルールに従い送信データを整形する
var ngsiContext = {
"entities":[ tempSensor ],
"actionType" : "APPEND"
};
// Orionにデータを送る
orion.batchUpdate( ngsiContext , function (data, status) {
console.log("STATUS : " + status + "\n");
});
await sleep(10000); // 10000 ミリ秒 = 10秒ごとにチェック・送信する
}
};
```
---
## Step7 FIWAREへの登録(温度センサー)
### データ連携のイメージ

---
## Step8. IoTシステム(プッシュスイッチ→Lチカ)
### 配線図
#### 配線図 Step2と同じです。

### プログラム
#### スイッチ状態送信プログラムを実行するWebアプリ
step6.htmlを使います。
#### スイッチ状態送信プログラムの本体
step6.jsを使います。
---
## Step8. 呼び出しIoT(プッシュスイッチ→Lチカ)
### プログラム
#### スイッチ状態受信プログラムを実行するWebアプリ(step8.html という名前で保存)
```html=
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width" name="viewport">
<title>Sync-LED</title>
</head>
<body>
<!-- ブラウザによる動作の違いを吸収する -->
<script src="https://r.chirimen.org/polyfill.js"></script>
<!-- 基本ライブラリを読み込む -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<!-- FIWAREのライブラリを読み込む -->
<script src="fiware-api/ngsi.js"></script>
<script src="fiware-api/orion.js"></script>
<script src="fiware-api/config.js"></script>
<!-- プッシュスイッチON/OFFプログラムを読み込む -->
<script src="step8.js"></script>
</body>
</html>
```
---
## Step8. 呼び出しIoT(プッシュスイッチ→Lチカ)
### プログラム
#### スイッチ状態受信プログラムの本体(step8.js という名前で保存)
```javascript=
main();
async function main() {
var gpioAccess = await navigator.requestGPIOAccess(); // GPIO を操作する
var port = gpioAccess.ports.get(26); // 26 番ポートを操作する
var v = 0; // ポートを出力モードに設定
await port.export("out");
for (;;) {
// Orionにアクセスしてエンティティを取得する
orion.getEntities({
id : "jp.kagawa.takamatsu.e-topia.tactSwitch.0001",
type: "TactSwitch"
})
.then(function(entities){
var val = entities[0].status.value;
console.log(entities); // 確認のため出力する
// スイッチはPullupで離すと1なので反転させる
port.write(val === 0 ? 1 : 0); // LED を ON/OFF する
});
await sleep(5000); // 繰り返し毎に 5000ms 待機
}
}
```
---
## Step8. IoTシステム(プッシュスイッチ→Lチカ)
### データ連携のイメージ

---
## Step8. 呼び出しIoT(プッシュスイッチ→Lチカ)
### プログラムの実行その1
-- 受講者の皆さんは、Geany で step8.js を開き、idの値を
'jp.kagawa.takamatsu.e-topia.tactSwitch.0002'
に変えてください。
-- 受講者の皆さんは、Chromium で step8.htmlを開きましょう
-- 講師は、Geanyでstep6.jsを開き、上のidに合わせます。
-- 講師は、Chromiumで step6.htmlを開き、タクトスイッチを押します。
-- LEDは光りましたか?
<br><br>
### プログラムの実行その2
-- 隣同士ペアになってください。
-- 左の方は、Geany で step8.js を開き、idの値を
'jp.kagawa.takamatsu.e-topia.tactSwitch.{自分の座席番号}'
に変えてください。
-- そのまま、Chromium で step8.htmlを開きましょう
-- 右の方は、Geanyでstep6.jsを開き、上のidに合わせます。
-- 右の方は、Chromiumで step6.htmlを開き、タクトスイッチを押します。
-- LEDは光りましたか?
---
## Step9. IoTシステム(温度センサー→モーター)
### 配線図
Step5と同じです。

### プログラム
#### 温度状態送信プログラムを実行するWebアプリ
step7.htmlを使います。
#### 温度状態送信プログラムの本体
step7.jsを使います。
---
## Step9. IoTシステム(温度センサー→モーター)
### プログラム
Webアプリ(step9.html という名前で保存)
```html=
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width" name="viewport">
<title>Motor</title>
</head>
<body>
<p id="head">TEST</p>
<!-- ブラウザによる動作の違いを吸収する -->
<script src="https://r.chirimen.org/polyfill.js"></script>
<!-- 基本ライブラリを読み込む -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<!-- FIWAREのライブラリを読み込む -->
<script src="fiware-api/ngsi.js"></script>
<script src="fiware-api/orion.js"></script>
<script src="fiware-api/config.js"></script>
<!-- センサー値取得プログラムを読み込む -->
<script src="step9.js"></script>
</body>
</html>
```
---
## Step9. IoTシステム(温度センサー→モーター)
### プログラム
プログラム本体(step9.js という名前で保存)
```javascript=
// noprotect (JSBin の無限ループ検知・停止機能を無効化)
main();
async function main() {
var gpioAccess = await navigator.requestGPIOAccess();
var gatePort = gpioAccess.ports.get(26); // FET(ゲート)のポート
await gatePort.export("out");
for (;;) { // 無限ループ
// Orionにアクセスしてエンティティを取得する
orion.getEntities({
id : "jp.kagawa.takamatsu.e-topia.tempSensor.0001",
type: "TempSensor"
})
.then(function(entities){
var value = entities[0].status.value;
console.log(entities); // 確認のため出力する
head.innerHTML = value ? `${value} degree` : "Measurement failure";
if(value > 30.0){
console.log('Over 30 ℃'); //Consoleに表示
gatePort.write(1); //30.0℃を超えたら gatePortの値を1にする。(モーター作動)
}else{
console.log('30 ℃ or under'); //Consoleに表示
gatePort.write(0); //30.0℃以下なら gatePortの値を0にする。(モーター停止)
}
});
await sleep(5000); // 5秒間休止する
}
}
```
---
## Step9. IoTシステム(温度センサー→モーター)
### データ連携のイメージ

---
## Step9. IoTシステム(温度センサー→モーター)
### プログラムの実行その1
-- 受講者の皆さんは、Geany で step9.js を開き、idの値を
'jp.kagawa.takamatsu.e-topia.tempSensor.0002'
に変えてください。
-- 受講者の皆さんは、Chromium で step9.htmlを開きましょう
-- 講師は、Geanyでstep7.jsを開き、上のidに合わせます。
-- 講師は、Chromiumで step7.htmlを開き、温度センサを温めます。
-- ファンは回りましたか?
<br><br>
### プログラムの実行その2
-- 隣同士ペアになってください。
-- 左の方は、Geany で step9.js を開き、idの値を
'jp.kagawa.takamatsu.e-topia.tempSensor.{自分の座席番号}'
に変えてください。
-- そのまま、Chromium で step9.htmlを開きましょう
-- 右の方は、Geanyでstep7.jsを開き、上のidに合わせます。
-- 右の方は、Chromiumで step7.htmlを開き、温度センサを温めます。
-- ファンは回りましたか?
---
## Step10 GPSセンサーの利用
### 配線図
GPSセンサーの配線は、
<a href="https://denor.jp/raspberry-pi%e3%81%ab%e3%80%8c%e3%81%bf%e3%81%a1%e3%81%b3%e3%81%8d%e3%80%8d%e5%af%be%e5%bf%9cgps%e3%83%a2%e3%82%b8%e3%83%a5%e3%83%bc%e3%83%ab%e3%82%92%e6%8e%a5%e7%b6%9a">こちら</a>
を参考にしてください。
GPS信号を受信できていれば点滅する
<iframe width="560" height="315" src="https://www.youtube.com/embed/xWc4jAz4mEQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
---
## Step10 GPSセンサーの利用
### プログラム
#### GPSセンサープログラムの本体(step10.js という名前で保存)
```javascript=
// シリアルポートへの接続モジュール
var SerialPort = require('serialport');
var Readline = SerialPort.parsers.Readline;
var parser = new Readline('\r\n');
var port = new SerialPort('/dev/serial0', {
baudRate: 9600,
parser: parser
});
// GPSデータの取得
var GPS = require('gps');
var gps = new GPS;
// 最新のGPSデータを保持するための変数
var lat = null;
var lon = null;
// シリアルポートを監視して信号を処理
port.on('data', function(data) {
gps.updatePartial(data);
});
// GPSデータを抽出
gps.on('data', function(data) {
if(typeof data.lat !== "undefined" && typeof data.lon !== "undefined"){
lat = data.lat;
lon = data.lon;
}
});
// 定期的にデータ処理を実行する
setInterval(function(){
console.log(lat+ ","+ lon);
}, 5000);
```
---
## Step10 GPSセンサーの利用
### プログラムの実行
- 左上のラズベリーアイコン>設定>Raspberry pi の設定をクリック
-「インターフェイス」タブをクリックし、以下を設定してください。
- Serial Port の「有効」にチェックする
- Serial Console の「無効」にチェックする
- 再起動する
- LXterminalを開き、以下を実行してください。
- `npm install serialport`
- `npm install gps`
- `sudo nodejs /home/pi/Desktop/web-iot/step10.js`
---
## Step11 FIWAREへの登録(GPSロガーを作る)
### 配線図
GPSセンサーの配線は、
<a href="https://denor.jp/raspberry-pi%e3%81%ab%e3%80%8c%e3%81%bf%e3%81%a1%e3%81%b3%e3%81%8d%e3%80%8d%e5%af%be%e5%bf%9cgps%e3%83%a2%e3%82%b8%e3%83%a5%e3%83%bc%e3%83%ab%e3%82%92%e6%8e%a5%e7%b6%9a">こちら</a>
を参考にしてください。
GPS信号を受信できていれば点滅する
<iframe width="560" height="315" src="https://www.youtube.com/embed/xWc4jAz4mEQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
---
## Step11 FIWAREへの登録(GPSロガーを作る)
### プログラム
#### GPSセンサープログラムの本体(step11.js という名前で保存)
```javascript=
// 最新のGPSデータを保持するための変数
var lat = null;
var lon = null;
// FIWAREモジュールを読み込む
var fiware = require("./fiware-api/config.js");
var orion = fiware.orion;
var ngsi = fiware.ngsi;
// シリアルポートとの通信を開始する
openPort();
function openPort(){
console.log("シリアルポートと通信を開始します。");
try {
Serialport = requireUncached("serialport");
GPS = requireUncached("gps");
Readline = Serialport.parsers.Readline;
parser = new Readline('\r\n');
port = new Serialport('/dev/serial0', {
baudRate: 9600,
parser: parser
});
gps = new GPS;
port.on('data', function(data) {
try{
gps.updatePartial(data);
} catch(e){
console.log("ERROR parsing serial data\n");
lat = null; lon = null;
resetPort();
}
});
gps.on('data', function(data) {
console.log("gpsデータが更新されました。");
if(typeof data.lat !== "undefined" && typeof data.lon !== "undefined"){
lat = data.lat;
lon = data.lon;
}
});
} catch (ex){
console.log("ERROR opening port\n" + ex);
resetPort();
}
}
// シリアルポートに再接続する
function resetPort(){
console.log("シリアルポートに再接続します。");
if (port.isOpen) {
port.close();
}
setTimeout(openPort, 10000);
}
// シリアルポートに再接続するためにモジュールをリセットする
function requireUncached(module){
console.log(module + "を再読み込みします。");
delete require.cache[require.resolve(module)];
return require(module);
}
// 定期的にデータ処理を実行する
setInterval(function(){
console.log(lat+ ","+ lon);
// GPSロガーをデータとして表現する
var gpsLogger = {
id: "jp.kagawa.takamatsu.e-topia.gpsLogger.0001",
type: "GpsLogger",
location: {type: "geo:point", value: lat + "," + lon, metadata: {}},
name: { type: "Text", value: "gpsLogger001", metadata: {} },
};
// ルールに従い送信データを整形する
var ngsiContext = {
"entities":[ gpsLogger ],
"actionType" : "APPEND"
};
// Orionにデータを送る
orion.batchUpdate( ngsiContext , function (data, status) {
console.log("STATUS : " + status + "\n");
});
}, 5000);
```
---
## Step11 FIWAREへの登録(GPSロガーを作る)
### プログラムの実行
- LXterminalを開き、以下を実行してください。
- `npm install jsdom`
- `npm install jquery`
- `sudo nodejs /home/pi/Desktop/web-iot/step11.js`
### プログラムの動作確認
http://komelabo.sakura.ne.jp/webxiot2019/gps-loggers.html

---
## Step12 FIWAREへの登録(移動温度センサーを作る)
### 配線図
#### GPSセンサーの配線
<a href="https://denor.jp/raspberry-pi%e3%81%ab%e3%80%8c%e3%81%bf%e3%81%a1%e3%81%b3%e3%81%8d%e3%80%8d%e5%af%be%e5%bf%9cgps%e3%83%a2%e3%82%b8%e3%83%a5%e3%83%bc%e3%83%ab%e3%82%92%e6%8e%a5%e7%b6%9a">こちら</a> を参考にしてください。
#### 温度センサーの配線
Step3と基本同じですが、対象GNDをGPSセンサが占有しているので、
別のGNDに差してください。

---
## Step12 FIWAREへの登録(移動温度センサーを作る)
### プログラム
#### 移動温度センサープログラムの本体(step12.js という名前で保存)
```javascript=
// 最新のGPSデータ、温度データを保持するための変数
var lat = null;
var lon = null;
var adt7420 = null;
var tmp = null;
// FIWAREモジュールを読み込む
var fiware = require("./fiware-api/config.js");
var orion = fiware.orion;
var ngsi = fiware.ngsi;
const {ADT7420} = require('i2c-adt7420');
const config = {
pollingInterval: 5000,
i2cBusNumber: 1
};
ADT7420.open({
i2cBusNumber: config.i2cBusNumber
})
.then((instance) => {
adt7420 = instance;
return adt7420.configure({
resolution: 16,
lowPowerMode: (config.pollingInterval >= 1000)
});
})
.then(() => {
console.log('Configured ADT7420');
})
.then(() => {
})
.catch((err) => {
console.error(err);
process.exit(3);
});
// シリアルポートとの通信を開始する
openPort();
function openPort(){
console.log("シリアルポートと通信を開始します。");
try {
Serialport = requireUncached("serialport");
GPS = requireUncached("gps");
Readline = Serialport.parsers.Readline;
parser = new Readline('\r\n');
port = new Serialport('/dev/serial0', {
baudRate: 9600,
parser: parser
});
gps = new GPS;
port.on('data', function(data) {
try{
gps.updatePartial(data);
} catch(e){
console.log("ERROR parsing serial data\n");
lat = null; lon = null;
resetPort();
}
});
gps.on('data', function(data) {
console.log("gpsデータが更新されました。");
if(typeof data.lat !== "undefined" && typeof data.lon !== "undefined"){
lat = data.lat;
lon = data.lon;
}
});
} catch (ex){
console.log("ERROR opening port\n" + ex);
resetPort();
}
}
// シリアルポートに再接続する
function resetPort(){
console.log("シリアルポートに再接続します。");
if (port.isOpen) {
port.close();
}
setTimeout(openPort, 10000);
}
// シリアルポートに再接続するためにモジュールをリセットする
function requireUncached(module){
console.log(module + "を再読み込みします。");
delete require.cache[require.resolve(module)];
return require(module);
}
// 定期的にデータ処理を実行する
setInterval(function(){
console.log(lat+ ","+ lon);
adt7420.readTemperature()
.then((result) => {
tmp = result;
// GPSロガーをデータとして表現する
var tempSensor = {
id: "jp.kagawa.takamatsu.e-topia.tempSensor.0001",
type: "TempSensor",
location: {type: "geo:point", value: lat + "," + lon, metadata: {}},
name: { type: "Text", value: "tempSensor001", metadata: {} },
status: { type: "Number", value: tmp.celsius, metadata: {} },
};
// ルールに従い送信データを整形する
var ngsiContext = {
"entities":[ tempSensor ],
"actionType" : "APPEND"
};
// Orionにデータを送る
orion.batchUpdate( ngsiContext , function (data, status) {
console.log("STATUS : " + status + "\n");
});
});
}, 5000);
```
---
## Step12 FIWAREへの登録(移動温度センサーを作る)
### プログラムの実行
- LXterminalを開き、以下を実行してください。
- `npm install i2c-adt7420`
- `sudo nodejs /home/pi/Desktop/web-iot/step12.js`
### プログラムの動作確認
http://komelabo.sakura.ne.jp/webxiot2019/temp-sensors.html

---
## Step12 FIWAREへの登録(移動温度センサーを作る)
### フィールドワーク
#### インターネット接続の確保
- Android端末を貸与します。
- 設定アプリを開き、「ネットワークとインターネット」→「アクセスポイントとテザリング」とクリック
- アクセスポイントの名称を確認、アクセスポイントがONになっているか確認
- Raspberry PiのWi-Fi設定で上記のアクセスポイントを選択、アクセスパスワードは「kometani」
<img src="https://i.imgur.com/vW2v5VP.jpg" width="100">
#### 電源の確保
- モバイルバッテリーを差した状態で駆動する
- 電源コード - モバイルバッテリー - Raspberry Pi と間にかまして駆動させておくと脱着が容易
- フィールドワークに出るときは、モバイルバッテリー+Raspberry Piを持ち歩く
---
## Step12 FIWAREへの登録(移動温度センサーを作る)
### フィールドワーク
#### プログラムの動作
- 配線はstep12と同じにしてください。
- LXTerminalのウィンドウないしタブを2つ準備
- それぞれで step11.js、step12.js を動作させたままにする
#### モニタリングの準備
- 手持ちのスマートフォンで以下を開いておく
- http://komelabo.sakura.ne.jp/webxiot2019/gps-loggers.html
- http://komelabo.sakura.ne.jp/webxiot2019/temp-sensors.html
#### 上の準備ができたら、屋外に出て測位できるか、データをモニタリングできるかを確認してみましょう