LoginSignup
2
0

スマートロック sesame を line から開閉してみた

Last updated at Posted at 2023-12-08

この記事について

この記事は Akatsuki Games Advent Calendar 2023 の8日目の記事です。
Advent Calendar の7日目はなかひこくんの
Terraform で CloudRun + Identity-Aware Proxy をやっていく 2023 でした。
記事内にある基盤は本当にお世話になっていて、自分もクライアントの立場から貢献をしていきたいところです…!

作るきっかけ

自分は 自宅のドア と アパートのエントランスドア(この規模では珍しい気がする)を開ける解錠ボタン にスマートロックのsesameを使用しています。
また、wifiモジュールを使用してbluetooth圏外からも操作できるようにしています。
ただ操作はsesame公式のアプリを使用していたのですが、wifi経由だと反応しない場合が何回かあり家に入りたいのに入れない!という状況があったためより使いやすい手段を探す事にしました。

使用するもの

  • line bot
  • aws lambda
  • python3.10.11

line botを選んだ理由は

  • lineの公式アカウントとかでメニューからメッセージを送る機能が個人的にはわかりやすかった
  • line botにちょっと興味があった

aws lambdaを選んだ理由は

  • こちらも単純に興味から

フロー

このようなフローでとりあえず実装をしていきます

line botの構築

構築ページ

上記リンクにアクセスして、ログインをします

新規プロバイダーの作成

Line Developerトップ から Providersの赤枠Createを選択します

Messaging API channelの作成

今回はメッセージのやり取りを行うので Messaging API channel を選択します

アクセストークンの作成

作成したchannelを開いて、Messaging APIを選択します

一番下にアクセストークンを発行する項目があるので、Issue を押して発行します
なお、出てきた文字列はメモをしてください

account managerへ移動する

作成したchannelのページから、 赤枠の Line Official Account Manager へアクセスします

line account managerでメニューを構築する

リッチメニューの作成

作成

account manager の タブから ホーム を選択して、左のメニューから リッチメニュー を選択します
すると、リッチメニューを作成 と出ているので選択します

タイトルと表示期間を設定

とりあえず 2037年まで有効にしておきます

テンプレートと画像を変更する

テンプレートは3つのボタンに

画像 を選択すると、全体かエリア毎が出てくるのでエリア毎にします

とりあえず単色塗りつぶしをしておきます。

押した時のアクション

タイプを テキスト にして、開ける、閉める、エントランス用で設定します
ここのテキストは後ほど実行するコードで合わせる必要があります。

webhookの有効化

上のタブの右側にある設定を選択して 左のメニューから 応答設定 を選択して 応答機能 にある Webhook のみ有効にしておきます

sesame apiにアクセスするための設定

api利用のために登録

https://partners.candyhouse.co/login/
上記リンクにアクセスしてログインをします

Keyを取得する

  • ご利用中のapi key をメモしておく
  • 既にデバイスを登録している場合は、赤枠の user devices を選択してデバイスを取得します
  • 右側の赤枠のデバイスを選択すると、UUIDとSecret Keyが表示されるのでメモをしておきます

AWS Lambdaで実装する

使用するpythonのライブラリをまとめる

仮想環境にインストール

必要なライブラリのみzip化していくので仮想環境内にインストールしていきます

mkdir aws-line-bot
cd aws-line-bot
python -m venv venv
./venv/scripts/activate 
python -m pip install line-bot-sdk

zip化

仮想環境にline-bot-sdkをインストールしたら、これをzip化していきます

  1. pythonフォルダを作成し、./venv/Lib/site-packages下のフォルダをpythonフォルダへコピーします
  2. pythonフォルダをzip化

レイヤーにライブラリを登録する

スクリーンショット 2023-12-08 060038.png
aws Lambdaにアクセスしたら、左のメニューから その他のリソース -> レイヤー -> レイヤーの作成 を選択します

先程zip化したpythonライブラリを登録します。
また、今回はpython3.10 + windows11を用いて作成したのでpython 3.10とx86_64を指定します

関数を作成する

では、本題の関数を作成します
AWS Lambda から 左のメニューより 関数 -> 関数の作成 を選択します

一から作成を選択した後は、ライブラリの時と同じバージョンをとアーキテクチャを指定しておきます

環境変数に必要な情報を登録しておく

関数を作成したら、まずは必要になる環境変数を登録していきます

  • sesameのAPI Key
  • sesameのデバイス毎のUUIDとSecret Key
  • Line botのAccess Token
    以上を登録します

自分はこんな感じになりました
sesame botはエントランスを開ける用のsesame botで
upperとlowerに分かれているのは玄関ドアには2つ鍵があるためです

使用するレイヤーを登録する

ページ一番下に レイヤー があるので レイヤーの追加 を選択します

先程zip化してアップロードしたレイヤーを追加

そして、もう一つ pycryptodome を使用するために下記ページからARNを持ってきます
https://github.com/keithrozario/Klayers/tree/master/deployments/python3.10

サンプルの実行コード

https://doc.candyhouse.co/ja/SesameAPI#web-api-%E3%81%AB%E3%82%88%E3%82%8B%E6%96%BD%E8%A7%A3%E9%8C%A0
sesame apiのドキュメントはこちら

ここで注意してほしいのが、sesame botを操作する場合のコマンドコードは 89 となります
ドキュメントには以下のコマンドがありますが、このコマンドでsesame botを動かすと回転量がおかしくなってしまいます。

コマンドコードリスト
toggle:88
lock:82
unlock:83

※ 1つ謝罪として89で動く事を発見したブログ記事があったのですが、今探しても全然見つからず参考に載せられませんでした。もしありましたらコメントに書き込んでいただけると助かります。

以下がサンプルの実行コードとなります

import os
import json
from linebot import LineBotApi
from linebot.models import TextSendMessage

# sesame apiと通信する時に使用する
import Crypto.Cipher.AES as AES
from Crypto.Hash import CMAC
import json
import base64
import datetime
import requests

LINE_CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN')
SESAME_KEY = os.getenv('SESAME_KEY')
# エントランスドアを開けるsesame bot
SESAME_BOT_ID = os.getenv('SESAME_BOT_ID')
SESAME_BOT_SECRET_KEY = os.getenv('SESAME_BOT_SECRET_KEY')
# 玄関のドアにあるsesame
SESAME_UPPER_ID = os.getenv('SESAME_UPPER_ID')
SESAME_UPPER_SECRET_KEY = os.getenv('SESAME_UPPER_SECRET_KEY')

bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)

def sesame_post(id, key, command):
    url = f'https://app.candyhouse.co/api/sesame2/{id}/cmd'
    headers = {"x-api-key" : SESAME_KEY} 
    
    message = int(datetime.datetime.now().timestamp()).to_bytes(4, byteorder='little').hex()[2:8]
    cmac = CMAC.new(bytes.fromhex(key), bytes.fromhex(message), ciphermod=AES)
    sign = cmac.hexdigest()
    body = {"cmd":command, "sign":sign,"history":base64.b64encode("Linebotから".encode()).decode()}
    # sesame web apiへリクエスト
    requests.post(url, headers=headers, data=json.dumps(body))
    
def lambda_handler(event, context):
    try:
        events = json.loads(event['body'])['events']
        # メッセージではない場合は終了する
        if events[0]['type'] != 'message':
            return {'statusCode': 200, 'body': json.dumps('成功')}
        # メッセージの種類がテキスト以外だった場合は終了する
        if events[0]['message']['type'] != 'text':
            return {'statusCode': 200, 'body': json.dumps('成功')}
            
        # line botから送られてきたメッセージを判定する
        messageText = events[0]['message']['text']
        if messageText == "鍵を開ける":
            sesame_post(SESAME_UPPER_ID, SESAME_UPPER_SECRET_KEY, 83)
        elif messageText == "鍵を閉める":
            sesame_post(SESAME_UPPER_ID, SESAME_UPPER_SECRET_KEY, 82)
        elif messageText == "エントランス開ける":
            sesame_post(SESAME_BOT_ID, SESAME_BOT_SECRET_KEY, 89)
        replyToken = events[0]['replyToken']
        bot_api.reply_message(replyToken, TextSendMessage(text="完了"))
    except Exception as e:
        print(e)
        return {'statusCode': 500, 'body': json.dumps('失敗')}
    return {'statusCode': 200, 'body': json.dumps('成功')}

デプロイ

コードソースより Deploy を選択してデプロイを行い実装は完了となります

AWS API Gatewayに登録

作成

関数が出来たらAPIのトリガーに登録をします。

関数の概要より、 トリガーを追加を選択します

ひとまず動作を行いたいので、Create a new APIREST API を選び追加をします

URLのコピー

白塗りつぶしの部分にURLがありますので、コピーをします

LinebotのWebhookにAPI URLを登録する

Line Developersに戻り、Webhook settings より先程コピーしたURLを登録します

実行する端末からLinebotを友だち登録する

Line Developers のチャンネルから Messaging APIを開いて、QRコードを読み取ります
これで全ての作業が完了しました。

実際の動作の様子

色々と変えていますが、以下のように終わったら返答が返ってきます。

結果

目的にあった反応しないを解消するについては今のところ達成できています。
ただし、サンプルのままでは複数のデバイスを動かすと都度待ってしまいますので、async等を使用して非同期でそれぞれを実行するのが良いかと思います。

参考

明日の記事は Yusuke Nakajimaさんより UnityのProjectWindowに表示履歴機能を付けるエディタ拡張 とのことです。
エディタ拡張いいですよね!既存のProjectWindowにつけるということでどう付けるか気になるところです。

2
0
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
2
0