micropython實現MQTT數據發佈中移動OneNet平臺(含繼電器使用說明)及對mysql數據庫的操作

import utptime

uftptime.settime()   #同步網絡時間

這次我們在OneNET平臺上新建數據流,同時使用MQTT協議中publish報文格式上傳數據點。

MQTT協議實現方式

實現MQTT協議需要客戶端和服務器端通訊完成,在通訊過程中,MQTT協議中有三種身份:

發佈者(Publish):發佈數據點
代理(Broker)(服務器):接受C端連接,處理髮,訂,退,轉數據信息
訂閱者(Subscribe):訂閱數據點
其中,消息的發佈者pub訂閱者sub都是客戶端,消息代理broker是服務器,消息發佈者可以同時是訂閱者。

MQTT傳輸的消息分爲:主題(Topic)和負載(payload)兩部分:

  • (1)Topic,可以理解爲消息的類型,訂閱者訂閱(Subscribe)後,就會收到該主題的消息內容(payload);
  • (2)payload,可以理解爲消息的內容,是指訂閱者具體要使用的內容。

Payload消息體

Payload消息體位MQTT數據包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四種類型的消息:

  • (1)CONNECT,消息體內容主要是:客戶端的ClientID、訂閱的Topic、Message以及用戶名和密碼。
  • (2)SUBSCRIBE,消息體內容是一系列的要訂閱的主題以及QoS。
  • (3)SUBACK,消息體內容是服務器對於SUBSCRIBE所申請的主題及QoS進行確認和回覆。
  • (4)UNSUBSCRIBE,消息體內容是要訂閱的主題。

 

from umqtt.simple import MQTTClient
from machine import Pin
import network
import time
import json

CLIENT_ID = "588234870" #設備ID
username = "3297741" #產品ID
password = "vaGMSmffsdfecCzMz4rs7y=rQ8gmo="  #APIKEY
SERVER = 'mqtt.heclouds.com'  #183.230.40.39
TOPIC = 'wefdaidu'
state = 0
c=None

def sub_cb(topic, msg):
  global state
  print((topic, msg))
  if msg == b"on":
    #led.value(1)
    state = 0
    print("1")
  elif msg == b"off":
    #led.value(0)
    state = 1
    print("0")
  elif msg == b"toggle":
    #led.value(state)
    state = 1 - state
    
 
 #要上報的數據點
message = {'datastreams':[{'id':'temperature','datapoints':[{'value':27}]}]}

def pub_data(data):   #組合成協議要求的報文格式
    j_d = json.dumps(data)
    j_l = len(j_d)
    arr = bytearray(j_l + 3)
    arr[0] = 1 #publish數據類型爲json
    arr[1] = int(j_l / 256) # json數據長度 高位字節
    arr[2] = j_l % 256      # json數據長度 低位字節
    arr[3:] = j_d.encode('ascii') # json數據
    return arr
 
 
def main():
    server=SERVER
    c = MQTTClient(CLIENT_ID, server,6002,username,password,keepalive=60)     #創建客戶端連接
    c.set_callback(sub_cb)                    #set callback
    c.connect()                                      #connect mqtt
    c.subscribe(TOPIC)    #訂閱

    c.publish('$dp',pub_data(message))    #發佈
    #print('publish message:',message)
    time.sleep(5)

    try:
        while 1:
            c.wait_msg()
    except:
        c.disconnect()

  
if __name__ == '__main__':
    while True:
      main()

注:

OneNet平臺設備保活

MQTT connect 報文中,需要設置keepalive(即保活時間),keepalive支持範圍爲:10~1800,單位爲秒

設備若需保持長連接,則設備在連續的設置的keepalive 時間內,必須要有上行數據報文(包括 publish、ping、subscribe 等)

平臺若在連續的 設置的keepalive的1.5倍 的時間內沒有收到設備上行數據,則會設備斷開連接

 

-------------------------------

繼電器使用

簡單原理圖                         5v降壓模塊

在這裏插入圖片描述

 

 

因GPIO口輸出電流不足,繼電器操作可以引用電源或上拉一個10K電阻來觸發控制信號

-------------------------------------------

python操作mysql數據庫

一、Python連接MySQL數據庫

#導入模塊
import pymysql

#打開數據庫連接數據庫testdb
db = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='1234', db='testdb', charset='utf8')

#使用cursor方法創建一個遊標
cursor = db.cursor()

#查詢數據庫版本
cursor.execute("select version()")
data = cursor.fetchone()
print(" Database Version:%s" % data)

#創建數據庫test
cursor.execute("drop database if exists test")  #如果數據庫已經存在,那麼刪除後重新創建
sql = "create database test"
cursor.execute(sql)

#創建數據庫表
cursor.execute("drop table if exists employee")  #如果數據表已經存在,那麼刪除後重新創建
sql = """
CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )
"""
cursor.execute(sql)

#查詢數據表數據
sql = "select * from employee"
cursor.execute(sql)
data = cursor.fetchone()
print(data)

#插入數據
sql = "insert into employee values ('李','梅',20,'W',5000)"
cursor.execute(sql)
db.commit()

#查看插入後的結果
sql = "select * from employee"
cursor.execute(sql)
data = cursor.fetchone()
print(data)

#指定條件查詢數據表數據
sql = " select * from employee where income > '%d' " % (1000)
cursor.execute(sql)
data = cursor.fetchone()
print(data)

#更新數據庫
sql = " update employee set age = age+1 where sex = '%c' " % ('W')
cursor.execute(sql)
db.commit()

#查看更新後的結果
sql = "select * from employee"
cursor.execute(sql)
data = cursor.fetchone()
print(data)

#刪除數據
sql = " delete from employee where age > '%d' " % (30)
cursor.execute(sql)
db.commit()

#查看更新後的結果
sql = "select * from employee"
cursor.execute(sql)
data = cursor.fetchone()
print(data)

#關閉數據庫
db.close()

二、增、刪、改、查

增、刪、改:conn.commit()
獲取數據:fetchone,fetchall,fetchmany
獲取插入數據自增ID:cursor.lastrowid

1、增、改

import pymysql

user = '小黑'
pwd  = '06161086'
conn = pymysql.connect(host='localhost',user='root',password='',database='db1')
cursor = conn.cursor()
sql = "insert into userinfo(user,password) values(%s,%s)"#增
# sql = "update userinfo set password='06161088' where user='耿娃'"#改
r = cursor.execute(sql,user,pwd)#返回值r爲受影響的行數
# cursor.executemany(sql,[
#                         ('小張','06161085'),
#                         ('小王','06161084'),
#                         ('小段','06161083'),
#                         ('小余','06161082')])提交多條數據
conn.commit()
print(cursor.lastrowid)
cursor.close()
conn.close()

2、查

import pymysql
conn = pymysql.connect(host='localhost',user='root',password='',database='db1')
# cursor = conn.cursor()
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from userinfo"  #查
r = cursor.execute(sql)  #返回值r爲受影響的行數

# cursor.scroll(1,mode='relative')  #相對當前位置移動
# cursor.scroll(2,mode='absolute')  #相對絕對位置移動

# ret = cursor.fetchone()
# ret = cursor.executemany(4)  #一次取四個
ret = cursor.fetchall()
for rev in ret:
    print(rev)
cursor.close()
conn.close()

3、執行存儲過程

cursor.callproc('p1') #執行存儲過程

三、其他說明

1、說明

·上例中"sql=..."語句,是經典的MySQL語句的形式,將數據庫語句寫在雙引號內,形成類似字符串的形式;

·使用cursor對象的execute()方法具體執行數據庫的操作;

·對於插入、更新、刪除等操作,需要使用db.commit()來提交到數據庫執行,對於查詢、創建數據庫和數據表的操作不需要此語句。

2、爲有效避免因爲錯誤導致的後果,使用以下方式來執行數據庫的操作:

try:
  # 執行 SQL 語句
  cursor.execute(sql)
  # 提交修改
  db.commit()
except:
  # 發生錯誤時回滾
  db.rollback()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章