enebular/Node-REDでSORACOM Airを操作する

By |11月 13, 2015|enebular, IoT, Node-RED, Node.js, OSS, |0 comments


おかげさまで、SORACOMリレーブログに参加させていただくことになりました!

今回のエントリはリレーブログさせていただくきっかけにもなったNode-REDのsoracom nodeでSORACOM Airに対してグループ単位の一括処理をスケジュール定期実行します。

※Node-REDの基本的なことはNode-RED事始めをご覧ください

まず、soracom nodeをインストールしましょう。enebular agentならadminタブでnodeをサジェストでnpmから探せて…

node-admin

installボタンで簡単インストールできます!

soracom_node_install

余談ですが現在のところNode-REDではnpm installかnode-red-adminというコマンドラインツールでnodeを追加します。

enebular agentはGUIでnodeを検索/追加/削除/有効/無効できるようにすることで更に一段敷居を下げました。それでも勿論オープンソースとして公開してますし、Node-REDとの互換性を保ちつつ拡張していますし、拡張したものはユーザの反応を見てから本家とディスカッションして取り込んでもらうつもりです。

私たちはIoTを限られた人たちだけではなく多くの人たちに体験していただきたいという想いからオープンコミュニティに貢献しています。多くの人たちがIoTを体験することで新しいアイデアが生まれイノベーションが起きると思っています。

だからこそ誰もがIoTを実践できるようなエコシステムを形成しようとしているSORACOMさんに感銘を受けました。SORACOMリレーブログでも既にたくさんのアイデアが生まれています。敷居が下がることで裾野が広がるということを見せつけてくれました。

Node-REDコミュニティでも既にたくさんのアイデアが生まれています。オープンコミュニティとエコシステムがアイデアを生み出すスピードは追いきれないほど速くなっています。

Node-REDIFTTTTreasure Data/Fluentd/EmbulkmyThingsなどのサービスやプロダクトもまたエコシステムを形成する姿勢に惹かれたため我々は感銘を受けブログで取り上げてきました。

すみません、余談が過ぎました…

ユースケースとしてはソラコムの江木さんがソラコム山とNode-REDで取り上げていただいた通知系がありますが、説明は本記事に譲らせていただきまして1点だけ補足させていただきますと「Cron的に、指定した間隔で呼びだせるので、データ通信使用量をSlack で確認できます」のCron的なものはinject nodeの以下の設定です。

inject._node

このスケジュール実行的なトリガでSORACOM Airを操作することで、どの通信速度でも一律同料金の深夜時間帯(日本時間 午前2:00-午前6:00)は通信速度をs1.fastに変更することも簡単に実現できます。

ただ、実際のユースケースを想定した場合、恐らくグループ単位で一括操作をしたくなります。なので最初は以下のようにOperationにGroup Listを選択します。

soracom_groups

これを実行すると以下のようにDebugにグループリストの配列が表示されます。

groups_debug

次に配列をバラすのに便利なsplitter nodeをつなげて実行すると以下のようになります。これは先ほどの配列が要素毎にバラされて後続のdebug nodeに別々に渡されたのでアカウントに登録しているグループの数だけ(この場合は2枠)Debugに表示されたということです。

groups_splitter

次にchange nodeを置いて以下のように設定します。これはデータのメインストリームであるmsg.payloadオブジェクトのgroupIdの値を、この後もう1つ配置するsoracom nodeへ動的に渡すために必要な設定です。

change_node

それではdebug nodeを以下のようにmsg.payloadではなくmsg.targetIdの値をDebugに表示するように設定して実行してみましょう。以下のDebugのようにmsg.payload.groupIdがmsg.targetIdに反映されていればOKです。

change_debug

次はそれぞれのグループに属するSIMカードの情報を取得するためにsoracom nodeを追加し以下のように設定します。先ほどmsg.payload.groupIdをmsg.targetIdに反映したのはこのためです。つまりsoracom nodeより前のnodeでmsg.targetIdを指定することで後続のsoracom nodeへIMSIやGroup IDを動的に渡せるということです。

group_sims

これを実行すると以下のように今度はグループに属するSIMカードリストが配列で取得できます。

sims.ong

あとはグループリストの時と同様に配列をバラして個別のSIMカード毎に速度変更の設定をします。実行すると以下のように一括で速度が変更されます。

speed_update

SORACOMのコントロールパネルでも一括で変更されています(2枚しかなくてすみません)

soracom_web

最後に当初の目的である深夜2:00と早朝6:00に起動するinject nodeを設定します。ちなみに同じflowを2つ作っても良いのですが相違点は通信速度クラスだけなので各inject nodeにstringとして登録しておき、後続のchange nodeでmsg.speedClassにセットしてあげることで以下のように1つのflowで済みます(flowの最後の通信速度を変更するsoracom nodeにデフォルトで速度クラスが設定されていてもmsg.speedClassが設定されていれば上書きされます)

comp

以下をインポートすると手持ちのenebular agent/Node-REDでflowを再現できます。

[
    {
        "id": "fafb3aea.0504c8",
        "type": "soracom",
        "email": ""
    },
    {
        "id": "dfad8035.20528",
        "type": "inject",
        "name": "2:00",
        "topic": "",
        "payload": "s1.fast",
        "payloadType": "string",
        "repeat": "",
        "crontab": "00 2 * * *",
        "once": false,
        "x": 133,
        "y": 33,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "418c5f71.be73a"
            ]
        ]
    },
    {
        "id": "768fb4d8.89704c",
        "type": "debug",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "payload",
        "x": 287,
        "y": 314,
        "z": "8d260617.72d9f8",
        "wires": []
    },
    {
        "id": "65bee831.9a4118",
        "type": "soracom in",
        "soracom": "fafb3aea.0504c8",
        "targetId": "",
        "operation": "subscribers",
        "speedClass": "s1.minimum",
        "recentXminutes": "",
        "period": "month",
        "name": "",
        "x": 151,
        "y": 197,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "85992052.7a66e"
            ]
        ]
    },
    {
        "id": "85992052.7a66e",
        "type": "splitter",
        "name": "",
        "property": "payload",
        "x": 300,
        "y": 195,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "67cb9b0f.983464"
            ]
        ]
    },
    {
        "id": "67cb9b0f.983464",
        "type": "change",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "targetId",
                "to": "msg.payload.imsi"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 172,
        "y": 254,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "3c68b2aa.c3974e"
            ]
        ]
    },
    {
        "id": "3c68b2aa.c3974e",
        "type": "soracom in",
        "soracom": "fafb3aea.0504c8",
        "targetId": "",
        "operation": "updateSpeedClass",
        "speedClass": "s1.minimum",
        "recentXminutes": "",
        "period": "month",
        "name": "",
        "x": 337,
        "y": 253,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "768fb4d8.89704c"
            ]
        ]
    },
    {
        "id": "a8ba0d92.5745f",
        "type": "soracom in",
        "soracom": "fafb3aea.0504c8",
        "targetId": "",
        "operation": "groups",
        "speedClass": "s1.minimum",
        "recentXminutes": "",
        "period": "month",
        "name": "",
        "x": 306,
        "y": 86,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "a2a4b476.5d5b48"
            ]
        ]
    },
    {
        "id": "a2a4b476.5d5b48",
        "type": "splitter",
        "name": "",
        "property": "payload",
        "x": 148,
        "y": 145,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "d0166b86.2fe998"
            ]
        ]
    },
    {
        "id": "d0166b86.2fe998",
        "type": "change",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "targetId",
                "to": "msg.payload.groupId"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 323,
        "y": 143,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "65bee831.9a4118"
            ]
        ]
    },
    {
        "id": "418c5f71.be73a",
        "type": "change",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "speedClass",
                "to": "msg.payload"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 150,
        "y": 85,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "a8ba0d92.5745f"
            ]
        ]
    },
    {
        "id": "12d2cc76.ed2d34",
        "type": "inject",
        "name": "6:00",
        "topic": "",
        "payload": "s1.minimum",
        "payloadType": "string",
        "repeat": "",
        "crontab": "00 6 * * *",
        "once": false,
        "x": 298,
        "y": 27,
        "z": "8d260617.72d9f8",
        "wires": [
            [
                "418c5f71.be73a"
            ]
        ]
    }
]

インポートのしかたは以下で開くダイアログに上記JSONを貼付けてください(Node-REDも同じです)

import

ちなみに起動が同じインスタンスで不安な場合はenebular agentを別のインスタンスにインストールしてスケジュール実行は外部からhttpかなにかで起こすというのもアリですし、そのインスタンスの死活監視もさらに別のインスタンスのenebular agentでやるというのもアリです。

OSSで手軽にデプロイできenebular.comで無償でagentを一元的に管理できるからこそ実現できます。

あと、SORACOMにはイベントハンドラという機能があります。もしかしたら上記のこともイベントハンドラでやればできるのかもしれません(未検証)

最後にグループ単位でSIMを一括操作するAPIは今のところ無いという認識なんですがあっても良い気がしました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です