さて、前回カウンターの値を、ソケット通信でサーバに接続して、
送るところまでやりましたが、
サーバを一度落としてしまうと、
サーバが再起動しても、クライアントの再接続がなかなかできず、苦労しました。
最終的に実現した方法は。
① カウントのプログラムは独立させて、カウントをテキストに記録し続ける。
② 通信プログラムを用意し、カウントのテキストを読み込んで、サーバに送信する。
③ サーバへの送信に失敗したら、シェルスクリプトを使用して、通信プログラムを再起動し、自分は終了する。
④ 通信プログラムは接続できるまで待機し続けるので、サーバが再起動されると、再接続される。
最初は計数のカウントと通信を同時にpython でやろうとしたのですが、
計数カウントを取り続けながら、サーバへ再接続するのが難しくて、
分離して単純化しました。
通信プログラムで、サーバへの送信が失敗した時に、単純に再接続しようとしましたが、うまくいきませんでした。再接続不能になるか、何度も接続と切断を繰り返してしまうような挙動になってしまいました。
うまくいかないので、通信プログラム自体を再起動することにし、シェルスクリプトで実装しました。
以下、新しいカウンターのプログラム
import RPi.GPIO as GPIO
import struct
import time
from time import sleep
import socket
import sys
def write_count(count):
f = open('/home/XXXXX/count.txt' ,'w')
f.write(str(count))
f.close()
def callBackRising(channel):
if GPIO.input(24):
# GPIO.output(25,GPIO.HIGH)
global count
count += 1
try:
print(str(count))
write_count(count)
except:
pass
else :
pass
# GPIO.output(25,GPIO.LOW)
def read_do():
f = open('/home/XXXXX/do.txt','r')
doStr = f.read()
if (doStr == 'True'):
return True
elif (doStr == 'False'):
return False
else:
return True
def main():
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)
global count
count = 0
f = open("/home/XXXXX/count.txt","r")
countstr = f.read()
try:
count = int(countstr)
except:
count = 0
pin = 24
flg = False
#start_time = time.time() - start_time
GPIO.setup(pin, GPIO.IN)
#GPIO.add_event_detect(pin, GPIO.RISING, callback=callBackRising,bouncetime=100)
#GPIO.add_event_detect(pin, GPIO.FALLING, callback=callBackFalling, bouncetime=150)
GPIO.add_event_detect(pin, GPIO.BOTH, callback=callBackRising, bouncetime=200)
DoFlg = True
count_try = 0
try:
while DoFlg:
DoFlg = read_do
sleep(1)
finallizeFlg = False;
c_socket.close()
GPIO.cleanup()
except KeyboardInterrupt:
print("end cleanup")
GPIO.cleanup()
if __name__ == '__main__':
main()
***********ここまでがカウンター**************************************************
次は通信プログラムです。
import struct
import time
from time import sleep
import socket
import sys
import signal
import os
HOSTNAME = "192.168.30.131"
PORT = 8600
INTERVAL = 3
RETRYTIMES = 1
global c_socket
def write_count(count):
f = open('/home/shared/tp-1/count.txt' ,'w')
f.write(str(count))
f.close()
def read_do():
f = open('/home/shared/tp-1/do.txt','r')
doStr = f.read()
if (doStr == 'True'):
return True
elif (doStr == 'False'):
return False
else:
return True
def read_count():
f = open('/home/shared/tp-1/count.txt','r')
countStr = f.read()
try:
return int(countStr)
except:
pass
def SendCount(arg1, arg2):
try:
count = read_count()
c_socket.send(str(count))
except:
savelog('exception happend')
os.system('/home/hsmt_system/XXXXXX/restart.sh &')
savelog('after sh')
sys.exit(0)
def savelog(msg):
f = open('/home/hsmt_system/h_counter/log.txt' ,'a')
f.write(str(msg) + '\n')
f.close()
def socket_connect(host, port, interval, retries):
global c_socket
c_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
for x in range(retries):
try:
c_socket.connect*1
return c_socket
except socket.error:
print "wait"+str(interval)+"s"
time.sleep(interval)
c_socket.close()
return None
def main():
passFlg = False
c_socket = socket_connect(HOSTNAME,PORT,INTERVAL,RETRYTIMES)
while c_socket is None:
c_socket = socket_connect(HOSTNAME,PORT,INTERVAL,RETRYTIMES)
if c_socket is None:
print "system exit:connection error"
sys.exit(0)
if __name__ == '__main__':
main()
signal.signal(signal.SIGALRM, SendCount)
signal.setitimer(signal.ITIMER_REAL, 0.2, 0.2)
connectFlg = False
errorFlg = False
while True:
time.sleep(1)
try:
c_socket.close()
GPIO.cleanup()
except KeyboardInterrupt:
print("end cleanup")
c_socket.close()
*************ここまでが通信プログラム**********************************
最後に、再起動用のシェルスクリプトです。
#!/bin/sh
python /home/xxxx.py
*1:host, port