基于Python3的远程访问温湿度传感器并将获取的数据传入数据库之三(将数据导入数据库)

说明:本文是承接上篇微博的进一步完善:基于Python3的远程访问温湿度传感器并将获取的数据传入数据库之二(建立并连接数据库):https://blog.csdn.net/myclass1312/article/details/80485257

本次实验目的是将之前采集到的数据传入数据库,其中需要用到数据库中存温湿度的cdsjb表,与其关联的cdb表和bcxmb表。

1、在开始实验前需要做的准备如下:

(1)打开虚拟机查看ip;


(2)用得到的ip+/phpmyadmin进入phpmyadmin



(3)打开python创建空白文本文件:last_data和inputdata.py


2、实验代码:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
u'''
Created on 2018年5月28日

@author: lenovo
'''
__author__ = 'lxd <[email protected]>'
__version__ = '1.0.0'
__company__ = u'重庆交大'
__updated__ = '2018-05-29'

import socket
import codecs
import time
import pymysql
import datetime
import struct
''' 
client   
connect()   
recv()   
send()   
sendall()     
'''

# 以字典形式创建数据库配置信息,方便修改
PY_MYSQL_CONN_DICT = {
    "host": '10.1.161.149',#虚拟机IP
    "port": 3306,
    "user": 'bridge',#pypmyadmin中自己创建的用户名
    "passwd": 'wlw123456',#用户名密码
    "db": 'bridge',#数据库名称
    "charset": 'utf8'
}

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校验
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):
    u''' 
    16进制转字节流 
    '''
    if not isinstance(x, str):
        x = str(x, 'ascii')
    return bytes.fromhex(x)

def bytestohex(x):
    u''' 
        字节流转16进制 
    '''
    if not isinstance(x, bytes):
        x = bytes(x, 'ascii')
    return ''.join(["%02x" % i for i in x]).strip()


def fetchone():
    conn = 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 insertone(**kwargs):
    conn = 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()

def fetchtwo():
    conn = dbConnect()
    cursor = conn.connect()
    cursor.execute("select * from cdsjb")
    result = cursor.fetchall()
    conn.close()
    print("success")
    return result

def inserttwo(**kwargs):
    conn = 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()

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

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

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 = "631507030118lxd", "温湿度处理"  # 自己设定的工程项目编码和名称,用于后面对gcxmb表的操作
    # 定义工程编码和名称,因为需要对温度和湿度进行操作,所以定义两个,也是用于后面对cdb表的操作
    cdbm1, cdbm2 = "shidu", "wendu"
    cdmc1, cdmc2 = "湿度", "温度"

    while True:
        list_wendu = []
        list_shidu = []
        global inst_wendu  # 实时温度
        global inst_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(result[:-2])  # 进行CRC16-2校验
            if crc == result[-2:]:
                print('CRC16成功')
            shidu, wendu = struct.unpack(
                '>hh', result[3:7])  # 用struct方法解析湿度和温度
            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)
                end_time = time.time()  # 获取结束时的时间戳
                if(end_time - begin_time > 5):  # 如果如果两次间隔大于五秒,停止读取数据,开始对数据进行处理
                    inst_wendu = list_wendu[-1]  # 数组最后一个就是当时的瞬时值
                    inst_shidu = list_shidu[-1]
                    time.sleep(0.1)
                    break
                else:  # 时间没有大于五秒则继续读取数据
                    continue
        cur_time = time.strftime(
            "%Y-%m-%d %H:%M:%S", time.localtime())  # 记录处理完成的时间
        print(cur_time)
        print("实时温度%s" % (inst_wendu))
        print("实时湿度%s" % (inst_shidu))
        print("开始向数据库传入数据...")
        gcxmb_data = fetchthree()  # 先对gcxmb表进行查询,如果存在数据,则进行下一步,如果不存在就插入数据
        if not gcxmb_data:
            try:
                insertthree(gcxmbm, gcxmmc)
            except Exception:
                print("工程项目表插入失败")
        cdb_data = fetchone()  # 对cdb表进行查询,存在数据则跳过,不存在则插入数据
        if not cdb_data:
            try:
                insertone(gcxmbm=gcxmbm, cdbm=cdbm1, cdmc=cdmc1,
                          cgqbm="03", jldw="RH", sflb=1)
                insertone(gcxmbm=gcxmbm, cdbm=cdbm2, cdmc=cdmc2,
                          cgqbm="03", jldw="摄氏度", sflb=1)
            except Exception:
                print("测点表插入失败 ")
        try:  # 插入处理后的数据
            inserttwo(gcxmbm=gcxmbm, cdbm=cdbm1,
                      clsj=cur_time, inst=inst_shidu)
            inserttwo(gcxmbm=gcxmbm, cdbm=cdbm2,
                      clsj=cur_time, inst=inst_wendu)
            print("传入成功")
        except:
            print("测点数据表插入失败")
    sk.close()


main()

3、实验结果

(1)python中的结果


last_data文件中的内容:


(2)phpmyadmin中的结果

cdb表中的内容:


cdsjb表中的内容


gcxmb表中的内容:



猜你喜欢

转载自blog.csdn.net/myclass1312/article/details/80498799
今日推荐