目的
設置した複数のRaspberry Piがネットに繋がっているかをCSVファイルから確認したい。(直接手動でpingコマンドをいちいちうつのは面倒であるため、ファイルから確認できるようにしたい。)
ただし、pingを送信するのは別のRaspberry Piとする。
案
CSVファイルに予めRaspberry PiのIPアドレスを書いておく。
そのIPアドレスにpingを打って、応答があればCSVテーブルに現在日時を書く。
こうすれば、日時が最近のものであればネットに繋がっている、日時が古いものであればネットに繋がっていない、すべての日時が古いものであればping送信しようとしているラズパイがネットに繋がってないと解釈できると考えた。
ソースコードの説明
pingの送信間隔はあとから設定できるように変数に入れています。
ここでは、現在日時が00秒になったら、CSVにあるIPアドレスにpingを送信します(1分間隔)。
pingはラズパイごと順番にやっているとつっかえたときに時間の遅れが出そうなので、それぞれのスレッドで送信しようとしています。多分そうすればすべてのラズパイに対して同じ時間にping送信できる(?)。
ping応答があれば、そのIPアドレス行の更新日時列に現在時間のデータを書きます。なければ何もしません。
作成したソースコード
Python
1from datetime import datetime 2import configparser 3import csv 4import re 5import subprocess 6import threading 7import time 8 9cnt = 0 10exe_time = ["**:**:00"] 11 12 13def read_csv(): 14 path = "/home/pi/デスクトップ/table.csv" 15 data = [] 16 with open(path, "r", newline="", errors="ignore") as rf: 17 f = csv.reader(rf, lineterminator="\r\n") 18 for row in f: 19 data.append(row) 20 return data 21 22 23def write_csv(row, data): 24 path = "/home/pi/デスクトップ/table.csv" 25 with open(path, "w", newline="", encoding="utf_8_sig") as wf: 26 writer = csv.writer(wf, lineterminator="\r\n") 27 now_str = datetime.now().strftime("%Y/%m/%d %H:%M:%S.%f")[:-3] 28 for i in data: 29 # ping成功時のデータは更新する 30 if i[1] == row[1]: 31 writer.writerow([row[0], row[1], row[2], now_str]) 32 # ping失敗時のデータはそのまま 33 else: 34 writer.writerow([i[0], i[1], i[2], i[3]]) 35 36 37# pingコマンド実行タイミング 38# exe_time = ["**:**:00"] で 1分間に1回 39def timing(): 40 global cnt, exe_time 41 for i in range(len(exe_time)): 42 exe_time[i] = exe_time[i].replace("*", r"\d") 43 if re.match(exe_time[i], format(datetime.now(), "%H:%M:%S")) != None: 44 if cnt == 0: 45 cnt = 1 46 return True 47 return False 48 # フラグ処理 49 if cnt == 1: 50 cnt = 0 51 52 53def ping_exe(row, data): 54 cmd = "ping -c 3 " + row[1] 55 ret = subprocess.call(cmd.split(" ")) 56 57 # 試験的にpingの成功失敗デバイスを指定 58 59 if row[1] == "192.168.0.20" or row[1] == "192.168.0.30": 60 ret = 0 61 else: 62 ret = 1 63 64 65 print("ret: {}".format(ret)) 66 if ret == 0: 67 write_csv(row, data) 68 69 70if __name__ == "__main__": 71 try: 72 while True: 73 if timing() == True: 74 data = read_csv() 75 for row in data: 76 threading.Thread(target=lambda:ping_exe(row, data)).start() 77 time.sleep(0.1) 78 79 except KeyboardInterrupt: 80 print("Ctrl + C") 81 82 except Exception as e: 83 print(type(e), e) 84
csv
1ホスト名,IPアドレス,場所,更新日時 2user01,192.168.0.10,玄関, 3user02,192.168.0.20,廊下, 4user03,192.168.0.30,自室,
症状
ping応答したラズパイが複数ある場合に更新日時が反映されないものがある。
(たとえばこの例ではuser02とuser03が成功しているとして、反映されているのが片方だけであったりする。)
スレッドを使って1つのファイルに対して複数のアクセスがあるからこうなってしまうのでしょうか?
また、上の方法では時間データでネット接続を判断していますが他にいい方法があれば教えて下さい。
回答1件
あなたの回答
tips
プレビュー