網(wǎng)站付款接口這么做今日資訊最新消息
需求:
做一個(gè)小型的監(jiān)控,類似電子貓眼,監(jiān)測(cè)到人之后,取一張圖 然后發(fā)送到自己的郵箱。
架構(gòu):
1.sr602 傳感器監(jiān)測(cè)到人
2. esp32 cam 取圖 并通過mqtt協(xié)議傳到遠(yuǎn)端服務(wù)器
3, 服務(wù)器利用python 搭建一個(gè)mqtt客戶端,訂閱到數(shù)據(jù)后 將圖片保存,并發(fā)送到指定郵箱
?硬件連接:
結(jié)構(gòu)設(shè)計(jì):
?
軟件:
服務(wù)端代碼
#mqtt客戶端
import paho.mqtt.client as mqtt
import logging
import os
import email_sendAPPEAR_TOPIC = "APPEAR_TOPIC"
DETAIL_TOPIC = "DETAIL_TOPIC"
mqtt_server = 'xxxxxxxxxx'
image_path="images"image_index=0def on_connect(client, userdata, flags, rc):logging.info('連接到MQTT服務(wù)器 '+str(rc))def on_message(client, userdata, msg):print(msg.topic + " " + str(msg.payload))global image_indexif msg.topic ==APPEAR_TOPIC:if image_index!=0:#發(fā)送全部圖片image_index=0email_send.send_email(image_path)logging.info('發(fā)送到郵箱完畢')if msg.topic == DETAIL_TOPIC:logging.info('收到圖片,準(zhǔn)備保存到本地')save_location = "images/"+str(image_index)+".jpg" f = open(save_location, 'wb') data = msg.payload f.write(data) f.close()image_index+=1logging.info('圖片保存到本地完畢')def run():logging.basicConfig(level=logging.INFO)client = mqtt.Client(protocol=3)client.on_connect = on_connectclient.on_message = on_messageclient.connect(host=mqtt_server,port=1883,keepalive=60,bind_address="")client.subscribe(APPEAR_TOPIC)client.subscribe(DETAIL_TOPIC)logging.info('啟動(dòng) MQTT客戶端... \n')try:client.loop_forever()except KeyboardInterrupt:passlogging.info('停止 MQTT 客戶端\n')if __name__ =='__main__':run()#郵件發(fā)送import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from datetime import datetime
import logging
import os
import shutildef send_email(img_path=""):# 設(shè)置發(fā)件人、收件人和郵件主題from_email = "xxxx"to_email = "xxxx"subject = "注意,有人出現(xiàn)"logging.info('設(shè)置收發(fā)地址...')# 創(chuàng)建郵件對(duì)象msg = MIMEMultipart()msg['From'] = from_emailmsg['To'] = to_emailmsg['Subject'] = subject# 添加郵件正文body = datetime.now().strftime("%Y-%m-%d %H:%M:%S")msg.attach(MIMEText(body, 'plain'))logging.info('添加正文...')for root,dirs,files in os.walk(img_path):for file in files:if file.endswith(".jpg"):img = os.path.join(root,file)# 添加附件attachment_filename = imgattachment_path = imgattachment = open(attachment_path, "rb")part = MIMEBase('application', 'octet-stream')part.set_payload(attachment.read())encoders.encode_base64(part)part.add_header('Content-Disposition', f'attachment; filename= {attachment_filename}')msg.attach(part) # 連接到SMTP服務(wù)器smtp_server = "smtp.yeah.net" # 修改為你的SMTP服務(wù)器smtp_port = 465smtp_username = "xxxx" # 修改為你的郵箱地址smtp_password = "xxxx" # 修改為你的郵箱密碼server = smtplib.SMTP_SSL(smtp_server,smtp_port)logging.info('登錄郵件服務(wù)器...')server.login(smtp_username, smtp_password)logging.info('發(fā)送郵件')# 發(fā)送郵件server.sendmail(from_email, to_email, msg.as_string())# 關(guān)閉連接server.quit()shutil.rmtree(img_path)# 重新創(chuàng)建空文件夾os.makedirs(img_path)if __name__ =='__main__':logging.basicConfig(level=logging.INFO)send_email("images",True)
客戶端代碼
#include "esp_camera.h"
#include <WiFi.h>
#include <PubSubClient.h>#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"//WIFI 用戶名 密碼
//const char* ssid = "xxxx";
//const char* password = "xxxx";
const char* ssid = "xxxx";
const char* password = "xxxx";//MQTT 服務(wù)器地址
const char* mqttServer = "xxxx";
uint16_t mqttPort = 1883;
const char* APPEAR_TOPIC = "APPEAR_TOPIC";
const char* DETAIL_TOPIC = "DETAIL_TOPIC";//檢測(cè)是否有人
uint8_t FOUND_PEOPLE_PIN = 14;//人出現(xiàn)的次數(shù)
uint8_t found_count = 0;WiFiClient espClient;
PubSubClient client(espClient);void setup() {//調(diào)試串口Serial.begin(115200);Serial.setDebugOutput(true);//人體紅外檢測(cè)引腳pinMode(FOUND_PEOPLE_PIN, INPUT);//配置相機(jī)camera_config_t config;config.ledc_channel = LEDC_CHANNEL_0;config.ledc_timer = LEDC_TIMER_0;config.pin_d0 = Y2_GPIO_NUM;config.pin_d1 = Y3_GPIO_NUM;config.pin_d2 = Y4_GPIO_NUM;config.pin_d3 = Y5_GPIO_NUM;config.pin_d4 = Y6_GPIO_NUM;config.pin_d5 = Y7_GPIO_NUM;config.pin_d6 = Y8_GPIO_NUM;config.pin_d7 = Y9_GPIO_NUM;config.pin_xclk = XCLK_GPIO_NUM;config.pin_pclk = PCLK_GPIO_NUM;config.pin_vsync = VSYNC_GPIO_NUM;config.pin_href = HREF_GPIO_NUM;config.pin_sccb_sda = SIOD_GPIO_NUM;config.pin_sccb_scl = SIOC_GPIO_NUM;config.pin_pwdn = PWDN_GPIO_NUM;config.pin_reset = RESET_GPIO_NUM;config.xclk_freq_hz = 20000000;config.pixel_format = PIXFORMAT_JPEG;config.frame_size = FRAMESIZE_VGA;config.jpeg_quality = 10;config.fb_count = 1;// 相機(jī)初始化esp_err_t err = esp_camera_init(&config);if (err != ESP_OK) {Serial.printf("Camera init failed with error 0x%x", err);return;}sensor_t* s = esp_camera_sensor_get();s->set_vflip(s, 1);s->set_brightness(s, 2);s->set_saturation(s, -2);s->set_framesize(s, FRAMESIZE_VGA);//連接 WIFIWiFi.begin(ssid, password);WiFi.setSleep(false);while (WiFi.status() != WL_CONNECTED) {Serial.println("Connecting to WIFI ...");delay(500);}Serial.println("WiFi connected");//連接mqtt 服務(wù)器。 640*480 圖片大小client.setBufferSize(50 * 1024);client.setServer(mqttServer, mqttPort);while (!client.connected()) {if (client.connect("app")) {Serial.println("Connected to MQTT");} else {Serial.println("Failed to connect to MQTT server, ");Serial.print(client.state());delay(1000);}}Serial.print(WiFi.localIP());
}//上傳圖片
void take_send_photo() {Serial.println("Taking picture...");camera_fb_t* fb = NULL;fb = esp_camera_fb_get();if (!fb) {Serial.println("Camera capture failed");return;}if (client.beginPublish(DETAIL_TOPIC, fb->len + sizeof(long), false)) {unsigned long m = millis();int noBytes;noBytes = client.write(fb->buf, fb->len);noBytes = client.write((byte*)&m, sizeof(long));if (!client.endPublish()) {Serial.println("\nupload image error.");}}esp_camera_fb_return(fb);Serial.println("upload image ok.");
}void loop() {//檢測(cè)到有人后 拍照并上傳if (digitalRead(FOUND_PEOPLE_PIN) == 1) {take_send_photo();found_count += 1;delay(2000);} else {found_count = 0;}if (found_count >= 3) {found_count = 0;client.publish(APPEAR_TOPIC, "", 0);}client.loop();
}
注意事項(xiàng):
1,接收?qǐng)D片的郵箱,需要開通smtp服務(wù)。
2,mqtt發(fā)送圖片,不需要轉(zhuǎn)成base64格式,但是需要重新設(shè)置下緩存大小。
3,這個(gè)玩意 發(fā)熱很嚴(yán)重,還沒測(cè)試 兩節(jié)18650電池能用多久。