2024年4月26日金曜日

AWSで管理しているLoRA WANデバイスの情報を取得する AWS IoT Wireless

  AWSのIoT Coreでは、LoRA WAN通信のデバイスを登録してデバイスの状態をクラウドから取得することができます。デバイスの登録はコンソール画面から行うのですが、いろいろと面倒なところがあり、これをAPIっぽくカスタムのサイト上で行えるようにしたくなりました。ところが参考となる資料がなかなかないため、ここで紹介します。

必要なパッケージ

using Amazon.IoTWireless.Model;
using Amazon.IoTWireless;
using Amazon.Runtime;

登録しているデバイスの取得

var credentials = new BasicAWSCredentials("YOUR_KEY", "SECRET_KEY");

AmazonIoTWirelessClient client = new AmazonIoTWirelessClient(credentials, Amazon.RegionEndpoint.APNortheast1);

ListWirelessDevicesRequest request = new ListWirelessDevicesRequest(); request.WirelessDeviceType = WirelessDeviceType.LoRaWAN; request.MaxResults = 100;

ListWirelessDevicesResponse response = client.ListWirelessDevices(request);

デバイスの登録

var credentials = new BasicAWSCredentials("YOUR_KEY", "SECRET_KEY");

AmazonIoTWirelessClient client = new AmazonIoTWirelessClient(credentials, Amazon.RegionEndpoint.APNortheast1);

OtaaV1_0_x otaa = new OtaaV1_0_x() {

    AppKey = appkey,     AppEui = appeui };

LoRaWANDevice lora = new LoRaWANDevice {     OtaaV1_0_x = otaa,     DevEui = deveui,     DeviceProfileId = deviceprofileid,     ServiceProfileId = serviceprofileid };

CreateWirelessDeviceRequest request = new CreateWirelessDeviceRequest {     Name = devname,     LoRaWAN = lora,     DestinationName = destination,     Type = WirelessDeviceType.LoRaWAN };

名前はオプションですが、これで最低限のデバイスの登録が行えます。ほかにもデバイスの説明や位置情報なども追加できます。

2024年4月24日水曜日

LoRaWAN のローミングを試す

 LoRaWANはゲートウェイを中心としたスター型の通信になっていますので、基本的には1台のゲートウェイと通信をするんですが、ローミングの機能もあってゲートウェイが変わっても継続して通信することができます。LoRaWANでは通信開始時にJOINという手続きが必要なんですが、ここでの継続して通信というのはこのJOINをゲートウェイが変わってもやり直さなくてよいということになります。

今回はこれを実際に試してみようと思います。ちなみにLoRaWANサーバはAWSのIoT Coreを使用しています。

まず事務所に設置してる1台のゲートウェイから離れた場所に移動して、一時的にゲートウェイを動かしてそちらでJOINを行います。


JOINできたのを確認して、一応データ送信してみます。

うまく飛んでます。ここでゲートウェイは電源を落として、PCは電源落とさないように注意して事務所まで移動します。


窓にゲートウェイ貼っつけてあります。

ここで先程のPCで続けてデータ送信してみます。

あっさり飛びました。すぐに応答があったので、JOIN等の手続きをしているようには見えません。これで一度JOINすれば、通信するゲートウェイが変わっても問題なく通信できることがわかりました。




2024年2月28日水曜日

頭に近づけるとリーダーの読み取り距離は伸びるのか実験

車のロックを遠隔で解除する、鍵についているリモコンキーがありますね。以前このリモコンキーについて面白い記事を見かけました。
どうやら鍵を頭に近づけてボタンを押すと、車のロックをより遠くの距離から解除できるそうです。前から裏技としてこのテクニックは知られていたようで、シミュレーションで検証する記事もありました。

さらに気になるのはこのリモコンキーが扱う周波数です。
二つの記事をざっと見た感じだとだいたい300MHzあたりのようで、超短波(VHF)寄りの極超短波(UHF)になるのでしょうか?

もしかしたらこのリモコンキーのテクニックはRFIDリーダーにも応用できるかもしれません。
そういうわけで、実際にUHF帯のリーダーを頭やペットボトルに近づけたりして距離が変わるのか試してみました。

広い空間で検証する必要があったので、今回はDENSOさんのハンディリーダーSP1を使用します。
SP1の周波数はだいたい916~920MHzになります。リモコンキーの周波数とは結構差があると思いますが、試してみます。



屋外なのでカバンのなかにタグをいれ、これを読み取れる距離をはかります。


結構簡単な検証だと思っていましたが、屋外だと風があるせいか、標準になる限界の距離がどこなのかなかなかつかめませんでした。

これでだいたい5mくらいでした。
ここからリモコンキーの記事にあったように、リーダーを頭やあごあたりに近づけつつ後ずさりしてみました。

頭に近づけた結果としては、確かに距離が伸びたように感じる瞬間があった、程度でした。
リーダーを頭に近づけたり離したりを繰り返すと、読み取りもそれに応じて、頭に近づけるたびに反応があるということが起きました。しかし結構偶然に近いような感じで、あまり再現できませんでした。

今度は天然水のペットボトルを使います。


頭に近づける必要があるのは、頭にアンテナのように電波を延長させてくれる水分があるためなので、これをリーダーに近づければもっと効果があるかもしれません。


結果としては、頭に近づけるときと同様にイマイチでした。


やはりICタグと水分の相性は悪いと考えたほうがよいのでしょうか。
もっと電波について勉強したいと思える実験でした。

2024年2月27日火曜日

LoRaWANの電波強度を測定してみる

 おかげさまで最近よく沖縄のニュースなどで取り上げていただいている「ミマモライド」ですが、こちら通信に LoRaWAN を使用しております。エンドデバイスは自動販売機などに設置していて地面に近いところにあります。なのでゲートウェイはなるべく高いところに設置をしています。

使用しているゲートウェイは DRAGINO の DLOS8 です。

ところが、設置後に通信のテストしていると、あれ?何か届かなくね?みたいのが発生したりします。よくよく調べると、アンテナのコネクタがきちんと刺さってなかったのか、そのあたりをイジってるときちんと電波飛ぶようになるときがあります。

設置場所は気軽に入れない場所がほとんどで、後から何か電波弱いね―みたいになると非常に面倒です。なのでアンテナが付いているときと付いてないときで電波強度にどのくらいの差が出るのかを事前に測定したいと思いました。

アンテナをきちんと接続した状態と、アンテナを外した状態でそれぞれ10m、20m、30m離れたところから2回ずつ電波を出して、ゲートウェイでどのくらいのRSSIで受信できたのかを測定しました。


結果がこちら。SFはすべて10でした。いちおう各測定ごとにJOINから開始しています。これを見るとやはり結構な差が出ています。これをもとにゲートウェイ設置後、近くで送信してみてRSSIが-50くらいであれば大丈夫というような認識でOKのようです。

2023年10月2日月曜日

GAE/J で排他制御したい

 GAEとっても便利なんですが、どうしても排他制御したい処理が出てきてしまいました。特定のファイルの更新とかそんな感じの処理です。syncronized で同じインスタンスなら排他制御できるので大丈夫なんですが、GAEの場合オートスケールするので同じインスタンスからのアクセスとは限らずその技は通用しません。

ググるとこういうときは Memcache を使って実現するようなのが多いようです。

Memcache の使用方法

これの、「同時書き込みの処理」のところを使って、ロックフラグみたいのをいじるようにすると実現できそうです。

というわけで実装してみたわけですが、、、ちゃんと動作しません。なんだろう、ソースそのまま使ってるしなーと思って上記のソースを眺めていると、、、あれ?これってキーがまだ無いときに複数同時に処理されると皆んな0で作っちゃうんじゃね?ということに気づきました。

ここの処理の肝は putIfUntouched を使って、特定の1スレッドだけが処理を完了できるところにあります。が、キーが無いときはただ 0 を put してるだけなのでここが被ると排他にならないわけです。

putIfUntouched で 0→1 は特定の1スレッド限定にできるんですが、 null→0 をやりたいときは putIfUntouched は IllegalArgumentException を投げてくるので使えません。

キーがない → 0でput → putIfUntouched で1にできた人勝ち

とやりたいところなんですが、勝ちが決まった瞬間に0でputの人が出てくると上書きされてしまうのです。

こまった。どうしたらいいんだ。ということで思いついた苦肉の策が、「putした人はしばらくロックバトルに参加できなくする」という作戦です。putした人の動きをしばらく止めておけば、後から来た人はキーが存在する状態なので putIfUntouched で勝者を決めることができます。

    public void LockFile(String filePath) {
        Random rand = new Random();
        MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
        
        while (true) {
            byte[] oneValue = BigInteger.valueOf(1).toByteArray();
            byte[] zeroValue = BigInteger.valueOf(0).toByteArray();

            IdentifiableValue lockValue = syncCache.getIdentifiable(filePath);
            if (lockValue == null) {
                syncCache.put(filePath, zeroValue, Expiration.byDeltaSeconds(30));
                try {
                    Thread.sleep(1000);  // ロック情報を作成したスレッドは1秒間ロック取得競争に参加できないようにする
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                if (new BigInteger((byte[])lockValue.getValue()).intValue() == 0 && syncCache.putIfUntouched(filePath, lockValue, oneValue, Expiration.byDeltaSeconds(30))) {
                    // ここに来れるのは1スレッドのみ
                    logger.info("Lock File : " + filePath);
                    break;
                }                
            }
            
            try {
                Thread.sleep(rand.nextInt(100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }        
    }
    
    public void UnlockFile(String filePath) throws Exception {
        MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
        syncCache.put(filePath, BigInteger.valueOf(0).toByteArray(), Expiration.byDeltaSeconds(30));        
        logger.info("Unlock File : " + filePath);
    }

いちおうこれで考えてたような処理が無事できました。

競合が居ない(かつキーが無い)場合は最低1秒待たされることになりますがまぁ仕方ないかな。

2023年7月19日水曜日

AGCさんの電波吸収遮へいガラスを試してみた

 従来の電波吸収体といえばパネルやカーテンみたいなもので遮蔽すると向こうが見えないのが普通でした。これをシースルーで実現させたのが、先日のリテールテックでも展示してありましたAGCさんの電波吸収遮へいガラスです。

東芝テックのRFIDウォークスルーゲート、AGCの電磁波吸収/遮蔽ガラスを採用

この製品のサンプルをAGCさんのご厚意によりお借りすることができましたので実際に試してみました。

試すにあたっていろいろ設置してやってみたのですが、電波の反射や回り込みの影響があるのでなかなか効果を測定することが難しかったので最終的にこんな感じで測定をすることにしました。

簡易測定装置

床にアンテナを置いて、そのすぐ上に電波吸収ガラスを設置します。これだと反射や回り込みもあまり影響しないのでうまく測定できるかなと。上に付いてるのは簡易的なスペアナのアンテナです。

実際にガラスを置いたところ

リーダはマスプロさんの1W機を使いました。アンテナが大きいのが無かったのでシートアンテナを使いました。このアンテナは利得が3dBiなのでフルパワーとはいきませんがまぁ、これしか無かったのですいません。

電波を出してみて、スペアナで見てみます。

ガラス無しの状態

ガラスありの状態

明らかに山の形が小さくなっているのがわかります。ピークっぽいところを比較すると、ガラス無しで 20dB がガラスありで 35dB くらいになってるので電力で換算すると30分の1くらいになってます。これはスゴいですね!

実際にタグを置いて読ませると、


4枚置いてますが2枚しか読めませんでした。読めた2枚もRSSIで見ると-80くらいだったのでかろうじて読めてるという印象です。シースルーでここまで出来るとは驚きでした。

2023年7月12日水曜日

MANICAモバイル用のゲートを作る その3

 前回は1WリーダのSR7と人感センサーを組み合わせて作りましたが、やっぱりハンディも欲しいよねーということでこちらのリーダで実装してみました。

国産で信頼性バッチリのタカヤさんのハンディリーダーです。形はシンプルですが、手元で出力調整も出来て使いやすい仕上がりになっております。

完成したのがこちら

ハンディにトリガボタンがあるのでそれを使うことにして、前回使った人感センサーは使用しませんが、それだとつまらないので温湿度センサーと気圧センサーをつけました。リーダで読み取った環境データも同時に取得できるという無理やりくっつけた感満載の機能です。

実際に動作させてみたのがこちらです。


このセットだけでMANICAモバイルのゲートとして使えます。