夜の地震の時に明かりを自動でつけるデバイスをRaspberry pi3とArduino nanoで作る

#けんきゅう(???)
##動機(こじつけ)
日本では夜の地震が多い、というような記事を見かけた。というわけで夜に安全な避難をするためには何が必要か考えた。夜って暗いうえに地震でパニクるので足元がおろそかになるじゃないかな〜。やっぱりその時に明かりがあると安全な避難ができるんじゃないか、ということで緊急地震速報と連動して明かりつけてくれたりしたら便利なんじゃね？ってことで備忘録も兼ねてこの記事を書く
ついでにカーテン閉めとけばガラスの飛散も安心だね
明かりは赤外線リモコンでつくものをしよう

##構成
ざっくり作り方
##使用機器
・raspberry pi3 model B
・arduino nano ch340（amazonで1個4~500円の互換品
・赤外線LED
・赤外線受光モジュール（OSRB38C9AA）　http://akizukidenshi.com/catalog/g/gI-04659/
##仕組み
raspberry piでtwitterの緊急地震速報botから地震のデータを取得する
地震の速報ツイートを取得したらi2cでarduinoに信号を与えて赤外線の信号を送る（※raspberry piで赤外線リモコン組もうとして挫折した
##参考にしたURL
raspberry piとarduinoのi2c
https://sites.google.com/site/memorandumjavaandalgorithm/raspberry-pi-jiang-zuo-arduino-i2c-jie-xu
arduinoの赤外線信号の解析と送信
https://www.erestage.com/arduino/remo_recv/
https://www.erestage.com/arduino/arduino-send-remo/
##緊急地震速報のbotさん
今回はこちらのかたのツイッターで行います
なんでツイッターなのか？こうしたら授業中でも研究の名目でツイッターができるじゃないか
<img width="298" alt="スクリーンショット 2019-01-17 0.56.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/263501/3395fdda-1fd3-87d3-275a-3fcefee1eb0c.png">
##raspberry pi側の地震でarduinoを動かすプログラム
基本的には前に書いたqiitaにURlのarduinoのプログラムを合わせただけ
https://qiita.com/nya3_neko2/items/d7214cce1ae00db3ade0

```python
#!/usr/bin/env python 
# coding: utf-8 
#import tweepy
import smbus                #I2C通信するためのモジュールsmbusをインポートする
from twython import Twython,TwythonError 
import datetime
import time
#twitterの認証情報を入力 
CONSUMER_KEY = ""
CONSUMER_SECRET = '' 
ACCESS_KEY = '' 
ACCESS_SECRET = '' 
api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET) 
print('Auth Done!')

bus = smbus.SMBus(1)    ##I2C通信するためのモジュールsmbusのインスタンスを作成
adress = 0x04           #arduinoのサンプルプログラムで設定したI2Cチャンネル

#日時取得
now = datetime.datetime.now()
print(now)
tw_text = ('First value')
print(tw_text)

try:
    user_timeline = api.get_user_timeline(screen_name='v0x0o',count=1)
except TwythonError as e:
    print('error')
    print (e)

while True:
    #重複処理
    print(tw_text)
    for tweet in user_timeline:
        print(tweet['text'])
        print("From now on, checking duplication")

        #TL取得更新
        try:
            user_timeline = api.get_user_timeline(screen_name='v0x0o',count=1)
            print("GET TL")
        except TwythonError as error:
            print('error')
            print (error)
        if tw_text != tweet['text'] :
            print(tw_text)
            print(tweet['text'])
            print('This is new tweet')
             #TLの取得
            try:
                user_timeline = api.get_user_timeline(screen_name='v0x0o',count=1)
                print("GET TL")
            except TwythonError as error:
                print('error')
                print (error)
            for tweet in user_timeline:
                print("tw_textに代入")
                target1 = '地震速報'
                fb1 = 0
                fd1 = tweet['text'].find(target1)
                print('find' + str(fd1))
                if fd1 == -1:
                    print('This tweet is not order')
                if fd1 != -1:
                    print('This is earthquake flash news!')
                    target2 = '港区'#設置場所の情報を入力
                    fb2 = 0
                    fd2 = tweet['text'].find(target2)
                    if fd2 != -1:
                        print('Action for earthquake!')
                        #arduinoを動かすためのI2Cのデータ送信
                        try:
                            #Arduinoへ文字『R』を送る、ordはアスキーコードを取得
                            bus.write_byte(adress, ord('R'))

                            #Arduinoからのメッセージを取得し表示する、chrはアスキーコードを文字へ変換
                            #msg = chr(bus.read_byte(adress))
                            #print(msg)
                            #Arduinoからデータ取得する場合はコメントアウトを解く
            tw_text = tweet['text']
        else :
            print("I have seen")
    print('4')
    print(tw_text)
    print(tweet['text'])
    print("==========================================================")
    time.sleep(5)#〜秒ごとに繰り返す
```

#更新
何県の地震で震度がいくつかも認識するように書き換えました

##カーテン
カーテン動かす機構作るのか〜。とりあえずしめる機構は作ったから緊急時はそれでOK。

##リファクタリング
前のコードを書いたのは3ヶ月も前でした
あの時の自分は馬鹿すぎる
なぜあんなコードを書いたのか
もっとマシにしました
地震の判定プログラムです
またtwitterの速報も一番早い速報をするアカウントを調べました。
Twitterで「緊急地震速報」で検索し、時間順に並べてその中で一番早いものを調べました。
ちなみに結果はNERVが一番早かったです。でもNERVって名前だと本当にそのアカウントが信頼できるのか？って思われそうなので今回はやめときます。またNERVは地震以外の情報もツイートするので抽出が少しめんどくさいです。
[リンク]https://github.com/nyanko3142592/kaken_main

````main.py
#!/usr/bin/env python
# coding: utf-8
import time
import re

from twython import Twython,TwythonError
from timeout_decorator import timeout, TimeoutError

import config

global user_name
user_name = "zishin3255"


#twitterの認証情報を入力
api = Twython(config.CONSUMER_KEY, config.CONSUMER_SECRET, config.ACCESS_KEY, config.ACCESS_SECRET)
print('Auth Done!')


@timeout(5)
def get_new_tweet():
    global user_name
    try:
        user_timeline = api.get_user_timeline(screen_name=user_name, count=1)
        for tweet in user_timeline:
            now_tweet = tweet['text']
        return now_tweet
    except KeyboardInterrupt:
        pass
    except TwythonError as e:
        write_error(e)


def write_error(string):
    f = open('error.txt', 'a')  # 書き込みモードで開く
    f.write("\n" + str(string))  # 引数の文字列をファイルに書き込む
    f.close()  # ファイルを閉じる


def write_earthquake_info(string):
    string = str(string)
    f = open('last_earthquake.txt', 'a')  # 書き込みモードで開く
    f.write("\n" + string)  # 引数の文字列をファイルに書き込む
    f.close()  # ファイルを閉じる


def read_last_line():
    f = open('last_earthquake.txt')
    data1 = f.read()  # ファイル終端まで全て読んだデータを返す
    f.close()
    lines = data1.split('\n')  # 改行で区切る(改行文字そのものは戻り値のデータには含まれない)
    return lines[-1]


def earthquake_log(new_tweet):
    if new_tweet != read_last_line():
        write_earthquake_info(new_tweet)
        return True
    else:
        return False


def get_info_earthquake(string):
    try:
        announce_num = str(re.search(r'■■緊急地震速報\(第?最?(\D+)報\)■■', string).group(1))
        epicienter = str(re.search(r' (\D+)で地震', string).group(1))
        intensity = str(re.search(r'最大震度 (\d)', string).group(1))
        return announce_num, epicienter, intensity
    except Exception as e:
        write_error(e)


def main():
    # 起動処理　地震速報アカウントの最新ツイートを取得　書き込み
    earthquake_log(get_new_tweet())
    try:
        while True:
            new_earthquake = get_new_tweet() #real
            if earthquake_log(new_earthquake):
                if int(get_info_earthquake(new_earthquake)[2]) >= 3:
                    print("close")
                    #処理送信
            else:
                pass
            time.sleep(5)
    except KeyboardInterrupt:
        pass
    except Exception as e:
        write_error(e)


if __name__ == '__main__':
    main()

````

#2019/09/06更新
まあ緊急時ですからね、赤外線で動かないと困りますよね。赤外線は基本的には親機と子機の間に障害物があると動きませんね。それはやばいってことで通信方式を変えます。
Arduino nano -> ESP32 dev kit moduleにします。
通信はbluetoothでもWi-Fiでもいいと思っています。
基本は一緒です。Raspberry piからの指示をESPに渡して、子機のESPに通信してモーターを動かせば終わり！
たぶんBluetoothでやれば親機にESP必要ない気もしますけどググってESP->Raspberry piはごろごろあるんですけど逆は見当たらなかったのでやりません
WiFiを経由する方法もありますがSSIDなどの事前設定が必要なものは初期設定が煩雑なものになるためやりません
親機のRaspberry pi to ESPのシリアル通信はうまくいかなかったのでRaspberry piのGPIOピンからHIGH, LOWで信号出力してそれをESPのピンでリードします
複雑な命令がしたかったらリードするピンを増やせばいいんです
HIGH, LOWの信号はここに置いときます
[リンク]https://github.com/nyanko3142592/kaken_curtain/blob/master/lchika.py
関数で指定したピンを一定時間Highにするプログラムです
Pythonから実行するには権限を有効にする必要があったりすると思うので詳しくは「Raspberry pi　Lチカ」で検索してください。
今度は開く機構も作っていきます。しめるのは簡単なんですけどね。開く機構考えるのめんどくさいっすわ。そもそも別に開かなくていい気もするし。外出先からカーテン開けたいなーって時あります？ないですよね？いらない気もするなー。
##カーテン動いたよ
カーテンの開閉機構が出来ました
ちなみに手動の開閉は不可です
この回路は優秀で停電時はちゃんとバッテリーに電源が切り替わります
いつもはコンセントから給電しておけばいいけど、その電源が死んだ時は切り替わります
パススルーの回路ですね
作った回路担当はすごいですね(ぼくは作ってない
あとこの開閉機構も結構すごくて紐をわっかにしてロープウェイみたいにしてるんじゃないんです
それだと負荷が大きいカーテンとかだと回転が正常に伝わらない可能性があるので巻き取り式です
片方のボビンから紐を出してもう片方のボビンで巻き取ります
しかも2つボビンはありますけど1個のモーターで行えてます
技術担当はすごいですね(ぼくは作ってません
あとで機構は詳しく書いていこうと思います（めんどくさいので書きません
https://twitter.com/nya3_neko2/status/1177839988358012928?s=21

# 2019/12
やばいよ。こんな感じでテキトーに作ったら知らんうちに学生科学賞の入選１等になっちゃったよ
どういうことだよ
作った期間が赤外線通信の試作機で１週間、ESPにして完全に０から作り直して１週間の研究だぞ
普通にマイコン触ってたり電子工作してる人間ならマジですぐに作れちゃうこんなのでいいのかよ
な〜んも研究してないし「こんなのあったら良さそうだから作った〜。実用性？評価？検証？そんなの知らな〜い」みたいなクソだぞ
これで課題研究とか名乗ってるの恥ずかしすぎる
そもそも研究じゃないやんけ
一応カーテン閉める閾値のためにデータ集めたりしたけどこの程度スクレイピングですぐできるし、これを鼻高々にポスターに乗っけるの恥ずかしすぎるだろ
https://twitter.com/nya3_neko2/status/1204105220025774086?s=20


#おわりに
この記事は実験してる途中なんで備忘録を兼ねて随時更新していきます
主に愚痴ですね
これ見て後輩がこんな感じにテキトーでいいんだあ〜って思ってくれたら幸い