Quantcast
Channel: OBDNマガジン
Viewing all 98 articles
Browse latest View live

[.tested] Planex GW-450D 無線LANアダプタ [AX3][A7][A6]

$
0
0
Planex GW-450Dは、802.11ac/n/a/g/bに対応したUSB無線LANアダプタです。
GW-450Dは、写真の小型のタイプと、稼働式アンテナのついたGW-450D KATANAがありますが、アンテナ以外は同一の設計の製品と思われます。
Openblocks AX3およびA7での動作検証を行いました。


OBDN技術ブログによる動作検証は、該当するデバイスの動作を保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
OpenBlocks AX3/4 Debian 7.5 kernel: 3.2.54
OpenBlocks A7 Debian 7.5 kernel:3.2.54

1. 対応ドライバと事前準備


GW-450Dは、MediaTek MT7610Uを採用しており、現在AX3およびA7/A6に搭載されたカーネル3.2.54ではサポートされていません。
Planex社の以下のページにおいて、開発者向け情報が公開されています。

開発者向け情報|無線LAN USBアダプタ|プラネックス:

ドライバのソースコードは、上記のページよりダウンロードできますが、今回はチップセットメーカであるMediaTek社のホームページよりダウンロードし、OpenBlocks向けにビルドしました。

・カーネル構築環境の導入

本ドライバは、ビルドする際に、カーネルの構築環境を参照するため、build-essentialsによる開発環境の構築のみでは、ドライバのビルドが出来ません。
以下の手順を参考に、カーネルのソースを導入し、make modules_installまでを行っておく必要があります。

カーネルのカスタマイズ手順について(非公式版) [AX3][A6]

・ソースコードの入手と展開

以下のページの、7610U USBよりファイルをダウンロードして下さい。

Downloads - MediaTek:

ダウンロードしたファイルは以下の手順で解凍してください。

# tar jxfv mt7610u_wifi_sta_v3002_dpo_20130916.tar.bz2
# cd mt7610u_wifi_sta_v3002_dpo_20130916

common/rtusb_dev_id.cを編集します。
同じバージョンのドライバパッケージを使用する場合は、以下のdiff出力をpatch適用して下さい。
アップデートにより内容が変更されている場合は、参考にして書き換えてください。

diff -u rtusb_dev_id.c.orig rtusb_dev_id.c
--- rtusb_dev_id.c.orig 2014-06-09 15:18:30.209980000 +0900
+++ rtusb_dev_id.c      2014-06-09 15:19:43.299980000 +0900
@@ -36,6 +36,7 @@
 /* module table */
 USB_DEVICE_ID rtusb_dev_id[] = {
 #ifdef MT76x0
+       {USB_DEVICE(0x2019,0xab31)}, /* MT7610U */
        {USB_DEVICE(0x148F,0x7610)}, /* MT7610U */
        {USB_DEVICE(0x0E8D,0x7610)}, /* MT7610U */
        {USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7630, 0xff, 0x2, 0xff)}, /* MT7630U */

os/linux/config.mkを編集し、wpa_supplicantのサポートをyにします。

# diff -u config.mk.orig config.mk
--- config.mk.orig      2014-06-09 15:22:00.759980000 +0900
+++ config.mk   2014-06-09 15:22:17.039980000 +0900
@@ -23,12 +23,12 @@

 # Support Wpa_Supplicant
 # i.e. wpa_supplicant -Dralink
-HAS_WPA_SUPPLICANT=n
+HAS_WPA_SUPPLICANT=y


 # Support Native WpaSupplicant for Network Maganger
 # i.e. wpa_supplicant -Dwext
-HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n
+HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y

 #Support Net interface block while Tx-Sw queue full
 HAS_BLOCK_NET_IF=n

変更後、make および installを行います。

# make install

README_STA_usbを参考に、コンフィギュレーションファイルをコピーします。

# mkdir /etc/Wireless/RT2870STA
# cp RT2870STA.dat  /etc/Wireless/RT2870STA/RT2870STA.dat

A7の場合は、デバイスをUSBポートに差し込めば認識するのですが、AX3の場合は、ubootが設定したvmallocのサイズの関係で、ドライバがvmallocに失敗したというメッセージを出し、起動しません。
起動時に一旦ubootに入り、

# openblocks> setenv miscargs vmalloc=200M

として、拡張する必要がありました。

デバイスは、/dev/ra0となります。

ra0       Link encap:Ethernet  HWaddr 00:22:cf:e2:4d:39
          inet addr:192.168.10.95  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::222:cfff:fee2:4d39/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:247723 errors:9 dropped:0 overruns:0 frame:0
          TX packets:1591 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:62913475 (59.9 MiB)  TX bytes:128084 (125.0 KiB)

起動時に立ち上がらない場合は、
/etc/modulesに
mt7650u_sta
を追加してください。

2. wpasupplicantパッケージの導入および設定


以下の記事を参照して下さい。

[.tested] Logitec LAN-W150N/U2WH(BK) 無線LANアダプタ [AX3]

以下の通り、クライアントモードでの動作を確認しました。

# iwconfig ra0
ra0       Ralink STA  ESSID:"******"  Nickname:"MT7610U_STA"
          Mode:Managed  Frequency=2.412 GHz  Access Point: 00:1D:73:C2:F4:00
          Bit Rate=108 Mb/s
          RTS thr:off   Fragment thr:off
          Encryption key:9394-8D4B-D889-F2A3-0EF7-E943-73A8-719C [3]   Security mode:open
          Link Quality=64/100  Signal level:-73 dBm  Noise level:-73 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

3. さいごに


今回は、クライアント接続のみのテストとしています。
AP化に関しては、hostapdが本アダプタをサポートしておらず、また、realtek社の様に専用のhostapdの配布もされていないため、今回は特に追いかけていません。
新たな情報が入り次第、追記させていただきます。


[.tested] Wireshark [debian Wheezy][AX3][A7][A6]

$
0
0
GUI版のネットワークアナライザ、WiresharkをOpenBlocks Aシリーズで利用するためのTipsです。

 Wireshark · Go Deep.:

<検証環境>
Debian 7.1 Wheezy
OpenBlocks AX3/4 kernel: 3.2.54
OpenBlocks A7 kernel 3.2.54

<使用機器>
OpenBlocks AX3 DPパッケージ (もしくは、SSD搭載モデル)
OpenBlocks A7 DPパッケージ (もしくは、SSD搭載モデル)

1. 導入前の準備


OpenBlocks Aシリーズは本体にグラフィック表示機能を持ちません。
X環境を導入するためには、USB VGAディスプレイアダプタを利用するか、X端末ソフトウェアなどを利用する必要があります。

USB VGAディスプレイアダプタについては、以下の記事を参考にしてください。

【.tested】RATOC REX-USBDVI2 ディスプレイアダプタ [Debian Wheezy][AX3][A6]

X端末ソフトウェアの導入方法に関しては、SourceForgeの以下の記事などを参考にしてください。


2. Wiresharkの導入


debianのパッケージを導入します。
 
#aptitude install wireshark

3. 動作確認


メニューより起動するか、xtermなどからwiresharkを直接起動します。

wiresharkは、セキュリティ上のポリシーから、rootで直接起動することを推奨していません。
rootで起動した場合は、以下の警告メッセージが出力されます。



そのため、一般ユーザでログインして、wiresharkを立ち上げることになりますが、 dumpcapというパケットキャプチャプログラムに許可を与える必要があります。

# setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /usr/bin/dumpcap

ただし、このFile Capabilitiesの仕組みは、aufsでは対応しておらず、aufsによるOpenBlocksのディスク共有モードで利用する場合は、setcapによる許可が与えられません。

ユーザモードによる動作を行いたい場合は、aufsではなく、ext4などのファイルシステムでシステムを構成する必要があります。
rootfsの変更方法に関しては、以下の記事にて解説しています。

OpenBlocks Aシリーズ rootfs変更方法 (FlashROMブート) [debian Wheezy][AX3][A7][A6]
 
今回は、ext4にて作成したrootfsに変更することにより、dumpcapのFile Capabilityを変更しました。

表示画面は以下のようになります。



なお、上記の画面は、Xmingを利用し、OpenBlocksにはwiresharkだけをインストールして使用しています。

4. さいごに


今回は、wiresharkの利用方法についてご紹介しました。
GUIを使用しない場合、tsharkもdebianのパッケージとして提供されていますので、お試しください。

[.tested] OpenECHO [debian Wheezy][AX3][A7][A6]

$
0
0
OpenECHOは、ECHONET LiteをJavaで実装したライブラリであり、以下のサイトで公開されています。


今回は、OpenBlocks A7の内部GPIOポートを用い、ECHONET Lite対応機器として、簡単な実装を行ってみました。

OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
OpenBlocks A7 Debian 7.5 kernel:3.2.54

1. ハードウェアの準備


今回は、A7の基板上に実装された内部GPIOポートを利用しました。

(A6の場合は、背面よりGPIOポートが接続可能です。AX3の場合は、GPIOのポートがないため、USB-GPIOアダプタなどを利用する必要があります。 )


実際に何か照明機器を接続するといいのですが、今回は、LEDを抵抗(470Ω)と直列に接続しています。

A7の内部GPIOピンは、以下の配置になっています。

1: MPP17(GPIO_17)
2: MPP7 (GPIO_7) ※PD禁止
3: MPP29 (GPIO_29)
4: MPP28 (GPIO_28)
5: MPP35 (GPIO_35)
6: MPP34 (GPIO_34)
7: MPP40 (GPIO_40)
8: 未使用
9: 外部リセット入力
10: GND

ピンの配置
| 9| 7| 5| 3| 1|
|10| 8| 6| 4| 2|

今回は、P7(GPIO 40)へLEDを接続しました。

2. ソフトウェア (一般照明機器としての設定)


A7を一般照明機器としてセットアップする方法です。

今回は、新たにGPIO回りのライブラリを作成せず、簡単なセットアップで試しました。

・GPIOデバイスの作成

GPIOデバイスは、以下の手順により操作可能となります。
今回、プログラム上では、この設定を行っていませんので、下記の手順を実行した後、評価プログラムを起動させてください。

# cd /sys/class/gpio
# echo 40 > export
# cd gpio40
# echo out > direction

ポートのON/OFF(LED点灯)テストは以下の操作により行います。

# echo 1 > value
# echo 0 > value

・OpenECHOによるサンプルプログラム

今回は、以下のサイトのプログラムの一部を修正して使用しました。

 Howto : ArmadilloでECHONET Lite (まとめ)

ellight.jarのソースパッケージである、ellight.zipを展開して、Netbeans IDE 8.0により修正、ビルドしてください。
今回、A7に搭載されたJREが、

Java(TM) SE Embedded Runtime Environment (build 1.7.0_40-b43, headless)

となりますので、JDKも7を導入して指定しています。


MyLighting.javaを書き換えます。

package ellight;

import com.sonycsl.echo.eoj.device.housingfacilities.GeneralLighting;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyLighting extends GeneralLighting {
    byte[] mStatus = {0x31};
    byte[] mMode = {0x41};
    byte[] mLocation = {0x00};
    byte[] mVersion = {0x01, 0x01, 0x61, 0x00};
    byte[] mFaultStatus = {0x42};
    byte[] mManufacturerCode = {0x00, 0x00, 0x00}; /* 未定義 */

    @Override
    protected boolean setOperationStatus(byte[] edt) {
        Runtime rt = Runtime.getRuntime();
        Process pr = null;
        try {
            /* LEDをON/OFF */
            if (edt[0] == 0x30)
                pr = rt.exec(new String[]
                             { "/bin/sh", "-c",
                               "echo 1 > /sys/class/gpio/gpio40/value" });
            else if (edt[0] == 0x31)
                pr = rt.exec(new String[]
                             { "/bin/sh", "-c",
                               "echo 0 > /sys/class/gpio/gpio40/value" });
            if (pr != null)
                pr.waitFor();
            /* 状態をECHNET Lite送信 */
            inform().reqInformOperationStatus().send();
        } catch (InterruptedException | IOException ex) {
            Logger.getLogger(MyLighting.class.getName()).log(Level.SEVERE,
                                                             null, ex);
        }
        return true;
    }

    @Override
    protected byte[] getOperationStatus() {
        try {
            Runtime rt = Runtime.getRuntime();
            /* LEDの点灯状態を取得 */
            Process pr = rt.exec("cat /sys/class/gpio/gpio40/value");
            InputStream is = pr.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line = br.readLine();
            if (line != null && line.equals("0"))
                mStatus[0] = 0x31;
            else
                mStatus[0] = 0x30;
        } catch (IOException ex) {
            Logger.getLogger(MyLighting.class.getName()).log(Level.SEVERE, null, ex);
        }
        return mStatus;
    }

    @Override
    protected boolean setLightingModeSetting(byte[] edt) {
        mMode[0] = edt[0];

        try {
            inform().reqInformLightingModeSetting().send();
        } catch (IOException ex) {
            Logger.getLogger(MyLighting.class.getName()).log(Level.SEVERE,
                                                             null, ex);
        }
        return true;
    }

    @Override
    protected byte[] getLightingModeSetting() {
        return mMode;
    }

    @Override
    protected boolean setInstallationLocation(byte[] edt) {
        mLocation[0] = edt[0];

        try {
            inform().reqInformInstallationLocation().send();
        } catch (IOException ex) {
            Logger.getLogger(MyLighting.class.getName()).log(Level.SEVERE,
                                                             null, ex);
        }
        return true;
    }

    @Override
    protected byte[] getInstallationLocation() {
        return mLocation;
    }

    @Override
    protected byte[] getStandardVersionInformation() {
        return mVersion;
    }

    @Override
    protected byte[] getFaultStatus() {
        return mFaultStatus;
    }

    @Override
    protected byte[] getManufacturerCode() {
        return mManufacturerCode;
    }
}

ビルドしたパッケージを以下の構成でA7に転送します。

# ls -lsR
.:
total 16
4 -rw-r--r-- 1 root root 1323 Jul 17 13:29 README.TXT
8 -rw-r--r-- 1 root root 5395 Jul 16 17:54 ellight.jar
4 drwxr-xr-x 2 root root 4096 Jul 17 13:29 lib

./lib:
total 1040
1040 -rw-r--r-- 1 root root 1061315 Jul 17 16:02 OpenECHO.jar

起動方法は以下の通りです。

# java -jar ellight.jar

3. ソフトウェア (コントローラ)


コントローラとしては、Kadecot [公開実験版]を利用させてもらいました。
Androidマシンを用意し、PlayStoreよりアプリをダウンロードして使用します。


 Kadecot: 機器のリスト画面



画面の照明機器をクリックすることにより、本体のLEDの点灯制御を行っています。

3. さいごに


今回はOpenECHOを評価するのが目的でしたので、GPIO回りの実装は、最低限動作確認出来る程度のものとなっています。

OpenBlocks IoT BX1 開発者向け情報など

$
0
0
OpenBlocks IoTファミリ BX1を発表しました。

M2M・IoTシステムの構築に最適な極小サイズのマイクロサーバー「OpenBlocks® IoTファミリ BX1」を発表

OpenBlocksシリーズは、従来より複数のLANポートを持ち小型堅牢かつ汎用のLinux環境を提供するマイクロサーバとして、ネットワークの監視管理、ゲートウェイなど、様々なシーンで利用していただいていましたが、今回のBX1シリーズにおいては、Wifi/3G/BlueTooth(BLE対応)を標準サポートした、無線通信に重点を置いた製品となっています。

発表ではスケルトンカバーに入った製品としてお見せしていますが、まずは内部写真をここに公開します。


カバーは試作品のため、スケルトン仕様となっていますが、製品ではホワイトとなる予定です。


外部コネクタ。上部がオプション有線接続用端子となり、ケーブルを交換することにより、USB(有線LAN含む)、シリアル(RS-232C/RS-485)、GPIO(最大19ポート)に対応します。
下部がSIMスロットです。


標準でUSBケーブルが添付します。本ケーブルはUSB側からの給電と、シリアル通信をサポートしており、PCに接続する場合は、 USBシリアル経由のコンソールとして見えます。


本体基板の裏側です。


本体基板の上部写真です。

本体の仕様は以下の通り。

CPUモデルインテル® Atom™ プロセッサー 500MHz (デュアルコア)
動作速度500MHz (デュアルコア)
メインメモリオンボード1GB (LPDDR3)
FLASH ROM4GB (eMMC)
内部インターフェイス3G(W-CDMA)※1
Bluetooth 4.0
Wi-Fi (IEEE802.11a/b/g/n)
外部インターフェイスUSB 2.0(Type-A)ケーブル
GPIO (最大19ポート) オプションケーブルにて対応
シリアル 1ポート RS-232C/RS-485
寸法 (mm)41.6mm(W)x 96mm(D)x 11.3mm(H)(突起部含まず)
電源DC 5〜48V
出荷時OSDebian GNU/Linux

※1 NTTドコモ FOMA網に対応予定。他通信事業者向けも検討中。

開発環境は、Debian GNU/Linuxを標準でサポートし、従来のOpenBlocksシリーズと同様に、実機ベースでの手早い開発環境をBXでも提供していきたいと考えています。

提供時期ですが、開発者向けに、本体と各種IOを外だし出来るボードをセットにしたDPパッケージを先に提供し(時期は未定)、製品としては2月を予定しています。

展示会の情報などは、以下のページでご案内しています。

特設サイトURL:
http://openblocks.plathome.co.jp/products/special/bx1_sp/

Facebook:

https://www.facebook.com/OpenBlocksIoT



現在、DPパッケージのリリースに前後して、いち早く製品をご覧いただけるよう、ハンズオンdayやハッカソン、アイディアソンなどを企画しておりますので、日程が決まり次第またお知らせします。


OpenBlocks IoT BX1 ハンズオン開催中

$
0
0
OpenBlocks IoT BX1のハンズオンDayを正式にスタートしました。

今週より、BX1本体およびDockBoard(ES版)との組み合わせにてご利用いただけます。

 
天王洲アイル、Samurai Startup Islandにて毎週水曜日(10:00-18:00)に開催。
予約制となりますので、以下の開催概要にそってご予約下さい。
当日でも空いていれば予約可能です。

現在ほぼマンツーマンのハンズオンとなっており、使用できるセットも限られているため、多人数となる場合は、早めにご連絡いただき、機材などの調整をさせてください。


------

「ハンズオンDay」開催概要

  • 実施内容
    当社IoT向けマイクロサーバー「OpenBlocks® IoT BX1」を使用したハンズオンです。
    実際にOpenBlocks® IoT BX1の実機や開発環境に触れながら基本操作の確認や、アプリケーション開発、システム構築に必要となる事項の事前サーベイなどが可能です。

    参考:OpenBlocks® IoT BX1特設サイトURL
    http://openblocks.plathome.co.jp/products/special/bx1_sp/
  • 対象となる方
    IoTのアプリケーション開発や、センサーデバイス接続開発、IoTサービス開発などを検討している方に最適です。
  • 開催スケジュール
    原則、毎週水曜日に実施致します。詳細なスケジュールは下記URLよりご確認下さい。
    http://goo.gl/vUxmwv
  • 参加方法
    機材の都合上事前予約が必要となります。開催スケジュールをご確認のうえ、当社WEBサイトの参加申込フォームよりお申込み下さい。

    参加申込フォームURL
    https://openblocks.plathome.co.jp/form/bx1_handson/input.html
  • 参加費用
    無料です。
  • 開催場所
    Samurai Startup Island
    住所:東京都品川区 東品川2-2-28 Tビル2F
    アクセス:天王洲アイル駅より徒歩5分
    http://samurai-startupisland.asia/access

[.tested] TI CC2541 Sensor TagのデータをIBM Bluemixで処理するためのセンサーゲートウェイ [BX1]

$
0
0
この1月24日,25日に、天王洲のSamurai Startup Islandにおいて、

「IoTハック新年会2015」

を行いました。
このイベントは、IBMとSamurai Incubateが共催で『日常生活で使うモノ』をテーマ行うアイディアソン、ハッカソンで、クラウド環境としては、IBM BlueMix、デバイスとしては、TI CC2541センサータグ、ゲートウェイとして、OpenBlocks BX1を用意しています。

今回は、上記ハッカソンで使用した、OpenBlocks BX1側のTI CC2541 SensorTagデバイスゲートウェイ実装方法について紹介します。



OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
OpenBlocks IoT BX1 Debian wheezy 7.8 / kernel 3.10.17-poky-edison

1. 事前準備


・ネットワークへの接続

BX1を外部ネットワークに接続可能な状態にします。本体にSIMを入れることにより3G通信も可能ですが、開発環境の構築や、パッケージの入手などはWifi環境に接続するか、USB分岐ケーブルにUSB-Etherアダプタなどを利用して有線LAN接続することをおすすめします。

・bluetoothの設定

Bluetoothは、初期状態ではblockしてありますので、rfkillコマンドによりunblockしてください。
具体的には、以下の手順で手動で行うか、

# bluetooth_rfkill_event &
# rfkill unblock bluetooth

以下の3行をrc.localに追加します。

bluetooth_rfkill_event &
sleep 1
rfkill unblock bluetooth

・開発環境および関連ツールのインストール

node.jsをビルドするためには、開発環境が必要です。(IO開発ボード付きセットの場合は開発環境をプリインストールしています)
また、今回必要になるパッケージ類を以下の手順でインストールします。

# aptitude update
# tasksel install standard
# aptitude install build-essential
# aptitude install git

・node.jsのインストール

node.jsはdebianのパッケージを使用せず、最新版を以下のサイトから入手し、ビルドしています。

Node.js

# wget http://nodejs.org/dist/v0.12.0/node-v0.12.0.tar.gz
# tar xvzf  http://nodejs.org/dist/v0.12.0/node-v0.12.0.tar.gz
# cd node-v0.12.0
# ./configure
# make -j3
# make install

2. センサーゲートウェイソフトウェアの構築


IBM Internet of Thingsの以下のレシピページより、BeagleBone用のゲートウェイプログラムを入手します。

Texas Instruments BeagleBone with SensorTag - Internet of Things:

# git clone http://github.com/ibm-messaging/iot-beaglebone

以下のディレクトリに移動し、setup.shを編集し、checkInstall bluezの行をコメントアウトします。
(bluezはすでにインストールされているものを使用します。debian wheezyのaptで導入されるものは、BLEに対応していないバージョンのため使用しません)

     :
# checkInstall bluez
checkInstall libbluetooth-dev
  :

編集後、setup.shにより、動作環境の構築を行います。

#./setup.sh

次に、ゲートウェイプログラム本体の若干の修正を行います。
これは、beaglebone向けに書かれていて、データを受け取りLEDを点滅させる記述があるのですが、 このLEDの点灯処理部分だけをコメントアウトしてしまいます。
ここは、OpenBlocksのLEDの仕様で書き換えれば同様にBluemix側からLEDの点灯処理ができるのですが、今回は行っていません。

# vi iot_sensortag.js

50行以下を以下の様に編集します。

// LED functions
// run asynchronously, callbacks just trap unexpected errors
function ledWrite(extra, content, callback) {
//  fs.writeFile(ledPath+extra, content, function(err) {
//      if (err) throw err;
//  });
//  if (callback) callback();
}

2. センサーゲートウェイソフトウェアの起動


TI CC2541 SensorTagを用意し、編集したJavascriptプログラムを起動します。

root@bx1:~/iot-beaglebone/samples/nodejs# node iot_sensortag.js
Press the side button on the SensorTag to connect

メッセージに従い、センサータグのサイドボタンを押すと、接続を行い、BluemixへMQTTによるデータ送信を開始します。

root@bx1:~/iot-beaglebone/samples/nodejs# node iot_sensortag.js
Press the side button on the SensorTag to connect
SensorTag connected
Discovering services and characteristics
Device name = TI BLE Sensor Tag
System id = 34:b1:f7:0:0:d5:d5:2a
Serial number = N.A.
Firmware revision = 1.01 (Feb  7 2013)
Hardware revision = N.A.
Software revision = N.A.
Manufacturer name = Texas Instruments
Enable IR temperature
Enable accelerometer
Enable humidity sensor
Enable magnetometer
Enable barometer
Enable gyroscope
MQTT clientId = d:quickstart:iotsample-ti-bbst:98f170697445
MQTT Connected
Sending data
MAC address = 98f170697445
Go to the following link to see your device data;
http://quickstart.internetofthings.ibmcloud.com/#/device/98f170697445/sensor/

3. Bluemix側の設定


Bluemixは、試用期間が30日あり、登録して30日間は無料ですべての機能を試すことが出来ます。
(無料期間終了後は、クレジットカードの登録が必要ですが、375GB時間までは無料で使用できるようになっています)

カタログのボイラープレートより、左上のNode-Redを使用したInternet of Things Foundationアプリケーションを選択します。


インスタンスを起動します


最初に簡単なサンプルプレートがありますので、この左側のIBM IoT App Inに、上記で立ち上げたゲートウェイソフトウェア起動時に表示されるMAC Addressを入力します。


Deployし、すぐ右にあるDevice Dataのdebugタブを引き出すと、右のDebugウィンドウに、センサータグからデータがJSON形式で送信されていることが確認出来ます。


 様々な機能が用意されていますので、あとはPaaS側で処理を作成していくことになります。
この環境はそのまま実稼働環境へと移行させることも出来ます。


4. 最後に


今回は、TI CC2541 Sensor Tagを利用した例を紹介しました。
ibeacon仕様のビーコンタグのデータをBluemixへ送信するテストプログラムも作成していますので、次回ご紹介します。

[.tested] 受信したiBeaconの情報をIBM Bluemixで処理するためのゲートウェイ [BX1]

$
0
0

スマホをビーコンの受信機とした位置情報の取得は、現在各地で実証実験が行われているところですが、小型で安価なビーコンタグの普及の加速により、その逆の形として、ビーコンを取り付けたモノや人の位置情報をビーコンの受信機により検知し、クラウド処理する事案が増えています。

今回は、ibeaconの信号を受信し、uuid、受信したゲートウェイのデバイスID、電波強度であるrssiをIBMのBluemixで処理するためのゲートウェイソフトウェアの例を紹介します。



OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
OpenBlocks IoT BX1 Debian wheezy 7.8 / kernel 3.10.17-poky-edison

1. 事前準備


・ネットワークへの接続

BX1 を外部ネットワークに接続可能な状態にします。本体にSIMを入れることにより3G通信も可能ですが、開発環境の構築や、パッケージの入手などはWifi 環境に接続するか、USB分岐ケーブルにUSB-Etherアダプタなどを利用して有線LAN接続することをおすすめします。

・bluetoothの設定

Bluetoothは、初期状態ではblockしてありますので、rfkillコマンドによりunblockしてください。
具体的には、以下の手順で手動で行うか、

# bluetooth_rfkill_event &
# rfkill unblock bluetooth

以下の3行をrc.localに追加します。

bluetooth_rfkill_event &
sleep 1
rfkill unblock bluetooth

・node.jsのインストール

node.jsのインストール方法は、前回の記事を参照してください。

2. ibeaconゲートウェイソフトウェアの構築


ソフトウェアを構築するディレクトリを作成します。

# mkdir ibeacon
# cd ibeacon

node.jsを使用してibeaconの送受信を行うbleaconモジュールを導入します。
bleaconの導入には、 libbluetooth-devパッケージも必要なため、導入していない場合は合わせてインストールしてください。

# aptitude update
# aptitude install libbluetooth-dev
# npm install bleacon

bluemixへデータを送信するためのMQTTクライアントライブラリおよび、getmacライブラリをインストールします。

# npm install mqtt
# npm install getmac

次に、ゲートウェイプログラムを作成します。

# vi ib2b.js

ib2b.js

var bleacon = require("bleacon");
var mqtt = require('mqtt');
var getmac = require('getmac');

// constants
var u_port = "1883";
var s_port = "8883";
var pub_topic = "iot-2/evt/sample/fmt/json";
var sub_topic = "iot-2/cmd/blink/fmt/json";
var qs_org = "quickstart";
var reg_domain = ".messaging.internetofthings.ibmcloud.com";
var qs_host = "quickstart.messaging.internetofthings.ibmcloud.com";
var qs_type = "iotsample-ti-bbst";
var configFile = "./device.cfg";
var ledPath ="/sys/class/leds/beaglebone:green:usr";
var caCerts = ["./IoTFoundation.pem", "IoTFoundation-CA.pem"];


// globals
var org = qs_org;
var type = qs_type;
var host = qs_host;
var deviceId;
var clientId;
var password;
var username;

getmac.getMac(function(err, macAddress) {
    if (err) throw err;
     console.log(macAddress);
     deviceId = macAddress.replace(/:/g, '').toLowerCase();
     clientId = "d:" + org + ":" + type + ":" + deviceId;
     console.log('MQTT clientId = ' + clientId);
     client = mqtt.createClient(u_port, host, {
     clientId : clientId,
     keepalive : 30
     });
     console.log('MAC address = ' + deviceId);
     console.log('Go to the following link to see your device data;');
     console.log('http://quickstart.internetofthings.ibmcloud.com/#/device/' + deviceId + '/sensor/');
     bleacon.startScanning();
});

bleacon.on('discover', function(bleacon) {
        var tagData = {};
        tagData.d = {};
        //       console.log(bleacon);

        tagData.d.deviceid = deviceId;
        tagData.d.uuid = bleacon.uuid;
        tagData.d.rssi = bleacon.rssi;
        tagData.d.proximity = bleacon.proximity;

        tagData.toJson = function() {
           return JSON.stringify(this);
        };

        console.log(pub_topic, tagData.toJson());
        console.log(tagData.toJson());
        client.publish(pub_topic, tagData.toJson() );

});

3. ゲートウェイソフトウェアの起動


ibeaconの送信機を用意して、上記で作成したJavascriptプログラムを起動します。

root@bx1:~/ibeacon# node ib2b
34:95:db:28:41:d2
MQTT clientId3 = d:quickstart:iotsample-ti-bbst:3495db2841d2
createClient is deprecated, use connect instead
MAC address = 3495db2841d2
Go to the following link to see your device data;
http://quickstart.internetofthings.ibmcloud.com/#/device/3495db2841d2/sensor/
iot-2/evt/sample/fmt/json {"d":{"deviceid":"3495db2841d2","uuid":"1ae18c1c6c7b4aedb1664462634da855","rssi":-56,"proximity":"immediate"}}

デバッグ用にBluemixへ送信するデータの内容をコンソール出力していますので、不要な場合は削除してください。

3. Bluemix側の設定


Bluemix側は、前回と同じテンプレートが利用できます。



JSON形式で出力されるデータは、
deviceid: ゲートウェイのアドレス
uuid: 検出したibeaconのuuid
rssi: 電波強度
proximity: 相対距離の情報
となります。

bleaconライブラリで得られるパラメータを追加したい場合は、以下のJavascriptプログラムの出力を参考にしてください。

discover.js

var Bleacon = require("bleacon");
Bleacon.startScanning();
Bleacon.on("discover", function(bleacon) {
  console.dir(bleacon);
});

root@bx1:~/ibeacon# node discover.js
{ uuid: '1ae18c1c6c7b4aedb1664462634da855',
  major: 0,
  minor: 0,
  measuredPower: -82,
  rssi: -49,
  accuracy: 0.22312232579283153,
  proximity: 'immediate' }

4. 最後に


iBeaconのハードウェアレポートに関しては、若干古い情報にはなりますが、以下のページが参考になると思います。

The Hitchhikers Guide to iBeacon Hardware: A Comprehensive Report by Aislelabs



[.tested] TI CC2541 Sensor TagのデータをIBM Bluemixで処理するためのセンサーゲートウェイ マルチデバイス対応 [BX1]

$
0
0
今回は、以前ご紹介したTI CC2541 Sensor TagのデータをIBM Bluemixで処理するためのセンサーゲートウェイのマルチデバイス対応の実装方法についてご紹介します。


OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
OpenBlocks IoT BX1 Debian wheezy 7.8 / kernel 3.10.17-poky-edison

1. 事前準備


ネットワークへの接続、bluetoothの設定、開発環境および関連ツールのインストール、node.jsのインストールにつきましては前々回の記事を参照してください。

2. センサーゲートウェイソフトウェアの構築


ソフトウェアを構築するディレクトリを作成します。

# mkdir multi_device
# cd multi_device

今回必要なモジュールを導入します。
libbluetooth-devパッケージも必要なため、導入していない場合は合わせてインストールしてください。

# aptitude update
# aptitude install libbluetooth-dev
# npm install async
# npm install getmac
# npm install mqtt
# npm install sensortag

次に、ゲートウェイプログラムを作成します。
今回は温度データを取得し、Bluemixへ送信するサンプルです。

# vi multi_st2b.js

multi_st2b.js


var SensorTag = require('sensortag');
var async = require('async');
var mqtt = require('mqtt');
var getmac = require('getmac');

// constants
var u_port = "1883";
var pub_topic = "iot-2/evt/sample/fmt/json";
var qs_org = "quickstart";
var qs_host = "quickstart.messaging.internetofthings.ibmcloud.com";
var qs_type = "iotsample-ti-bbst";

// globals
var org = qs_org;
var type = qs_type;
var host = qs_host;
var deviceId;
var clientId;

getmac.getMac(function(err, macAddress) {
  if (err) throw err;
    console.log(macAddress);
    deviceId = macAddress.replace(/:/g, '').toLowerCase();
    clientId = "d:" + org + ":" + type + ":" + deviceId;
    console.log('MQTT clientId = ' + clientId);
    client = mqtt.createClient(u_port, host, {
    clientId : clientId,
    keepalive : 30
  });
  console.log('MAC address = ' + deviceId);
  console.log('Go to the following link to see your device data;');
  console.log('http://quickstart.internetofthings.ibmcloud.com/#/device/' + deviceId + '/sensor/');
});

function onDiscover(sensorTag) {
  console.log('discovered: ' + sensorTag.uuid + ', type = ' + sensorTag.type);

  sensorTag.on('disconnect', function() {
    console.log('disconnected! ' + sensorTag.uuid);
  });

  async.series([
      function(callback) {
        console.log('connectAndSetUp');
        sensorTag.connectAndSetUp(callback);
      },
      function(callback) {
        console.log('readDeviceName: ' + sensorTag.uuid);
        sensorTag.readDeviceName(function(error, deviceName) {
          console.log('\tdevice name = ' + deviceName);
          callback();
        });
      },
      function(callback) {
        console.log('enableIrTemperature');
        sensorTag.enableIrTemperature(callback);
      },
      function(callback) {
        setTimeout(callback, 2000);
      },
      function(callback) {
        sensorTag.on('irTemperatureChange', function(objectTemperature, ambientTemperature) {

          var tagData = {};
          tagData.d = {};

          tagData.d.deviceid = deviceId;
          tagData.d.uuid = sensorTag.uuid;
          tagData.d.rssi = sensorTag.rssi;
          tagData.d.proximity = sensorTag.proximity;
          tagData.d.objectTemperature = objectTemperature.toFixed(1);
          tagData.d.ambientTemperature = ambientTemperature.toFixed(1);

          tagData.toJson = function() {
            return JSON.stringify(this);
          };

          console.log(pub_topic, tagData.toJson());
          console.log(tagData.toJson());
          client.publish(pub_topic, tagData.toJson() );

          console.log(sensorTag.uuid);
            console.log('\tobject temperature = %d °C', objectTemperature.toFixed(1));
            console.log('\tambient temperature = %d °C', ambientTemperature.toFixed(1))
        });

        console.log('setIrTemperaturePeriod');
        sensorTag.setIrTemperaturePeriod(1000, function(error) {
          console.log('notifyIrTemperature');
          sensorTag.notifyIrTemperature(function(error) {
          });
        });
      },
      function(callback) {
        console.log('disableIrTemperature');
        sensorTag.disableIrTemperature(callback);
      },
    ]
  );
}

SensorTag.discoverAll(onDiscover);

3. センサーゲートウェイソフトウェアの起動


TI CC2541 SensorTagを複数用意し、上記で作成したJavascriptプログラムを起動します。

root@bx1:~/multi_device# node multi_st2b.js
34:95:db:28:41:0e
MQTT clientId = d:quickstart:iotsample-ti-bbst:3495db28410e
createClient is deprecated, use connect instead
MAC address = 3495db28410e
Go to the following link to see your device data;
http://quickstart.internetofthings.ibmcloud.com/#/device/3495db28410e/sensor/

ここでは2台で試してみました。それぞれのセンサータグのサイドボタンを押すと、以下のようなメッセージが表示され、BluemixへMQTTによるデータ送信を開始します。

discovered: 5c313ec119a5, type = cc2540
connectAndSetUp
discovered: 5c313ebff12e, type = cc2540
connectAndSetUp

4. Bluemix側の設定


Bluemix側は、前々回前回と同じテンプレートが利用できます。



今回は温度データのみですが、データを追加したい場合はインストールしたsensortagモジュール(node_modules/sensortag)にあるtest.jsなどを参照して、必要なデータを追加してください。

5. 最後に


今回は、TI CC2541 Sensor Tagを複数接続する例を紹介しました。
さらに詳しい情報が知りたい方は
https://github.com/sandeepmistry/node-sensortag
を参照してください。


OpenBlocks 600D向けDebian8ファームウェアの非公式(Unofficial)リリースについて

$
0
0
非公式となりますが、OpenBlocks 600D向けのDebian8パッケージを公開しました。

レポジトリは以下の場所となります。

http://ftp.plathome.co.jp/pub/OBS600/unofficial/debian/jessie/


本公パッケージの公開にあたり、カスタマーケア等でのサポートは行っておりませんのでご了承の上ご利用願います。
 
OBS600用ファームウェア 4.1.8-0の更新手順を記述します。

前準備


Debian6、Debian7のパッケージは使用できません。

ラムディスクモード時のflashに保存しているパッケージとストレージ併用モード時のCFに保存しているパッケージは消去する必要があります。

また、自作したプログラムは共有ライブラリを使用している場合は動作しない可能性があります。staticで作成したプログラムは動作すると思われます。


ラムディスクモードで使用していた場合


FLASH ROMのユーザ領域を初期化します。
  1. 必要なファイルはバックアップをとってください。
  2. shutdown後、INITボタンを押しながら電源ONしてください。
  3. 以下のコマンドでFLASH領域を初期化してください。
    # flashcfg -e

ストレージ併用モード(CF)で使用していた場合


CFをフォーマットします。
  1. 必要なファイルはバックアップをとってください。
  2. 以下のコマンドでストレージ併用モードを解除します。
    # e2label /dev/sda1 ""
  3. shutdown後、INITボタンを押しながら電源ONしてください。
  4. 再起動したら、念のため以下のコマンドでFLASH領域を初期化します。(必要なファイルがあった場合はバックアップをとっておいてください。)
    # flashcfg -e
  5. 以下のコマンドでCFをフォーマットした後、リブートします。
    # mkfs.ext4 -L DEBIAN /dev/sda1
    # reboot
前準備は完了です。

ファームウェアの更新


更新の手順は今までのDebianファームウェアと同じです。
まず、Debian8のファームウェアファイルを用意します。

2015/10/19時点:

http://ftp.plathome.co.jp/OBS600/unofficial/jessie/4.1.8-0/kernel-image-4.1.8-0.deb

以下のコマンドでインストールします。

# dpkg -i kernel-image-4.1.8-0.deb

インストール終了後、再起動してください。

補足


今回のファームウェアにおいては、(あまりにも使いにくいという理由で)systemdではなく、sysvinitに変更を行っています。



補足その2 (2015/11/26)

uboot-imageがないというご指摘があり、現在修正作業を行っています。
当面の回避策は以下の通りです。

以下のファイル
 
http://ftp.plathome.co.jp/pub/OBS600/unofficial/jessie/4.1.8-0/uImage.initrd.obs600 
 

をダウンロードします。

以下のコマンドを実行します。
# flashcfg -f uImage.initrd.obs600
 
 

OpenBlocks IoT Family で一時的な Wi-Fi クライアント接続を行う

$
0
0
Web ユーザーインターフェースの設定を変更せず、一時的に Wi-Fi クラアントとして OpenBlocks IoT Family を既設の Wi-Fi ネットワークへ接続する方法を紹介します。

OBDN 技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

はじめに


OpenBlocks IoT Family(以下OpenBlocks)の初期設定では、Wi-Fi インターフェースはアクセスポイントとして動作するようになっています。常時 3G や LTE のモバイル回線を利用する場合にこの設定は便利ですが、メンテナンス等の目的で一時的に Wi-Fi クライアントとして既設の Wi-Fi ネットワーク環境に接続したいことがあります。

もちろん Web ユーザーインターフェース経由で設定を変更しても良いのですが、設定を戻すのを忘れて別のネットワーク環境に移った場合、Web ユーザーインターフェースへアクセスできず、設定の初期化が必要になるなど後々少々面倒くさいことになります。

そこで Web ユーザーインターフェースの設定を変更せずに、一時的に OpenBlocks を Wi-Fi クライアントとして既設ネットワークへ接続する方法を紹介します。

Wi-Fi のアクセスポイントモードとクライアントモード


はじめに Wi-Fi のアクセスポイントになっている OpenBlocks がどういう状態であるかを整理してみましょう。ネットワークインターフェース(以下I/F)としては次のような状態になっています。
  • Wi-Fi I/F はアクセスポイントモードに設定
  • Wi-Fi I/F で DHCP のサービスが稼働
したがって次の三つを行えば、アクセスポイントモードからクライアントモードへ切り替えて、既設の Wi-Fi ネットワークに接続できます。
  1. DHCP サービスを停止
  2. Wi-Fi I/F をアクセスポイントモードからクライアントモードへ変更
  3. Wi-Fi クライアントとして必要な設定の投入
これらを順に説明します。

DHCP サービスの停止


DHCP サービスを停止するにはサービスを実施しているプロセスの dhcpd を停止するだけです。dhcpd については単純にkillで問題ありません。

# killall dhcpd

Wi-Fi I/F をアクセスポイントモードからクライアントモードへ変更


Wi-Fi I/F をアクセスポイントをクライアントのモードへ切り替えるのは、少し複雑です。というのも Wi-Fi I/F のドライバーがカーネルモジュールになっていて、モジュールのロード時にモード設定を行っているからです。また Wi-Fi アクセスポイントをサービスする hostapd というプロセスも動いています。手順としては次のようになります。
  1. hostapd の停止
  2. Wi-Fi I/F の停止
  3. ドライバーのモードの切り替え
  4. Wi-Fi I/F の起動
具体的には次の各コマンドを実行します。

# killall hostapd
# ifdown wlan0
# modprobe -r bcm4334x
# modprobe bcm4334x op_mode=1
# ifup wlan0

Wi-Fi クライアントとして必要な設定


以上まで完了したら、後は一般的な Linux を Wi-Fi に接続する場合と同じ手順となります。Wi-Fi クライアントとして必要な設定を行うには、次の2つの手順を踏むことになります。
  1. 既設 Wi-Fi 環境への接続
  2. DHCP クライアントとして設定
既設 Wi-Fi 環境へ接続するためには、SSID(ESSID)とパスフレーズを用意してwpa_supplicant を設定します。wpa_supplicant の設定の詳細は省略しますが、以下の例では /var/run/wpa.conf ファイルで Wi-Fi 接続の設定を行っています。最後に dhclient プログラムを起動すれば完了です。

# cat /var/run/wpa.conf
ctrl_interface=/var/run/wpa_supplicant
network={
        ssid="WIFISSID"
        scan_ssid=1
        key_mgmt=WPA-PSK
        psk="PASSWORD"
}
# wpa_supplicant -s -B -P /var/run/wpa_supplicant.wlan0.pid ¥
        -i wlan0 -D nl80211,wext -c /var/run/wpa.conf
# dhclient -v -pf /run/dhclient.wlan0.pid ¥
        -lf /var/run/dhclient.wlan0.leases wlan0

以上で Wi-Fi クライアントへの切り替えは完了です。この作業では何ら設定を保存していないため次に OpenBlocks を再起動した場合は本来の設定が有効になり、Wi-Fi I/F はアクスセスポイントとして動作します。

Wi-Fi クライアント設定のシェルスクリプト


上記に紹介した作業を毎回手作業で実施するには手順が多すぎますので、これらを実施するシェルスクリプトを最後に紹介します。

#!/bin/sh
#
# OpenBlocks IoT familyでWebのユーザーインターフェースの設定を変更せず
# 一時的にWi-Fiをクライアント設定に変更するシェルスクリプト
#
# このスクリプト中でsleep 1を多用しているのは、立て続けにコマンドを起
# するとうまく動かないものがあるため、待ち時間を確保している

export PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# 次の2行はWi-Fi環境に合わせて設定する
SSID=WIFISSID# Wi-Fi接続先のSSID
WKEY=PASSWORD# Wi-Fi接続先のパスフレーズ

IF=wlan0# 無線I/F名 OpenBlocksの場合wlan0
WPACONF=/var/run/wpa.conf# wpa_supplicantの設定ファイル名

# Wi-Fi I/Fのモード切り替え
killall dhcpd hostapd; sleep 1
ifdown wlan0; sleep 1
modprobe -r bcm4334x; sleep 1
modprobe bcm4334x op_mode=1; sleep 1
ifup wlan0; sleep 1

# /etc/network/interfaces の記載によって
# ifupで付加される余計なIPアドレスの削除
ip addr del 192.168.254.254/24 dev ${IF}

# wpa_supplicantの設定ファイル(ここでは/var/run/wpa.conf)の生成
#  一般的なWPAの事前共有鍵の設定を前提にしているため、
#  Wi-Fi環境の設定に応じて修正する
cat <<-EOT >$WPACONF
ctrl_interface=/var/run/wpa_supplicant
network={
   ssid="$SSID"
   scan_ssid=1
   key_mgmt=WPA-PSK
   psk="$WKEY"
}
EOT

# wpa_supplicantの起動
wpa_supplicant -s -B -P /var/run/wpa_supplicant.${IF}.pid \
-i ${IF} -D nl80211,wext -c $WPACONF
sleep 1

# dhcpクライアントサービスの起動
dhclient -v -pf /run/dhclient.${IF}.pid  \
-lf /var/run/dhclient.${IF}.leases ${IF}

# Wi-Fi経由でのssh 接続を許可する場合、
# 以下のコメントアウトを外してiptablesの行を有効にする
# iptables -A INPUT -p tcp --dport ssh -j ACCEPT

OpenBlocks IoT EX1 で microSDXC メモリーカードを利用する

$
0
0
OpenBlocks IoT EX1 には microSD メモリーカードスロットが用意されています。このスロットを使って実際に microSDXC メモリーカードを読み書きする方法について説明します。

OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

はじめに


OpenBlocks IoT EX1 (以下EX1)には、筐体内部に microSD メモリーカードスロットがあり microSDXC メモリーカード(以下 microSDXC)を利用できますが、実は、市販されている microSDXC をそのまま利用するためには、EX1側で少し設定作業が必要になります。

ここでは microSDHC メモリーカード(以下 microSDHC)と比べながら、microSDXC を EX1 で読み書きする方法について説明しましょう。

本文が長くなったので最後にまとめを用意してあります。ざっくりと概要を知りたい方は最後のまとめをお読みください。

microSDXC と miroSDHC


今回用意したメモリーカードは次の2枚で、左側の黒いカードが microSDHC 16GB、右側の上部が赤いカードが microSDXC 64GB です。


microSDHC の利用


まず microSDHC を EX1 にマウントしてみましょう。

EX1 で microSD メモリーカードを利用するために EX1 本体の蓋を開ける必要がありますが、蓋を固定してあるネジを外す際は次のようなグリッップの太いしっかりした0番のプラスドライバーを利用してください。


よくある細い精密ドライバーでは力が十分にかからず、ネジを開けられないことがあります。


この写真は microSDHC を EX1 に差し込んでいる途中の状態です。このままカチっと音がするまで奥に差し込みます。完全に差し込むと次のようになります。


ここに刺した microSDHC のデバイス名は、/dev/mmcblk1 となります。

次の例はまだ microSDHC カードを刺していない状態で、デバイスが存在しません。

# ls -l /dev/mmcblk1*
ls: cannot access /dev/mmcblk1*: No such file or directory

microSDHC を刺すと、次の通りデバイスが現れます。

# ls -l /dev/mmcblk1*
brw-rw---T 1 root floppy 179, 128 Feb 24 14:12 /dev/mmcblk1
brw-rw---T 1 root floppy 179, 129 Feb 24 14:12 /dev/mmcblk1p1

ここで /dev/mmcblk1 が microSDHC カード全体を表し、/dev/mmcblk1p1 が microSDHC の最初のパーティションを表していて、実際の記憶領域はこのパーティションとなります。

では実際に /dev/mmcblk1p1 をマウントしてみましょう。

# mount /dev/mmcblk1p1 /mnt     ← microSDHC パーティションのマウント
# mount | fgrep /mnt            ← マウントできたかどうかの確認その1
/dev/mmcblk1p1 on /mnt type vfat (rw,relatime,fmask=0022, dmask=0022,codepage=437,iocharset=iso8859-1, shortname=mixed,errors=remount-ro)
# df -h /mnt/.                  ← moountできたかどうかの確認その2
Filesystem      Size  Used Avail Use% Mounted on
/dev/mmcblk1p1   15G  2.2M   15G   1% /mnt

この通りマウントできています。あとは /mnt ディレクトリの配下で microSDHC のデータを読み書きできます。

ファイルのコピー等必要な作業が終わったら microSDHC を本体から抜きますが、抜く前には必ず unmount します。

# umount /mnt

これで安全に microSDHC カードを安全に本体から抜くことができます。

microSDXC の利用


今度は microSDXC で同様の作業を行ってみましょう。

まず本体に microSDXC カードを挿入します。



写真は差し込み途中のものですが、奥までしっかり差し込んで下さい。正しく差し込めば次のように microSDXC のデバイスが現れます。microSDXC でもデバイス名は microSDHC と同じ名前です。

# ls -l /dev/mmcblk1*
brw-rw---T 1 root floppy 179, 128 Feb 24 14:42 /dev/mmcblk1
brw-rw---T 1 root floppy 179, 129 Feb 24 14:42 /dev/mmcblk1p1
#

ではマウントしてみましょう

# mount /dev/mmcblk1p1 /mnt
mount: unknown filesystem type 'exfat'
#

exfatは知らないファイルシステムだというエラーメッセージが表示されました。df コマンドや、mount コマンドの結果を見ても次のように microSDXC のマウントはできていません。

# mount | fgrep /mnt
# df /mnt/.
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/root         198337 156166     31931  84% /
#

マウントに失敗した理由は、市販の microSDXC は exFAT 形式でフォーマットされていて、OpenBlocks IoT Familyの標準の状態では exFAT 形式のドライバを持っていないからです。

これに対して microSDHC は FAT32 形式でフォーマットしてあり、元々カーネルがドライバを持っています。

exFAT 形式のディスクを読み書きするためのドライバとツール類は、Debianのパッケージで用意されています。次のように exFAT 用のパッケージを探してみましょう。

# apt-get update             ← パッケージインデックスの更新
Hit http://ftp.plathome.co.jp ./ Release.gpg
---------- 中略 ---------- 中略 ----------
Hit http://cdn.debian.or.jp wheezy-updates/main Translation-en
Reading package lists... Done
#
# apt-cache search exfat     ← exFAT関係のパッケージの検索
exfat-utils - utilities to create, check, label and dump exFAT filesystem
exfat-fuse - read and write exFAT driver for FUSE

#

exfat-utils と exfat-fuse が見つかりました。ここでは exfat-utils をインストールします。exfat-fuse 並びに他に必要なパッケージが一緒にインストールされます。

# apt-get install exfat-utils
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  exfat-fuse fuse libfuse2
The following NEW packages will be installed:
  exfat-fuse exfat-utils fuse libfuse2
0 upgraded, 4 newly installed, 0 to remove and 23 not upgraded.
Need to get 348 kB of archives.
After this operation, 720 kB of additional disk space will be used.
Do you want to continue [Y/n]? y
---------- 中略 ---------- 中略 ----------
Done.
udev active, skipping device node creation.
Setting up exfat-fuse (0.9.7-2) ...
Setting up exfat-utils (0.9.7-2) ...
#

これで環境が整ったので microSDXC をマウントしてみます。

# mount /dev/mmcblk1p1 /mnt
FUSE exfat 0.9.7
# mount | fgrep /mnt
/dev/mmcblk1p1 on /mnt type fuseblk (rw,nosuid,nodev,relatime, user_id=0,group_id=0,allow_other,blksize=4096)
# df -h /mnt/.
Filesystem      Size  Used Avail Use% Mounted on
/dev/mmcblk1p1   60G   26M   60G   1% /mnt
#

マウントできたので、簡単に読み書きしてみます。

# cd /mnt
# ls
# touch test
# ls
test
# ls -l test
-rwxr-xr-x 1 root root 0 Feb 24 15:39 test
#

microSDXC を抜く時もアンマウントを忘れないようにしてください。

# umount /mnt

microSDXC を EXT4 形式で使う


microSDXC は exFAT 形式のまま使うには exFAT 形式サポート用のドライバとユーティリティが必要ですが、カード側をカーネルがサポートしているファイル形式に変換してから使う方法もあります。ここでは Linux で標準的な EXT4 形式でフォーマットしてみましょう。

# fdisk /dev/mmcblk1     ← fdisk コマンドでパーテションテーブルを変更する

Command (m for help): p  ← 現在の状態を確認する

Disk /dev/mmcblk1: 63.9 GB, 63864569856 bytes
255 heads, 63 sectors/track, 7764 cylinders, total 124735488 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk1p1           32768   124735487    62351360    7  HPFS/NTFS/exFAT

Command (m for help): t    ← パーテションタイプを変更
Selected partition 1
Hex code (type L to list codes): 83  ← Linux の "83"を指定する
Changed system type of partition 1 to 83 (Linux)

Command (m for help): p   ← 変更結果を確認する

Disk /dev/mmcblk1: 63.9 GB, 63864569856 bytes
255 heads, 63 sectors/track, 7764 cylinders, total 124735488 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk1p1           32768   124735487    62351360   83  Linux

Command (m for help): w   ← 変更を書き込んで fdisk を終了
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

# fdisk -l /dev/mmcblk1   ← 改めて変更結果を確認

Disk /dev/mmcblk1: 63.9 GB, 63864569856 bytes
255 heads, 63 sectors/track, 7764 cylinders, total 124735488 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk1p1           32768   124735487    62351360   83  Linux
#
# mkfs -t ext4 /dev/mmcblk1p1 ← ext4ファイルシステムの作成
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
3899392 inodes, 15587840 blocks
779392 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
476 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

# mount /dev/mmcblk1p1 /mnt ← マウントする
# mount | fgrep /mnt
/dev/mmcblk1p1 on /mnt type ext4 (rw,relatime,data=ordered)
# df /mnt/.
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/mmcblk1p161241372 5306458054356   1% /mnt

まとめ


OpenBlocks IoT EX1 で microSDXC を利用する方法をまとめます。
  • 市販の microSDXC は exFAT 形式でフォーマットされている
  • exFAT 形式はそのままでは Linux のカーネルがサポートしていないため、次のいずれかの対応が必要となる
    • exFAT 形式のドライバとユーティリティーをインストールして利用する
    • microSDXC のフォーマットを EXT4 などのLinux のファイルシステムに変換してから利用する
microSD メモリーカードはシステム運用に十分な信頼性を確保できない為、ファイル交換やログ保存用等の限定用途で利用するのが安全です。

また OpenBlocks IoT BX1, BX3 などでも、USB 二股ケーブルとUSBのメモリカードリーダライタを使って microSDXC を読み書きする場合には、同様の手続きが必要になります。

OpenBlocks IoT Familyをユーザー定義スクリプトと組み合わせて遠隔地へのアクセス手段として利用する

$
0
0
OpenBlocks IoT Family には、モバイル回線での接続が可能なモデルがあります。モバイル回線を使って、遠隔地のアクセス手段にOpenBlocks IoT Familyを利用する方法を紹介します。

OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

はじめに


OpenBlocks IoT Family (以下OpenBlcoks)には、モバイル回線の通信機能があります。IoTゲートウェイとしては多くの場合常時ネットワーク接続手段の一つとして利用しますが、 OpenBlocksではモバイル回線の ON / OFF を SMS のメッセージによって制御する機能が用意されています。つまり通常時は通信していない状態にしておき、必要な時だけ回線を接続できるのです。また SMS を使ってあらかじめ設定しておいたシェルスクリプトを動かす機能もあります。これらのSMSによる制御機能を活用して、遠隔地のネットワークへアクセス手段としての OpenBlocks を利用します。

なお SMS を使って OpenBlocks を制御するためには、SMS に対応した SIM を使う必要があります。データ通信のみの SIM では SMS を扱うことはできませんのでご注意下さい。

リモートアクセス


次の図を見て下さい。



このような環境で、遠隔地からメンテナンスなどでサーバーにアクセスしたいというのはシステムの運用ではごく普通の要望です。

OpenBlocks の中身は Debian GNU/Linux のサーバーですので、遠隔地からOpenBlocksへログインできれば、目的のサーバーやネットワーク機器へアクセスできます。このために SSH (Secure Shell)のトンネルを活用してみます。

SSHポートフォワーディング


SSHにはTCPの接続を中継する機能が用意されています。これはポートフォワーディングやトンネリングと呼ばれます。このSSHのTCPの中継機能を例をあげて説明しましょう。

ある会社のオフィス内にWebサーバー HostA があり、インターネット上にシステム運用者がアクセスできるサーバー HostB がある場合を例にします。オフィスには NAT を使ったファイアウォールが用意されていて、オフィス内部からインターネットへは比較的自由にアクセスできるような設定になっています。この場合以下の図のように HostA から HostB へ SSH を経由してログインするのは広く行われています。



ここでインターネット側にある HostB から HostA に SSH でログインしたい場合どうしたら良いのでしょうか。

前述の通り HostA → HostB は特別な設定を行わなくても SSH で接続できるのは明らかですが、HostB → HostA の SSH 接続はファイアウォールがあることと、HostA がプライベート IP アドレスを利用しているため簡単にはできません。ここで利用するのが SSHによるポートフォワーディングです。

次の図を見てください。



この例は HostA から接続する際に、SSH のポートフォワーディングの設定で、HostB のIPv4 ループバックアドレスである 127.0.0.1 のポート番号 10022 を、HostA の IPv4 ループバックアドレスである 127.0.0.1 の ポート番号 22 つまり HostA の SSH サービスへ接続しています。

具体的には HostA から HostB へ SSH 接続する場合に次のように SSH コマンドに -R オプションを指定して起動します。(注:今回 SSH接続のオプションは全てコマンドの引数で指定していますが、これらは SSH の config ファイルで指定できます)

HostA$ ssh -R 10022:127.0.0.1:22 HostB
..........
.....
..........
HostB$ 

SSH で HostA から HostB へログインできたら、前述のポートフォワーディングが設定できています。この状態になれば HostB 側で 次のように IPv4 アドレスで 127.0.0.1 ポート番号 10022 に接続する ssh コマンドを実行すると、HostA へログインできます

HostB$ ssh -p 10022 127.0.0.1
..........
.....
..........
HostA$ 

リモートアクセスのための SSH の設定


SSH ポートフォワーディングを理解できたところで、OpenBlocks を設定してみます。前述の例で HostA が OpenBlocks となります。

まずは OpenBlocks で SSH ログイン認証のための鍵を作ります。機械的なログインに利用するため、パスフレーズは空にします。

root@obsiot:~# ssh-keygen -t ecdsa -N "" -C "Remote Access for BX1"
Generating public/private ecdsa key pair.
Enter file in which to save the key (/root/.ssh/id_ecdsa):
Your identification has been saved in /root/.ssh/id_ecdsa.
Your public key has been saved in /root/.ssh/id_ecdsa.pub.
The key fingerprint is:
13:4d:49:02:63:b6:e5:ac:2b:77:c3:46:bb:d1:63:42 Remote Access for BX1
The key's randomart image is:
+--[ECDSA  256]---+
|      =.o.o.     |
|     o * +.      |
|      . + .      |
|       . .       |
|      . E        |
|       = +       |
|    . o O +      |
|     o o * .     |
|        .        |
+-----------------+
root@obsiot:~#
root@obsiot:~# ls -l .ssh/id_ecdsa*
-rw------- 1 root root 227 Mar 29 11:43 .ssh/id_ecdsa
-rw-r--r-- 1 root root 183 Mar 29 11:43 .ssh/id_ecdsa.pub
root@obsiot:~#

この鍵を HostB との間でログインに使うため、authorized_keys を設定します。

root@obsiot:~# cat .ssh/id_ecdsa.pub  >> .ssh/authorized_keys

またこの鍵のペアを HostB の SSH でログインするユーザー(ここでは tunuser )の ~/.ssh ディレクトリに設定します。

tunuser@HostB$ ls -l .ssh
total 8
-rw-------  1 tunuser wheel  227 Mar 29 11:43 id_ecdsa
-rw-r--r--  1 tunuser wheel  183 Mar 29 11:43 id_ecdsa.pub
tunuser@HostB$ cp .ssh/id_ecdsa.pub .ssh/authorized_keys
tunuser@HostB$ ls -l .ssh
total 12
-rw-r--r--  1 tunuser wheel  183 Mar 29 12:22 authorized_keys
-rw-------  1 tunuser wheel  227 Mar 29 11:43 id_ecdsa
-rw-r--r--  1 tunuser wheel  183 Mar 29 11:43 id_ecdsa.pub
tunuser@HostB$ 

以上が設定できたら OpenBlocks から HostB にログインできるかどうかを確認しみます。この時一緒にポートフォワーディングも指定しています。(注:OpenBlocks をインターネットへ接続した状態で実験しています)

root@obsiot:~# ssh -R 10022:127.0.0.1:22 tunuser@HostB
The authenticity of host 'HostB (XXX.XXX.XXX.XXX)' can't be established.
ECDSA key fingerprint is d5:5e:df:18:bb:69:8e:e7:91:11:f5:d5:ff:3d:90:c4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'HostB,XXX.XXX.XXX.XXX' (ECDSA) to the list of known hosts.
..........

.....
..........
tunuser@HostB$ 

この通りログインを確認できました。ポートフォワーディングも指定してあるので、HostB 側から OpenBlocks へログインしてみます。(注:OpenBlocks のデフォルトではSSH 接続が閉じているため設定で解放する必要があります)

tunuser@HostB$ ssh -p 10022 root@127.0.0.1
The authenticity of host '[127.0.0.1]:10022 ([127.0.0.1]:10022)' can't be established.
ECDSA key fingerprint is 08:03:4c:2f:35:7b:15:d2:99:b8:42:f5:66:8c:3a:68.
No matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:10022' (ECDSA) to the list of known hosts.
Linux obsiot.example.org 3.10.17-poky-edison #1 SMP PREEMPT Fri Mar 11 12:01:23 JST 2016 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Mar 29 11:07:29 2016
root@obsiot:~#

この通りポートフォワーディングを使って、インターネットにあるサーバー HostB から OpenBlocks へのログインが確認できました。

OpenBlocks の SMS コントロールコマンド(抜粋)


今回のリモートアクセスで利用するSMSコントロールコマンドを以下に挙げます。


コマンド
コマンドの内容
CON
モバイル回線を接続する
COFF
モバイル回線を切断する
SSHON
SSHを解放する
SSHOFF
SSHを閉鎖する
USCR1F
ユーザー定義のシェルスクリプトの1番をフォアグラウンドで実行する

OpenBlocks に設定した SIM の電話番号へ SMS を使ってこれらのコマンドを送ると、コマンドに応じて OpenBlocks が動作します。また SMS のコントロールコマンドは複数を"+"で接続して 1通の SMS で送ることで、連続した動作を指定できます。

例えば、モバイル回線を接続してユーザー定義シェルスクリプトの1番を実行し、モバイル回線を切断するには次のようなコマンドを送ります。

      CON+USCR1F+COFF

OpenBlocks の設定


SMS 制御でリモートアクセスを行うための OpenBlocks の設定の要点をまとめてみます。

  1. 通常時はモバイル回線は接続せず、回線の ON / OFF は SMS で制御する。
  2. モバイル回線が ON になったら SSH で HostB へ接続してポートフォワーディングを有効にするシェルスクリプトを用意する

まず上記 1 を設定します。これは WEB の設定メニューの「ネットワーク」メニューの「基本」タブの下部にある「サービスネットワーク (モバイル回線)」で設定します。



各項目の設定ポイントは次の通りです。
  • [使用設定]は「使用する」を選んでモバイル回線が利用できるようにします。
  • [APN]、[ユーザー名]、[パスワード]、[認証方式]の項目は利用する SIM に合わせて設定します。
  • [自動接続]は OpenBlocks の起動時にモバイル回線を接続するかどうかを設定するもので、通常時はモバイル回線は OFF にしておくので「自動接続しない」を選びます。
  • [SMSコントーロール]は「有効」を選択し、SMS の制御に使う電話番号を登録します。 OpenBlocks ではセキュリティ面から SMS の制御は、登録した電話番号からのみ受け付けるようになっています。

SSHポートフォワーディングを起動するシェルスクリプト


SSHポートフォワーディングを起動するシェルスクリプトは、[拡張]メニューの[スクリプト編集]のタブで、「ユーザー定義スクリプト1」を選んでから内容を入力します。



シェルスクリプトの内容は次の通りです。

#!/bin/sh

ssh -T -R 10022:127.0.0.1:22 tunuser@HostB sleep 600

この ssh コマンドはシェルスクリプトの中で起動するため、ユーザーのインタラクティブなコマンド操作を受け付ける必要はありません。そこで -T オプションを指定して、HostBでの pty を要求しないように設定しています。

ssh コマンドで HostB に対して「sleep 600」を設定します。これは SSH が 600秒間(つまり10分間)接続し、その後 sleep の終了とともに SSH の接続が終了します。何もしないと 10 分間で接続が切れる設定となります。「え?それじゃ 10分間しか SSH 接続が利用できないの?」という心配の必要はありません。SSH のポートフォワーディングでは、ポートフォワーディングの利用中は SSH 接続が切れることはありません。つまりこのスクリプトが起動してから10分以内にポートフォワーディングの接続を使って、HostB から OpenBlocks へログインすれば、そのポートフォワーディング経由のログインセッションが続いている限りSSH 接続も維持されます。

以上の設定が完了したら、OpenBlocksを一旦再起動します。

リモートアクセスを使ってみる


以上の設定が終わったので、実際に試してみましょう。OpenBlocks の SIM の電話番号に対して次の SMS のメッセージを送ります。

     CON+SSHON+USCR1F+SSHOFF+COFF

意味は、(1)モバイル回線を接続、(2)SSH接続を許可、(3)ユーザー定義シェルスクリプト1を実行、(4)シェルスクリプトの終了後SSH接続を不許可にし、(5)モバイル回線を切断、ということになります。

SMS の送信後 40秒ぐらいで OpenBlocks が HostB に SSH 接続を行います。その状態で HostB から以下のコマンドを実行すれば、OpenBlocks へログインできます。

tunuser@HostB$ ssh -p 10022 root@127.0.0.1

実際に試してみると SSH の接続までに 40秒近くかかるため、SSH 接続が成立したタイミングがはっきりしないという難点があることがわかりました。そこで例えばシェルスクリプトを次のように修正すると、tunuser アカウントのホームディレクトリに 「SSHOK」というファイルがあるか無いかで SSH 接続が成立しているかどうか判断できわかりやすくなります。

#!/bin/sh

ssh -T -R 10022:127.0.0.1:22 tunuser@HostB 'touch SSHOK ; sleep 600 ; rm SSHOK'

この他にもシェルスクリプトを工夫することで、HostB が停止している場合は別の HostC へ接続するなど様々なバリエーションが考えられます。

終わりに


SSH ポートフォワーディングは、ここで紹介したものとは逆向きつまり SSH の接続元から接続先へのポートフォワーディングもできます。ちなみに紹介例の向きのポートフォワーディングをリモートフォワード、逆向きをローカルフォワードと言います。本例での HostB から OpenBlocks へ SSH でログインする場合にもポートフォワーディングを併用できるので、サーバーのリモートデスクトップ接続を外部へ中継することなども可能です。

一昔前でしたらリモートアクセスには電話回線を通じてアナログモデムが使われているのが普通で、サーバーやネットワークのメンテナンスを行う人は必ずモデムを所有していました。しかし今ではモデムを所有している人は少なくなりつつあるどころか、モデムそのものの存在すら知らない人が増えているのも事実です。OpenBlocks のこのような使用例はモデムの代替の一つの解になるのではと思います。

OpenBlocks IoT シリーズをMicrosoft Azure IoT Hubへ接続し、Stream Analyticsを経由してPowerBIへデータを受け渡す手順について

$
0
0
OpenBlocks IoT シリーズの基本ソフトウェア 1.0.10より、Azure IoT HubおよびAzure Ivent HubへのWebUIでの接続設定に対応しました。
本記事では、Azure IoT Hubへの接続の手順、および、Stream Analytics jobを経由したPower BIへのデータの受け渡し手順について、解説しています。




OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
ゲートウェイ
 OpenBlocks IoT BX1 Debian wheezy 7.8 / kernel 3.10.17-poky-edison
 IIJmio 高速モバイル/D SIM
センサー
 FWM8BLZ02A-109047 温度/3軸加速度センサービーコン (BLE)
クラウド
 Microsoft Azure

1. 事前準備


・アカウント

Microsft Azureのアカウントが必要です。
Microsoft Azureのサービスポリシーに従って適切に設定してください。

注意点としてはAzure IoT Hubや、Stream Analyticsなどは個人アカウントでも開始できますが、Power BIを使用する場合は、試用であっても学校または職場のアカウントが必要となり、gmailでの個人登録アカウントなどではサインアップできません。
また、職場のアカウントで無料サインアップ出来ない場合は、職場のMS Azure管理権限のある担当に相談してください。

2.Microsoft Azure IoT Hubのデプロイと設定


 Azureアカウントにサインインします。

 

新規メニューより、IoT Hubを検索します。



IoT Hubを選択し、作成を押し、IoTハブのパネルで名前、サブスクリプション、リソースグループ、場所を入力して、作成を押します。
IoTハブ名など、この先でリソース名として受け渡す可能性のあるものには"-"をつけないことをお勧めします。
例えば、Stream Analytics jobのクエリの記述パネルでは"-"は使用できません。

今回の設定例は以下の通り。

名前:
  obxbx1
価格とスケールティア
  S1 - Standard 400kメッセージ/ユニット/日 ( F1 Freeの場合は8kメッセージ/ユニット/日 )
IoT Hub ユニット
  1
Device-to-cloud パーティション
  4パーティション
サブスクリプション
  Microsoft Azure エンタープライズ
リソースグループ
  plathome-goto
場所
  東日本

ダッシュボードにピン留めする場合は、チェックボックスにチェックを入れます。

 

 デプロイが開始されます。



デプロイ完了を確認します。



3.Device Explorerの導入と設定


以下のドキュメントを参考に、導入と設定を進めていきます。

How to use Device Explorer for IoT Hub device

Getting Device Explorerの項目より、以下のDevice Explorerのダウンロードページを開きます

https://github.com/Azure/azure-iot-sdks/releases


ページの最下部にある、Downloadsより、

SetupDeviceExplorer.msi

をダウンロードし、インストールして下さい。

実行すると、以下のパネルが表示されます。



上記で作成した、Azure IoT Hubより、「すべての設定」から、「共有アクセスポリシー」のパネルを呼び出します。



iothubownerを選択します。



接続文字列ープライマリーキーをコピーします。



コピーした文字列を、Device ExplorerのIoT Hub Connection Stringの入力パネルに貼り付け、Updateを押します。



4.OpenBlocks IoT 基本ソフトウェアのWebUI設定

 
WebUIの初期設定、ネットワーク設定、BLEセンサービーコンの登録


OpenBlocks IoT Family向けWEB UIセットアップガイド

に従って設定してください。
今回は富士通コンポーネントの温度/3軸加速度センサー付きのBLEユニットを使用しています。

出力される項目が変わりますが、標準で対応しているセンサー付きのBLE製品としては、FCL製品以外では、CC2650STK/CC2451 Sensor Tagがあります。
また今後他社製品(ALPS/OMRON/他)にも対応予定ですが、ALPS IoT Smart module開発キット(BLE)は8月中旬以降リリース予定の1.0.11で、それ以外のデバイスは1.0.11より先のリリースで対応を予定しています。
アドバタイズデータにセンサーデータを載せるタイプの製品は、データであれば、ビーコン送信機能で送信可能ですが、送信するJSON上のデータが一連のデータ列のままdataとして名前付けされますので、クラウド側で変換する必要があります。

また、基本ソフトウェアのPD Handlerで標準対応している、EnOceanセンサ、Wi-SUNによるBルートでの電力計測データも利用出来ます。EnOceanセンサは変換モードを有効にすることで多くのアーミンセンサでプロファイルに応じてデータを変換可能ですが、対応していないものは変換前のデータのままrawモードでの送信となりますので、クラウド側で変換が必要となります。

カスタムハンドラを作成される場合は、最終的に扱いたいデータの構造でJSON形式の送信データを構成するといいでしょう。

・Azure IoT Hubへの送信設定


以下のドキュメントに従って設定を進めていきます。

OpenBlocks IoT Family向け データ収集ガイド


先に、送信先設定を行います。
MS Azure IoT Hubを「使用する」にチェックし、各項目を設定してください。

インターバル
 収集したデータを送信する間隔です。
 この例ではデータの送信確認のために5秒としています。
 (実際には5分~1時間以上に設定されることが多いと思います)
有効時間
 データ送信できない場合において、保持する時間を設定します。
 0を指定した場合、データ送信が完了するまで保持し続けます。
ドメイン名
 送信するIoT Hubのホスト名を設定します。
 デフォルトでは、azure-devices.net が入力されています。
ポート番号
 送信先のポート番号を設定します。通常は5671から変更する必要はありません。
IoT Hub名
 上記で設定したIoT Hub名を入力します。

デバイス一括設定
 ビーコン及びデバイスの送信対象設定が”送信する”となっている各対象の
 送信先設定を一括で有効/無効を選択できます。



デバイス情報送信設定を行います。
送信対象を、「送信する」にチェックし、各項目を設定してください。

センサー信号強度[dbm]
 センサーに信号強度を設定できる機種の場合、設定したい信号強度を入力します。
 設定した信号強度が無い場合、近似値またはデフォルト値が設定されます。
取得時間間隔[ms]
 センサーからデータを取得する時間間隔を数字で設定します。単位はmsecです。送信先設定
 送信先をチェックします。同時に2か所までの送信が可能です。
 IoT Hubにチェックします。
デバイスID(IoT Hub)
 デバイスIDを設定します。今回はBLEデバイスのMACアドレスを使用しています。

 上記で設定したIoT Hub名を入力します。
デバイスキー
 IoT Hubに送信する際のデバイスキーを設定します。
 今回デバイスキーは下記の手順によりDevice Explorerで取得しています。

デバイスキーの取得方法

Device Explorerの「Management」タブを開き、「Create」ボタンより入力パネルを出し、上記のWebUIにて使用するデバイスIDを入力して「Create」を押します。



「Device Created」と表示されたパネルの文字列をCtrl-A/Ctrl-Cとしてコピーします。



この文字列に含まれる、PrimaryKeyをデバイスキーとしてWebUIの画面で入力し、設定を保存してください。



5.Device Explorerによる通信確認


先に、WebUIの収集ログにより、pd-handler-stdout.logおよびpd-emitter-lite.logを確認して、センサービーコンとの通信確認、およびAzure IoT Hubとの通信確認を行います。

pd-handler-stdout.logの確認



pd-emitter-lite.logの確認




次に、Device Explorerの「Data」タブより「Monitor」ボタンを押して確認してください。




6.Power BIの準備


Power BIにサインイン出来るように、準備をします。
すでに、お使いの方はこの作業は必要ありません。
以下のページより、サインアップを進めてください。



冒頭に書いた通り、職場または学校のアカウントであれば無料でサインアップできます。
無料の使用範囲は、データ容量1GB/ユーザー、ストリーミングデータが10k行/時間となり、グループでのチームコラボレーションは出来ません。
職場のアカウントでサインアップ出来ない場合は、職場の担当者に相談して下さい。




6.Stream Analytics jobのデプロイと設定


Azureのダッシュボードより、Stream Analytics jobを追加します。
 


 作成を押します。

 

ジョブ名、サブスクリプション、リソースグループ、場所を設定し、作成を押します。
今回の設定例は以下の通りです。

名前:
  streamtobi
サブスクリプション
  Microsoft Azure エンタープライズ
リソースグループ
  plathome-goto
場所
  東日本



デプロイを待ちます。



作成済と表示されたのち、ジョブトポロジを設定します。



入力のパネルをクリックし、、「+追加」を押して設定を行います。



入力のエイリアスを入力し、ソースをIoT Hubにすると、各項目は自動的に設定されますので、問題がなければ作成を押してください。(今回は入力のエイリアスはobxbx1と設定しています)



出力のパネルをクリックし、、「+追加」を押して設定を行います。



出力エイリアスを設定して、シンクのメニューよりPower BIを選択します。
今回は、出力エイリアスはpowerbibx1と設定しています。



接続の承認ボタンを押すと、サインイン画面が出ますので、サインインを行うと承認が終了しますので、データセット名とテーブル名を入力して作成を行います。
今回は、データセット名をfclsensor、テーブル名をsensorとしています。



クエリをクリックして、編集し、保存します。



変換などを行わいない場合は、以下のように入出力のエイリアスを設定するだけです。


SELECT
    *
INTO
    powerbibx1
FROM
    obxbx1



全て設定が終了したら、開始ボタンを押すとストリーミングジョブを開始します。







ストリーミングジョブが正常に開始されました、というメッセージを確認してください。



7.Power BIでのデータの確認と表示


Power BIにサインインすると、データセットに設定したデータセット名が表示されています。




表示されたデータセット名を押すと視覚化のメニューが出ます。



温度と時間を選択し、折れ線グラフを表示させてみます。



上記の画面が確認できれば、今回のチュートリアルは終了です。

8.さいごに


サンプル画面数が非常に多い記事となりましたが、Azureでの作業はデプロイ時間が短いこともあり、作業自体は非常に短時間で終わると思います。

とりあえず、tipsとしては"-"を使わない。これにつきます。

OpenBlocks IoT シリーズのAzure Event Hubへの接続について

$
0
0

前回、Azure IoT Hubへの接続の手順、および、Stream Analytics jobを経由したPower BIへのデータの受け渡し手順について、解説しました。
今回は、IoT Hubではなく、Event Hubへ接続する方法について簡単に説明します。
なお、全体の流れは前回の作業に沿って行ったものですので、WebUIでのデバイスの登録や、Stream Analytics、PowerBIの設定についての詳細な説明は行いません。




OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
ゲートウェイ
 OpenBlocks IoT BX1 Debian wheezy 7.8 / kernel 3.10.17-poky-edison
 IIJmio 高速モバイル/D SIM
センサー
 FWM8BLZ02A-109047 温度/3軸加速度センサービーコン (BLE)
クラウド
 Microsoft Azure

2.Microsoft Azure Event Hubのデプロイと設定


Azureアカウントにサインインし、新規メニューより、Event Hubを検索します。



Event Hubを選択し、作成を押しすと、旧ポータルへ飛ばされますので、今回はそのまま旧ポータルで作業を行います。
IoTハブ名など、この先でリソース名として受け渡す可能性のあるものには"-"をつけないことをお勧めします。
例えば、Stream Analytics jobのクエリの記述パネルでは"-"は使用できません。

今回の設定例は以下の通り。

イベントハブ名
  obsevhub
リージョン
  東日本

名前空間は自動で入力されます。 obsevhubというハブ名の場合は、obsevhub-nsとなります。

 

作成が終わって以下の画面から、作成したEvent Hub名をクリックします。

 

共有アクセスポリシーを作成します。
今回はtestという名前とし、権限を設定し、画面下部の「保存」を押します。




共有アクセスキー生成コンポーネントにある、ポリシー名、プライマリーキーを、次の項目で説明する、WebUIのSASキーの項目へ入力します。



Event Hubでの定作業は以上で終了です。

3.OpenBlocks IoT 基本ソフトウェアのWebUI設定


設定の全体の流れは前回の記事を参照してください。
作業として異なるのは、Azure IoT Hubへの送信が、Azure Event Hubへの送信となることです。 

・Azure Event Hubへの送信設定


以下のドキュメントに従って設定を進めていきます。

OpenBlocks IoT Family向け データ収集ガイド


先に、送信先設定を行います。
MS Azure IoT Hubを「使用する」にチェックし、各項目を設定してください。

インターバル
 収集したデータを送信する間隔です。
 この例ではデータの送信確認のために5秒としています。
 (実際には5分~1時間以上に設定されることが多いと思います)
有効時間
 データ送信できない場合において、保持する時間を設定します。
 0を指定した場合、データ送信が完了するまで保持し続けます。
ドメイン名
 送信するIoT Hubのホスト名を設定します。
 デフォルトでは、servicebus.windows.net が入力されています。
名前空間
 上記の管理ポータルで作成された名前空間を使用してください。
ポート番号
 送信先のポート番号を設定します。5670となっていますが、5671としてください。

デバイス一括設定
 ビーコン及びデバイスの送信対象設定が”送信する”となっている各対象の
 送信先設定を一括で有効/無効を選択できます。




デバイス情報送信設定を行います。
送信対象を、「送信する」にチェックし、各項目を設定してください。

センサー信号強度[dbm]
 センサーに信号強度を設定できる機種の場合、設定したい信号強度を入力します。
 設定した信号強度が無い場合、近似値またはデフォルト値が設定されます。
取得時間間隔[ms]
 センサーからデータを取得する時間間隔を数字で設定します。単位はmsecです。送信先設定
 送信先をチェックします。同時に2か所までの送信が可能です。
 Event Hubにチェックします。
Event Hub名
 Event Hub名を設定します。今回はobsevhubとなっています。
SASポリシー
 管理ポータルで作成した共有アクセスポリシーの名前を入力します。
SASキー
 管理ポータルで作成された共有アクセス生成キーコンポーネントよりプライマリーキーを
 コピーし、入力します。




保存を押し、収集ログタブにて、Event Hubへデータが送信されていることを確認してください。



4.Stream Analytics jobの設定について


前回との変更点として、入力がIoT HubからEvent Hubになり、リソース名も変わります。
また、サービス名を変更した場合は、クエリのFROMの記述も変更します。

5.Power BIでのデータの確認と表示


Power BIにサインインすると、データセットに設定したデータセット名が表示されています。
以下の画面では、Stream Analyticsでデータセット名を変えていますので、前回と違うデータセットが表示されています。





上記の画面が確認できれば、今回のチュートリアルは終了です。

6.さいごに


今回は、Event Hubへ変更した部分だけを説明しました。
WebUIでのポート番号だけは5671であることをご確認ください。



[.tested][IoT] Omron ヒューマンビジョンコンポ (HVC-P2) 評価用カスタムハンドラ

$
0
0
Omron HVC-P2は、人の状態を認識できる画像センサモジュールです。


HVC-P2|HVC(Human Vision Components )シリーズ|製品ラインナップ|オムロン人画像センシングサイト:+SENSING

SwapImage





OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
OpenBlocks IoT BX1/EX1/VX1 基本ソフトウェア Ver2.11 / kernel 3.10.17-poky-edison

githubに評価用ソースコードをcommitしましたので、ご利用ください。
本コードは、IoT基本ソフトウェア向けのカスタムハンドラとして動作します。
ユーザハンドラを定義して、WebUIにて送信先などの設定を行ってください。
すでに別のカスタムハンドラをご利用の場合は、ソースコードのunix domain socket名を変更する必要があります。

https://github.com/goto2048/hvcp2_for_openblocksiot


・注意点

OpenBlocks IoT BX1で使用する場合、内蔵のモデムが/dev/ttyACM0から始まるモデムデバイスとなります。
HVC P2も同様にttyACMxxというデバイスとして認識されるため、udev等で/dev/ttyACM7に固定しないと、本デバイスが先に認識される関係で、3G通信が出来なくなる可能性があります。
他のIoTシリーズで使用される場合は、dmesgでデバイス名の確認をし、SERIAL_PORTを変更してください。


顔認識の最大数は35ですが、35人分のjasonデータはopenblocks iotがWebUI設定により送信出来るペイロードのサイズ(4KB)を超えますので、適宜、最大数を設定する/コードで定義したkey名を短くするなどのパッチを当ててください。

評価用として、gotoがquick hackしたものですので、未サポートとなります。



OpenBlocks IoTシリーズ 基本ソフトウェアにより提供されるPLCクライアント(Modbus)機能について

$
0
0
PLCクライアント(Modbus)機能は、OpenBlocks IoT 基本ソフトウェア2.12より大幅に機能追加されました。

主として以下の項目があげられます。

・データタイプとして、符号のありなし、データサイズ(16bit/32bit)、ビッグ/リトルエンディアンの設定を追加
・データ取得の基準時刻の設定
・CSVファイルを用いた取得PLC対象の拡張

本機能の実装により、1入出力インタフェーズに対し、複数のデバイス、レジスタが割り付けられる場合に、基準時刻を指定してまとめてデータを取得することが可能となり,例えば、RS-485インタフェースに接続される複数のデバイスや、無線メッシュであるOKI SmartHopのRS-232C経由のmodbusペイロードなどでも、1つのデバイスインタフェースから複数個所のデータ(温度や電力データなど)を一定時間にまとめて取得出来るようになります。



今回は、本機能の設定方法について、紹介を行います。
内容に関しては、OpenBlocks IoTシリーズデータ収集ガイドからの抜粋となりますので、詳細に関しては以下のドキュメントをご参照ください。



・PLCクライアント(マスター)の設定方法


本機能は、OpenBlocks IoT Family から Modbus プロトコルを用いて PLC 機器のレジスタ、コイルもしくはステータスを用いて定期的に読み込む(ポーリングを行う)場合に用います。










WEB UI の「サービス」→「基本」タブにおいて、「PD Handler PLC Client」 が「使用する」に設定されている場合、同タブの「取得
PLC 対象数」に応じた入力フォームが表示されます。

※「取得 PLC 対象」(PLC デバイス)とは、PLC 機器そのものではなく、対象となる PLC機器への接続方法の他、データを取得するため
の「読込方法」や「読込開始アドレス」、「読込レジスタ数」等の設定の組み合わせを意図します。
PLC デバイス毎に送信対象項目にて”送信する”を選択すると、PLC デバイスの送信設定の詳細を設定できます。

※「使用プロトコル」としてModbus TCP(ネットワーク)を選択した場合の表示


※「使用プロトコル」としてModbus RTUを選択した場合の表示



”送信する”を選択した場合には、左のように各項目が表示されます。

デバイス番号:
OpenBlocks IoT Family の WEB UI 内で管理している番号です。変更はできません。

ユーザーメモ:
PLC デバイスにデータに付加する任意の文字列を設定します。データを処理する際の識別子等に利用して下さい。

読込方法:
「レジスタ」(レジスタ出力)、「入力レジスタ」(レジスタ入力)、「コイル」(ディジタル出力)、「入力ステータス」(ディジタル入力)から選択します。
「コイル」または「入力ステータス」を選んだ場合は、”0”または”1”の並びが出力されます。

データタイプ:
読込方法を「レジスタ」、「入力レジスタ」を選択した際に、出力のデータタイプを以下から選択します。

・符号なし 16 ビット整数
・符号付き 16 ビット整数
・符号なし 32 ビット整数/リトルエンディアン
・符号付き 32 ビット整数/リトルエンディアン
・符号なし 32 ビット整数/ビッグエンディアン
・符号付き 32 ビット整数/ビッグエンディアン

読込開始アドレス:
読み込みたいデータが格納されている PLC 機器上の開始アドレスを設定します。

読込レジスタ数:
「読込方法」として「コイル」または「入力ステータス」は、読み込まれるビット数と解釈されます。
「開始アドレス」に設定されるアドレスから読み込むレジスタ数もしくビット数を設定します。


取得時間間隔[sec]:
PLC デバイスからデータを取得する時間間隔を数字で設定します。単位は秒です
後述の基準時刻制御を使用する場合、時間間隔は以下の値へと内部的に変更されます。

・86400[sec]使整数倍
・43200[sec]
・28800[sec]
・21600[sec]
・14400[sec]
・10800[sec]
・7200[sec]
・3600[sec]
・1800[sec]
・900[sec]
・60[sec]

基準時刻制御:
毎日定時にデータを取得する場合、本機能を有効とし基準時刻を設定しください。

基準時刻:
定時にデータを取得する際の基準時刻を設定します。HH:MM 形式となります。

タイムアウト[msec]:
PLC デバイスからデータを取得する際のタイムアウトを設定します。単位はミリ秒です。

使用プロトコル:
「Modbus TCP」、「Modbus RTU」のいずれかを選択します。
「Modbus TCP」はネットワーク、「ModbusRTU」はシリアルです。

ユニット ID:
PLC 機器の Modbus ユニット ID を設定します。ユニット ID は、1~247 または 255 の数値です。


PLC 接続アドレス(Modbus TCP)
接続する PLC 機器の IP アドレスを設定します。

PLC 接続ポート(Modbus TCP)
接続する PLC 機器の TCP ポート番号を設定します。 デフォルト値は、502 です。

読込デバイスファイル(ModbusRTU)
PLC 機器を接続するシリアルポートのデバイスファイル名を設定します。

ボー・レート(Modbus シリアル):
PLC 機器を接続するシリアルポートのボー・レートを選択します。

パリティビット(Modbus シリアル):
PLC 機器を接続するシリアルポートのパリティビットを選択します。

データビット(Modbus シリアル):
PLC 機器を接続するシリアルポートのデータビット数を選択します。

ストップビット(Modbus シリアル):
PLC 機器を接続するシリアルポートのストップビット数を選択します。

送信先設定:
“使用する”を選択した送信先に対してチェックボックスが選択できるようになります。
チェックを付けたクラウド等に対して、送信を行います。


デバイス ID サフィックス(PD):
PD Exchange に送信する際のデバイス ID のサフィックスを設定します。

クライアント ID (AWSIoT):
AWSIoTに送信する際のクライアント ID を設定します。Thing Shadows を使用する場合、クライアント ID が Thing Name となります。

Thing Shadows(AWSIoT):
AWSIoT に送信する際の Thing Shadows を使用するかの設定を選択します。

トピック名(AWSIoT):
AWSIoT に送信する際のトピックを設定します。Thing Shadows を使用する場合、トピックはクライアントIDをThing Nameとして自動生成されます。

証明書(AWSIoT):
AWSIoT に送信する際に使用するデバイスの証明書を設定します。

プライベートキー(AWSIoT):
AWSIoT に送信する際に使用するデバイスのプライベートキーを設定します。

デバイスタイプ(Watson IoT/Device):
Watson IoT(Device)に送信する際のデバイスタイプを設定します。

デバイス ID(Watson IoT/Device):
Watson IoT(Device)に送信する際のデバイスID を設定します。

パスワード(Watson IoT/Device):
Watson IoT(Device)に送信する際のパスワードを設定します。

デバイスタイプ(Watson IoT/Gateway):
Watson IoT(Gateway)に送信する際のデバイスタイプを設定します。


デバイス ID(Watson IoT/Gateway):
Watson IoT(Gateway)に送信する際のデバイス ID を設定します。

Event hubs 名:
Event hubs に送信する際の Event hubs 名を設定します。

SAS ポリシー:
Event hubs に送信する際の SAS ポリシーを設定します。

SAS キー:
Event hubs に送信する際の SAS キーを設定します。

デバイス ID(IoT Hub):
IoT Hubに送信する際のデバイス ID を設定します。

デバイスキー(IoT Hub):
IoT Hub に送信する際のデバイスキーを設定します。

Gatway Name(T4D):
Toami for docomo に送信する際に用いるGateway Name を設定します。

App key(T4D):
Toami for docomo に送信する際に用いる AppKey を設定します。

イベントタイプ(IoT デバイスハブ):
IoT デバイスハブ(Nifty)に送信する際に用いるイベントタイプを設定します。

デバイス ID(IoT デバイスハブ):
IoT デバイスハブ(Nifty)に送信する際に用いるデバイス ID を設定します。

API キー(IoT デバイスハブ):
IoT デバイスハブ(Nifty)に送信する際に用いる API キーを設定します。

ユニーク ID (MQTT):
MQTT サーバに送信する際のユニーク ID を設定します。ユニーク ID は、トピックのサフ
ィックスとして扱われます。トピックのプレフィックスは、MQTT サーバに設定されるトピ
ックプレフィックスです。プレフィックスとサフィックスの間は '/'で区切られ送信されます。

※一部を除くクラウドに紐付く設定情報は編集ボタンにより編集可能になります。既存の
デバイス不良等の差し替え時に以前のものと同様に扱う為に設定を同一にすることを推奨
します。(不良となったデバイスは送信対象設定を“送信しない”へ変更してください。)
※証明書及びプライベートキーはシステム→ファイル管理タブからアップロードしてくだ
さい。

・CSV ファイルを用いた「取得 PLC 対象」の拡張


/var/webui/upload_dir ディレクトリに pd-handler-plc-client.csv というファイル名の CSVファイルを置くことで、WEB UI 管理にて割り当てされた 1 デバイス番号に対して複数の「取得 PLC 対象」を割り当てることが可能です。
尚、pd-handler-plc-client.csv ファイルは WEB UI の「システム」→「ファイル管理」タブのアップロード機能により置くことが可能です。
また、CSV ファイルの書式は、次の通りです。

デバイス番号,ユニット ID,読込方式,データタイプ,読込開始アドレス,読込レジスタ数

※行の先頭が#または/の場合、コメント行として扱います。
※CSV 内の”等での動作は保証いたしません。

パラメタデータの形式説明
デバイス番号半角英数字WEB UIによりれたデバイス番号記載します
WEB UIに設定されていないデバイス番号無視されます
ユニット番号半角英数字PLC機器のModbusユニットIDを設定します。
ユニットIDは、1~247 または 255 を記載します。
方式半角英数字読込方式として、以下のいずれかを記載します
設定内容Web UI表記
bitsコイル
input_bits入力ステータス
registerレジスタ
input_register入力レジスタ
データタイプ半角英数字データタイプとして以下設定してください
なお、読込方式を"bits"または"input_bits"を設定した場合カラムは無視されます
設定内容WEB UI表記
u_int16符号なし16ビット整数
int16符号き16ビット整数
u_int32lsb符号なし32ビット整数
リトルエイディアン
int32lsb符号き32ビット整数
リトルエイディアン
u_int32msb符号なし32ビット整数
ビッグエイディアン
int32msb符号き32ビット整数
ビッグエイディアン
読込開始アドレス半角英数字みたいデータが格納されているPLC機器開始アドレスを設定します。先頭が"0x"の場合は16進数解釈されます
読込レジスタ半角数字みたいレジスタ記載します。


・記載例

#localname,unit_id,read_function,data_type,read_addr,read_registers
device_plc_client_0000001,15,bits,u_int16,0x130,37
device_plc_client_0000001,15,input_bits,u_int16,0x1c4,22
device_plc_client_0000001,15,registers,u_int16,0x160,3
device_plc_client_0000001,16,input_registers,u_int32lsb,0x108,1
device_plc_client_0000002,17,bits,u_int16,0x130,37
device_plc_client_0000002,18,input_bits,u_int16,0x1c4,22
device_plc_client_0000002,19,registers,int16,0x160,3
device_plc_client_0000002,20,input_registers,int32lsb,0x108,1
device_plc_client_0000003,30,bits,u_int16,0x130,37
device_plc_client_0000003,30,input_bits,u_int16,0x1c4,22
device_plc_client_0000003,31,registers,u_int16,0x160,3
device_plc_client_0000003,31,input_registers,u_int32msb,0x108,1
device_plc_client_0000004,32,bits,u_int16,0x130,37
46/80
device_plc_client_0000004,32,input_bits,u_int16,0x1c4,22
device_plc_client_0000004,33,registers,int16,0x160,3
device_plc_client_0000004,33,input_registers,int32msb,0x108,1

CSV ファイルに定義したデバイス番号の「取得 PLC 対象」は、WEB UI の設定内容(CSVの定義内容)は破棄され、CSV ファイルの内容が使用されます。そのため、CSV ファイルに定義したデバイス番号の設定ついては、1 デバイス番号として取得対象とする全ての「取得PLC 対象」を記載してください。


最後に


今回の機能強化は、ビルや、工場などでの環境測定や、機器データの取得に際し、必要と思われるものをほぼ実装した形となります。
当社IDMアプライアンスなどと合わせてご利用いただき、環境測定やモニタリングシステムの構築に役立てていただければと思います。

OpenBlocks IoT FW3.xシリーズで下流方向の制御を行うハンドラの設定とテンプレート (C言語)

$
0
0
OpenBlocks IoT VX2およびVX1では、基本ソフトウェアとしてFW3.xが用意されます。
FW3.xシリーズでは、2.xシリーズの各機能に加え、以下のようなアップデートが行われています。

・メッセージの完全な双方向化
・Dockerに対応。エッジ処理モジュールをDockerコンテナで提供可能
・エッジ処理のみをNode-REDでも記述可能
・Luaによるデバイスハンドラ記述が可能
・Node-REDの最新環境を提供し、カスタマイズを容易に

Firmware 3.0 Architecture
Firmware 3.0 Architecture スタック

今回は、FW3.xで実装された、メッセージの双方向化における、下流方向のデータを用いたデバイスハンドラについて、まずは、C言語による記述と、設定方法について簡単に解説します。

メッセージの完全な双方向化に関しての詳細な情報は以下のドキュメントをご覧ください。

OpenBlocks IoT Family データハンドリングガイド

OpenBlocks IoT Family データハンドリング設定リファレンスガイド

先にご理解いただきたいのですが、メッセージの双方向化に関しては、現在は、
MQTT系の接続サービス、TCP接続、当社PD Exchangeとの接続、当社独自仕様のWebサーバーのみでご利用いただけます。対応の詳細に関しましては、上記ドキュメントを参照してください。

OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。


1.Userデバイスの作成と送受信設定


Userデバイスの作成
 サービスメニューより、基本機能、Userデバイスタブ、の順に選択します。
ユーザーメモを入力し、保存すると、一覧に作成したUserデバイスが表示されます。

送受信設定
サービスメニューより、IoTデータ、送受信設定の順に選択します。
今回は、例としてAzure IoT Hubへの送受信設定を行っています。


 上記、送受信の設定を行った後、Userデバイスに対してのデバイス設定を行います。
デバイス設定メニュー内の送受信設定にて、iothubにチェックを入れ、接続に必要なデバイスIDおよびデバイスキーを入力します。
なお、Azure IoT Hubへの接続方法に関しては、以下のOBDNマガジンの記事にて解説を行っています。

OpenBlocks IoT シリーズをMicrosoft Azure IoT Hubへ接続し、Stream Analyticsを経由してPowerBIへデータを受け渡す手順について

下流方向への制御を行うには、「受信設定」を「有効」にします。
制御に使用する、Unixドメインソケットは、作成したデバイス番号より生成されます。

2.送受信に使用するUnixドメインソケット

制御メッセージの送受信に使用するUnixドメインソケットは、データハンドリングガイドにて解説しています。

PD Repeaterからの下流方向

¥0/pd_handler/<デバイス番号>.sock

PD Repeaterへの上流方向


¥0/pd_repeater/<デバイス番号>.sock

今回の設定例では、デバイス番号はuserdev_0000001となります。

3.Cで記述した下流方向制御アプリケーションのサンプル

本サンプルは、Cで記述した下流方向制御アプリケーションのサンプルです。
PD Repeater側がクライアントとなり、下流方向の制御アプリケーションはUnixドメインソケットを使うサーバ側の実装となります。
本プログラムは下流制御機能の評価用に作成されたもので、Userデバイスとして定義されるUnixドメインソケットのuserdev_0000000からuserdev_0000031までをポーリングして受信したデータを表示します。

# apt-get update
# apt-get install libssl-dev

インストールされていないならば、libssl-devパッケージをインストールし、

# make rd_header

シンプルにmakeしてください。

/*
 *  Copyright (c) 2018
 *       Plat'Home CO., LTD. <support@plathome.co.jp>. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Plat'Home CO., LTD. nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/select.h>
#include <openssl/md5.h>
#ifdef __linux__
#include <sys/epoll.h>
#endif

#define N_DEVICE 32
#ifdef __linux__
#define ROOT_PATH"/pd_handler"
#else
#define ROOT_PATH"/tmp/pd_handler"
#endif
#define LOCALNAME"userdev_"

#define SOCKET_BUF4096

#ifdef __linux__
#define MAX_SOCKET_CONN 512
#else
#define MAX_SOCKET_CONN 64
#endif

#define SELECT_TIMEOUT0
#define SELECT_UTIMEOUT1
#define EPOLL_WAIT1

struct s_socket_t {
int fd;
struct sockaddr_un addr;
};

struct c_socket_t {
unsigned charid;
int fd;
struct sockaddr_un addr;
};

int main(int argc,char *argv[])
{
int i,j,k,m,n,rc;
char *buf, *socket_buf, *msg_buf;

#ifdef __linux__
int num_fd, epfd;
struct epoll_event ev;
struct epoll_event events[MAX_SOCKET_CONN];
int fcntl_flag;
#else
struct timeval timeout;
fd_set rd_set, rd_set_orig;
#endif
struct timeval tv;
socklen_t len;
struct s_socket_t *ss[N_DEVICE];
struct c_socket_t *cs[MAX_SOCKET_CONN - N_DEVICE];
u_int16_t topic_size;
char *p, *topic, *topic_p, *msg_buf_p;
unsigned char pl;
unsigned char ph;
unsigned char cloud_id, sub_id;
unsigned char md5[MD5_DIGEST_LENGTH];
char hash[MD5_DIGEST_LENGTH * 2 + 1];

buf = (char *)malloc(sizeof(char)*BUFSIZ);
if(!buf) {
perror("buf = malloc()");
exit(1);
}

socket_buf = (unsigned char *)malloc(sizeof(unsigned char)*SOCKET_BUF);
if(!socket_buf) {
perror("socket_buf = malloc()");
exit(1);
}

msg_buf = (unsigned char *)malloc(sizeof(unsigned char)*SOCKET_BUF);
if(!msg_buf) {
perror("msg_buf = malloc()");
exit(1);
}

topic = (char *)malloc(sizeof(char)*BUFSIZ);
if(!topic) {
perror("socket_buf = malloc()");
exit(1);
}

#ifdef __linux__
if ((epfd = epoll_create(MAX_SOCKET_CONN)) < 0) {
perror("epfd = epoll_create()");
exit(1);
}
#else
FD_ZERO(&rd_set_orig);
#endif

for(i=0;i<N_DEVICE;i++) {
ss[i] = (struct s_socket_t *)malloc(sizeof(struct s_socket_t));
if(!ss[i]) {
perror("ss[] = malloc()");
exit(1);
}
memset(ss[i], 0, sizeof(struct s_socket_t));

ss[i]->fd = socket(AF_UNIX, SOCK_STREAM, 0);
ss[i]->addr.sun_family = AF_UNIX;
#ifdef __linux__
snprintf(ss[i]->addr.sun_path + 1,sizeof(ss[i]->addr.sun_path) - 1,"%s/%s%07d.sock",
ROOT_PATH, LOCALNAME, i);
unlink(ss[i]->addr.sun_path);

rc = bind(ss[i]->fd, (struct sockaddr *)&ss[i]->addr, sizeof(sa_family_t) + strlen(ss[i]->
addr.sun_path + 1) + 1);
#else
snprintf(ss[i]->addr.sun_path,sizeof(ss[i]->addr.sun_path),"%s/%s%07d.sock",
ROOT_PATH, LOCALNAME, i);
unlink(ss[i]->addr.sun_path);

rc = bind(ss[i]->fd, (struct sockaddr *)&ss[i]->addr, sizeof(ss[i]->addr));
#endif
if (rc) {
snprintf(buf,sizeof(char)*BUFSIZ,"failed to bind(%s)",ss[i]->addr.sun_path);
perror(buf);
exit(1);
}

rc = listen(ss[i]->fd, N_DEVICE);
if (rc) {
snprintf(buf,sizeof(char)*BUFSIZ,"failed to listen(%s)",ss[i]->addr.sun_path);
perror(buf);
exit(1);
}

#ifdef __linux__
memset(&ev, 0, sizeof(struct epoll_event));
ev.events = EPOLLIN;
ev.data.fd = ss[i]->fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, ss[i]->fd, &ev);
#else
FD_SET(ss[i]->fd,&rd_set_orig);
#endif
printf("listen %s/%s%07d.sock\n", ROOT_PATH, LOCALNAME, i);
}

for(i=0;i<(MAX_SOCKET_CONN - N_DEVICE);i++) {
cs[i] = (struct c_socket_t *)malloc(sizeof(struct c_socket_t));
if(!cs[i]) {
perror("cs[] = malloc()");
exit(1);
}
memset(cs[i], 0, sizeof(struct c_socket_t));
cs[i]->fd = -1;
}

while(1) {
#ifdef __linux__
num_fd = epoll_wait(epfd, events, MAX_SOCKET_CONN, EPOLL_WAIT);
for(i=0;i<num_fd;i++) {
n=1;
for (j = 0; j < N_DEVICE; j++) {
if (events[i].data.fd == ss[j]->fd) {
for(k=0;k<(MAX_SOCKET_CONN - N_DEVICE);k++) {
if(cs[k]->fd == -1) {
break;
}
}
if(k == (MAX_SOCKET_CONN - N_DEVICE)) {
printf("exceeded maximum fd(%d) for accept()", MAX_SOCKET_CONN - N_DEVICE);
}
else {
len = sizeof(cs[k]->addr);
cs[k]->fd = accept(ss[j]->fd, (struct sockaddr *)&cs[k]->addr, &len);
if (cs[k]->fd != -1 ) {
cs[k]->id = j;
fcntl_flag = fcntl(cs[k]->fd, F_GETFL, 0);
fcntl(cs[k]->fd, F_SETFL, fcntl_flag | O_NONBLOCK);
memset(&ev, 0, sizeof(struct epoll_event));
ev.events = EPOLLIN;
ev.data.fd = cs[k]->fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, cs[k]->fd, &ev);
}
}
n = 0;
}
}
if(n) {
for(j=0;j<(MAX_SOCKET_CONN - N_DEVICE);j++) {
if ( events[i].data.fd == cs[j]->fd ) {
memset(socket_buf, 0, sizeof(char)*SOCKET_BUF);
rc = read(cs[j]->fd,(char *)socket_buf,SOCKET_BUF);
if(rc > 0) {
p = socket_buf;
cloud_id = *p++;
sub_id = *p++;
pl = (unsigned char)*p++;
ph = (unsigned char)*p++;
for(m=0;m<MD5_DIGEST_LENGTH;m++)
md5[m] = (unsigned char)*p++;
for(m=0; m<MD5_DIGEST_LENGTH;m++)
snprintf(hash + m + m, sizeof(char)*3, "%.2x", md5[m]);
topic_size = (u_int16_t)((ph & 0x00ff) * 256 + (pl & 0x00ff));
topic_p = topic;
for(m=0;m<topic_size;m++)
*topic_p++ = *p++;
*topic_p = 0x00;
msg_buf_p = msg_buf;
while(*p != 0x00)
*msg_buf_p++ = *p++;
*msg_buf_p = 0x0;
printf("subscrib: topic_size=%d topic=%s payload=%s md5=%s\n",
topic_size, topic, msg_buf, hash);
}
epoll_ctl(epfd, EPOLL_CTL_DEL, cs[j]->fd, &ev);
shutdown(cs[j]->fd,SHUT_RDWR);
close(cs[j]->fd);
cs[j]->fd = -1;
}
}
}
}
#else
timeout.tv_sec = SELECT_TIMEOUT;
timeout.tv_usec = SELECT_UTIMEOUT;

memcpy(&rd_set,&rd_set_orig,sizeof(rd_set_orig));

if(select(FD_SETSIZE,&rd_set,(fd_set *)NULL,(fd_set *)NULL,&timeout) == -1) {
perror("select()");
exit(1);
}

for(i=0;i<FD_SETSIZE;i++) {
if(FD_ISSET(i, &rd_set)) {
n=1;
for(j=0;j<N_DEVICE;j++) {
if ( i == ss[j]->fd ) {
for(k=0;k<(MAX_SOCKET_CONN - N_DEVICE);k++) {
if(cs[k]->fd == -1) {
break;
}
}
if(k == (MAX_SOCKET_CONN - N_DEVICE)) {
printf("exceeded maximum fd(%d) for accept()", MAX_SOCKET_CONN);
}
else {
len = sizeof(cs[k]->addr);
cs[k]->fd = accept(i, (struct sockaddr *)&cs[k]->addr, &len);
if (cs[k]->fd != -1 ) {
setsockopt(cs[k]->fd, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(struct timeval));
FD_SET(cs[k]->fd, &rd_set_orig);
cs[k]->id = j;
}
}
n = 0;
}
}
if(n) {
for(j=0;j<(MAX_SOCKET_CONN - N_DEVICE);j++) {
if (i == cs[j]->fd ) {
memset(socket_buf, 0, sizeof(char)*SOCKET_BUF);
rc = read(i,(char *)socket_buf,SOCKET_BUF);
if(rc > 0) {
p = socket_buf;
cloud_id = *p++;
sub_id = *p++;
pl = (unsigned char)*p++;
ph = (unsigned char)*p++;
for(m=0;m<MD5_DIGEST_LENGTH;m++)
md5[m] = (unsigned char)*p++;
for(m=0; m<MD5_DIGEST_LENGTH;m++)
snprintf(hash + m + m, sizeof(char)*3, "%.2x", md5[m]);
topic_size = (u_int16_t)((ph & 0x00ff) * 256 + (pl & 0x00ff));
topic_p = topic;
for(m=0;m<topic_size;m++)
*topic_p++ = *p++;
*topic_p = 0x00;
msg_buf_p = msg_buf;
while(*p != 0x00)
*msg_buf_p++ = *p++;
*msg_buf_p = 0x0;
printf("subscrib: topic_size=%d topic=%s payload=%s md5=%s\n",
topic_size, topic, msg_buf, hash);
}
shutdown(i,SHUT_RDWR);
close(i);
FD_CLR(i,&rd_set_orig);
cs[j]->fd = -1;
}
}
}
}
}
#endif
}
}




4.[補足] Cで記述したPD Repeaterへの上流方向へのデータ送信

他の記事で上流方向へデータを送信するカスタムハンドラについて記述していますが、FW3.xでの書き込み方法としては、以下のコードを参考にしてください。

#include<stdio.h>
#include<string.h>
#include<stdint.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<termios.h>
#include<unistd.h>
#include<time.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<errno.h>

/*
write data to unix domain socket */
write_uds( uint8_t *jbuf ) {
    int uds, ret;
    socklen_t socklen;
    struct sockaddr_un addr;

    uds = socket(AF_UNIX, SOCK_STREAM, 0);
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strcpy(addr.sun_path+1, "/pd_repeater/userdev_0000001.sock");
    socklen =  sizeof(sa_family_t) + strlen(addr.sun_path+1)+1;
    ret = connect(uds, (struct sockaddr *)&addr, socklen);

    if (ret < 0) {
        int err = errno;
        printf("connect NG (errno: %d)\n", err);
       close(uds);
       return 1;
    }
    else {
        printf("connect OK\n");
    }
    write(uds, jbuf, strlen(jbuf));
   
    close( uds );
    return 0;
}

5.さいごに

下流方向の制御に関して、PD Repeaterがクライアントであり、制御アプリケーションはサーバとしての実装が必要になります。

また、WebUIに連動して、起動、停止を行うためには、プロセスを外部から制御する実装を行ってください。





[VX2] Movidius Neural Compute Stick (Myriad2) NCSDK2の導入方法

$
0
0
Movidius Neural Compute Stickは、VPUと呼ばれる、ディープラーニング推論のためのアクセラレータです。
本製品は、Movidius Myriad2 VPUを使用したもので、開発用としてUSBスティックタイプのものが用意されています。

今回の記事は、本製品のSDKである、NCSDKの最新バージョンである、V2.04をOpenBlocks IoT VX2(VX1)で利用するためのTipsとなります。

Intel® Movidius | Neural Compute Stick | AI Programming



OBDN技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

<検証環境>
OpenBlocks IoT VX2 FW3.1



1. ncsdk2のインストール

ncsdk v2のブランチを利用するには、以下のように指定します。

git clone -b ncsdk2 https://github.com/movidius/ncsdk.git

先に、ncsdkディレクトリ下で

./install.sh

とするのですが、NCSDKは、Ubuntu16.04またはRasbian9に対応していますが、debian9などの他のディストリビューションには対応していません。
そのため、今回はRasbian9と認識させてインストールさせます。
install.shの以下の部分(30行目以降)に変更を加えます。

#    OS_DISTRO="${DISTRO:-INVALID}"
#    OS_VERSION="${VERSION:-255}"
    OS_DISTRO="raspbian"
    OS_VERSION="91"

このスクリプトが終了したら、apiの下で、

make install

として、sdkをインストールしてください。

・tensorflowについて

インストールは一通り終わりますが、インストールされたpython用のtensorflowはno gpuバージョンであっても、現在配布されているバージョンのモジュールはAVX命令をenableとしてビルドしているため、そのままでは使用できません。
tensorflowは別途SSE2のみでビルドする必要があります。
(VX2でセルフコンパイルをするのはリソース的に厳しいため、他のdebian/amd64のPCなどでwhlファイルを作成することをおすすめします)

bazelを使ったインストールはtensorflowのサイトのfrom Sourcesに従って行います。

Installing TensorFlow from Sources

bazelをAPT repositoryよりインストールした場合は、0.14.1がインストールされますが、tensorflowのサイトサンプルのようにgit checkout r1.0のように指定すると、古いリリースのものがcheckoutされてbazelの古いバージョンのものが必要となります。

git clone https://github.com/tensorflow/tensorflow
cd tensorflow
git checkout v1.9.0

tensorflow-hubなども使えるよう、新しいリリースのものをcheckoutします。
bazelのオプションは今回は以下のように設定しました。

bazel build -c opt --copt=-msse4.2 //tensorflow/tools/pip_package:build_pip_package

ビルド、パッケージ作成、インストールが終わったら、以下のスクリプトがエラーなく動作することを確認してください。

# Python3
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))

ここで、warningが出る場合は以下のモジュールアップデートが必要です。

pip3 install --upgrade h5py

・OpenCVについて

opencvもそのままでは不完全にインストールされるため、別途ソースコードからインストールしなおすか、暫定でpython対応だけでよいならば、

pip3 install opencv-python

としてインストールしてください。

opencvをビルドする場合のcmakeのオプションのサンプルは以下の通りです。

cmake -G "Unix Makefiles" --build . -D BUILD_CUDA_STUBS=OFF -D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF -D BUILD_JASPER=OFF -D BUILD_JPEG=OFF -D BUILD_OPENEXR=OFF \
-D BUILD_PACKAGE=ON -D BUILD_PERF_TESTS=OFF -D BUILD_PNG=OFF -D BUILD_SHARED_LIBS=ON \
-D BUILD_TBB=OFF -D BUILD_TESTS=OFF -D BUILD_TIFF=OFF -D BUILD_WITH_DEBUG_INFO=ON \
-D BUILD_ZLIB=OFF -D BUILD_WEBP=OFF -D BUILD_opencv_apps=ON -D BUILD_opencv_calib3d=ON \
-D BUILD_opencv_core=ON -D BUILD_opencv_cudaarithm=OFF -D BUILD_opencv_cudabgsegm=OFF \
-D BUILD_opencv_cudacodec=OFF -D BUILD_opencv_cudafeatures2d=OFF -D BUILD_opencv_cudafilters=OFF \
-D BUILD_opencv_cudaimgproc=OFF -D BUILD_opencv_cudalegacy=OFF -D BUILD_opencv_cudaobjdetect=OFF \
-D BUILD_opencv_cudaoptflow=OFF -D BUILD_opencv_cudastereo=OFF -D BUILD_opencv_cudawarping=OFF \
-D BUILD_opencv_cudev=OFF -D BUILD_opencv_features2d=ON -D BUILD_opencv_flann=ON \
-D BUILD_opencv_highgui=ON -D BUILD_opencv_imgcodecs=ON -D BUILD_opencv_imgproc=ON \
-D BUILD_opencv_java=OFF -D BUILD_opencv_ml=ON -D BUILD_opencv_objdetect=ON \
-D BUILD_opencv_photo=ON -D BUILD_opencv_python2=OFF -D BUILD_opencv_python3=ON \
-D BUILD_opencv_shape=ON -D BUILD_opencv_stitching=ON -D BUILD_opencv_superres=ON \
-D BUILD_opencv_ts=ON -D BUILD_opencv_video=ON -D BUILD_opencv_videoio=ON \
-D BUILD_opencv_videostab=ON -D BUILD_opencv_viz=OFF -D BUILD_opencv_world=OFF \
-D CMAKE_BUILD_TYPE=RELEASE -D WITH_1394=ON -D WITH_CUBLAS=OFF -D WITH_CUDA=OFF \
-D WITH_CUFFT=OFF -D WITH_EIGEN=ON -D WITH_FFMPEG=ON -D WITH_GDAL=OFF -D WITH_GPHOTO2=OFF \
-D WITH_GIGEAPI=ON -D WITH_GSTREAMER=OFF -D WITH_GTK=ON -D WITH_INTELPERC=OFF -D WITH_IPP=ON \
-D WITH_IPP_A=OFF -D WITH_JASPER=ON -D WITH_JPEG=ON -D WITH_LIBV4L=ON -D WITH_OPENCL=ON \
-D WITH_OPENCLAMDBLAS=OFF -D WITH_OPENCLAMDFFT=OFF -D WITH_OPENCL_SVM=OFF -D WITH_OPENEXR=ON \
-D WITH_OPENGL=ON -D WITH_OPENMP=OFF -D WITH_OPENNI=OFF -D WITH_PNG=ON -D WITH_PTHREADS_PF=OFF \
-D WITH_PVAPI=OFF -D WITH_QT=ON -D WITH_TBB=ON -D WITH_TIFF=ON -D WITH_UNICAP=OFF \
-D WITH_V4L=ON -D WITH_VTK=OFF -D WITH_WEBP=ON -D WITH_XIMEA=OFF -D WITH_XINE=OFF \
-D WITH_LAPACKE=ON -D WITH_MATLAB=OFF ..


・NCSの動作確認

NCSデバイスを認識すると、hello_ncs.pyの結果が以下のように表示されます。

#cd ~/ncsdk/examples/apps/hello_ncs_py
# python3 hello_ncs.py
D: [         0] ncDeviceCreate:221      ncDeviceCreate index 0

D: [         0] ncDeviceCreate:221      ncDeviceCreate index 1

D: [         0] ncDeviceOpen:415        File path /usr/local/lib/mvnc/MvNCAPI-ma2450.mvcmd

I: [         0] ncDeviceOpen:421        ncDeviceOpen() XLinkBootRemote returned success 0

I: [         0] ncDeviceOpen:450        XLinkConnect done - link Id 0

D: [         0] ncDeviceOpen:464        done

I: [         0] ncDeviceOpen:466        Booted 1.1-ma2450 -> VSC

I: [         0] getDevAttributes:287    Device attributes

I: [         0] getDevAttributes:290    Device FW version: 2.4.2450.e4

I: [         0] getDevAttributes:292    mvTensorVersion 2.4

I: [         0] getDevAttributes:293    Maximum graphs: 10

I: [         0] getDevAttributes:294    Maximum fifos: 20

I: [         0] getDevAttributes:296    Maximum graph option class: 1

I: [         0] getDevAttributes:298    Maximum device option class: 1

I: [         0] getDevAttributes:299    Device memory capacity: 522081584

Hello NCS! Device opened normally.
I: [         0] ncDeviceClose:656       closing device

Goodbye NCS! Device closed normally.

NCS device working.



2.ncappzooのv2用ブランチの入手

ncappzooもv2用のブランチが用意されています。
以下のオプションにてgit cloneしてください。

git clone -b ncsdk2 https://github.com/movidius/ncappzoo.git

READMEに従って必要なgraphファイルを作成するとともに、gstreamerなど、要求されるモジュールは別途インストールしてください。

また、opencvは、linuxで利用する場合は、ディスプレイとしてXを使います。
OpenBlocks IoT VX2(VX1)にはディスプレイヘッドはありませんので、Xサーバを別に用意する必要があります。


stream_inferの実行例
( 液晶モニタがmonitorとして認識されている )


3.最後に

ストレージ(eMMC)の制約から、VX2でなくVX1を使う場合は、外付けのUSB HDDなどを使用して環境のビルドを行ってください。
また、セルフビルドを行う場合、以下のようにTMPDIRの設定が必要な場合があります。

export TMPDIR=/var/tmp

なお、本SDKおよびサンプルアプリケーションであるncappzooをインストールしたdockerコンテナを作成しておりますので、別途公開する予定です。

Viewing all 98 articles
Browse latest View live