リモートカメラシステム（MQTT ブローカーの検証）

次のシステムを構築するための検証です。
[Grove IoT スターターキット for SORACOM で作るリモートカメラシステム](https://qiita.com/ekzemplaro/items/541b82908cec46f6aa7b)

>画像の受け渡しが MQTT ブローカー経由でできるか。
>画像ファイルは、計測した数値データと較べて、かなり大きい。

以下のプログラムを作成しました。
>jpg を JSON に変換するプログラム
>JSON を publish するプログラム
>subscribe で JSON を受け取るプログラム
>JSON を jpg に変換するプログラム

jpg を JSON に変換するプログラム

```py:jpg_to_json.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	jpg_to_json.py
#
#					Aug/17/2021
#
# ------------------------------------------------------------------
import	sys
import	os
import	json
import	base64
#
# ------------------------------------------------------------------
def file_write_proc(file_name,str_out):
	fp_out = open(file_name,mode='w',encoding='utf-8')
	fp_out.write(str_out)
	fp_out.close()
#
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

name_base = sys.argv[1]
file_jpg = name_base + ".jpg"
file_json = name_base + ".json"
sys.stderr.write(file_jpg + "\n")
sys.stderr.write(file_json + "\n")

file_data = open(file_jpg, "rb").read()
b64_data = base64.b64encode(file_data).decode('utf-8')
sys.stderr.write("len(b64_data) = %d\n" % len(b64_data))
#
unit_aa = {}
unit_aa['base64'] = b64_data
unit_aa['filename'] = file_jpg
#
out_str = json.dumps(unit_aa)
file_write_proc(file_json,out_str)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

JSON を publish するプログラム

```py:publish.py
#! /usr/bin/python3
#
#	publish.py
#
#					Aug/17/2021
# ------------------------------------------------------------------
import sys
import paho.mqtt.client as mqtt

MQTT_HOST = "violet.local"
MQTT_TOPIC = "sample/imageTopic"
MQTT_PORT = 1883
MQTT_KEEP_ALIVE = 60

# ------------------------------------------------------------------
def on_connect(mqttc, obj, flags, rc):
	print("rc: " + str(rc))

# ------------------------------------------------------------------
def file_to_str_proc(file_in):
	str_out = ""
	try:
		fp_in = open(file_in,encoding='utf-8')
		str_out = fp_in.read()
		fp_in.close()
	except Exception as ee:
		sys.stderr.write("*** error *** file_to_str_proc ***\n")
		sys.stderr.write(str (ee))
#
	return	str_out
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_in = sys.argv[1]
sys.stderr.write(file_in + "\n")
json_str = file_to_str_proc(file_in)

mqttc = mqtt.Client()
mqttc.on_connect = on_connect

mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)

mqttc.loop_start()

print(len(json_str))

mqttc.publish(MQTT_TOPIC,json_str)

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

subscribe で JSON を受け取るプログラム

```py:subscribe.py
#! /usr/bin/python3
#
#	subscribe.py
#
#					Aug/17/2021
# ------------------------------------------------------------------
import paho.mqtt.client as mqtt

MQTT_HOST = "violet.local"
MQTT_TOPIC = "sample/imageTopic"
MQTT_PORT = 1883                # brokerのport
MQTT_KEEP_ALIVE = 60            # keep alive
#
# ------------------------------------------------------------------
def on_connect(mqttc, obj, flags, rc):
	print("rc: " + str(rc))
#
# ------------------------------------------------------------------
def on_message(mqttc, obj, msg):
	file_name = "out01.json"
	print(msg.topic + " " + str(msg.qos))
	str_out = msg.payload.decode()
	print(len(str_out))
	fp_out = open(file_name,mode='w',encoding='utf-8')
	fp_out.write(str_out)
	fp_out.close()

# ------------------------------------------------------------------
mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)
mqttc.subscribe(MQTT_TOPIC)

mqttc.loop_forever()
# ------------------------------------------------------------------
```

JSON を jpg に変換するプログラム

```py:json_to_jpg.py
#! /usr/bin/python
#
#	json_to_jpg.py
#
#						Aug/17/2021
# --------------------------------------------------------------------
import sys
import json
import base64
import numpy as np
import cv2
#
# --------------------------------------------------------------------
file_json = sys.argv[1]
sys.stderr.write(file_json + "\n")
#
fp_in = open(file_json,encoding='utf-8')
json_str = fp_in.read()
fp_in.close()
#
dict_aa = json.loads(json_str)
data_64 = dict_aa["base64"]
file_jpg = dict_aa["filename"]
sys.stderr.write(file_jpg + "\n")
#
sys.stderr.write("len(data) = %d\n" % len(data_64))
#
img_binary = base64.b64decode(data_64)
#
jpg=np.frombuffer(img_binary,dtype=np.uint8)
img = cv2.imdecode(jpg, cv2.IMREAD_COLOR)
cv2.imwrite(file_jpg,img)
#
# --------------------------------------------------------------------
```

テスト方法
ブローカーは LAN 内の　violet.local にあるものを使いました。
RaspberryPi にインストールした mosquitto です。

テストに使った　jpg　は次の大きさです。

```text
-rw-r--r-- 1 uchida wheel  3870 Aug 17 08:41 camera.jpg
```

JSON に変換して送信するスクリプト

```bash
../jpeg_to_json/jpeg_to_json.py camera
#
../python/publish.py camera.json
```

別のフォルダーで受信をします。
送信前にこの操作が必要です。

```bash
./subscribe.py
```

受信すると out01.json で作成されます。

jpg に変換します。

```bash
./json_to_jpg.py out01.json
```

camera.jpg が作成されます。

結論
> 画像の受け渡しが MQTT ブローカー経由でできる。