Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What is going on with this article?
@sousoumt

SORACOM Enterprise Buttonの簡易位置情報を用い地域外での押しミスを防ぐ(CloudFunctions/Python版)

More than 1 year has passed since last update.

TL;DR(まとめ)

  • SORACOM Enterprise Buttonの簡易位置情報を用いて、ある地域でのみ動作するボタンを構築した
  • 2019/7/2 SORACOM Discoveryにて新発表されたSORACOM Funkを用い、GCPのCloudFunctionsを動作させた
  • 「地域外」はCloudFunctions側で判断しているので、ボタン動作回数は通常通り消費される

機材

SORACOM Enterprise Button (初期ボタン登録は済んでいるものとします)

主に使ったもの

SORACOM Funk
CloudFunctions(GCP)
pyjwt(JWT(Json Web Token)Python版ライブラリ)

構築内容

SORACOM Enterprise Buttonを押した際に、SORACOM Funk経由でCloudFunctionsを起動させます。
CloudFunctionsの中で位置情報を取得します。(このときにjwt使用)
地域外であれば動作、そうでなければ動作しないようにします。
判断するロジックの部分のみを記事にします。

構築手順

CloudFunctions設定

後でSORACOMのコンソールから起動関数を指定するため、先にCloudFunctionsを記載します。
CloudFunctionsの画面から関数の作成を選択し、以下の通りに入力しましょう。ここで★の部分のURLはSORACOM Funk設定にて用いるため取得しておきます。
関数の名前はなんでも良いですが、enterprise_buttonとでもしておきましょう。
デフォルトのNode.jsでも良いですが、Pythonでも記載できるのでPythonを選択しました。

01.png

続けてrequirements.txtの編集です。
pyjwtを用いるため、requirements.txtに以下記載をしましょう。(ここに記載した内容が pip installされるイメージです)

CloudFunctions(requirements.txt)
pyjwt

以下が実行関数です。デフォルトの起動関数名hello_worldからexec_buttonに変えているため、
実行関数名と環境変数の設定がこの後必要です。

SORACOMの説明では、httpヘッダにx-soracom-tokenがあり、それをJWTでデコードできるとのこと。
というわけでこうなります。

CloudFunctions(main.py)
import jwt
import os

def exec_button(request):
    if 'x-soracom-token' not in request.headers:
        return 'Not from soracom button.'

    # Decode jwt token. (algorithm : RS256)
    data = jwt.decode(request.headers.get("x-soracom-token"), verify=False)
    if not is_inside_area(data['ctx']['location']):
        return 'Out of area.'

    # Write your code here.
    return 'Inside area.'

def is_inside_area(position):
    northwest = {'lat': float(os.environ.get('northwest_lat', 1.0001)), 'lon': float(os.environ.get('northwest_lon', 178.0001))}
    southeast = {'lat': float(os.environ.get('southeast_lat', 0.0001)), 'lon': float(os.environ.get('southeast_lon', 179.0001))}
    if 'lat' not in position or not(isinstance(position['lat'], float)):
        return False
    if not(southeast['lat'] <= position['lat'] and position['lat'] <= northwest['lat']):
        return False
    if not(northwest['lon'] <= position['lon'] and position['lon'] <= southeast['lon']):
        return False
    return True

補足:is_inside_area関数では、取得した簡易位置情報(緯度経度)がその領域に含まれているかどうかを判断しています。

この枠内にあるか?を判断している
northwest - - - - -
-                 -
-                 -
-                 -
- - - - - southeast

実行関数名をexec_buttonにします。
詳細設定が必要なので、その下のEnvironment variables, networking, timeouts and moreをクリックします。

02.png

環境変数のみ以下の通りに指定します。(その他はデフォルトでOK)
デプロイしておきましょう。(関数を初回に作成する場合は「作成」です)

03.png

これでCloudFunctionsの設定は完了です。

SORACOM Enterprise Button設定

SORACOMコンソールから、Funkと位置情報の有効化の設定を行います。
該当するEnterprise Buttonが所属するSIMグループの設定ページを開いてください。(私はenterprisebuttonというグループ名)
設定する箇所は赤枠で囲った2箇所です。

04.png

では順に設定していきましょう。
SORACOM Air for Cellular設定 : 位置情報の取得を有効化します。また、バイナリパーサとして@buttonを設定します。

05.png

SORACOM Funk設定 : FunkでCloudFunctionsを実行するようにします。★で取得した関数のエンドポイントを記載します。

06.png

これで位置情報が取得できた場合に、地域外を判定することができます。
これにより地域外で誤って押してしまった際に動作をさせない、なんてことができますね。
参考になれば幸いです。

2
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
sousoumt
Node.js/Python/Actions On Google/Dialogflow/Firebase/Arduino/Raspberry Pi/Redis/Lambda/SORACOM

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
2
Help us understand the problem. What is going on with this article?