【NFSサーバー】ラズパイ同士のファイル共有によって最新データを取得する [4]

2024/02/20

Discord NFS ファイル共有 ラズパイ

  • B!
[ DHT11シリーズ ]

前回までに作ってきたプログラムでは1日分のデータをすべて記録しないとGoogleDriveにアップロードされませんでした。

これでは過去のデータしか見れないため、少し不便です。

今回は、

  • データをアップロードするプログラムの修正
  • アップロードされているデータのリストを出力
  • 最新データの取得

をやっていきます。

今回使用するもの

  • RaspberryPi(温湿度記録用)
  • RaspberryPi(Bot用)

修正箇所

前回作成した温湿度測定用プログラムでは、1日経過したら前日のデータをアップロードするという処理を行っています。

ですが、前日のデータが無かった場合の処理を書いてないため、初回起動時にエラーが出てしまう欠陥がありました。

また、データの記録を行っていない日があった場合も同様です。

よって、前日のデータが無かった場合はスルーするコードを追加しました。

example.py
def csv_upload(dt_csv_yesterday):
    folder_id = 'Google DriveのフォルダID'
    file_path = 'data/' + str(dt_csv_yesterday) + '.csv'
    file_name = str(dt_csv_yesterday) + '.csv'
    
    is_file = os.path.isfile(file_path)
    if is_file:
        #前日のデータがあった時
        gauth = GoogleAuth()
        gauth.LocalWebserverAuth()
        drive = GoogleDrive(gauth)
        
        file = drive.CreateFile({'title': file_name, 'parents': [{'id': folder_id}]})
        file.SetContentFile(file_path)
        file.Upload()
        print('[INFO] <' + str(datetime.datetime.now().replace(microsecond=0)) + '> Uploaded', file_name)
        
    else:
    	#前日のデータが無かった時
        print('[INFO] <' + str(datetime.datetime.now().replace(microsecond=0)) + '> Not Found', file_name)

データリスト取得(Bot)

以前のBotではグラフ化したい日付のデータを指定する必要がありますが、長く使った場合、いつのデータがあるのか気になる場合があると考えられます。

そのため、今までに記録したデータのファイル名を出力するコマンドを作成します。

raspi_discord.py
@bot.slash_command(name="datalist")
async def data_list_slash(ctx: discord.ApplicationContext):
    """保存されたデータのリストを返します。"""
    gauth = GoogleAuth()
    drive = GoogleDrive(gauth)
    drive_folder_id = 'GoogleDriveのフォルダID'
    query = {'q': '"{}" in parents and trashed=false and title contains ".csv"'.format(drive_folder_id)}

    data_list = []
    for f in drive.ListFile(query).GetList():
        data_list.append(f['title'])
    print('[INFO] <' + str(datetime.datetime.now().replace(microsecond=0)) + '>', 'Sent list of data')
    await ctx.respond('[ Data List ]\n' + '\n'.join(data_list))

実行結果

このように保存されたCSVファイルのリストが送られてきます。

最新の計測データを取得する

では、最新のデータを得る方法を考えていきます。

① 最新のデータを記録する用のCSVをGoogleDriveにアップロードする
② NASを用意してラズパイを接続する
③ RaspberryPi(記録用)とRaspberryPi(Bot用)をNFSで接続する

①では最新データを記録するたび(15分毎)にGoogle Driveにアップロードします。

そのため最新データが欲しくない時でもGoogleDriveAPIを使用します。

APIの使用回数が多くなりすぎるため却下します。


②はNASとラズパイを接続します。

「ラズパイA → NAS → ラズパイB」というようなルートでファイルを共有します。

実現できそうですがNASを用意するコストが高いです。


③はNFSサーバーを立ててラズパイ同士を接続します。

「ラズパイA → ラズパイB」というようにファイルを共有します。

「ラズパイB → ラズパイA」も可能です。

②と比較してラズパイの間に挟むものが無いのでコストがかかりません。

簡単にラズパイ間のファイル共有ができてしまうのもポイントです。

今回は③の方法を使っていきます。

NFSサーバーの設定

RaspberryPi(Bot用)

#サーバーのインストール
sudo apt-get install nfs-kernel-server

#/etc/exports に追記
sudo nano /etc/exports

#以下を追記
共有したいフォルダのパス RaspberryPi(温湿度記録用)のIP(rw,sync,no_subtree_check)
#例 => /mnt/hdd/data  192.168.x.xx(rw,sync,no_subtree_check)

RaspberryPi(温湿度記録用)

sudo apt-get install nfs-common

マウントするフォルダを作成

#例
/home/pi/Desktop/DiscordBot/Latest

#マウントの実行
sudo mount -t nfs RaspberryPi(温湿度記録用)のIP:共有するパス  マウントするフォルダ(Bot用)
#例 => sudo mount -t nfs 192.168.x.xx:/mnt/hdd/data  /home/pi/Desktop/DiscordBot/Latest

注意

両方のラズパイの設定で「ネットワーク接続を確立するまでブートを待つ」を有効にします。

無効のままだとネットワーク接続が確立する前にNFSサーバーが起動してしまいマウントできません。

これで、ラズパイ間の共有設定が終わりました。

最新データの記録

今までCSVファイルにデータを書き込んでいた場所の下にコードを追加します。

このCSVファイルは温湿度を取得するたびに書き換えが行われます。

example.py
#Write to CSV file [LatestData]
latest = 'LatestData/latest_data.csv'
with open(latest, 'w', newline='') as f:
	fieldnames  = ['DateTime', 'Temperature', 'Humidity']
	writer = csv.DictWriter(f, fieldnames=fieldnames )
	writer.writeheader()
	writer = csv.writer(f)
	writer.writerows(data)

最新データのリクエスト

Botにコマンドを追加します。

raspi_discord.py
@bot.slash_command(name="latestdata")
async def data_list_slash(ctx: discord.ApplicationContext):
    """最新のデータを送ります"""
    path = 'Latest/latest_data.csv'
    with open(path,newline='') as f:
        csvreader = csv.reader(f)
        content = [row for row in csvreader]
    
    dt_latest = '[LatestData]\n' + str(content[1][0]) + '\n'
    temp_latest = 'Temp : ' + str(content[1][1]) + '℃\n'
    humi_latest = 'Humi : ' + str(content[1][2]) + '%'
    send_data = dt_latest + temp_latest + humi_latest
    print('[INFO] <' + str(datetime.datetime.now().replace(microsecond=0)) + '>', 'Sent latest data')
    await ctx.respond(send_data)

実行結果

新しいデータが記録されると共有フォルダ内のCSVファイルが更新されて、最新データが送信されています。

まとめ

今回はラズパイ同士のファイル共有を可能にし、最新データを送信する事ができました。

ラズパイ同士のファイル共有だけでなくPCとラズパイのファイル共有をSambaサーバーで行えば、GoogleDriveを使う必要がなくなります。

GoogleDriveから脱却することで15GBの制限からのがれることも可能です。

ラズパイで監視カメラを作成する場合など、容量の大きいファイルを扱う場合は大容量のHDD、SSDを使ってUSB Bootさせたラズパイを用いるとより開発の幅が広がります。

Ranking

Community

Search