enebularで値の見えるWebページを作る（http post版）

1年以上前に書いた記事になりますが、[新しくなったenebularを使ってみる Vol.1　～値の見えるWebページを作る～](https://qiita.com/jksoft/items/e3d047ac44237e0cb30e)で使用しているmilkcocoaが残念ながらサービス終了となりました。
milkcocoaリアルタイムにデータの更新や保存、取得ができるサービスとして結構気に入っていたので、非常に残念です。
4年ほど前になると思いますが、milkcocoaの中の人からお声がけ頂いて、[mbed用のmilkcocoaライブラリ](https://os.mbed.com/components/Milkcocoa/)を書いたことを思いましました。当時、私はWeb系の知識に乏しく、Webとマイコンでリアルタイムに双方向通信できることに感動しました。そんなこともあり、マイコン、センサー、Webを簡単に繋げられるように[Simple IoT Board](http://jksoft.cocolog-nifty.com/blog/2015/10/simple-iot-boar.html)という基板を企画し、販売しました。

当時ワークショップも数回行い、好評でした。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/358f7555-6ff5-c75c-92ed-abea0ed5b064.png)](https://mbed.doorkeeper.jp/events/33185)

思い出話はこの辺にして、本題に入ります。

# milkcocoaの代替え
今では、代替えとして使えるサービス（fire base? pubnub?）も多いと思いますので、それに置き換えればよいのですが、以前の記事での範囲では、そもそもデータをストアする必要は無く、最新の値が取れれば良いので、マイコンからhttp postしてセンサーデータを定期的に更新することにします。

# milkcocoaをhttp postを受けるノードに置き換え
単純に置き換えてfuncionノードをちょっと変えて、http responseノードを追加しただけです。
1年以上前に作ったフローで、どう作ったかもほとんど記憶が無く、もちろん設計書もありませんでしたが、ビジュアルプログラムだとぱっと見で動きが把握できるので、簡単ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/f73fea62-6526-dd99-84d5-fa71245b5d96.png)

元のフローは、[前の記事](https://qiita.com/jksoft/items/e3d047ac44237e0cb30e#%E4%BD%9C%E3%81%A3%E3%81%9F%E3%83%95%E3%83%AD%E3%83%BC)を見て下さい。
（比較してみるとenebulerの画面もデザインが変わっていますね。milkcocoaノードも無くなっています。フローエディタ―以外もデザインが変わっていて、デスクトップツールである[enebular editor](https://docs.enebular.com/ja/EnebularEditor/)のデザインに合わせているそうです。）

新しいフローのJSONはこちらです。

```json
{ "flow": [ { "id": "6aa9aa96.b860d4", "type": "tab", "label": "Flow 1" }, { "id": "a6c73505.9ab108", "type": "http in", "z": "6aa9aa96.b860d4", "name": "HTTP GETを受けたら", "url": "/environment", "method": "get", "upload": false, "swaggerDoc": "", "x": 400, "y": 180, "wires": [ [ "39fe9905.051d66" ] ] }, { "id": "9ea2b2ed.b8e1f", "type": "http response", "z": "6aa9aa96.b860d4", "name": "レスポンスを返す", "statusCode": "", "headers": {}, "x": 889.3000869750977, "y": 224.60005855560303, "wires": [] }, { "id": "c698864a.c07b28", "type": "function", "z": "6aa9aa96.b860d4", "name": "センサ値取得", "func": "var id = msg.payload.body.id;\nglobal.set(id + \".temperature\",msg.payload.body.temperature);\nglobal.set(id + \".humidity\",msg.payload.body.humidity);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 720, "y": 340, "wires": [ [ "73e6c6d5.d732f8", "eadb2b23.f62188" ] ] }, { "id": "39fe9905.051d66", "type": "function", "z": "6aa9aa96.b860d4", "name": "ID正常", "func": "var id = msg.payload.id\nmsg.payload =\"<h1>環境情報</h1>\";\nmsg.payload += \"温度：\" + global.get(id + \".temperature\") + \"度<br>\";\nmsg.payload += \"湿度：\" + global.get(id + \".humidity\") + \"％<br>\";\nmsg.payload += \"Co2：212ppm<br><br>\";\nmsg.payload += \"<img src=\\\"http://jksoft.cocolog-nifty.com/img_floorplan1.png\\\">\";\nmsg.payload += \"<meta http-equiv=\\\"refresh\\\" content=\\\"10\\\" >\";\nreturn msg;\n", "outputs": 1, "noerr": 0, "x": 626.0000228881836, "y": 184.00000500679016, "wires": [ [ "9ea2b2ed.b8e1f" ] ] }, { "id": "856a08f4.9365f8", "type": "catch", "z": "6aa9aa96.b860d4", "name": "異常が起こったら", "scope": null, "x": 390, "y": 260, "wires": [ [ "9c294e41.deda6" ] ] }, { "id": "9c294e41.deda6", "type": "function", "z": "6aa9aa96.b860d4", "name": "ID異常", "func": "msg.payload =\"<h1>存在しないIDです</h1>\"\nreturn msg;", "outputs": 1, "noerr": 0, "x": 630, "y": 260, "wires": [ [ "9ea2b2ed.b8e1f" ] ] }, { "id": "73e6c6d5.d732f8", "type": "debug", "z": "6aa9aa96.b860d4", "name": "デバッグ用", "active": true, "console": "false", "complete": "payload", "x": 950, "y": 340, "wires": [] }, { "id": "4db0f145.b06b6", "type": "inject", "z": "6aa9aa96.b860d4", "name": "", "topic": "", "payload": "", "payloadType": "date", "repeat": "", "crontab": "", "once": true, "x": 409.5, "y": 544.4000177383423, "wires": [ [ "21f51e40.247802" ] ] }, { "id": "21f51e40.247802", "type": "function", "z": "6aa9aa96.b860d4", "name": "センサ値取得", "func": "var id = 1;\nglobal.set(id + \".temperature\",25.1);\nglobal.set(id + \".humidity\",32);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 704.7999877929688, "y": 559, "wires": [ [] ] }, { "id": "9f421ede.430d7", "type": "http in", "z": "6aa9aa96.b860d4", "name": "HTTP PUSHを受けたら", "url": "/push", "method": "post", "upload": false, "swaggerDoc": "", "x": 470, "y": 340, "wires": [ [ "c698864a.c07b28" ] ] }, { "id": "eadb2b23.f62188", "type": "http response", "z": "6aa9aa96.b860d4", "name": "レスポンスを返す", "statusCode": "", "headers": {}, "x": 1000, "y": 420, "wires": [] } ], "packages": {}, "credentialIds": [] }
```

細かいところはデバイス側と合わせて説明しますが、単純にセンサーの値とIDをJSONで受け取って、保存しているだけです。

# デバイス側

デバイス側は前の記事の一例と同じくNUCLEO-L432KC（Mbed）+ Multi IoT Boardを使います。（実はMulti IoT BoardはSimple IoT Boardのバージョン2となってます。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/568c4022-3407-a34a-ec27-8cc0fd19adae.png)

NUCLEO-L432KCのプログラムは[Mbed Studio](https://os.mbed.com/docs/mbed-studio/0.5/introduction/index.html)を使って作りました。MbedのHttpライブラリはわかりにくいので、使いやすくまとめたライブラリを作りました。もうすぐ公開するつもりなので、別にまとめて記事を書きます。

# スマホで確認