Python对接OneNet云平台实现物联网开发

本次项目设计的是厨房安全监控系统,基于ESP8266WiFi模块进行数据发送,利用Arduino开发板集成ESP8266模块,采集传感器检测的数据,然后用WiFi发送到指定的OneNet云平台的设备地址,使用Python的Flask框架对接云平台,获取数据自动保存到数据库中,前端利用Ajax进行数据访问的操作,结果以列表的形式在浏览器上展示。

1.准备开发环境:Pycharm,Python3.x,MySQL,Navicat,WebStorm/Sublime/VSCode,Arduino IDE;

开发板:WeMosD1R3继承了ESP8266模块,在Arduino IDE首选项中的开发板地址粘贴以下地址:

https://github.com/esp8266/Arduino/releases/download/2.5.0/package_esp8266com_index.json

然后在开发板中点击开发板管理,输入ESP8266,点击ESP8266Community进行安装,之后点击开发板选择WeMosD1开发板.

连接各类传感器,我这里使用的是火焰传感器,人体红外传感器,温湿度传感器,一氧化碳传感器分别检测厨房的火焰,温度,人员和燃气值,使用继电器控制风扇的转动,加上蜂鸣器和LED进行报警功能.

硬件部分代码:

#include <ESP8266WiFi.h>
#include <HttpPacket.h>
#include <ArduinoJson.h>
#include "DHT.h"

//初始化数据包和引脚
HttpPacketHead packet;
#define myPeriodic 5
#define DHTPIN 5
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

int LED = D1;      //LED
int human = D3;    //人体
int fire = D2;     //火焰
int gas_pin = A0;  //MQ-2模拟口
int gas = D6;      //MQ-2数据口
int buzzer = D8;   //蜂鸣器
int relayPin = D10;  //继电器

//配置路由器和
int sent = 0;
char OneNetServer[] = "api.heclouds.com";  //云平台网址
const char ssid[] = " ";			   //路由器名称
const char password[] = " ";		   //路由器密码
char device_id[] = " ";
char API_KEY[] = " ";	//设备api_key地址
//发送的数据
char sensor_id1[] = "温度";
char sensor_id2[] = "火焰";					
char sensor_id3[] = "燃气";
char sensor_id4[] = "人员";

//连接路由器
void connectWifi()
{  Serial.print("Connecting to " + *ssid);
 WiFi.begin(ssid, password);
 while (WiFi.status() != WL_CONNECTED) {
   delay(1000);
   Serial.print(".");  
   }
 Serial.println("");
 Serial.println("Connected");
 Serial.println("");
 digitalWrite(0, HIGH);
 delay(1000);
 digitalWrite(0, LOW);
 delay(1000);
 digitalWrite(0,HIGH);
}

//发送数据给云平台
void postDataToOneNet(char* API_VALUE_temp, char* device_id_temp, char* sensor_id_temp, float thisData)
{  WiFiClient client;
 StaticJsonBuffer<250> jsonBuffer;
 JsonObject& myJson = jsonBuffer.createObject();
 JsonArray& datastreams= myJson.createNestedArray("datastreams");
 JsonObject& id_datapoints = datastreams.createNestedObject();
 id_datapoints["id"] = sensor_id_temp;
   JsonArray& datapoints = id_datapoints.createNestedArray("datapoints");
 JsonObject& value = datapoints.createNestedObject();
   value["value"] =thisData;
 char p[180];
 myJson.printTo(p, sizeof(p));
 packet.setHostAddress(OneNetServer);
 packet.setDevId(device_id_temp);
 packet.setAccessKey(API_VALUE_temp);
 packet.createCmdPacket(POST, TYPE_DATAPOINT, p);
 if (strlen(packet.content))
   Serial.print(packet.content);
 Serial.println(p);
 char cmd[400];
 memset(cmd, 0, 400);  
 strcpy(cmd, packet.content);
 strcat(cmd, p);
 if (client.connect(OneNetServer, 80)) { 
   Serial.println("WiFi Client connected ");
   client.print(cmd);
   delay(1000);
 }
 client.stop();
}

//传感器初始化
void setup() {
 pinMode(A0,INPUT);
 pinMode(LED,OUTPUT);         // LED为输出模式
 pinMode(buzzer, OUTPUT); 
 pinMode(relayPin, OUTPUT); 
 pinMode(human, INPUT); //设置人体红外接口为输入状态
 pinMode(fire,INPUT);
 Serial.begin(9600); 
 connectWifi();
}

//主循环程序
void loop() {
 int t = dht.readTemperature();
 int x = analogRead(A0);
 int gas = 5.00*(x/1023.00);
 int h = digitalRead(human);
 int f = digitalRead(fire);
 if(t>25){
    digitalWrite(LED,HIGH);
    digitalWrite(relayPin,HIGH);
    digitalWrite(buzzer,HIGH);
 }
 if(gas>280){
    digitalWrite(LED,HIGH);
    digitalWrite(relayPin,HIGH);
    digitalWrite(buzzer,HIGH);
 }
 postDataToOneNet(API_KEY, device_id, sensor_id1, t);
 delay(100);
 postDataToOneNet(API_KEY, device_id, sensor_id2, f);
 delay(100);
 postDataToOneNet(API_KEY, device_id, sensor_id3, gas);
 delay(100);
 postDataToOneNet(API_KEY, device_id, sensor_id4, h);
 sent++;
 int count = myPeriodic;
 while (count--){
   delay(1000);
 }
 delay(100);    
}

2.Flask框架进行数据库连接配置:

import os

debug = True

HOSTNAME = 'localhost'
PORT = '3306'
DATABASE = 'kitchen'
USERNAME = 'root'
PASSWORD = '123456'
DB_URI = "mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8".format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI

SQLALCHEMY_TRACK_MODIFICATIONS = False

SECRET_KEY = os.urandom(24)

编写主程序代码:

import urllib
import re
from flask import Flask,render_template
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from flask_login import LoginManager
from wtforms import StringField,PasswordField,SubmitField
from wtforms.validators import DataRequired, EqualTo, ValidationError
from datetime import datetime

import config

#初始化Flask程序
app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)    #绑定app对象到数据库
login_manager = LoginManager(app)

#自己的设备ID和api_key
DEVICE_ID = '*****'
API_KEY = '*********'

#创建设备表
class Device(db.Model):
    __tabelname__ = 'Device'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True, nullable=False)
    temp = db.Column(db.String(10), nullable=False)
    fire = db.Column(db.String(10), nullable=False)
    gas = db.Column(db.String(10), nullable=False)
    human = db.Column(db.String(10), nullable=False)
    time = db.Column(db.DateTime, default=datetime.now())


@app.route('/')
def getData():
    #指定设备数据流url
    url = 'http://api.heclouds.com/devices/' + DEVICE_ID + '/datapoints'
    #访问该url
    request = urllib.request.Request(url)
    request.add_header('api-key', API_KEY)
    #设置HTTP的访问方式为GET请求
    request.get_method = lambda: 'GET'
    #request获取到了设备的数据流
    request = urllib.request.urlopen(request)
    text = str(request.read())
    #对字符串进行解析
    text = text[text.find("data") + 6:]
    text = re.sub('[\/]', '', text)
    text = text[text.find("value") + 7:]
    temp = text[0]+text[1]
    if text[1] == "}":
        text[1] = " "
    text = text[text.find("value")+7:]
    if text[1] == "}":
        print("燃气值: "+text[0])
        gas = text[0]
    elif text[2] == "}":
        print("燃气值: "+text[0]+text[1])
        gas = text[0]+text[1]
    else:
        print("燃气值: " + text[0] + text[1] + text[2])
        gas = text[0]+text[1]+text[2]
    text = text[text.find("value")+7:]
    status = ""
    human  = ""
    if text[0] == "1":
        status = "有火"
    elif text[0] == "0":
        status = "无火"
    text = text[text.find("value") + 7:]
    if text[0] == "1":
        human = "有人"
    elif text[0] == "0":
        human = "无人"
    else:
        human = "有人"
    print("火焰: " + status)
    print("温度: " + temp)
    value = Device(temp=temp, fire=status, gas=gas, human=human,time=datetime.now())
    db.session.add(value)
    db.session.commit()
    Device_list = Device.query.all()
    return render_template("device.html",devices = Device_list)

if __name__ == '__main__':
    db.create_all()
    app.run()

3.前端部分代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>基于ESP8266的厨房安全监控系统</title>
    <style>
        #audit {
            margin-top: 20px;
        }

        thead > tr {
            border: 1px solid #cc0000;
        }

        .filter {
            margin-left: 20px;
        }

        .status-picker {
            display: inline-block;
        }

        .status-picker select {
            border-radius: 5px;
            width: 180px;
            float: left;
            height: 37px;
            margin-bottom: -13px;
            border: 1px solid skyblue;
            padding: 0 10px;
            margin-right: 20px;
        }

        .container {
            margin-top: 30px;
        }

        .jtp {
            margin-top: 10px;
            display: inline-block;
        }

        .jtp .ui.icon.input input {
            padding: 0.5em !important;
            width: 32px;
        }

        .modal .content {
            display: flex !important;
            justify-content: center;
            align-items: center;
        }

        .button {
            text-align: center;
        }

        .container {
            margin-left: 20px;
        }

        .first {
            background: #F9FAFB;
        }

        .bk{
            border-bottom:1px solid #cccccc;
            border-left:1px solid #cccccc;
            border-right:1px solid #cccccc;
        }
    </style>
</head>
<body>
<div align="center"><p style="font-family: 'Adobe 楷体 Std R';font-size: xx-large">基于ESP8266的厨房安全监控系统</p></div>
    <div align="center"><p style="font-family: 'Adobe 黑体 Std R';font-size: x-large">设备数据信息</p></div>
    <table border="1px" id="table" align="center">
        <thead>
        <tr bgcolor="#f5f5f5" style="height: 30px;font-size: larger;solid-color:#EEEEEE; border-color: #9F9F9F; font-style: revert">
            <th width="100">温度</th>
            <th width="100">火焰</th>
            <th width="100">燃气</th>
            <th width="100">人员</th>
            <th width="250">时间</th>
        </tr>
            {% for device in devices %}
             <tr>
            <td>    温度: {{ device.temp}}  </td>
            <td>    火焰: {{ device.fire}}  </td>
            <td>    燃气: {{ device.gas}}   </td>
            <td>    人员: {{ device.human}} </td>
            <td>    时间: {{ device.time}}  </td>
             </tr>
            {% endfor %}
        </thead>
        <tbody>
        </tbody>
    </table>

</body>
<script type="application/javascript" src="../static/device.js"></script>
</html>

最后的运行结果如图所示:

发布了58 篇原创文章 · 获赞 31 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_37504771/article/details/103120386