遠程訪問傳感器獲取數據並傳入數據庫----Three

上次實驗已經成功連接數據庫...

這次實驗就是將數據傳入數據庫,因爲數據庫中存溫溼度的 表是cdsjb,與其關聯的表有cdb和bcxmb,所以需要對三個表都做處理才能正常傳入數據。

程序如下:

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

@author: RJ
'''
__author__ = 'RJ <[email protected]>'
__version__ = '1.0.0'
__company__ = u'重慶交大'
__updated__ = '2018-05-22 16:43'

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.209',
        "port": 3306,
        "user": 'bridge',
        "passwd": '123456',
        "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 = "631507030233冉傑", "溫溼度處理"  # 這個爲自己設定的工程項目編碼和名稱,用於後面對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 = datetime.datetime.now()  # 記錄處理完成的時間  
            print("瞬時溫度%s" % (inst_wendu), cur_time)  
            print("瞬時溼度%s" % (inst_shidu), cur_time)  
            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()

運行之前記得連接校網,打開虛擬機,ifconfig查詢ip,修改程序。

運行結果:


插入後打開數據庫查看數據:

cdb表:

cdsjb表:

gcxmb表:

這次實驗這裏只是將獲得的數據做簡單的處理傳進去,

並沒有獲取平均值,最大值,最小值一同傳進去。

下次實驗是對數據做處理......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章