IoT&HomeServer計画まとめ(3)
IoTコントローラにディフォルトの機能をつけておくことにする。
仕様を公開して、『ユーザーにつくってもらおう』って時は、サンプルが必須ですよねー。
なので、サンプルとして、ディフォルトで機能にいれておこうって話にします。
どんな機能かとういうと。
機能として、以下を考えます。
・画像を10枚用意して、それをbase64したものを、一定時間繰り返し送り続ける
というものです。
PNGを読んでwidthとheightを。
まぁ普通に考えれば、Imageをつかって読み込んで巾と高さを、、ですが、
ここではこうやります。
def getSmileImage64(idx):
AR = ["smile10_1","smile10_2","smile10_3","smile10_4","smile10_5","smile10_6","smile10_7","smile10_8","smile10_9","smile10_0"]
fn = "img/" + AR[idx] + ".png"
#img = Image.open(fn)
#print("img",img)
#ww,hh = img.size
##img.close() #そもそも、なくてよい
A = hiraFile()
if A.open(fn,"r"):
d = A.read()
if d:
www = d[0x13] + d[0x12]*256 + d[0x11] * 256 * 256 + d[0x10] * 256 * 256 * 256
hhh = d[0x17] + d[0x16]*256 + d[0x15] * 256 * 256 + d[0x14] * 256 * 256 * 256
#print("www",www)
#print("hhh",hhh)
S = base64.b64encode( d )
return www,hhh,S
return False
まぁPNGのwidth,heightなんか、ヘッダに書いてあるので、
それを読みます。
どうせファイルを読んでbase64するので、こうやってみました。
これをプラグイン的な役目である、
mhcExec.py
に組み込みます。
mhcExecへの組み込み
#------------------------------------------------------------------------------
def getSmileImage64(self,idx):
AR = ["smile10_1","smile10_2","smile10_3","smile10_4","smile10_5","smile10_6","smile10_7","smile10_8","smile10_9","smile10_0"]
fn = "img/" + AR[idx] + ".png"
A = hiraFile()
if A.open(fn,"r"):
d = A.read()
if d:
www = d[0x13] + d[0x12]*256 + d[0x11] * 256 * 256 + d[0x10] * 256 * 256 * 256
hhh = d[0x17] + d[0x16]*256 + d[0x15] * 256 * 256 + d[0x14] * 256 * 256 * 256
S = base64.b64encode( d )
return www,hhh,S
return False,False,False
#------------------------------------------------------------------------------
def smile10(self):
hash = self.OBJ["hash"]
com = self.OBJ["command"]
while True:
for w in range(10):
www,hhh,S = self.getSmileImage64(w)
if S:
o8 = b"{\"code\":0,\"status\":\"OK\"" + b",\"com\":\"" + str(com).encode("utf8") + b"\",\"hash\":\"" + str(hash).encode("utf8") + b"\",\"width\":" + str(www).encode("utf8") + b",\"height\":" + str(hhh).encode("utf8") + b",\"ret\":\"data:image/png;base64," + S + b"\"}"
self.svReturnDirect(o8)
#------------------------------------------------------------------------------
# go
#------------------------------------------------------------------------------
def go(self,o,DAT):
self.OBJ = o
self.DAT = DAT
com = o["command"]
hash = o["hash"]
#-------------------------------------------------
# 機能サンプル
#-------------------------------------------------
if com=="SMILE10": # SAMPLE 消さないでね!
self.smile10() # if文と合わせて関数を呼ぶ
#-------------------------------------------------
まぁなんていうか、、、
文字列をバイナリに変換したり云々が、なんとなくオーバーヘッド多そうな気がするので、
あえて、読みずらいけど、バイナリの【+】演算子なんかでjsonを作り出しています。
ここでのgo関数は、非同期の戻しの方で、
ひとつのリクエストにいくつ返してもよいので、LOOPで10コ返してます。
要するに、『SMILE10』リクエストに対して、【image/pngのbase64を10コ】返しています。
連続で画像を変更すれば、ちょっとは動いて見えるかな(o^^o)
で、ここまでやって気づくこと。遅^^;
戻り値をjsonにして、
{
"code":0
,"status":"OK"
,"com":"SMILE10"
,"hash":"abcd123456"
,"width":400
,"height":400
,"ret":"data:image/png;base64,iVBORw0KGgoAAAA~~~~~~
}
こんな感じで受け取るようにしたのですが、そう、気づくわけです。
これを、
o = json.loads(mes)
こんな風に受け取ってしまうと、
print("type ret ",type(o["ret"]))
が、情け容赦なく、、
type ret < class ‘str’>
なんて表示しちゃいますよ。
そうすると、ちょっと大きい画像のストリームのbase64をいちいちstrに変換されちゃったりとかってのが、どうしても面白くないので、
全てのI/FはJSONで
って思ってたけど、ここは、
ヘッダ付き可変長
あたりがイイ感じですかねー。
まぁ、ヘッダ部分はJSONにしてもよいですしねー。
つづく