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を設定して戻してます。
つづく。