MQTT接收库 paho.mqtt
数据库服务 PyMySQL
MQTT服务器 mosquitto
一、介绍
1、paho.mqtt
本文档描述了Eclipse Paho MQTT Python客户端库的源代码,该库实现了MQTT协议的3.1版和3.1.1版。
该代码提供了一个客户端类,该客户端类使应用程序能够连接到MQTT代理以发布消息,订阅主题并接收已发布的消息。它还提供了一些帮助程序功能,使将一次性消息发布到MQTT服务器变得非常简单。
它支持Python 2.7或3.x,对Python 2.6的支持有限。
MQTT协议是机器对机器(M2M)/“物联网”连接协议。作为一种非常轻量级的发布/订阅消息传递传输而设计,它对于与需要较小代码占用和/或网络带宽非常宝贵的远程位置的连接非常有用。
Paho是Eclipse Foundation项目。
2、PyMySQL
该软件包包含一个基于PEP 249的纯Python MySQL客户端库。
[PEP 249] – Python Database API Specification v2.0
二、安装
根据链接内说明安装,
或下载压缩包,解压后进入文件夹目录,通过下方代码安装
python setup.py
MQTT服务器安装向导:Windows环境下安装配置Mosquitto服务及入门操作介绍
三、程序运行
1、paho.mqtt
- Err 11004 getaddrinfo failed python
MQTT服务器IP错误 - on_connect() takes 3 positional arguments but 4 were given
连接程序参考 参考:Python实现MQTT接收订阅数据
因为版本升级的原因 ,on_connect需要修改为
def on_connect(mqttc, obj, rc, properties=None):
print("OnConnetc, rc: "+str(rc))
2、PyMySQL
连接数据库代码
import pymysql
conn = pymysql.connect(host="localhost", port=3306, user="user", passwd="pwd", db="mysql")
cur = conn.cursor()
cur.execute("SELECT Host,User FROM user")
print(cur.description)
print()
for row in cur:
print(row)
cur.close()
conn.close()
3、多进程multiprocessing
- 将文件命名为“multiprocessing”,运行报错。注意文件名不要与库文件重名。
参考链接:import resolves to its containing file 问题,pycharm导模块,模块名下有横线 - 进程池 multiprocess.Pool
import multiprocessing
import time
def func(msg):
print ("*msg: ", msg)
time.sleep(3)
print ("*end")
if __name__=="__main__":
pool = multiprocessing.Pool(processes=3)
for i in range(10):
msg = "hello [{}]".format(i)
# pool.apply(func, (msg,))
pool.apply_async(func, (msg,)) # 异步开启进程, 非阻塞型, 能够向池中添加进程而不等待其执行完毕就能再次执行循环
print ("--" * 10)
pool.close() # 关闭pool, 则不会有新的进程添加进去
pool.join() # 必须在join之前close, 然后join等待pool中所有的线程执行完毕
print('All subprocesses done.')
参考链接:python多进程并发之multiprocessing
四、服务端流程
五、踩坑记录
- MQTT接收到的JSON字符串是“b”/byte 格式,使用json_loads(str)报错
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
解决办法,使用编码“utf-8”
str(msg.payload,"utf-8")
2.MQTT接收到消息,存储进数据库
参考:Python Mqtt+Mysql+Json处理简单数据初试
3.查询数据库得到“字典”数据
参考:pymysql fetchall 查询结果返回字典
from pymysql.cursors import DictCursor
………………
cursor = db.cursor(DictCursor)
4.写入/更新数据库
参考:python往mysql数据库中写入数据和更新插入数据
数据主键“id”为“0”时,添加一条新数据
data = {
'id':aid,
'hid':hid,
'online':1,
'last_date':int(time.time())
}
table = 'ap'
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
sql = 'INSERT INTO {table}({keys}) VALUES ({values}) ON DUPLICATE KEY UPDATE'.format(table=table, keys=keys, values=values)
update = ','.join([" {key} = %s".format(key=key) for key in data])
sql += update
cursor.execute(sql, tuple(data.values())*2)
5.获取时间戳
参考:Python获取秒级时间戳与毫秒级时间戳
import time
import datetime
t = time.time()
print (t) #原始时间数据
print (int(t)) #秒级时间戳
print (int(round(t * 1000))) #毫秒级时间戳
print (lambda:int(round(t * 1000))) #毫秒级时间戳,基于lambda
print (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) #日期格式化
- 定时查询数据库,得到数据没有更新
db.commit()