IoT+WEBのためのホームサーバ計画の実装編1。IoTコントローラの実装の1(o^^o)

前回、次回は Webサーバ周りの設定、、、なんて書いておきながら、
やっぱりプログラム書きたくなったの実装編突入にしました。

最初は、IoTコントローラです。
でも、対抗というか、、通信先が必要なので、HomeServerもちょっとやりましょう。

最初にちょっと、
https://stackoverflow.com/questions/12706145/how-to-simulate-const-variable-in-python
ここらあたりを参考に、というかパクって、const.pyを作っときますよ。

そして、constものをひとつにまとめときましょう。
現段階ではこれだけです。

#-------------------------------------------------------
import const
#-------------------------------------------------------
const.HIRA_USE_UDP_PORT = 60011
const.HIRA_USE_TCP_PORT = 60009
#--------------------------------------

さて、IoTコントローラですね。
ネーミングですが、ここでは、【mhc】としました。
必要なのは、
●UDP_client
● TCP_server
● 実行本体
●実行のタイムアウト検出
の4つです。

さて、なにがプロセスで何がThreadかなんて話を前にしかけましたが、
実は、タイムアウト検出クラス(のインスタンス)は、TCP_serverを通ってから、
実行本体へ参照が渡されます。
そして、実行本体から実行プロセスを生成し、
そのプロセスのタイムアウトを検知することになるので、

参照渡しの部分が別プロセスだと、コピーされた実体が渡ってしまう

ということに注意をしなくちゃならないです。

よって、UDP_clientと、その他くらいしか、プロセスとしては分離できませんでした。
ということで、こんな感じです。

def	watcher(T):
  #監視するクラス。ここでTCP_serverを生成する
def	reciever(conn,mes,alter):
  #TCP_serverが受信したときに、呼び出される関数
def register():
  #ある間隔でブロキャスしつづける
if __name__ == '__main__':
 T = hiraTimeOuter(5)#※1
	T.loop()※2
	O = {"timeouter":T}※3

	p = multiprocessing.Process(target = register)※4
	p.start()※5

	q = threading.Thread(target = watcher,args=(O,))※6#ここをプロセスにすると、Oのコピーが渡ってしまう。
	q.start()※7

では、詳細を。

最初に、タイムアウトクラスのインスタンスを生成。※1
そして、1秒のLOOPに入ります。※2
そして、変数にObjectを入れます。※3
とくに意味は無いのですが、あとから何か情報を追加したいときのためにだけこうしてます。

そして、ブロードキャストしつづける関数を別プロセスで起動して実行します。※4※5
そして、TCP_serverを生成する関数をスレッドで生成して実行します。※6※7

で、SRCはというと、、

#-------------------------------------------------------
import const
import os
import sys
import json
import socket
import traceback
import time
import threading
import multiprocessing
#--------------------------------------
from hiraSockUDPC	import hiraSockUDPC		#	UDP client
from hiraSockTCP	import hiraSockTCP		#	TCP server
from hiraTimeOuter	import hiraTimeOuter	#	TimeOut
from mhcExec		import mhcExec			#	CUSTOM execute 
#--------------------------------------
import hiraSetting	# only port number
#--------------------------------------
def	getinfo(id):
	filename = os.path.abspath("mhc.n")
	with open(filename, "br") as f:
		try:
			J = json.loads(f.read())
			if J['id'] == '':
				f.close()
				J['id'] = id
				jstr	= json.dumps(J,separators=(',', ':'))
				jstr8	= jstr.encode('utf-8')
				with open(filename, "bw") as f:
					f.write(jstr8)
			J["status"] = "OK"
		except Exception as e:
			J	= {"status":"NG"}
		return	J
#----------------------------------
#	TCP SERVER 起動
#----------------------------------
def	watcher(T):
	#print("watcher.alter:",T)
	print("TCP SERVER WATCH START.")
	laddress = socket.gethostbyname(socket.gethostname())
	with hiraSockTCP(laddress,const.HIRA_USE_TCP_PORT) as S:
		S.setFunc(reciever)
		S.setAlter(T)
		S.exec()
#----------------------------------
#	TCP SERVER RECV imprement
#	conn:	connection
#	mes:	recv message
#	alter:	alternated info ➡ hiraTimeOuter
#----------------------------------
def	reciever(conn,mes,alter):
	try:
		o		= json.loads(mes)
		sign	= o['sign']
		cmd		= o['cmd']
		print("called [",cmd,"]")
		if sign != "FINRED":
			raise()
		if cmd == "GETINFO":	#mhc.nのidを書き換えて送信。
			J = getinfo(o['uuid'])
			rets	= json.dumps(J,separators=(',', ':'))
			conn.sendall(rets.encode('utf-8'))
		else:
			ret		= {"status":"OK"}
			rets	= json.dumps(ret,separators=(',', ':'))
			conn.sendall(rets.encode('utf-8'))
			mhcExec.exec(conn,mes,alter)
	except Exception as e:
		ret		= {"status":"NG"}
		rets	= json.dumps(ret,separators=(',', ':'))
		conn.sendall(rets.encode('utf-8'))
#----------------------------------
#	UDPで知らせる方。
#----------------------------------
def register():
	#for w in range(100):
	while True:
		C = hiraSockUDPC()
		C.exec("FINRED_BROADING")
		print("upto FINRED_BROADING")
		time.sleep(30)
#----------------------------------
if __name__ == '__main__':
	T = hiraTimeOuter(5)
	T.loop()
	O = {"timeouter":T}
	p = multiprocessing.Process(target = register)
	p.start()
	q = threading.Thread(target = watcher,args=(O,))
	q.start()
#--------------------------------------

こんな感じです。

そうそう、【GETINFO】のコマンドのときに、mhc.nというファイルにIDを設定して戻してます。

つづく。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です