Hyungsun Yoon

[HW] Rpi4 Code added with MQTT Support

...@@ -9,4 +9,5 @@ ...@@ -9,4 +9,5 @@
9 ## 일정 9 ## 일정
10 + 2021.05.03: Init(개인 아두이노 코드 git에서 이전) 10 + 2021.05.03: Init(개인 아두이노 코드 git에서 이전)
11 + 2021.05.11: Arduino 개발 중단, RaspberryPi Pico로 플랫폼 이전, C++ -> MicroPython 11 + 2021.05.11: Arduino 개발 중단, RaspberryPi Pico로 플랫폼 이전, C++ -> MicroPython
12 -+ 2021.05.12: RaspberryPi Pico v0.1 code complete. Now working on rpi4 with MQTT.
...\ No newline at end of file ...\ No newline at end of file
12 ++ 2021.05.12: RaspberryPi Pico v0.1 code complete. Now working on rpi4 with MQTT.
13 ++ 2021.05.13: RaspberryPi4 v0.1 code complete. with MQTT. + Pico code bug fix.
...\ No newline at end of file ...\ No newline at end of file
......
1 +# RaspberryPi4용 코드
2 +
3 +- rpi.py
4 +```
5 +라즈베리파이 메인코드
6 +```
7 +- serverside_mqtt_stest.py
8 +```
9 +server에서 데이터 보낼 예제
10 +```
11 +- serverside_mqtt_rtest.py
12 +```
13 +server에서 수신한 데이터
14 +```
15 +python rpi.py동작 후, test코드 활용해서 테스트 가능
1 +paho-mqtt
...\ No newline at end of file ...\ No newline at end of file
1 +import paho.mqtt.client as mqtt
2 +import paho.mqtt.publish as publish
3 +
1 from bluetooth import * 4 from bluetooth import *
2 import time 5 import time
3 6
7 +MQTT_BLOCK = False
8 +
9 +BT_MAC_ADDRESS = '00:18:91:D8:24:39'
10 +MED_BOTT_NO = '1'
11 +
4 client_socket = BluetoothSocket( RFCOMM ) 12 client_socket = BluetoothSocket( RFCOMM )
5 -client_socket.connect(("00:18:91:D8:24:39", 1)) 13 +client_mqtt = mqtt.Client()
6 -print("bluetooth connected!")
7 14
15 +# --------------------------------------------------- #
16 +# INTERNAL FUNCTIONS
17 +# --------------------------------------------------- #
8 def _send_data(msg:str): 18 def _send_data(msg:str):
19 + ''' Bluetooth를 통해 데이터를 송신한다
20 + '''
9 client_socket.send(msg) 21 client_socket.send(msg)
10 22
11 def _recv_data(): 23 def _recv_data():
24 + ''' Bluetooth를 통해 데이터를 수신한다
25 + '''
12 # 소켓에 2초간 받을 수 있는 시간을 준다 26 # 소켓에 2초간 받을 수 있는 시간을 준다
13 client_socket.settimeout(2) 27 client_socket.settimeout(2)
14 28
...@@ -21,23 +35,99 @@ def _recv_data(): ...@@ -21,23 +35,99 @@ def _recv_data():
21 while time.time() < timeout_start + timeout: 35 while time.time() < timeout_start + timeout:
22 data += client_socket.recv(1024).decode('utf-8') 36 data += client_socket.recv(1024).decode('utf-8')
23 except: 37 except:
24 - print("INFO: DATA RECV TIMEOUT") 38 + print('INFO: DATA RECV TIMEOUT')
25 finally: 39 finally:
26 return data 40 return data
27 41
28 42
29 -while True: 43 +def _sub_mqtt(client, userdata, flags, rc):
30 - sel_mode = input("SELECT MODE: ") 44 + ''' MQTT에서 subscribe한다
45 + '''
46 + print("Connected with result code "+str(rc))
47 + client.subscribe(f'bottle/1/stb')
31 48
32 - if sel_mode == 'W': 49 +def _work_mqtt(client, userdata, msg):
33 - msg = input("send message : ") 50 + ''' MQTT에서 데이터를 받으면 알맞게 로직을 수행한다
34 - _send_data(msg) 51 + '''
35 - 52 + print('DOING SOMETHING')
36 - elif sel_mode == 'WR': 53 + global MQTT_BLOCK
37 - msg = input("send message : ") 54 + MQTT_BLOCK = True
38 - _send_data(msg) 55 +
56 + received_msg = msg.payload.decode('utf-8')
39 57
58 + data = ''
59 + data_list = []
60 +
61 + # 만약 req메시지를 받았다면
62 + if received_msg == 'req':
63 + while len(data_list) != 4:
64 + _send_data('REQ')
65 + data = _recv_data()
66 + data_list = data.split('/')
67 + # 데이터를 Publish한다
68 + _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost')
69 +
70 + # 만약 res메시지를 받았다면
71 + elif received_msg.split('/')[0] == 'res':
72 + _send_data(received_msg.split('/')[1])
40 data = _recv_data() 73 data = _recv_data()
41 - print(f"Received: {data}") 74 + data_list = data.split('/')
75 + while len(data_list) != 4:
76 + _send_data('REQ')
77 + data = _recv_data()
78 + data_list = data.split('/')
79 + # 데이터를 Publish한다
80 + _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost')
81 +
82 + print("DEBUG")
83 + print(data)
84 + print(data_list)
85 + print(received_msg)
86 + MQTT_BLOCK = False
87 +
88 +def _pub_mqtt(topic:str, payload:str, hostname:str):
89 + ''' MQTT를 통해 데이터를 publish한다
90 + '''
91 + publish.single(
92 + topic=topic,
93 + payload=payload,
94 + hostname=hostname)
95 +
96 +
97 +# --------------------------------------------------- #
98 +# MAIN
99 +# --------------------------------------------------- #
100 +def _run():
101 + # CONNECT BT
102 + client_socket.connect((BT_MAC_ADDRESS, 1))
103 + print('bluetooth connected!')
104 +
105 + # SUBSCRIBE MQTT
106 + client_mqtt.on_connect = _sub_mqtt
107 + client_mqtt.on_message = _work_mqtt
108 + client_mqtt.connect_async("localhost")
109 + client_mqtt.loop_start()
110 +
111 +
112 + while True:
113 + if MQTT_BLOCK is False:
114 + # 항상 데이터를 받을 상태로 있는다
115 + data = _recv_data()
116 +
117 + # 만약 데이터가 ''가 아니면 무언가 온 것이므로 처리한다
118 + if data != '':
119 + print('DATA IN')
120 + data_list = data.split('/')
121 +
122 + # 만약 데이터가 불량하게 왔을 경우, 제대로 올때까지 반복시도한다
123 + while len(data_list) != 4:
124 + data = _recv_data()
125 + data_list = data.split('/')
126 +
127 + # 데이터를 Publish한다
128 + _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost')
129 +
130 + client_socket.close()
42 131
43 -client_socket.close()
...\ No newline at end of file ...\ No newline at end of file
132 +if __name__ == '__main__':
133 + _run()
...\ No newline at end of file ...\ No newline at end of file
......
1 +import paho.mqtt.client as mqtt
2 +
3 +import time
4 +
5 +def on_connect(client, userdata, flags, rc):
6 + print("Connected with result code "+str(rc))
7 + client.subscribe("bottle/1/bts") # 요거 수정해서 확인하세요
8 +
9 +def on_message(client, userdata, msg):
10 + print(msg.topic)
11 + print(msg.payload.decode('utf-8'))
12 +
13 +client = mqtt.Client()
14 +client.on_connect = on_connect
15 +client.on_message = on_message
16 +
17 +client.connect_async("localhost")
18 +client.loop_start()
19 +
20 +while True:
21 + print("TESTing")
22 + time.sleep(1)
...\ No newline at end of file ...\ No newline at end of file
1 +import paho.mqtt.publish as publish
2 +
3 +# hub -> server
4 +# msgs = \
5 +# [
6 +# {
7 +# 'topic':"bottle/1/bts",
8 +# 'payload':"1/30.4/32.2/1"
9 +# }
10 +# ]
11 +
12 +# server -> hub with date
13 +# msgs = \
14 +# [
15 +# {
16 +# 'topic':"bottle/1/stb",
17 +# 'payload':"res/0513"
18 +# }
19 +# ]
20 +
21 +# server -> hub without date
22 +msgs = \
23 +[
24 + {
25 + 'topic':"bottle/1/stb",
26 + 'payload':"req"
27 + }
28 +]
29 +
30 +publish.multiple(msgs, hostname="localhost")
...@@ -8,8 +8,9 @@ display4 = tm1637.TM1637(clk=Pin(12), dio=Pin(13)) ...@@ -8,8 +8,9 @@ display4 = tm1637.TM1637(clk=Pin(12), dio=Pin(13))
8 # --------------------------------------------------- # 8 # --------------------------------------------------- #
9 def work_tm1637(data:str): 9 def work_tm1637(data:str):
10 display4.show(data) 10 display4.show(data)
11 - sleep(2) 11 +
12 - mydisplay.show(' ') 12 +def off_tm1637():
13 + display4.show(' ')
13 14
14 # # Show a word 15 # # Show a word
15 # mydisplay.show("Pico") 16 # mydisplay.show("Pico")
......
...@@ -10,6 +10,21 @@ import reed ...@@ -10,6 +10,21 @@ import reed
10 import display4 10 import display4
11 11
12 # --------------------------------------------------- # 12 # --------------------------------------------------- #
13 +# FUNCTIONS
14 +# --------------------------------------------------- #
15 +def _collect_sensor_datas(reed_data:int) -> str:
16 + # Collect Humidity, Temperature
17 + dht_data = dht.work_dht()
18 + if dht_data == False:
19 + dht_data = [0,0]
20 + # Collect Ultrasonic distance
21 + ultrasonic_data = ultrasonic.work_sr04()
22 + # Make data string
23 + send_data_str = str(reed_data) + '/' + str(dht_data[1]) + '/' + str(dht_data[0]) + '/' + str(ultrasonic_data)
24 +
25 + return send_data_str
26 +
27 +# --------------------------------------------------- #
13 # LOOP ENTRYPOINT 28 # LOOP ENTRYPOINT
14 # --------------------------------------------------- # 29 # --------------------------------------------------- #
15 def _run(): 30 def _run():
...@@ -37,22 +52,16 @@ def _run(): ...@@ -37,22 +52,16 @@ def _run():
37 52
38 # IF INPUT MEANS GET MESSAGE or MEDICINE LID STATUS CHANGED 53 # IF INPUT MEANS GET MESSAGE or MEDICINE LID STATUS CHANGED
39 if input_data == 'REQ' or reed_data != current_reed_data: 54 if input_data == 'REQ' or reed_data != current_reed_data:
40 - # Collect Humidity, Temperature
41 - dht_data = dht.work_dht()
42 - if dht_data == False:
43 - dht_data = [0,0]
44 - # Collect Ultrasonic distance
45 - ultrasonic_data = ultrasonic.work_sr04()
46 - # Make data string
47 - send_data_str = str(reed_data) + '/' + str(dht_data[1]) + '/' + str(dht_data[0]) + '/' + str(ultrasonic_data)
48 # Send data using BT 55 # Send data using BT
49 - bto.send_data_bt(send_data_str) 56 + bto.send_data_bt(_collect_sensor_datas(reed_data))
50 -
51 else: 57 else:
52 # Refine BT data 58 # Refine BT data
53 input_data = input_data.strip() 59 input_data = input_data.strip()
54 display4.work_tm1637(input_data) 60 display4.work_tm1637(input_data)
55 neopixel.work_led() 61 neopixel.work_led()
62 + display4.off_tm1637()
63 + # Send data using BT
64 + bto.send_data_bt(_collect_sensor_datas(reed_data))
56 65
57 # Update reed state 66 # Update reed state
58 reed_data = current_reed_data 67 reed_data = current_reed_data
......