|
最近实验有需要用到MQTT传输图像的需求,本人也不太会写除Python以外的代码,恰好今天读到嵌入式圈内的大佬@DS小龙哥的文章:基于阿里云物联网平台设计的实时图传系统_采用MQTT协议传输图像受大佬启发,今天利用Python写一个简单的MQTT图传程序。软件:PycharmMQTTXWireshark手机端APP:IoTMQTTPanel由于大佬在文章中已经写了关于在阿里云创建产品、设备及消息转发的相关设置,本文将不再赘述,添加设备后如下图所示:我们利用Python脚本发送随机数检查设备接收信息的情况:importtimeimportjsonimportrandomimportpaho.mqtt.clientasmqtt#username和password#可直接在设备页面一键复制client_id=f"client_id"timestamp=str(int(time.time()))username=f"username"password=f"password"#MQTT连接地址broker=f"mqtthosturl"port=1883#回调函数defon_connect(client,userdata,flags,rc):print("Connectedwithresultcode"+str(rc))client.subscribe(f"/sys/${ProductKey}/${deviceName}/thing/event/property/post")#注意把自己的设备信息更换defon_message(client,userdata,msg):print(msg.topic+""+str(msg.payload))#创建客户端client=mqtt.Client(client_id=client_id)client.username_pw_set(username,password)#绑定回调函数client.on_connect=on_connectclient.on_message=on_message#连接到阿里云物联网平台client.connect(broker,port,60)#启动MQTT客户端client.loop_start()#发送随机数的函数defpublish_random_number():topic=f"/sys/${ProductKey}/${deviceName}/thing/event/property/post"whileTrue:random_number=random.randint(1000000000,9999999999)payload={"method":"thing.event.property.post","params":{"image":str(random_number)}}client.publish(topic,json.dumps(payload))print(f"Published:{json.dumps(payload)}")time.sleep(1)#启动发送随机数的循环publish_random_number()12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152运行此脚本:可以在平台的设备监测里看到:OK,设备连接正常,下一步我们来搞一下图片传输由于@DS小龙哥使用的是QT客户端我们要用Python实现此功能需要重新编写脚本,原理很简单,就是将图片转为base64编码,然后发送端建立与平台的连接,通过MQTT协议发送,平台中转给接收端,接收端可以解码此图片呈现。直接上代码:importosimporttimeimportjsonimportbase64importhmacimporthashlibimportpaho.mqtt.clientasmqtt#阿里云物联网平台的参数product_key="product_key"device_name="video_1"device_secret="device_secret"region_id="cn-shanghai"#选择你的阿里云区域#username和password#可直接在设备页面一键复制client_id=f"client_id"timestamp=str(int(time.time()))username=f"username"password=f"password"#MQTT连接地址broker=f"mqtthosturl"port=1883#回调函数defon_connect(client,userdata,flags,rc):ifrc==0:print("Connectedsuccessfully.")else:print(f"Connectionfailedwithresultcode{rc}")client.subscribe(f"/sys/{product_key}/{device_name}/thing/event/property/post")defon_message(client,userdata,msg):print(msg.topic+""+str(msg.payload))defon_publish(client,userdata,mid):print(f"Message{mid}published.")defon_log(client,userdata,level,buf):print("log:",buf)#创建客户端client=mqtt.Client(client_id=client_id)client.username_pw_set(username,password)#绑定回调函数client.on_connect=on_connectclient.on_message=on_messageclient.on_publish=on_publishclient.on_log=on_log#连接到阿里云物联网平台print(f"Connectingtobroker{broker}onport{port}")client.connect(broker,port,60)#启动MQTT客户端client.loop_start()#读取图像并转换为Base64编码的块defget_image_base64_chunks(image_path,chunk_size=102400):withopen(image_path,"rb")asimage_file:image_data=base64.b64encode(image_file.read()).decode('utf-8')foriinrange(0,len(image_data),chunk_size):yieldimage_data[i:i+chunk_size]#发送Base64图像块的函数defpublish_image_chunk(image_chunk,chunk_index):topic=f"/{product_key}/{device_name}/user/update"payload={"method":"thing.event.property.post","params":{"image":image_chunk,"chunk_index":chunk_index}}result=client.publish(topic,json.dumps(payload))print(f"Publishingchunk{chunk_index}:{json.dumps(payload)}withresult:{result}")#启动发送Base64图像块的循环defpublish_images_from_directory(directory):whileTrue:#无限循环image_files=[fforfinos.listdir(directory)ifos.path.isfile(os.path.join(directory,f))andf.lower().endswith(('.png','.jpg','.jpeg'))]forimage_fileinimage_files:image_path=os.path.join(directory,image_file)chunk_index=0forimage_chunkinget_image_base64_chunks(image_path):publish_image_chunk(image_chunk,chunk_index)chunk_index+=1time.sleep(1)#可以根据需要调整发送间隔时间time.sleep(2)#每秒发送一张图片try:publish_images_from_directory(r"imagesdirect")#替换为你的图像目录路径exceptKeyboardInterrupt:print("StoppedbyUser")client.loop_stop()client.disconnect()123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899手机端查看接收的图片:下载这个APP,安卓:IoTMQTTPanel,iOS:IoTMQTTPanel网络问题自行解决哈按照平台一键复制的数据填写保存后自动连接成功了添加一个面板面板设置如下:让我们启动脚本:图片以base64编码的形式发送了手机端也接收到图片了MQTTX看看收到的消息:Wireshark抓包
|
|