生産ラインのエラーを可視化してみる

#何処でエラーが出て止まっているんだ？

私は工場に勤めていて設備が故障で停止した際の対処も仕事の一つです、長い生産ラインどこでエラーが出て止まているのか、今まではエラーが出ても現場にある表示機に映すだけで、現場に行かなければどんなエラーがどの場所で出ているかわからない(積層灯でなんとなく場所はわかっても細かい内容まではわからない)、、、**ライン内の「どこで」「どのような」エラーがでて止まているのか可視化**することで、**現場についてから考えない**ですむなどのメリットがあったり、マネジャーであれば**現場の状況を把握**したいなどあると思います。

#かっこよく映したい

生産数や稼働率は文字やグラフで出しているけど、文字やグラフ表示で**「文字を読まなくてはならない」**と思います。
A-Frameを使って**3D表現で可視化**して設備に紐づけてラインを横断して映し出すことができれば、「稼働率の低い機械はどこ？」なんてことも一発で解決できる！あと3D表示されているDashboardは**「かっこいい」**と思い挑戦してみました。

#作ったもの
https://eloquent-shockley-90175d.netlify.app/


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">生産ラインのエラーの可視化に挑戦してみました！3Dは苦手意識がありましたが何とか形はできた！<a href="https://twitter.com/hashtag/Protoout?src=hash&amp;ref_src=twsrc%5Etfw">#Protoout</a>　<a href="https://twitter.com/hashtag/JavaScript?src=hash&amp;ref_src=twsrc%5Etfw">#JavaScript</a>　<a href="https://twitter.com/hashtag/NodeRed?src=hash&amp;ref_src=twsrc%5Etfw">#NodeRed</a> <a href="https://twitter.com/hashtag/RaspberryPi?src=hash&amp;ref_src=twsrc%5Etfw">#RaspberryPi</a> <a href="https://t.co/cHfZRQhQB5">https://t.co/cHfZRQhQB5</a> <a href="https://t.co/MtdfMMO4Ft">pic.twitter.com/MtdfMMO4Ft</a></p>&mdash; Toshiki (@Hirasawa1987) <a href="https://twitter.com/Hirasawa1987/status/1306377454978646016?ref_src=twsrc%5Etfw">September 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##使用した技術
- Vue.js
- A-Frame
- Firebase
- axios
- Raspberry Pi4(ロボットと仮定して使用)
- Node-RED


##構成図
[![Image from Gyazo](https://i.gyazo.com/942453671764a320069c0aa66ea1e7fc.png)](https://gyazo.com/942453671764a320069c0aa66ea1e7fc)

##コード
コードはこちらにあります
https://gist.github.com/Toshiki0324/4a84065db800f717eaa2cb6228b6157d




#躓いた部分

###3Dモデルの読み込み
今回は無料でダウンロードできる3Dモデルを使用しました、実際に工場で使用するときにはCADで書いたものを`.obj`や`.gltf`といった拡張子にエクスポートして使います、使用できるファイルの種類は[公式サイト](https://aframe.io/docs/1.0.0/introduction/models.html)に記載されています。
作ったhtmlファイルをブラウザから開いても表示されない・・・という現象に陥りました、原因はいまいちわかりませんでしたが、以下の方法で解消しました。
> [A-Frameで3Dモデルを使用するときのメモ](https://qiita.com/Toshiki0324/items/f918d2a1d6c4195b18bf)

###要素の位置調整
要素の動かし方にも悩みました、テキストをどのあたりに出すか、線をどこからどこに引くかなど、どうしたらいいんだと悩んでいたら`<ctrl> + <alt> + i`で編集ができるという文言を発見、[公式サイト](https://aframe.io/docs/1.0.0/introduction/visual-inspector-and-dev-tools.html)にも載っていました。Visual Inspector と言うらしいです。
[![Image from Gyazo](https://i.gyazo.com/6dfc8da81f1b4d5a46923c7835a059c4.png)](https://gyazo.com/6dfc8da81f1b4d5a46923c7835a059c4)
左側で要素のを選択でき、右側で調整したりできます。
ちなみに終了すると元に戻るので、いじった項目と数字はメモか[Gyazo](https://gyazo.com/)しましょう、めちゃくちゃ便利です。


###謎の警告
いざ3D表現を完成させた後Consoleを見てみると警告だらけ。
以下のものが連続して出ていました。

>[Vue warn]: Unknown custom element: 
<a-entity> - did you register the component correctly?
 For recursive components, make sure to provide the "name" option.

こちらの警告は以下で解決しました。
>[vue.jsでA-Framを使う](https://qiita.com/Toshiki0324/items/23d82cc0f58685a164c6)

Vue.jsで使う場合は`Vue.config`に設定が必要みたいです。

###データの読み込み
今回はFirebaseのCloudFirestoreを使用しましたmemosというコレクションIDにデータを作成したのでmemosのデータを監視して
変更があったら読み込む形でリアルタイムに反映されるようにしました。
以下はCloudFirestoreの内容です。

[![Image from Gyazo](https://i.gyazo.com/e94d63df369adc3d4456b71a47346727.png)](https://gyazo.com/e94d63df369adc3d4456b71a47346727)

```app.js
  db.collection('memos')
      .onSnapshot(function (querySnapshot) {
          for (let change of querySnapshot.docChanges()) {
              if (change.type === 'added') {
                  // データが追加された時
              }
              else if (change.type === 'modified') {
                  // データが変更された時
                  console.log("!!!!!!!!!");
                  location.reload();

            }
              else if (change.type === 'removed') {
                  // データが削除された時
              }
          }
      })

```
firestoreのデータに変更があった場合の処理に参考に察せていたできました
>[firestoreのonSnapshotを使う際に気を付けたいこと](https://qiita.com/mktu/items/17a993f675ccd6d17aed)



#エラーはRaspberryPiで
実際に工場の設備からデータを吸い上げることを考えて今回は`RaspberryPi4`を使用しました。ラインが実際のものではないので今回は設置は行いません、`Node-RED`を使用しUIを作成して疑似的なエラーを想定し実装しました。
以下のノードを使用しています

- [node-red-contrib-component-dashboard]
(https://flows.nodered.org/node/node-red-contrib-component-dashboard)
- [node-red-contrib-cloud-firestore](https://flows.nodered.org/node/node-red-contrib-cloud-firestore)

```
[{"id":"8d8035c6.7855c8","type":"tab","label":"フロー 1","disabled":false,"info":""},{"id":"82b42594.911fe8","type":"debug","z":"8d8035c6.7855c8","name":"debug","active":true,"tosidebar":true,"console":true,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":540,"y":280,"wires":[]},{"id":"25fc6b77.52d974","type":"Firestore out","z":"8d8035c6.7855c8","name":"","collection":"memos","document":"japan","operation":"set","admin":"7db223e2.29c07c","eject":false,"x":390,"y":280,"wires":[["82b42594.911fe8"]]},{"id":"8d096c01.5f39d","type":"ui_button","z":"8d8035c6.7855c8","name":"","group":"2b01090b.1c7886","order":0,"width":0,"height":0,"passthru":false,"label":"エラー","tooltip":"","color":"","bgcolor":"","icon":"","payload":"{     \"age\": \"エラー発生中\",     \"name\": \"test0915\",     \"flag\": true }","payloadType":"json","topic":"","x":210,"y":260,"wires":[["25fc6b77.52d974"]]},{"id":"16ddc24c.589f5e","type":"ui_button","z":"8d8035c6.7855c8","name":"","group":"2b01090b.1c7886","order":1,"width":0,"height":0,"passthru":false,"label":"解除","tooltip":"","color":"","bgcolor":"","icon":"","payload":"{\"age\":\"\",\"name\":\"test0915\",\"flag\":false}","payloadType":"json","topic":"","x":210,"y":300,"wires":[["25fc6b77.52d974"]]},{"id":"7db223e2.29c07c","type":"firebase admin","z":"","name":""},{"id":"2b01090b.1c7886","type":"ui_group","name":"Group 1","tab":"792f850.1442c7c","order":1,"disp":true,"width":6},{"id":"792f850.1442c7c","type":"ui_tab","name":"Tab 1","icon":"dashboard","order":1}]
```

[![Image from Gyazo](https://i.gyazo.com/f9040d735a3a0281547a2854e1b2e4b0.png)](https://gyazo.com/f9040d735a3a0281547a2854e1b2e4b0)

同じWi-Fi環境であればこんなかんじ↓でラズパイのipアドレス`http://192.168.1.〇〇:1880/ui/`にアクセスできUIが表示されます。

[![Image from Gyazo](https://i.gyazo.com/76ac796fdc6005df968c79e7b2993e27.png)](https://gyazo.com/76ac796fdc6005df968c79e7b2993e27)

#CodePenでグラフを探す
3Dのみの表示だと味気ない気がしたので、今回はCodePenから素敵な見た目のものを持ってきました
https://codepen.io/amcharts/pen/gbLpMR
[![Image from Gyazo](https://i.gyazo.com/c1d1989b7ae81543318f938628e69b71.png)](https://gyazo.com/c1d1989b7ae81543318f938628e69b71)

データの内容は全く関係ありませんがこんな感じ
[![Image from Gyazo](https://i.gyazo.com/98d3d32daffe039f3c2860be4370f636.png)](https://gyazo.com/98d3d32daffe039f3c2860be4370f636)


#「カッコイイ！！」までは行けなかった

今回は１ヶ所しかエラーを実装できませんでしたしかも「エラー発生中」せっかくVue.jsを使用したので内容も表示できればよかった、ですが3Dで可視化できたことはうれしかった！作りこんでいくことでライン全体、若しくは工場全体を表示することも可能になりそう。