**智慧魚缸** --- 透過Raspberry pi所連接的sensor觀察魚缸所處環境的溫度,並使用LINE通訊軟體控制燈照、餵飼料、觀察溫度及濕度歷史紀錄及魚缸即時影像。 --- 實際照片 --- ![](https://i.imgur.com/baGfD3G.jpg) ![](https://i.imgur.com/De9NLCk.jpg) ![](https://i.imgur.com/NIuQV9c.jpg) --- 影片連結 --- {%youtube gs6Pcj3StGc %} https://youtu.be/gs6Pcj3StGc --- 使用硬體材料 --- * Raspberry pi 4b *1 * DHT22 Temperature Humidity Sensor Module *1 https://www.sparkfun.com/products/10167 * 外接USB LED燈 * sg90伺服馬達 --- 使用軟體 --- Python 3.7.3 https://www.python.org/ Apache 2.4.38 https://httpd.apache.org/ Cacti 1.2.2 https://www.cacti.net/ Mariadb 10.3.31 https://mariadb.org/ LINE Bot Message API https://developers.line.biz/zh-hant/services/messaging-api/ --- Step 1. 溫溼度感測器安裝及收集歷史資料 --- 1. 連接DHT22溫溼度感測器,根據腳位上方描述接到Raspberry pi上對應的腳位並調整程式碼 VCC -> power 正極 GND -> Ground 負極 DAT -> GPIO 收資料 NC -> 不用接 2. 參考以下網頁進行安裝cacti(記錄歷史溫溼度使用)、設定排程收集資料、上傳cacti、設定cacti看得懂的資料格式 > Raspberry Pi 搭配Cacti監控溫濕度 > https://kingfff.blogspot.com/2018/05/raspberry-pi-cacti-weather-dht22-temperature-humidity.html * 安裝時發現網頁中所提供之套件Adafruit_DHT已不再維護,目前已改用Adafruit CircuitPython > Adafruit_DHT 顯示DEPRECATED LIBRARY Adafruit Python DHT Sensor Library > https://github.com/adafruit/Adafruit_Python_DHT > > Adafruit CircuitPython > https://github.com/adafruit/circuitpython Step 2. 外接USB燈源及控制開啟或關閉 --- {%youtube OjEqofjlxNs %} 1. 程式碼參考uhubctl github 因為我是用Raspberry pi所以只用到以下列出的部份,針對不同作業系統甚至不同Raspberry pi版本有不同的安裝或者執行方式。 > uhubctl github > https://github.com/mvp/uhubctl * To fetch uhubctl source and compile it: ``` git clone https://github.com/mvp/uhubctl cd uhubctl make ``` * This should generate uhubctl binary. You can install it in your system as /usr/sbin/uhubctl using: ``` sudo make install ``` 2. 最後依照上方github說明使用指令控制USB供電以達到外接LED燈開啟或關閉的效果 * USB off ``` sudo uhubctl -l 2 -a 0 ``` * USB on ``` sudo uhubctl -l 2 -a 1 ``` Step 3. 使用LINE Message API實現手機控制Raspberry pi --- * 參考LINE Document,此次只用到Text message及Image message > LINE Message type introduction > https://developers.line.biz/en/docs/messaging-api/message-types/ 1. Message API申請方式及ngrok建置方式參考以下網址進行申請及建置,ngrok用途為使Raspberry pi與外界溝通,以達成接收及傳送LINE訊息的目的 > Rasbperry Pi 結合 LINE messaging API > https://blog.cavedu.com/2021/12/06/rasbperry-pi-line-messaging-api/ 2. 程式部分LINE github即有完整Example可參考,實際使用範例主要參考日文網頁中鑰匙開關之控制方式。 > line-bot-sdk-python > https://github.com/line/line-bot-sdk-python > > 在 LINE 上解鎖和開鎖 (日文) > https://qiita.com/t-funaki/items/2a3bbed8f63d2dc660a3 Step 4. LINE Message API 回傳即時溫度 (Text message) --- {%youtube fjk1BDTcHHc %} 1. 參考以下日文網頁,調整一下在收到指定訊息時呼叫function取得dht22的即時溫度及回傳 > 在 LINE 上解鎖和開鎖 (日文) > https://qiita.com/t-funaki/items/2a3bbed8f63d2dc660a3 程式主要部份: * main ``` if message.count("顯示現在溫度"): temperature = function.temperature() line_bot_api.reply_message(event.reply_token, TextSendMessage(text="現在溫度是" + str(temperature) + "度C")) ``` * function ``` dht = adafruit_dht.DHT22(board.D4) def temperature(): temperature = dht.temperature humidity = dht.humidity return temperature ``` Step 5. LINE Message API 回傳歷史溫度紀錄 (Image message) --- {%youtube mjDmqGCm2ME %} * 根據LINE Message API documentation說明,Bot回傳的Image必須是HTTPS URL及使用TLS 1.2加密或更高版本,並且僅能傳送PNG或是JPEG檔案。因此不能直接將回傳圖片的路徑指向本機資料夾內的某個檔案,這大大加深了難度。 > Image message說明 > https://developers.line.biz/en/reference/messaging-api/#image-message * 嘗試過想要把圖檔丟到免費的 Imgur.com 再回傳但一直失敗,下面提供的兩種方法我都試過,都遇到上傳失敗或是找不到module的問題,最後想到直接用ngrok的那個動態網址丟回去。 > 用 Python 上傳圖片至 Imgur 圖床 (試不成功) > https://ithelp.ithome.com.tw/articles/10241006 1. 為了達成自動化取得ngrok URL的目的,接收到指定訊息時必須呼叫function取得URL再寫到後續的code裡面。 > 取得ngrok URL的方式 > https://stackoverflow.com/questions/34322988/view-random-ngrok-url-when-run-in-background 2. 有了URL之後必須將cacti中所收集的dht22歷史溫溼度圖片取回來才能發送回去,因此這邊執行了另一支python(download_graph_45)將cacti上的圖取回放在static資料夾。 > 這個部份參考如下網址,但在Google上搜尋有多個相同的網頁,不確定這網址是否為真。 >https://www.itread01.com/p/456374.html > > 另一個更簡單的方法: > cacti免登入檢視graph > https://blog.xuite.net/jyoutw/xtech/536474338-Cacti+%E5%85%8D%E7%99%BB%E5%85%A5%E6%AA%A2%E8%A6%96+Graph * 在cacti圖片上點右鍵Graph -> Copy graph link可查看圖片編號 ![](https://i.imgur.com/XtKJgXm.png) * URL說明如下: local_graph_id -> 這張圖片ID graph_start -> 圖片開始時間 graph_end -> 圖片結束時間 graph_width=414 -> 圖片寬度 graph_height -> 圖片高度 ``` http://localhost/cacti/graph_image.php?local_graph_id=45&graph_start=1641882527&graph_end=1641968927&graph_width=414&graph_height=99 ``` 3. 後續和Text message差不多,Text部份是使用Token+Text,圖片部份就是換成token+URL回傳給使用者,其中URL我換成自動取到到ngrok URL,路徑則指向static資料夾下。 程式主要部份: * main ``` elif message.count('顯示溫濕度紀錄'): ngrok_url = function.get_ngrok_url() exec(open("download_graph_45.py").read()) line_bot_api.reply_message(event.reply_token, ImageSendMessage(original_content_url = ngrok_url + "/static/cacti_graph_45.png", preview_image_url = ngrok_url + "/static/cacti_graph_45.png")) ``` * function ``` def get_ngrok_url(): url = "http://localhost:4040/api/tunnels" res = requests.get(url) res_unicode = res.content.decode("utf-8") res_json = json.loads(res_unicode) return res_json["tunnels"][0]["public_url"] ``` Step 6. 控制餵食器 --- {%youtube _ReGPnu5ONE %} * 這個部份設定為接收到訊息時控制SG90伺服馬達,但是要進行轉速控制,否則來回的速度太快會把掉下的飼料打到到處都是 程式主要部份: * main ``` elif message.count('餵飼料'): os.system('python3 sg90.py') line_bot_api.reply_message(event.reply_token, TextSendMessage(text="餵食完畢")) ``` * sg90 ``` import time import RPi.GPIO as GPIO CONTROL_PIN = 17 PWM_FREQ = 50 STEP=15 GPIO.setmode(GPIO.BCM) GPIO.setup(CONTROL_PIN, GPIO.OUT) pwm = GPIO.PWM(CONTROL_PIN, PWM_FREQ) pwm.start(0) def angle_to_duty_cycle(angle=0): duty_cycle = (0.05 * PWM_FREQ) + (0.19 * PWM_FREQ * angle / 180) return duty_cycle for angle in range(0, 60, 10): dc = angle_to_duty_cycle(angle) pwm.ChangeDutyCycle(dc) time.sleep(0.1) for angle in range(60, -1, -10): dc = angle_to_duty_cycle(angle) pwm.ChangeDutyCycle(dc) time.sleep(0.1) pwm.stop() GPIO.cleanup() ``` > RASPBERRY PI 3 MOBEL B 利用 PWM 控制伺服馬達 > https://blog.everlearn.tw/%e7%95%b6-python-%e9%81%87%e4%b8%8a-raspberry-pi/raspberry-pi-3-mobel-3-%e5%88%a9%e7%94%a8-pwm-%e6%8e%a7%e5%88%b6%e4%bc%ba%e6%9c%8d%e9%a6%ac%e9%81%94 Step 7. 設定Rich menu --- 1. 這邊是設計Bot介面的圖文選單,我這邊直接用LINE線上的LINE offical Account Manager功能設計rich menu,這個方法最多可支援六個指令 ![](https://i.imgur.com/DmBABFN.png) * 設計好選單並上傳圖片後可依據不同位置設定要傳送的文字,Raspberry pi接收到指令後再搭配上面的程式執行不同動作 ![](https://i.imgur.com/cbXHCRa.png) > rich menu說明 > https://developers.line.biz/zh-hant/docs/messaging-api/using-rich-menus/#using-rich-menus-introduction > > LINE offical Account Manager > https://manager.line.biz/ > > PNG素材 > https://www.pngsucai.com/ > > rich meau template > https://static.line-scdn.net/biz-app/16bd9ea9e03/manager/static/LINE_rich_menu_design_template.zip --- 完整程式碼 --- https://github.com/qJAgZPiW94pn/IoT --- Reference --- Adafruit_CircuitPython_DHT https://github.com/adafruit/Adafruit_CircuitPython_DHT Raspberry Pi 搭配Cacti監控溫濕度 https://kingfff.blogspot.com/2018/05/raspberry-pi-cacti-weather-dht22-temperature-humidity.html LINE Messaging API SDK for Python https://github.com/line/line-bot-sdk-python Raspberry Pi 3+DHT22 で気温を通知するLINEbotを作る② https://qiita.com/zakopuro/items/ed6720f4c27773cb58c7 LINEでおうちの鍵を開け締めする https://qiita.com/t-funaki/items/2a3bbed8f63d2dc660a3 uhubctl - USB hub per-port power control https://github.com/mvp/uhubctl Rasbperry Pi 結合 LINE messageing API https://blog.cavedu.com/2021/12/06/rasbperry-pi-line-messaging-api/ PNG素材 https://www.pngsucai.com/ View random ngrok URL when run in background https://stackoverflow.com/questions/34322988/view-random-ngrok-url-when-run-in-background Line Messaging API 的各種訊息格式 https://ithelp.ithome.com.tw/articles/10198142 python 自動登陸cacti獲取主機流量圖 https://www.itread01.com/p/456374.html PiCamera & Python – How to add text on images and video https://www.meccanismocomplesso.org/en/picamera-python-how-to-add-text-on-images-and-video/ TAIWANIOT https://www.taiwaniot.com.tw/ RASPBERRY PI 3 MOBEL B 利用 PWM 控制伺服馬達 https://blog.everlearn.tw/%e7%95%b6-python-%e9%81%87%e4%b8%8a-raspberry-pi/raspberry-pi-3-mobel-3-%e5%88%a9%e7%94%a8-pwm-%e6%8e%a7%e5%88%b6%e4%bc%ba%e6%9c%8d%e9%a6%ac%e9%81%94