【やってみた】僕の愛しのペットがTwitterでSOSを発信するようにしてみた。

2020 4/01
【やってみた】僕の愛しのペットがTwitterでSOSを発信するようにしてみた。

おまたせいたしました。ちゆりです。
前回のIoT考えてみたで以下の記事を書きました。

あわせて読みたい
僕の愛しのペットがTwitterでSOSを発信するようにしてみる。
僕の愛しのペットがTwitterでSOSを発信するようにしてみる。こんにちは。さっそくちゆりです。僕には愛しのペットがいるのだが,あいにく動物であるため,喋ることすらない。「腹減った」「眠い」「暑い」「寒い」「ジャグラー打...

僕の愛しのペットがTwitterでSOSを発信するような仕組み
今回はこちらを実際にIoTを活用して作成してみましたので,どうぞご覧ください。

目次

構成から準備編

ざっくりな構成はこんな感じ

今回は,使用する材料(モジュール等)の価格,技術的なハードルが高くなかったため,前回の記事で考えていた構成通り,うまく順調に作成できましたね。
以下ざっくり構成図。

画像
ざっくり構成図

やりたいこと

15分間隔で温度を監視し,15度以下の場合は「寒い…」的なツイートを,28度以上の場合は「暑い…」的なツイートを行っていきます。
もし,2時間適温が続くと僕のペットは「ジャグラーを打ちたい」と生意気なことを言うようになります。

それでは,実装していきます。

実装までに必要な準備

以下作成のために準備したものです。

  • Raspberry Pi (僕はRaspberry Pi3 B+を使用しました。ラズパイあれば大体なんでも大丈夫です。)
  • 温度を取得するモジュール (今回はUSB温度計Temperを使用)

個人的には温度測定モジュールはGPIOを使わないUSB温度計Temperが非常にかんたんで扱いやすいかと思います。

Temperの詳しい使い方セットアップは以下の記事が参考になります。

USB温度計『TEMPer』を使ってRaspberryPiで温度を測定する。

ラズパイとUSB温度計「TEMPer」(413d:2107)で温度を監視したいのだが,うまく動かない!?

いざ,実装編

登録・インストール

Twitterアクセストークン取得

TwitterのAPIを使ってプログラムからツイートを行うにはまずは,API登録(アカウント申請)を行いましょう。
API登録を行い,アクセストークンを取得します。

取得方法は以下の記事でまとめられています。

Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ ※2019年8月時点の情報

Python pipモジュールの取得

今回の実装はpythonを使ってコーディングしていきます。
Twitterアクセス用のpipモジュールがありますので,インストールしておきましょう。

以下のコマンドで一括でインストールしておきます

pip3 install requests requests-oauthlib

コーディング

今回実装したコードは以下になります。

config.pyにはアクセストークンの情報を記述します

Consumer_API_keys = "*******************"
Consumer_API_secret_key = "*******************"
ACCESS_TOKEN = "*******************"
ACCESS_TOKEN_SECRET = "*******************"

SOSTweet.pyに温度を取得し,ツイートを行う処理を記述します。

import subprocess   #コマンドを実行するために必要
from time import time   #sleepを実行するために必要
import json, config #標準のjsonモジュールとconfig.pyの読み込み
from requests_oauthlib import OAuth1Session #OAuthのライブラリの読み込み

CK = config.Consumer_API_keys
CSK = config.Consumer_API_secret_key
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK, CSK, AT, ATS) #認証処理

url = "https://api.twitter.com/1.1/statuses/update.json" #ツイートポストエンドポイント
THRESHOLD_LOW = 15.0    #これ以下の温度で「寒い」とつぶやく #①
THRESHOLD_HIGH = 28.0   #これ以上の温度で「暑い」とつぶやく #②
juggler_cnt = 0     #ジャグラーを打ちたくなるまでのカウント #③
#####温度取得関数#####
#温度を取得する場合は適宜温度を取得する関数を作成しましょう。

#例)Temperを使って温度を取得する場合はTemperセットアップ後,この関数で温度取得可能です。
def getTemperature(): #④
    response = subprocess.check_output("tempered",universal_newlines=True)  #temperedコマンドの呼び出し
    temperature = response.split(" ")[3]    #不必要な出力は省き,温度のみ取得
    return float(temperature)

####################

while(True):
    time.sleep(900) #15分間隔で温度監視
    temperature = getTemperature()
    if temperature <= THRESHOLD_LOW:
        #寒いツイート
        tweet = "寒いよ。震える。" + str(temperature) + "度とかまじありえん。無理。"
        params = {"status" : tweet}
        res = twitter.post(url, params = params) #post送信

        if res.status_code == 200: #投稿成功
            print("Tweet Success.")
        else: #何らかの理由で投稿失敗
            print("Tweet Failed. ercd:%d"% res.status_code)
        juggler_cnt = 0

    elif temperature >= THRESHOLD_HIGH:
        #暑いツイート
        tweet = "暑いよ。喉乾いた。" + str(temperature) + "度とかまじありえん。無理。"
        params = {"status" : tweet}
        res = twitter.post(url, params = params) #post送信
        if res.status_code == 200: #投稿成功
            print("Tweet Success.")
        else: #何らかの理由で投稿失敗
            print("Tweet Failed. ercd:%d"% res.status_code)
        juggler_cnt = 0


    else:
        juggler_cnt = juggler_cnt + 1
        if juggler_cnt >= 8:
            #ジャグラー打ちたいツイート
            tweet = "ジャグラー打ちたい。資本金は" + str(temperature) + "万円ほしい。"
            params = {"status" : tweet}
            res = twitter.post(url, params = params) #post送信
            if res.status_code == 200: #投稿成功
                print("Tweet Success.")
            else: #何らかの理由で投稿失敗
                print("Tweet Failed. ercd:%d"% res.status_code)
            juggler_cnt = 0

実装ポイント

  1. THRESHOLD_LOW…温度のしきい値(下限値)
    • この温度を下回ると「寒いよ。震える…」とツイートします
  2. THRESHOLD_HIGH…温度のしきい値(上限値)
    • この温度を上回ると「暑いよ。喉乾いた…」とツイートします
  3. juggler_cnt…ジャグラーを打ちたくなるまでのカウンター
    • 暑くも寒くもなく適温な状態が2時間続くと「ジャグラー打ちたい…」とツイートします
  4. getTemperature()関数…温度取得関数
    • 使用モジュールによって適宜温度の取得方法が変わるかと思います。
    • Temperを使う際はこの関数のままおそらく動くはずです。
      (Temperのロットによってはコマンドによる温度出力が異なる場合もありますが…)

動かしてみた

今回のIoTやってみたの機器構成はラズパイ+USB温度計のみということで非常にシンプル構成!!
ラズパイにUSBぶっ刺すだけですからね。GPIOを避けた結果がこうなりました..。まぁいいんですけどね。シンプル・イズ・ベストですから。

画像
USB温度計Temperとラズパイ

今回のポイントとしてはUSB温度計をラズパイに直挿ししないことです。え?上記画像では直刺ししていますが,これは悪い例ですね。ラズパイに直刺しするとラズパイの熱が温度計に回り込み,実際の温度よりもかなり高めに温度を出力してしまいます。USBハブとかを噛ましてあげると良いですね。

果たして無事SOSツイートできているのか。

うん。できてるね。SOSツイート。にしてもペットルーム暑いな。暖房入れてるからね。
喉乾いたSOSを見た方は僕の愛しのペットの心配もぜひ,お願いしますね。

今回の苦労ポイント

今回苦労したのはラズパイでpythonスクリプトを長時間実行すると自動でLinuxのOSにKillされてしまうことですかね。
実際に今回のコードでラズパイで動かしてみると,10数分でpythonスクリプトが自動で終了させられてしまいます。
おそらくOOM Killerたるものの影響だと思います。

Linux OOM Killerについて

ここらへんは今回は深く追求できていないので,今後勉強して対策とまとめ記事を作成していきますかね。

2020/04/01追記
OOM KillerでプロセスをkillさせないためにはSupervisorでデーモン化するのも効果あり

CreepFablic
ラズパイでsupervisorを動かしてデーモン化 | ハイパー猫背
ラズパイでsupervisorを動かしてデーモン化 | ハイパー猫背ラズパイの起動時にpythonプロセスを起動させるためにsupervisorをインストールしてデーモン化してみる。confファイルの書き方を以下のように書くことで常時起動、自動再起...

最後に

ラズパイからツイートをさせるなんて便利な時代になりましたね。
IoTの定番ラズパイSNSの定番ツイッターを組み合わせるとIoTを活用して全世界に発信できるようなことができて非常に面白いですね。

なにかやってほしいアイデア,疑問点等ありましたら気軽にコメントなりツイッターなりで連絡していただければ優しくお答えしますのでお待ちしていますね。

では,またおもしろいアイデアを考えてきます。ばいちゃ。

目次