python温湿度数据远程接收处理入库程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pengyangyan/article/details/80343415
程序结构

Brige---+

  •         ----dbconnect.py    (数据库连接和配置信息)
  •         ----crc16.py     (CRC16校验程序)
  •         ---- cdb.py        (对数据库cdb表的操作)
  •         ----cdsjb.py        (对数据库cdsjb表的操作)
  •         ----gcxmb.py        (对数据库gcxmb表的操作)
  •         ----last_data.txt       (用于保存上一次读取的温湿度,用于筛选波动太大的数据)
  •         ----mian.py                (第一版  未对数据进行处理的主函数)
  •         ----maincopy.py    (第二版 对数据进行处理后的主函数)
  •         ----+

程序内容       

dbconnect.py 

#以字典形式创建数据库配置信息,方便修改
PY_MYSQL_CONN_DICT = {                
    "host": '10.103.102.96',
    "port": 3306,
    "user": 'bridge',
    "passwd": '123456',
    "db": '现场终端数据',
    "charset": 'utf8'
}
import pymysql
class dbConnect:
    def __init__(self):
        self.conn = None
        self.cursor = None
        self.__conn_dict = PY_MYSQL_CONN_DICT

    def connect(self, cursor=pymysql.cursors.DictCursor):
        try:
            self.conn = pymysql.connect(**self.__conn_dict)
            self.cursor = self.conn.cursor(cursor=cursor)    #数据库连接成功并返回游标
            return self.cursor
        except Exception as e:
            print("连接失败:%s"%e)

    def close(self):
        self.conn.commit()
        self.cursor.close()
        self.conn.close()

crc16.py

def crc16(x):
    u'''
    @summary: 计算CRC16值
    @param x: bytes
    @return: 返回2字节值,类似:b'\x7B\x2A'。
    '''
    if not isinstance(x, bytes):
        raise ValueError('Parameter must be a bytes type')
    b = 0xA001
    a = 0xFFFF
    for byte in x:
        a = a ^ byte
        for _ in range(8):
            last = a % 2
            a = a >> 1
            if last == 1:
                a = a ^ b
    aa = '0' * (6 - len(hex(a))) + hex(a)[2:]
    ll, hh = int(aa[:2], 16), int(aa[2:], 16)
    rtn = '%x' % (hh * 256 + ll & 0xffff)
    while len(rtn) < 4:
        rtn = '0' + rtn
    rtn = hextobytes(rtn)
    return rtn
def hextobytes(x):
    if not isinstance(x, str):
        x = str(x, 'ascii')
    return bytes.fromhex(x)
def bytestohex(x):
    if not isinstance(x, bytes):
        x = bytes(x, 'ascii')
    return ''.join(["%02x" % i for i in x]).strip()

cdb.py

from Brige import dbconnect
def fetchone():
    conn = dbconnect.dbConnect()
    cousor = conn.connect()
    sql ="""SELECT  gcxmbm cdbm, cdmc, cgqbm, jldw, sfqy, sjlx, sflb, lbfs, lbcs, bz FROM cdb WHERE 1 """
    cousor.execute(sql)
    result = cousor.fetchone()    #获取第一一条数据并返回结果
    conn.close()
    return result

def insert(**kwargs):
    conn = dbconnect.dbConnect()
    cursor = conn.connect()
    sql = """insert into cdb(%s) values(%s)"""
    key_list = []
    value_list = []
    for k, v in kwargs.items():
        key_list.append(k)
        value_list.append('%%(%s)s' % k)
    sql = sql % (','.join(key_list), ','.join(value_list))
    cursor.execute(sql, kwargs)
    conn.close()

cdsjb.py

from Brige import dbconnect

def fetch():
    conn = dbconnect.dbConnect()
    cursor = conn.connect()
    cursor.execute("select * from cdsjb")
    result = cursor.fetchall()
    conn.close()
    print("success")
    return result
def insert(**kwargs):
    conn = dbconnect.dbConnect()
    cursor =conn.connect()
    sql = """insert into cdsjb(%s) values(%s)"""
    key_list = []
    value_list = []
    for k, v in kwargs.items():
        key_list.append(k)
        value_list.append('%%(%s)s' % k)
    sql = sql % (','.join(key_list), ','.join(value_list))
    cursor.execute(sql, kwargs)
    conn.close()

gcxmb.py

from Brige import dbconnect

def insert(gcxmbm,gcxmmc):
    conn = dbconnect.dbConnect()
    cursor = conn.connect()
    sql = """insert into gcxmb(gcxmbm,gcxmmc) values(%s,%s)"""
    cursor.execute(sql,(gcxmbm,gcxmmc))
    conn.close()

def fetch():
    conn = dbconnect.dbConnect()
    cursor = conn.connect()
    sql =""" select * from gcxmb """
    cursor.execute(sql)
    result = cursor.fetchone()
    conn.close()
    return result

main.py

import socket
import codecs
import time
import datetime
from Brige import crc16
import struct
from Brige import cdsjb,cdb,gcxmb

"""
client
    connect()
    recv()
    send()
    sendall()

"""
def main():
    sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    print(sk)
    address = ('10.1.156.82', 8001)
    sk.connect(address)
    inp = '030300000002c5e9'
    gcxmbm, gcxmmc = "631507030103彭阳宴", "温湿度处理"
    cdbm1, cdbm2 = "shidu", "wendu"
    cdmc1, cdmc2 = "湿度", "温度"
    while True:
        sk.send(codecs.decode(inp, 'hex'))
        try:
            result = sk.recv(1024)
        except socket.timeout:
            print('timeout')
        crc=crc16.crc16(result[:-2])
        if crc==result[-2:]:
            print('CRC16成功')
        shidu,wendu=struct.unpack('>hh',result[3:7])
        shidu/=100
        wendu/=100
        #比较上一次的温湿度的波动
        with open("last_data",'r') as r:
            last_data =  r.read()
        if not last_data:
            continue
        last_wendu,last_shidu = last_data.split("%")
        last_wendu,last_shidu = float(last_wendu),float(last_shidu)
        if(abs(shidu-last_shidu)>5 or abs(wendu-last_wendu>5)):
            print("数字波动太大,未写入数据库")
            continue
        else:
            #将当前温度湿度写入文档作为记录
            data = str(wendu) + "%"+str(shidu)
            with open("last_data",'w') as f:
                f.write(data)
            cur_time = datetime.datetime.now()
            print("湿度:%s,温度:%s" % (shidu, wendu),datetime.datetime.now())
            print("开始向数据库传入数据...")
            gcxmb_data = gcxmb.fetch()
            if not gcxmb_data:
                try:
                    gcxmb.insert(gcxmbm,gcxmmc)
                except Exception:
                    print("工程项目表插入失败")
            cdb_data = cdb.fetchone()
            if not cdb_data:
                try:
                    cdb.insert(gcxmbm=gcxmbm,cdbm=cdbm1,cdmc=cdmc1,cgqbm="03",jldw="RH",sflb=1)
                    cdb.insert(gcxmbm=gcxmbm, cdbm=cdbm2, cdmc=cdmc2, cgqbm="03", jldw="摄氏度", sflb=1)
                except Exception:
                    print("测点表插入失败 ")
            try:
                cdsjb.insert(gcxmbm=gcxmbm,cdbm=cdbm1,clsj=cur_time,inst=shidu)
                cdsjb.insert(gcxmbm=gcxmbm, cdbm=cdbm2, clsj=cur_time, inst=wendu)
                print("传入成功")
            except:
                print("测点数据表插入失败")
            time.sleep(5)
    sk.close()
main()
maincopy.py
import socket
import codecs
import time
import datetime
from Brige import crc16
import struct
from Brige import cdsjb,cdb,gcxmb

"""
client
    connect()
    recv()
    send()
    sendall()

"""
def main():
    sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    print(sk)
    address = ('10.1.156.82', 8001)
    sk.connect(address)
    inp = '030300000002c5e9'   #远程需要接受的参数
    gcxmbm, gcxmmc = "631507030103彭阳宴", "温湿度处理"     #这个为自己设定的工程项目编码和名称,用于后面对gcxmb表的操作

    #提前定义工程编码和名称,因为需要对温度和湿度进行操作,所以定义两个,也是用于后面对cdb表的操作
    cdbm1, cdbm2 = "shidu", "wendu"
    cdmc1, cdmc2 = "湿度", "温度"

    while True:
        total_wendu,total_shidu=0,0
        list_wendu = []
        list_shidu = []
        global inst_wendu   #瞬时温度
        global inst_shidu   #瞬时湿度 
        global avg_wendu    #平均温度
        global avg_shidu    #平均湿度
        global max_wendu    #最大温度
        global max_shidu    #最大湿度
        global min_wendu    #最小温度
        global min_shidu    #最小湿度
        n =0
        begin_time = time.time()     #开始读取是的时间戳
        while True:
            sk.send(codecs.decode(inp, 'hex'))
            try:
                result = sk.recv(1024)
            except socket.timeout:
                print('timeout')
            crc=crc16.crc16(result[:-2])     #进行CRC16-2校验
            if crc==result[-2:]:
                print('CRC16成功')
            shidu,wendu=struct.unpack('>hh',result[3:7])    #用struct方法解析湿度和温度,看不懂可以自行百度了解struct.unpack的用法
            shidu/=100
            wendu/=100
            #比较上一次的温湿度的波动
            with open("last_data",'r') as r:
                last_data =  r.read()
            if not last_data:  #如果last_data.txt中没有数据,就把当前温室度作为上一次温湿度进行比较
                last_data = str(wendu)+'%'+str(shidu)   #字符串拼接
            last_wendu,last_shidu = last_data.split("%")   #字符串以%拆分,得到温湿度
            last_wendu,last_shidu = float(last_wendu),float(last_shidu)   #转化为float型数值
            if(abs(shidu-last_shidu)>5 or abs(wendu-last_wendu>5)):   #比较当前温湿度与上一次温湿度差异,如果波动大于5就过滤掉
                print(abs(shidu-last_shidu),abs(wendu-last_wendu))
                print("数字波动太大,未记录")
                continue
            else:
                # 将当前温度湿度写入文档作为记录
                data = str(wendu) + "%" + str(shidu)
                with open("last_data", 'w') as f:
                    f.write(data)
                n += 1
                list_shidu.append(shidu)    
                list_wendu.append(wendu)
                total_wendu += wendu    #对每一次温度进行累加
                total_shidu +=shidu     #对每一次湿度进行累加   
                end_time = time.time()    #获取结束时的时间戳
                if(end_time-begin_time>5):    #如果如果两次间隔大于五秒,停止读取数据,开始对数据进行处理
                    inst_wendu = list_wendu[-1]    #数组最后一个就是当时的瞬时值
                    inst_shidu = list_shidu[-1]
                    list_wendu.sort()            #对数组进行排序 从小到大
                    list_shidu.sort()
                    avg_wendu = total_wendu/n    #求平均值
                    avg_shidu = total_shidu/n
                    max_wendu = list_wendu[-1]    #此时数组最后一个对最大值
                    max_shidu = list_shidu[-1]
                    min_wendu = list_wendu[0]    #数组第一个为最小值
                    min_shidu = list_shidu[0]
                    time.sleep(0.1)
                    break
                else:  #时间没有大于五秒则继续读取数据
                    continue
        cur_time = datetime.datetime.now()    #记录处理完成的时间
        print("最大温度%s,最小温度%s,平均温度%s,瞬时温度%s" %(max_wendu,min_wendu,avg_wendu,inst_wendu),cur_time)
        print("最大湿度%s,最小湿度%s,平均湿度%s,瞬时湿度%s" % (max_shidu, min_shidu, avg_shidu, inst_shidu),cur_time)
        print("开始向数据库传入数据...")
        gcxmb_data = gcxmb.fetch()     #先对gcxmb表进行查询,如果存在数据,则进行下一步,如果不存在就插入数据
        if not gcxmb_data:
            try:
                gcxmb.insert(gcxmbm,gcxmmc)
            except Exception:
                print("工程项目表插入失败")
        cdb_data = cdb.fetchone()    #对cdb表进行查询,存在数据则跳过,不存在则插入数据
        if not cdb_data:
            try:
                cdb.insert(gcxmbm=gcxmbm,cdbm=cdbm1,cdmc=cdmc1,cgqbm="03",jldw="RH",sflb=1)
                cdb.insert(gcxmbm=gcxmbm, cdbm=cdbm2, cdmc=cdmc2, cgqbm="03", jldw="摄氏度", sflb=1)
            except Exception:
                print("测点表插入失败 ")
        try:    #插入处理后的数据
            cdsjb.insert(gcxmbm=gcxmbm,cdbm=cdbm1,clsj=cur_time,avg=avg_shidu,max=max_shidu,min=min_shidu,inst=inst_shidu)
            cdsjb.insert(gcxmbm=gcxmbm, cdbm=cdbm2, clsj=cur_time,avg=avg_wendu,max=max_wendu,min=min_wendu,inst=inst_wendu)
            print("传入成功")
        except:
            print("测点数据表插入失败")
    sk.close()
main()

运行截图:




注意:

    1.main.py和maincopy.py只需要运行其中一个,last_data.txt最开始为空。

    2.运行时注意修改配置信息

    3.程序有时候可能有bug,多运行几次就好了。

    4.所有py文件创建在一个名为Brige的包下面,也可以自己修改            


猜你喜欢

转载自blog.csdn.net/pengyangyan/article/details/80343415