LoginSignup
4
1

More than 1 year has passed since last update.

GPSマルチユニットSORACOM Edition を使って、自宅のドアの鍵を開けよう。

Last updated at Posted at 2022-01-02

はじめに

自宅に近づいたらドアの鍵が自動で開いたらいいなとの思いから開発しました。

構成図

bb86a9df4fe6d2a11df6_01.PNG

解説

  1. みちびきからGPS情報を取得
  2. GPSマルチユニットで受信し、SORACOMに送信
  3. 受け取った情報から、SORACOM Funkを起動
  4. SORACOM Funkから、AWS Lambdaを実行
  5. Lambdaで受け取ったGPS情報から、Amazon Location Service PlacesTrackingを起動
  6. GPS情報を元に、Placesで可視化
  7. GPS情報を元に、Trackingに登録
  8. Trackingで取得した情報を元に、Geofencingを用いて自宅周辺の地理的境界を判定
  9. 地理的境界に入った場合、EventBridgeでLambdaを起動
  10. Lambdaで、SESAMEとNature RemoのAPIにリクエスト
  11. APIリクエストを元に、SESAMEがドアの鍵を開け、Nature Remoがリビングの電気ONを実行
  12. 作業用PCでコード修正し、GitHubにPush
  13. GitHubのPushから、CircleCIが起動
  14. CircleCIでLambdaにコードをデプロイ
  15. CircleCIのデプロイ成否をSlackに通知

GPS マルチユニット SORACOM Editionについて

ユーザーガイドが詳しいです。

SORACOM Funkから、AWS Lambdaが呼び出される時にeventに連携されるJSON

{
    "lat": 35.6892712,
    "lon": 139.6927462,
    "bat": 3,
    "rs": 0,
    "temp": 27.5,
    "humi": 63,
    "x": -64,
    "y": 832,
    "z": 576,
    "type": 0
}

受け取ったJSONの経度緯度情報から、現在地の地名をAmazon Location Place indexesで検索

Amazon Location Place indexesに、Nameを入力し作成してください。このNameはあとで使用します。

bb86a9df4fe6d2a11df6_02.PNG

以下のドキュメントを元に、簡単なコードを書くとこのようになります。Boto3は最新版にしてください。

# -*- coding:utf-8 -*-
import json
import boto3

location = boto3.client('location')

# GPSユニットから受信したJSONとする。
event = {
    "lat": 35.6892712,
    "lon": 139.6927462,
    "bat": 3,
    "rs": 0,
    "temp": 27.5,
    "humi": 63,
    "x": -64,
    "y": 832,
    "z": 576,
    "type": 0
}

# 先に作成したPlace indexesの、Nameを使用します。
response = location.search_place_index_for_position(
    IndexName = 'xxx',
    Language = 'ja',
    MaxResults = 1,
    Position = [event['lon'],event['lat']]
)
print(json.dumps(response, ensure_ascii = False))

緯度経度情報から取得した情報です。日本語名で取得できました。

{
    "ResponseMetadata": {
        "RequestId": "d83ddd7a-bb15-4e67-81a5-bb20f33ecc35",
        "HTTPStatusCode": 200,
        "HTTPHeaders": {
            "date": "Sat, 22 Jan 2022 06:57:18 GMT",
            "content-type": "application/json",
            "content-length": "387",
            "connection": "keep-alive",
            "x-amzn-requestid": "d83ddd7a-bb15-4e67-81a5-bb20f33ecc35",
            "access-control-allow-origin": "*",
            "x-amz-apigw-id": "MVegUH8sNjMF0tg=",
            "access-control-expose-headers": "x-amzn-errortype,x-amzn-requestid,x-amzn-errormessage,x-amzn-trace-id,x-amz-apigw-id,date",
            "x-amzn-trace-id": "Root=1-61ebaace-151333031b17ac202e457aa6"
        },
        "RetryAttempts": 0
    },
    "Results": [
        {
            "Distance": 97.11527157871623,
            "Place": {
                "AddressNumber": "1",
                "Country": "JPN",
                "Geometry": {
                    "Point": [
                        139.69170523793048,
                        35.689486328367835
                    ]
                },
                "Interpolated": false,
                "Label": "東京都新宿区西新宿2-8-1",
                "Neighborhood": "2",
                "PostalCode": "1600023",
                "Region": "東京都"
            }
        }
    ],
    "Summary": {
        "DataSource": "Esri",
        "Language": "ja",
        "MaxResults": 1,
        "Position": [
            139.6927462,
            35.6892712
        ]
    }
}

経度緯度情報から、ある地点間の直線距離を測定する

from math import sin, cos, acos, radians
earth_rad = 6378.137

def latlng_to_xyz(lat, lng):
    rlat, rlng = radians(lat), radians(lng)
    coslat = cos(rlat)
    return coslat*cos(rlng), coslat*sin(rlng), sin(rlat)

def dist_on_sphere(pos0, pos1, radius=earth_rad):
    xyz0, xyz1 = latlng_to_xyz(*pos0), latlng_to_xyz(*pos1)
    return acos(sum(x * y for x, y in zip(xyz0, xyz1)))*radius

# 呼び出すとkm(キロメートル)
# position(計測地点) = 経度(lat), 緯度(lon)
# unit(GPSマルチユニット位置) = 経度(lat), 緯度(lon)
km = dist_on_sphere(position, unit)
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1