Hyungsun Yoon

[HW] Rpi4 Code added with MQTT Support

......@@ -10,3 +10,4 @@
+ 2021.05.03: Init(개인 아두이노 코드 git에서 이전)
+ 2021.05.11: Arduino 개발 중단, RaspberryPi Pico로 플랫폼 이전, C++ -> MicroPython
+ 2021.05.12: RaspberryPi Pico v0.1 code complete. Now working on rpi4 with MQTT.
+ 2021.05.13: RaspberryPi4 v0.1 code complete. with MQTT. + Pico code bug fix.
\ No newline at end of file
......
# RaspberryPi4용 코드
- rpi.py
```
라즈베리파이 메인코드
```
- serverside_mqtt_stest.py
```
server에서 데이터 보낼 예제
```
- serverside_mqtt_rtest.py
```
server에서 수신한 데이터
```
python rpi.py동작 후, test코드 활용해서 테스트 가능
paho-mqtt
\ No newline at end of file
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
from bluetooth import *
import time
MQTT_BLOCK = False
BT_MAC_ADDRESS = '00:18:91:D8:24:39'
MED_BOTT_NO = '1'
client_socket = BluetoothSocket( RFCOMM )
client_socket.connect(("00:18:91:D8:24:39", 1))
print("bluetooth connected!")
client_mqtt = mqtt.Client()
# --------------------------------------------------- #
# INTERNAL FUNCTIONS
# --------------------------------------------------- #
def _send_data(msg:str):
''' Bluetooth를 통해 데이터를 송신한다
'''
client_socket.send(msg)
def _recv_data():
''' Bluetooth를 통해 데이터를 수신한다
'''
# 소켓에 2초간 받을 수 있는 시간을 준다
client_socket.settimeout(2)
......@@ -21,23 +35,99 @@ def _recv_data():
while time.time() < timeout_start + timeout:
data += client_socket.recv(1024).decode('utf-8')
except:
print("INFO: DATA RECV TIMEOUT")
print('INFO: DATA RECV TIMEOUT')
finally:
return data
while True:
sel_mode = input("SELECT MODE: ")
def _sub_mqtt(client, userdata, flags, rc):
''' MQTT에서 subscribe한다
'''
print("Connected with result code "+str(rc))
client.subscribe(f'bottle/1/stb')
if sel_mode == 'W':
msg = input("send message : ")
_send_data(msg)
def _work_mqtt(client, userdata, msg):
''' MQTT에서 데이터를 받으면 알맞게 로직을 수행한다
'''
print('DOING SOMETHING')
global MQTT_BLOCK
MQTT_BLOCK = True
elif sel_mode == 'WR':
msg = input("send message : ")
_send_data(msg)
received_msg = msg.payload.decode('utf-8')
data = ''
data_list = []
# 만약 req메시지를 받았다면
if received_msg == 'req':
while len(data_list) != 4:
_send_data('REQ')
data = _recv_data()
print(f"Received: {data}")
data_list = data.split('/')
# 데이터를 Publish한다
_pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost')
# 만약 res메시지를 받았다면
elif received_msg.split('/')[0] == 'res':
_send_data(received_msg.split('/')[1])
data = _recv_data()
data_list = data.split('/')
while len(data_list) != 4:
_send_data('REQ')
data = _recv_data()
data_list = data.split('/')
# 데이터를 Publish한다
_pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost')
print("DEBUG")
print(data)
print(data_list)
print(received_msg)
MQTT_BLOCK = False
def _pub_mqtt(topic:str, payload:str, hostname:str):
''' MQTT를 통해 데이터를 publish한다
'''
publish.single(
topic=topic,
payload=payload,
hostname=hostname)
# --------------------------------------------------- #
# MAIN
# --------------------------------------------------- #
def _run():
# CONNECT BT
client_socket.connect((BT_MAC_ADDRESS, 1))
print('bluetooth connected!')
# SUBSCRIBE MQTT
client_mqtt.on_connect = _sub_mqtt
client_mqtt.on_message = _work_mqtt
client_mqtt.connect_async("localhost")
client_mqtt.loop_start()
while True:
if MQTT_BLOCK is False:
# 항상 데이터를 받을 상태로 있는다
data = _recv_data()
# 만약 데이터가 ''가 아니면 무언가 온 것이므로 처리한다
if data != '':
print('DATA IN')
data_list = data.split('/')
# 만약 데이터가 불량하게 왔을 경우, 제대로 올때까지 반복시도한다
while len(data_list) != 4:
data = _recv_data()
data_list = data.split('/')
# 데이터를 Publish한다
_pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost')
client_socket.close()
client_socket.close()
\ No newline at end of file
if __name__ == '__main__':
_run()
\ No newline at end of file
......
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe("bottle/1/bts") # 요거 수정해서 확인하세요
def on_message(client, userdata, msg):
print(msg.topic)
print(msg.payload.decode('utf-8'))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect_async("localhost")
client.loop_start()
while True:
print("TESTing")
time.sleep(1)
\ No newline at end of file
import paho.mqtt.publish as publish
# hub -> server
# msgs = \
# [
# {
# 'topic':"bottle/1/bts",
# 'payload':"1/30.4/32.2/1"
# }
# ]
# server -> hub with date
# msgs = \
# [
# {
# 'topic':"bottle/1/stb",
# 'payload':"res/0513"
# }
# ]
# server -> hub without date
msgs = \
[
{
'topic':"bottle/1/stb",
'payload':"req"
}
]
publish.multiple(msgs, hostname="localhost")
......@@ -8,8 +8,9 @@ display4 = tm1637.TM1637(clk=Pin(12), dio=Pin(13))
# --------------------------------------------------- #
def work_tm1637(data:str):
display4.show(data)
sleep(2)
mydisplay.show(' ')
def off_tm1637():
display4.show(' ')
# # Show a word
# mydisplay.show("Pico")
......
......@@ -10,6 +10,21 @@ import reed
import display4
# --------------------------------------------------- #
# FUNCTIONS
# --------------------------------------------------- #
def _collect_sensor_datas(reed_data:int) -> str:
# Collect Humidity, Temperature
dht_data = dht.work_dht()
if dht_data == False:
dht_data = [0,0]
# Collect Ultrasonic distance
ultrasonic_data = ultrasonic.work_sr04()
# Make data string
send_data_str = str(reed_data) + '/' + str(dht_data[1]) + '/' + str(dht_data[0]) + '/' + str(ultrasonic_data)
return send_data_str
# --------------------------------------------------- #
# LOOP ENTRYPOINT
# --------------------------------------------------- #
def _run():
......@@ -37,22 +52,16 @@ def _run():
# IF INPUT MEANS GET MESSAGE or MEDICINE LID STATUS CHANGED
if input_data == 'REQ' or reed_data != current_reed_data:
# Collect Humidity, Temperature
dht_data = dht.work_dht()
if dht_data == False:
dht_data = [0,0]
# Collect Ultrasonic distance
ultrasonic_data = ultrasonic.work_sr04()
# Make data string
send_data_str = str(reed_data) + '/' + str(dht_data[1]) + '/' + str(dht_data[0]) + '/' + str(ultrasonic_data)
# Send data using BT
bto.send_data_bt(send_data_str)
bto.send_data_bt(_collect_sensor_datas(reed_data))
else:
# Refine BT data
input_data = input_data.strip()
display4.work_tm1637(input_data)
neopixel.work_led()
display4.off_tm1637()
# Send data using BT
bto.send_data_bt(_collect_sensor_datas(reed_data))
# Update reed state
reed_data = current_reed_data
......