Python-树莓派-采集温度并上传云端

Python-树莓派-采集温度并上传云端

2019-2020上学期,终端与网关大作业

目的:用树莓派当网关,ZigBee协调器和路由器之间实现终端通信(无代码),采集终端温度数据,通过串口连接到树莓派上,树莓派与onenet之间实现数据的传输。
流程图:
Python-树莓派-采集温度并上传云端_第1张图片

1. 数据采集-路由器
路由器节点上电后触发发送温度事件
处理发送温度的事件函数

uint16 router_ProcessEvent( uint8 task_id, uint16 events )
{
     
  (void)task_id;  // Intentionally unreferenced parameter
  ................................
  /* 自定义事件入口 */
  if ( events & ROUTER_SEND_PERIODIC_MSG_EVT )
  {
     
    
      return (events ^ ROUTER_SEND_PERIODIC_MSG_EVT);
  }
    if(events & ROUTER_TPM_SEND_EVT)
  {
     
      unsigned char tmp[3];
      gettmperval(tmp);       /*采集温度*/
      NodeSendRFDate(&router_epDesc, tmp, 3, 0, afAddr16Bit, NODE_TMP_SEND_CLUSTERID);  /*温度发送*/
      osal_start_timerEx(  router_TaskID, ROUTER_TPM_SEND_EVT,
ROUTER_SEND_MSG_TIMEOUT );      
      return (events ^ ROUTER_TPM_SEND_EVT);
  }
  return 0;
}
#DS18B20GetTemperValue是采集DS18B20的数据

由路由器节点将温度传感器上的数据读出通过zigbee网络向协调器发送温度数据上,再由协调器将收到的数据打印到串口上。数据采集的代码烧到ZigBee实验箱上,路由器上插温度采集的硬件板子。其他代码烧到树莓派上。

2.数据采集-协调器

#协调器接收函数
static void _process_sys_event_wd_msg(afIncomingMSGPacket_t *msg_pack)
{
     
    uint16_t cluster_id = 0;
    uint8 *ReceiveData; 
    cluster_id = msg_pack->clusterId;                    /*簇号*/ 
    if(cluster_id == NODE_TMP_SEND_CLUSTERID)
    {
     
        unsigned char buff[10]; 
        ReceiveData = msg_pack->cmd.Data;              /*数据包头指针*/ 
        buff[0]=*ReceiveData;
        buff[1]=*(ReceiveData+1);
        buff[2]='.';
        buff[3]=*(ReceiveData+2);
        HalUARTWrite(0,buff,4);//将接收过来的温度数据通过串口发送
        HalUARTWrite(0,"\r\n",2);
    }
}

流程图
Python-树莓派-采集温度并上传云端_第2张图片
3.树莓派通过串口接收协调器发送的数据,采用队列方式进行线程间的通信,将获取到的数据保存到文件中。将如下代码烧到树莓派上,通过两个线程实现终端与网关之间的通信(包括数据格式的转换及储存)

import serial
import time
import json
import threading
from time import ctime,sleep
import queue
q = queue.Queue()
ser = serial.Serial("/dev/ttyUSB0",115200,timeout=0.5)
def Zigbee():
    while True:
        count = ser.inWaiting()
        if count != 0:
            recv = ser.readline()
            ser.flushInput()
            #q.put(recv.decode())
            
            data = recv.decode('utf-8')
            #data = recv
            #humidity= float(data)
            tmp_output = open("tmp_data1.txt",'r')
            
            tmp_output.write(data)
            
            tmp_output.flush()
            #humidity = float(tmp_output.read())
            
            tmp_output.close()
            print(recv.decode())
        sleep(0.1)

def Zigbee_json ():
    global recv
    i=2
    while True:
        if q.empty:
            pass
        else:
            data = q.get()
            humidity= float(data)
            tmp_output = open("tmp_data2.txt",'w')
            
            tmp_output.write('111')
            
            tmp_output.flush()
            humidity = float(tmp_output.read())
            
            tmp_output.close()
            
            
            print(data)
            sleep(1)
            

threads = []
t1 = threading.Thread(target = Zigbee)
#t1 = threading.Thread(target = Lora,args = ('',))

threads.append(t1)
t2 = threading.Thread(target = Zigbee_json)
#t2 = threading.Thread(target = Lora,args = ('',))
threads.append(t2)


if __name__ == '__main__':
    for t in threads:
        t.start()
    t1.join()
    t2.join()
#    while True:
#        sleep(2)

4.将树莓派保存的数据上传到onenet上

#-*-coding:utf-8 -*-
from __future__ import print_function

import paho.mqtt.client as mqtt
import struct
import json
import datetime
# CONNECT 方式:
# client_id:     DEV_ID
# username:  PRO_ID
# password:   AUTHINFO(鉴权信息)
# 可以连接上设备云,CONNECT 和 CONNACK握手成功
# temperature:已创建的一个数据流
#更多请查阅OneNet官方mqtt文档与paho-mqtt开发文档

#修改成自己的即可
DEV_ID = "************" #设备ID
PRO_ID = "***" #产品ID
AUTH_INFO = "******************"  #APIKEY
#AUTH_INFO = "159635"

#file = open("/home/pi/ZB_data/tmp_data1.txt")
file = open("tmp_data1.txt")
humidity= float(file.read())
#humidity= float(20)
time = datetime.datetime.now().isoformat()

TYPE_JSON = 0x01
TYPE_FLOAT = 0x17

#定义上传数据的json格式  该格式是oneNET规定好的  按格式修改其中变量即可
body = {
     
        "datastreams":[
                {
     
                    "id":"humi",  #对应OneNet的数据流名称
                    "datapoints":[
                        {
     
                            "at":time , #数据提交时间,这里可通过函数来获取实时时间
                            "value":humidity   #数据值
                            }
                        ]
                    }
                ]
            }


def build_payload(type, payload):
    datatype = type
    packet = bytearray()
    packet.extend(struct.pack("!B", datatype))
    if isinstance(payload, str):
        udata = payload.encode('utf-8')
        length = len(udata)
        packet.extend(struct.pack("!H" + str(length) + "s", length, udata))
    return packet

# 当客户端收到来自服务器的CONNACK响应时的回调。也就是申请连接,服务器返回结果是否成功等
def on_connect(client, userdata, flags, rc):
    print("连接结果:" + mqtt.connack_string(rc))
    #上传数据
    json_body = json.dumps(body)
    packet = build_payload(TYPE_JSON, json_body)
    client.publish("$dp", packet, qos=1)  #qos代表服务质量


# 从服务器接收发布消息时的回调。
def on_message(client, userdata, msg):
    print("湿度:"+str(msg.payload,'utf-8')+"%RH")


#当消息已经被发送给中间人,on_publish()回调将会被触发
def on_publish(client, userdata, mid):
    print("mid:" + str(mid))


def main():
    client = mqtt.Client(client_id=DEV_ID, protocol=mqtt.MQTTv311)
    client.on_connect = on_connect
    client.on_publish = on_publish
    client.on_message = on_message

    client.username_pw_set(username=PRO_ID, password=AUTH_INFO)
    client.connect('183.230.40.39', port=6002, keepalive=120)

    client.loop_forever()

if __name__ == '__main__':
    main()

你可能感兴趣的:(python,物联网)