2018年6月27日水曜日

ラズパイで制御したAlienリーダからAzure IoT Hubに連携してみた

前回、ラズパイでAlienリーダを制御してみました。今回はラズパイからクラウド(Azure)に連携してみようと思います。Azure Web Appsへの連携は前々回やったので、今度はAzure IoT Hubへ連携してみようと思います。

といっても、こちらのドキュメントの通りやるだけです。Microsoft.Azure.Devices.Clientを組み込んでサンプルアプリの通り、JSONでデータを作って送るだけで完成しました。送信部分はこんな感じです。

        private static async void reader_FindTag(object sender, TagEventArgs e)
        {
            var dataPoint = new
            {
                eventName = "FindTag",
                tagID = e.TagID,
            };
            var messageString = JsonConvert.SerializeObject(dataPoint);
            var message = new Message(Encoding.ASCII.GetBytes(messageString));
            await client.SendEventAsync(message);
            Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
        }

実行してみるとこんな感じ。ただログが表示されているだけでよくわかりませんが。


受信側はサンプルにあったもの(read-d2c-messages)をそのまま使いました。上記の送信されたイベントがこんな感じで受信できました。


何やらIoT Hubを使うとクラウドからデバイスに対してコマンドを送れるようなので、クラウドからリーダの制御もできてしまうようです。ただ、リーダのそばで制御したほうがよいこともあるだろうし、そのあたりはバランス感覚が問われそうです。

2018年6月21日木曜日

中国の無人コンビニタグを調べてみた

中国の無人コンビニが話題になっていますが、RFIDを利用するタイプも出てきています。で、うちのメンバーが中国の無人コンビニに行ったときに買ってきたお菓子をお土産に持ってきてくれたので、早速調べてみました。


これ。2元なので40円弱


タグは Impinj の H47 のように見えます。
https://www.amazon.com/Impinj-H47-Rfid-Wet-Inlay/dp/B013QK2JBI

UHFタグは TID を読めばメーカーやモデルがわかるようになっています。ので早速読んでみると、


先頭の8ビットは E2 で Gen2 のタグであることを示しています。で次の12ビットがチップのメーカになっていて、 003 がエイリアン、801 がImpinj とか決まっています。このタグは 801 なので Impinj のチップですね。それ以降がモデル番号になっていて 10C です。

Monza4 のデータシート を参照すると、10C は Monza4E であることがわかりました。ということで正真正銘の H47 モデルタグのようです。

何か変なのが出てくるんじゃないかと大いに期待心配していましたが(笑)普通のタグでした。

2018年6月11日月曜日

ラズパイでAlienリーダを制御してみた

前回、Alienリーダをノンプログラミングでクラウド連携ということで、試してみましたが、Alienリーダだけだと制限があって難しいことが分かりました。そこで、まずはラズパイを使って、Alienリーダを制御できるか試してみたいと思います。

開発環境は、Windows 10+Visual Studio 2017+.NET Core SDK
実行環境は、raspbian+.NET Core runtime
開発言語は、C#。

初めに、Alienリーダに付属のライブラリ「AlienRFID2.dll」がそのまま使えないかをテストしたところ、下記のエラーが発生。

pi@raspberrypi:~/work/HelloAlien/publish $ ./HelloAlien

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.IO.Ports, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.

   at nsAlienRFID2.CAlienComPort2..ctor(Boolean log)
   at nsAlienRFID2.clsReader..ctor(String ipAddress, Int32 port)
   at HelloAlien.Program.Main(String[] args) in C:\Users\hnakano\source\repos\HelloAlien\HelloAlien\Program.cs:line 11
Aborted

ダメだったので、nugetからSystem.IO.Portsをインストールして試したところ、今度は下記のエラー。
pi@raspberrypi:~/work/HelloAlien/publish $ ./HelloAlien

Unhandled Exception:
Unhandled Exception: System.PlatformNotSupportedException: System.IO.Ports is currently only supported on Windows.
   at System.IO.Ports.SerialPort.Dispose(Boolean disposing)
   at System.ComponentModel.Component.Finalize()
Aborted
COMポート使うつもりはないんだけどなあと思いつつ、この方法も断念。

社内のリーダ制御ライブラリにTelnetプロトコルを使って、Alienリーダを制御するクラスがあったので、ちょこっと改変して流用してみたところ、すんなりと読取できるところまで確認できました。


2018年6月7日木曜日

Cloud Tools for Eclipse環境でMavenを使ってGWT+JDOのプロジェクトをビルド&デプロイする

きっかけ:Java8へのマイグレーション

去年辺りから、GAEはjava7をサポートしなくなるので、java8対応してくださいね、というお知らせがGoogleから来ていました。

マイグレーションのページ
https://cloud.google.com/appengine/docs/standard/java/migrating-to-java8
を見ると、appengine-web.xmlにちょっと書き足せばいいだけっぽいので楽勝だなとか思って即対応はせず、先日まで放置していたのですが、いざやってみたら大変でかなり焦りました。

slim3を使用している場合はCloud tools for Eclipseの環境に移行してちょっと直せば終わりみたいな感じで、簡単なようなのですが、私が担当したプロジェクトはslim3は使っておらず、GWT+JDOを使用しており、移行の最中さまざまなエラーが出て、さらに日本語の情報が少なく、かなり苦労しました。

以下、私が都度調べながら実際に行った作業を記します。他にいい方法、あるいは記述自体に間違いがある可能性が充分あるので、(万一参考にするなら)ご注意ください!!

作業開始

元々の開発環境はEclipse Juno (4.2) + Google Plugin for Eclipseです。
これで、フロントエンドはGWT、データベースはJDOを使ったプロジェクトを作っていました。

■appengine-web.xmlに追記
まず、マイグレーションのページに従ってappengine-web.xmlに<runtime>java8</runtime>を追加しました。
で、ビルドすると、xmlのパースエラーが発生しました。
使用しているAppEngineのSDKが1.9.12と(相当)古いせいで、xsdに<runtime>タグが定義されていないせいのようです。
SDKのdocs\appengine-web.xsdを見るとわかりました。

■SDKを新しく
なので現時点で最新のSDK(1.9.63)をダウンロード、これを使用するようにしました。xsdに<runtime>タグがあり、パースエラーにはならず、ビルドとデプロイができました。管理ページのインスタンス情報を見るとjava8となっており、よし完了!と思った
のですが・・・

サイトにアクセスし、Datastoreへアクセスする処理を実行すると、サーバーエラーが発生します。ログを見ると「Persistent class ○○ does not seem to have been enhanced.」と出力されていました。
プロジェクトをクリーンしたりすると解消する、という情報などなどあるものの、何をやっても解消しませんでした。

(これは結局未解決)

■Cloud Tools for Eclipseに移行
そもそも今の環境(Eclipse Juno (4.2) + Google Plugin for Eclipse)は古く、Cloud tools for Eclipseへの移行が推奨されています。
https://cloud.google.com/eclipse/docs/migrating-gpe?hl=ja

古い環境で悩みながらやるよりも、いっそ環境を新しくすれば解決するのでは?という根拠のない予想のもと、上記ページを参照し、新環境を作成しました。

いきなり問題のプロジェクトを新環境に移行するのも怖いので、GWT+JDOを使用するテストプロジェクトを新規作成します。

ビルドしたところエラーなく完了し、Cloud tools for Eclipseによるデプロイも成功しました。これでどうかな、とテストしてみると…

■GWTのモジュールがアップロードされてない?

トップページにアクセスすると、GWTモジュールを使用している部分が真っ白です。ブラウザの開発ツールを使用し詳細を見てみると、xxxx.nocache.jsが404になっています。

nocache.jsはGWTが出力するファイルで、これがどうもアップロードされていないようです。

Cloud tools for Eclipseによるデプロイは、ログが出るものの、基本的にプラグインにおまかせになるので、原因が良くわかりません。ログにも特に変なことは書かれていません。

さらに・・・

■Persistent class ○○ does not seem to have been enhanced.がまた出た

JDOを使用してDatastoreの処理を行う部分を実行すると、サーバーエラー。ログを見ると、旧環境の本物のプロジェクトで出ていたPersistent class ○○ does not seem to have been enhanced.が、このテストプロジェクトでも出ていました。

旧環境で出ていた原因は結局わかりませんでしたが、新環境でこのエラーになる理由はわかりました。

https://cloud.google.com/eclipse/docs/migrating-gpe?hl=ja
の中程に↓という記述があります。
【DataNucleus(JPA & JDO)
Cloud Tools for Eclipse はエンティティ クラスを自動拡張しません。
この機能には Maven を使用することができます。】

そんな…Maven?

■Maven
Mavenとは、で検索するといっぱい情報ありますので詳しくはそちらに譲りますが、要はpom.xmlというファイルにプロジェクト情報、参照ライブラリ、ビルド手順などを記述するタイプのビルドツールです。

pom.xmlをどうやって書けばいいのでしょう。

①App Engine Standard Projectのpom.xmを手に入れる


Cloud tools for Eclipseでプロジェクトを作る際、Create as Maven projectというチェックボックスがあります。デフォルトはOFFですが、ONにして作成すると、プロジェクトのルートディレクトリにpom.xmlが作成されます。

pom.xmlを見るとApp Engineに関する記述がありますが、当然ながらGWTに関する記述はありません。

そこで、、、

②GWTのpom.xmlを手に入れる


GWT Eclipse Plugin (V3)でプロジェクトを作成する際の画面も、よく見るとGenerate a Maven Projectというチェックボックスがあります。(デフォルトはOFF)

ONにして作成すると、GWTに関する記述が含まれたpom.xmlが作成されます。

③datanucleusに関するpom.xmlを手に入れる

そもそもMavenでのデプロイにチャレンジしたのは
【DataNucleus(JPA & JDO)
Cloud Tools for Eclipse はエンティティ クラスを自動拡張しません。
この機能には Maven を使用することができます。】

これが原因です。pom.xmlに、JDOを使用する&エンテティクラスを拡張してくれるよう記述しないといけません。
http://www.datanucleus.org/products/accessplatform_4_1/jdo/maven.html
このあたりを参考にします。

■①+②+③ = pom.xml完成!

Mavenが初めてなので綱渡りな感じだったのですが、なんとか完成しました。概ね①+②+③のpom.xmlを作成した感じです。ビルドするとエラーが出たりしましたが、エラーメッセージで検索して都度微調整しました。(長くなるので割愛)

■Datastoreのインデックスが作られない
サイトにアクセスすると、GWTもDatastoreも使用できます。やった!

しかし、一部処理でエラーが出ます。ログを見ると、そのクエリにはこういうインデックスが必要だよ。という良く見る内容が出ていました。datastore-indexes.xmlは既にそのように書いていて、mvn packageで出来るwarファイルにも含まれているのになぜ?

https://cloud.google.com/appengine/docs/standard/java/config/indexref?authuser=3&hl=ja

datastore-indexes.xmlはApp Engine SDK for Javaに基づくツールで使われる、とのこと。Mavenでビルド、デプロイの際には使われないようです。(ファイル自体が含まれるのは含まれるようですが)

これに関する解決方法は2つあります。
・datastore-indexes.xmlを適用するために、適当なバージョンを指定してCloud tools for Eclipseによるデプロイだけ行う。
・gcloudツールでindex.yamlを使用してインデックスを作成する。
https://cloud.google.com/datastore/docs/tools/?hl=ja#the_development_workflow_using_gcloud