樹莓派:基於物聯網做的指紋打卡器


  今天我就分享一波自己的成果。

  心心念念的想做一個物聯網的東西出來,終於在上個月搞定了,雖說肯定是有些漏洞(目前我是沒有找出來的),但是效果看起來還不錯。學了這么久的Python、Qt、liunx命令總算派上用場了。

材料:

  • 樹莓派一台
  • 指紋模塊(AS608光學指紋識別模塊)
  • OLED液晶屏
  • usb轉TTL
  • 杜邦線

 

先說明一下

博客園無法分享附件就只能這樣分享了

如果想要附件可以點擊下面 鏈接,我在csdn上注冊了一個號可以去下載:

樹莓派上的源碼下載

電腦上的上位機源碼下載

oled上的字體

 

先上個最終成果的圖

 

           

 

看起來感覺還可以,基本完成了電腦和手機都可以獲得日志的效果

 

大家最期待的過程了

  現在我來說是我的想法和思路

  剛開始看到隔壁實驗室的指紋打卡機時好像是那種用usb讀取數據的(好像是節約成本吧),我就想能這也太不智能了吧,就想着能不能讓它智能些,比如通過電腦看到它的日志啊,或者用手機看到它的日志啊什么的(后來我才知道淘寶上TM已經出現這種完善的成品指紋考勤機了)。光想沒用啊,還是要靠實踐來檢驗真理。於是我就想到了手上的樹莓派,想想就有些興奮,可以向網上那些大佬一樣DIY一個東西出來了,由於我的知識有限,無法自己搞個指紋打卡模塊,就到網上買了一個,先開始買的正點原子的指紋模塊,原子哥不愧是我原子哥,和他討論問題時真是盡心盡力。文檔很好,不過他那個和模塊通信的程序不是很全,就幾個,可以能是直接儲存在模塊里的緣故,可是我不想儲存在模塊里啊,我學了Python加上Mysql,我想直接存在數據庫里,這樣更加安全可靠。於是我就開始解決通信問題,將他發回來的數據解碼,搗鼓了2天才完成,有點心酸。

先把配置文件分享了,下面代碼會用到

# 用戶root 給電腦連接的
[root]
pwd = 123

# 數據庫
[db]
db_port = 3306
db_user = root
db_host = 127.0.0.1
db_pwd = 123456
db_database = finger
db_table = test1

# smtpServer 發送請求服務
# popServer 接收請求服務
# smtpSrcAddr 服務端的地址
# smtpSrcAddrPwd 服務端的密碼
# smtpDstAddr 發送的目的郵箱
# smtpPort 端口號  qq端口號為 465
[email]
smtpServer = smtp.qq.com
popServer = pop.qq.com
smtpSrcAddr = 發送請求的你的郵箱
smtpSrcAddrPwd = 允許的密碼
smtpDstAddr = 目的郵箱
smtpPort = 465 # TCP服務 [TCP] ip = 192.168.137.249 port = 9090 # 串口服務 [serial] port = /dev/ttyAMA0 (先不用這個串口,這個是我配置過的,你可以先用usb轉ttl連接樹莓派的usb口和指紋模塊) baudrate = 57600 timeout = 10 # 樂聯網 網關信息 [lewei] ip = tcp.lewei50.com port = 9960 userKey = 你自己的userKey gatewayNode = 02

 

1.首先要在電腦上調通指紋發送數據的所有命令

 分享一波代碼

要用電腦和指紋模塊通信首先要裝

python要serial模塊,在cmd命令行中用命令 pip install serial 就可以下載serial 了

  1 # -*-coding=utf8-*-
  2 
  3 import serial
  4 import serial.tools.list_ports
  5 
  6 import os, sys
  7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  8 sys.path.append(PATH)
  9 
 10 SureCore = {
 11     0x00: True,  # 表示指令執行完畢或OK;
 12     0x01: 101,  # 表示數據包接收錯誤;
 13     0x02: 102,  # 表示傳感器上沒有手指;
 14     0x03: 103,  # 表示錄入指紋圖像失敗;
 15     0x06: 202,  # 表示指紋圖像太亂而生不成特征;
 16     0x07: 203,  # 表示指紋圖像正常,但特征點太少而生不成特征;
 17     0x15: 204,  # 表示圖像緩沖區內沒有有效原始圖而生不成圖像;
 18     0x08: 302,  # 表示指紋不匹配;
 19     0x09: 402,  # 表示沒搜索到;此時頁碼與得分為 0
 20     0x0a: 502,  # 表示合並失敗(兩枚指紋不屬於同一手指);
 21     0x0d: 802,  # 表示指令執行失敗;
 22     0x0f: 1002,  # 表示不能發送后續數據包;
 23 }
 24 '''返回= 999 校驗和錯誤'''
 25 
 26 
 27 class DealBuff:
 28     """切割收到的數據"""
 29     HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
 30 
 31     def __init__(self, buff):
 32         self.buff = buff
 33         """處理讀出的指紋數據用到"""
 34         self.tag = list()  # 包標識
 35         self.data = list()
 36         self.check = list()
 37         pass
 38 
 39     def read(self):
 40         buff = [x for x in bytes(self.buff)]
 41         check = self.slit(buff)
 42         return self.tag, self.data, check
 43 
 44     def listCut(self, buff, num):
 45         """切割數組"""
 46         rec = list()
 47         for i in range(num):
 48             bytes_buf = (buff.pop(0))
 49             # rec.append(buff.pop(0))
 50             rec.append(bytes_buf)
 51         return rec, buff
 52         pass
 53 
 54     def slit(self, buff):
 55         """"選擇數據"""
 56         # 初始化中間變量
 57         popList = list()
 58         check_Num = 0
 59         check = list()
 60         head = list()
 61 
 62         if len(buff) < 6:  # 判斷是否有效數據
 63             return True
 64 
 65         head, buff = self.listCut(buff, 6)  # 選擇出頭及判斷
 66         for i in range(6):
 67             if head[i] != self.HEAD[i]:
 68                 return False
 69 
 70         popList, buff = self.listCut(buff, 1)  # 取出包標識
 71         self.tag.append(popList)
 72         check_Num += popList[0]  # 計算校驗和
 73 
 74         popList, buff = self.listCut(buff, 2)  # 取出包長度
 75         check_Num += popList[0] + popList[1]  # 計算校驗和
 76 
 77         popList, buff = self.listCut(buff, popList[0] * 16 + popList[1])  # 取出包數據
 78         check.append(popList.pop())  # 取出校驗數據
 79         check.append(popList.pop())
 80         for i in popList:  # 計算校驗和
 81             check_Num += i
 82 
 83         self.data.extend(popList)  # 導入有用數據
 84         if check_Num % 65535 != check[0] + check[1]*256:  # 檢驗校驗和
 85             return False
 86 
 87         rec = self.slit(buff)  # 得到是否正確分析完數據
 88         return rec
 89         pass
 90 
 91     def write(self):
 92         """要寫的數據打包"""
 93         pack = self.dataSeparate(self.buff, 128)   # 將數據分成每組128個元素
 94         return pack
 95         pass
 96 
 97     def dataSeparate(self, buff, numPart):
 98         """把數據分組打包"""
 99         num = int(len(buff) / numPart)
100         newData = list()
101         for i in range(num):
102             newData.append(buff[i * numPart:(i+1) * numPart])
103 
104         packData = list()
105         for i in range(num-1):
106             data = self.packData(newData[i], 0x02)  # 數據包沒結束
107             packData.extend(data)
108 
109         packData.extend(self.packData(newData[num-1], 0x08))  # 數據包結束
110         return packData
111         pass
112 
113     def packData(self, buff, flage):
114         num = len(buff) + 2
115         senddata = [flage, int(num / 256), int(num % 256)] + buff
116         sum = 0
117         for i in senddata:
118             sum += i
119         senddata = self.HEAD + senddata
120         senddata.append(int(sum / 256))
121         senddata.append(int(sum % 256))
122         return senddata
123         pass
124 
125     pass
126 
127 
128 class DealFingeer:
129     """和指紋模塊交互"""
130     HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
131     tag = list()  # 包標識
132     cmd = list()  #
133     data = list()
134     ser = serial.Serial()
135     def __init__(self, cmd, data=None, server=None):
136         """初始化函數"""
137         self.cmd = cmd
138         self.data = data
139         self.server = server
140         pass
141 
142     def run(self):
143         if hasattr(self, self.cmd):
144             func = getattr(self, self.cmd)
145             return func(self.data)
146         pass
147 
148     def link(self):
149         """連接串口"""
150         self.ser.port = "COM5"
151         self.ser.baudrate = 57600
152         self.ser.bytesize = 8
153         self.ser.parity = 'N'
154         self.ser.xonxoff = 0
155         self.ser.rtscts = 0
156         self.ser.close()
157         self.ser.open()
158         pass
159 
160     def finger(self, data):
161         self.link()
162         check = self.getImage()  # 檢測獲取圖像
163         if check is not True:
164             return check, []
165 
166         self.link()
167         check = self.genChar(data)  # 檢測生成特征值
168         if check is not True:
169             return check, []
170         # ================= 生成特征值時圖像會清除,所以要重新采集 ========================== #
171         self.link()
172         check = self.getImage()  # 檢測獲取圖像
173         if check is not True:
174             return check, []
175 
176         if self.server is not None:
177             self.server.send("True".encode("utf8"))  # 發送數據說明准備好了
178 
179         self.link()
180         check = self.upImage()  # 上傳圖像
181         if check is not True:    # 校驗和錯誤
182             return check, []
183         self.tag, self.data = self.getUpImage()
184 
185         if len(self.tag) is 0 and len(self.data) is 0:  # 得到數據錯誤
186             return False, []
187         return True, []
188 
189     def save(self, data=None):
190         self.link()
191         check = self.regModel()
192         if check is not True:    # 校驗和錯誤
193             return check, []
194 
195         self.link()
196         check = self.upChar(data)  # 上傳特征值
197         if check is not True:  # 校驗和錯誤
198             return check, []
199         self.tag, self.data = self.getUpChar()
200 
201         if len(self.tag) is 0 and len(self.data) is 0:  # 得到數據錯誤
202             return False, []
203         return True, []
204         pass
205 
206     def check(self, data=None):
207         """檢驗指紋, 生成特征值"""
208         self.link()
209         check = self.match()   # 比較指紋特征
210         if check is not True:
211             return check, []
212         score = self.data[1]*255 + self.data[2]  # 返回的分數值
213 
214         self.link()
215         check = self.regModel()  # 合成指紋特征值
216         if check is not True:
217             return check, []
218         return True, score
219         pass
220 
221     def isFinger(self, data=None):
222         """判斷現在的指紋和下載的指紋是否相同"""
223         self.link()
224         check = self.downCharCheck()
225         if check is not True:    # 判斷是否可以發送數據
226             return check, []
227         """下載指紋"""
228         self.link()
229         self.downCharData(data)
230         """檢驗指紋"""
231         self.link()
232         check = self.match()
233         if check is not True:
234             return check, []
235         score = self.data[1] * 255 + self.data[2]  # 返回的分數值
236         return True, score
237         pass
238 
239     def getImage(self, data=None):
240         """獲取圖像"""
241         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05]   # 發送命令獲取內容
242         return self.isOk(cmd, 12)
243         pass
244 
245     def genChar(self, data=None):
246         """生成特征文件"""
247         if data == "1":
248             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x01, 0x00, 0x08]  # 發送命令
249             return self.isOk(cmd, 12)  # 圖像接收數據 12 大小
250         elif data == "2":
251             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x02, 0x00, 0x09]  # 發送命令
252             return self.isOk(cmd, 12)  # 圖像接收數據 12 大小
253         pass
254 
255     def match(self, data=None):
256         """比較指紋特征"""
257         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x03, 0x00, 0x07]   # 發送命令獲取內容
258         return self.isOk(cmd, 14)
259         pass
260 
261     def regModel(self, data=None):
262         """合成指紋特征值"""
263         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09]   # 發送命令獲取內容
264         return self.isOk(cmd, 12)
265         pass
266 
267     def upChar(self, data=None):
268         """上傳特征模塊檢測"""
269         buff = bytes()
270         if data == "1":
271             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x01, 0x00, 0x0e]  # 發送命令
272             return self.isOk(cmd, 12, False)
273         elif data == "2":
274             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0F]  # 發送命令
275             return self.isOk(cmd, 12, False)
276         pass
277 
278     def getUpChar(self, data=None):
279         """上傳特征模塊數據"""
280         buff = self.ser.read(834)
281         self.ser.close()
282         subpackage = DealBuff(buff)   # 分割內容
283         self.tag, self.data, check = subpackage.read()
284         if check is not True:    # 校驗和錯誤
285             return 999
286         return self.tag, self.data
287 
288     def downCharCheck(self, data=None):
289         """
290         下載特征值檢測
291         先要初始化,發送獲取圖像命令
292         """
293         self.getImage()
294         self.link()
295         cmd = self.HEAD + [0x01, 0x00, 0x04, 0x09, 0x02, 0x00, 0x10]  # 發送命令 下載的數據放在buff2中
296         return self.isOk(cmd, 12)
297         pass
298 
299     def downCharData(self, data):
300         """下載特征值的數據"""
301         self.writeRead(data, 0)  # 發送數據 接收為0
302         pass
303 
304 
305     def upImage(self, data=None):
306         """上傳圖像檢測"""
307         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x0a, 0x00, 0x0e]  # 發送命令
308         return self.isOk(cmd, 12, False)
309         pass
310 
311     def getUpImage(self, data=None):
312         """獲取后續的圖像數據"""
313         buff = self.ser.read(40032)
314         self.ser.close()
315         subpackage = DealBuff(buff)   # 分割內容
316         self.tag, self.data, check = subpackage.read()
317         if check is not True:    # 校驗和錯誤
318             return [], []
319         return self.tag, self.data
320 
321     def writeRead(self, cmd, length, close=True):
322         """發送命令讀取原始字節"""
323         cmd = bytes(cmd)
324         self.ser.write(cmd)
325         buff = self.ser.read(length)   # 圖像接收數據
326         if close:
327             self.ser.close()    # 接受完數據斷開com
328         return buff
329         pass
330 
331     def isOk(self, cmd, length, close=True):
332         """判斷數據是否合格"""
333         buff = self.writeRead(cmd, length, close)  # 圖像接收數據 12 大小
334         subpackage = DealBuff(buff)   # 分割內容
335         self.tag, self.data, check = subpackage.read()
336         # 檢驗數據是否可靠
337         if check is not True:   # 校驗和錯誤
338             return 999
339         return self.check_code(self.data)
340         pass
341 
342     def check_code(self, data):
343         """檢驗指令碼"""
344         return SureCore[data[0]]
345         pass
346 
347     pass
348 
349 
350 if __name__ == "__main__":
351     # HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
352     # data = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x0A, 0x00, 0x0E]
353     # data = HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05]
354     # data = HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09]
355     # data = HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0f]
dealFinger.py

 注意:

  1. 可以先在串口調試助手上輸入命令,看看數據是怎么樣子的然后在分析數據,最后寫程序處理數據
  2. 按照說明書提示最好不要改 模塊的地址和密碼,不然可能會成為磚頭
  3. 非常重要!!!本人是吃了虧的,真是日了狗, 指紋模塊中有個設置波特率的,說明書上是說波特率可以設置為9600倍數,其實並不是這樣的,我先開始覺得速度太慢了就設置了先開始是12倍,覺得可以用還是太慢,就設置了24倍,還是可以用,但是還是慢,我一沖動就設置成了96倍,我的個乖乖,然后就是不管怎么喚它都沒反應,為此我還和原子哥討論了很久,結果就是這東西成板磚了。 然后不得已就又買了個便宜的(原子哥雖然服務好,技術支持好,就是東西太貴了,弄懂原理了就不用再買貴的了)。

2.就是寫一個服務器和客戶端啦

我是用Qt寫的客戶端,用python寫的服務器,模擬兩個電腦通信(雖然只要一個自己的電腦)

 先來一波服務器的代碼

里面用到了mySql, 用來存儲指紋數據

 同時為了上傳圖像到客戶端還要下載numpy, PIL 模塊,其中python3中沒有PIL 要下pillow

用到的cmd命令 pip install numpy,  pip install pillow

  1 # -*-coding=utf8-*-
  2 
  3 import socketserver
  4 from collections import Iterable
  5 import json
  6 
  7 import os, sys
  8 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  9 sys.path.append(PATH)
 10 
 11 from core import dealFinger
 12 from core.dealFinger import DealFinger
 13 from core.dealSql import mySqlDeal
 14 from core import dealFile
 15 from core import clockIn
 16 import core
 17 
 18 import configparser
 19 
 20 check = {
 21     0x00: True,  # 表示指令執行完畢或OK;
 22     0x01: 101,  # 表示數據包接收錯誤;
 23     0x02: 102,  # 表示傳感器上沒有手指;
 24     0x03: 103,  # 表示錄入指紋圖像失敗;
 25     0x06: 202,  # 表示指紋圖像太亂而生不成特征;
 26     0x07: 203,  # 表示指紋圖像正常,但特征點太少而生不成特征;
 27     0x15: 204,  # 表示圖像緩沖區內沒有有效原始圖而生不成圖像;
 28     0x08: 302,  # 表示指紋不匹配;
 29     0x09: 402,  # 表示沒搜索到;此時頁碼與得分為 0
 30     0x0a: 502,  # 表示合並失敗(兩枚指紋不屬於同一手指);
 31     0x0d: 802,  # 表示指令執行失敗;
 32     0x0f: 1002,  # 表示不能發送后續數據包;
 33     "occupyError": "occupyError",  # 占用指紋資源失敗
 34     "releaseError": "releaseError",  # 釋放指紋資源失敗
 35     "getLogError": "getLogError",  # 獲取日志失敗
 36     "findError": "findError",  # 查找人失敗
 37     "outPutError": "outPutError"  # 導出數據庫失敗
 38 }
 39 
 40 isTcpOccupy = 0
 41 
 42 class JudgeLoad:
 43     """判斷是否是合理的用戶登陸"""
 44     def __init__(self, server, addrIP):
 45         self.server = server
 46         self.addrIP = addrIP
 47         pass
 48 
 49     def isLoad(self, data, addr):
 50         """判斷是否登陸成功"""
 51         if isinstance(data, dict):
 52             isTrue1 = self.isFind("userName", data.keys())   # 判斷類型是否符合
 53             isTrue2 = self.isFind("passWord", data.keys())   # 判斷類型是否符合
 54             if isTrue1 is True and isTrue2 is True:
 55                 return self.isUser(data["userName"], data["passWord"], addr)
 56             else:
 57                 isTrue = self.isFind(self.addrIP, addr)  # 判斷是否有登陸過
 58                 if isTrue is not True:
 59                      return False
 60                 isTrue1 = self.isFind("cmd", data.keys())  # 判斷類型是否符合
 61                 isTrue2 = self.isFind("value", data.keys())  # 判斷類型是否符合
 62                 if isTrue1 is True and isTrue2 is True:
 63                     return True
 64             return False
 65         return False
 66         pass
 67 
 68     def isUser(self, user, pwd, addr):
 69         """判斷用戶名和密碼是否正確"""
 70         try:
 71             cf = configparser.ConfigParser
 72             cf = dealFile.readConf(cf)
 73             pwdconf = cf.get(user, "pwd")
 74             if pwd == pwdconf:
 75                 ischeck = self.isFind(self.addrIP, addr)
 76                 if ischeck is not True:
 77                     addr.append(self.addrIP)  # 添加主機ip 確定登陸成功
 78                 self.server.send("True".encode("utf8"))
 79                 return "loadSuccess"
 80         except Exception as e:
 81             print(e)
 82         return "loadFalse"
 83         pass
 84 
 85     def isFind(self, child, parent):
 86         """尋找parent 中是否有 child"""
 87         if isinstance(parent, Iterable) is not True:   # 判斷是否是可迭代類型
 88             return False
 89         for i in parent:
 90             if child == i:
 91                 return True
 92         return False
 93         pass
 94 
 95     pass
 96 
 97 
 98 class SeverHandle(socketserver.BaseRequestHandler):
 99     """
100     任務分發
101     將客戶端的請求分發下去
102     """
103     # addr = ["127.0.0.1"]
104     addr = list()
105     Occupy = list()
106     def init(self):
107         self.Finger = None
108         pass
109 
110     def handle(self):
111         """連接的一個客戶端"""
112         self.init()
113         print("------------------連接成功-----------------")
114         print("conn :", self.request)
115         print("addr :", self.client_address)
116         # 接收客戶端數據
117         buff = self.request.recv(1024).decode("utf8")
118         data = eval(buff)
119 
120         judgeLode = JudgeLoad(self.request, self.client_address[0])
121         isTrue = judgeLode.isLoad(data, self.addr)  # 判斷是否登陸
122         if isTrue is not True:
123             if isTrue is "loadSuccess":
124                 return
125             elif isTrue is "loadFalse":
126                 print("error")
127                 self.request.send("error".encode("utf8"))
128                 return
129             elif isinstance(data, dict):
130                     isTrue1 = judgeLode.isFind("cmd", data.keys())  # 判斷類型是否符合
131                     isTrue2 = judgeLode.isFind("value", data.keys())  # 判斷類型是否符合
132                     if isTrue1 is True and isTrue2 is True:
133                         print("error")
134                         self.request.send("error".encode("utf8"))
135             return
136 
137         print(data)
138         if hasattr(self, data["cmd"]):     # 命令分發
139             func = getattr(self, data["cmd"])
140             func(data["cmd"], data["value"])
141         pass
142 
143     def finger(self, cmd, value):
144         """采集手指數據"""
145         self.Finger = DealFinger(cmd, value, self.request)
146         check, buff = self.Finger.run()
147         if check is not True:
148             self.request.send(str(check).encode("utf8"))
149             return
150         print(self.Finger.data)
151         fileName = dealFile.createImage(self.Finger.data, "finger.bmp")
152         self.sendData(fileName)
153 
154     def check(self, cmd, value):
155         """檢驗指紋是否合格"""
156         self.Finger = DealFinger(cmd, value, self.request)
157         check, score = self.Finger.run()
158 
159         if check is not True:
160             self.request.send(str(check).encode("utf8"))
161             return
162         senddata = "%s##%s" % ("True", score)   # 拼接發送格式
163         self.request.send(senddata.encode("utf8"))
164         pass
165 
166     def save(self, cmd, data):
167         """儲存數據到數據庫"""
168         self.Finger = DealFinger(cmd, "2")   # 讀取buff2 中的模板
169         check, buff = self.Finger.run()
170 
171         if check is not True:
172             self.request.send(str(check).encode("utf8"))
173             return
174         """儲存到硬件"""
175         dataFinger = list()
176         dataFinger.append(self.Finger.data)
177         self.Finger = DealFinger("saveToHard")   # 讀取buff2 中的模板
178         check, buff = self.Finger.run()
179         if check is not True:
180             self.request.send(str(check).encode("utf8"))
181             return
182         print(buff)
183         num = buff[1] * 256 + buff[2]
184         print(num)
185         """儲存到數據庫里"""
186         print(data)
187         buff = data.split("##")
188         data = {
189             "num": num,
190             "id": buff[0],
191             "name": buff[1],
192             "date": buff[2],
193             "finger": str(dataFinger[0])
194         }
195         sql = mySqlDeal("insertData", data)   # 儲存指紋
196         sql.run()
197         print("save True......")
198         self.request.send("True".encode("utf8"))  # 發送成功信息
199         """發送更新檢測指紋"""
200         core.qIsNewSql.put(True)
201         pass
202 
203     def occupy(self, cmd, data):
204         global isTcpOccupy
205         """搶占指紋"""
206         if isTcpOccupy is 1:
207             senddata = "%s" % (check["occupyError"])  # 拼接發送格式
208             self.request.send(senddata.encode("utf8"))
209             return
210 
211         core.qToClockOccupy.put(True)
212 
213         if isTcpOccupy is 2:
214             pop = self.Occupy.pop()
215             print(pop)
216             if pop != self.client_address[0]:
217                 senddata = "%s" % (check["occupyError"])  # 拼接發送格式
218                 self.request.send(senddata.encode("utf8"))
219                 return
220         self.Occupy.append(self.client_address[0])  # 記錄哪個客戶端
221 
222         isTcpOccupy = 2   # 標記客戶端搶占的
223         self.request.send("True".encode("utf8"))  # 發送成功信息
224 
225     def release(self, cmd, data):
226         """釋放指紋"""
227         global isTcpOccupy
228 
229         core.qToClockOccupy.put(False)
230 
231         if isTcpOccupy is 0:
232             senddata = "%s" % (check["releaseError"])  # 拼接發送格式
233             self.request.send(senddata.encode("utf8"))
234             return
235         isTcpOccupy = 0
236         self.Occupy.pop()
237         self.request.send("True".encode("utf8"))  # 發送成功信息
238 
239     def getLog(self, cmd, data):
240         """獲取日志"""
241         fileName = dealFile.getFilePath("log.txt")
242         if fileName is False:
243             self.request.send(check["getLogError"].encode("utf8"))  # 發送成功信息
244             return
245         self.request.send("True".encode("utf8"))  # 發送成功信息
246         self.sendData(fileName)
247         pass
248 
249     def findPeople(self, cmd, data):
250         """查找人"""
251         sql = mySqlDeal("selectId", data)   # 查找
252         ch, data = sql.run()
253         if ch is False:
254             self.request.send(check["findError"].encode("utf8"))  # 發送成功信息
255             return
256         self.request.send("True".encode("utf8"))  # 發送成功信息
257         fileName = dealFile.createFindFile(data, "find.txt")
258         self.sendData(fileName)
259         pass
260 
261     def delectPeople(self, cmd, data):
262         """刪除數據"""
263         sql = mySqlDeal("selectNum", data)   # 刪除
264         check, fingerNum = sql.run()
265         for i in fingerNum:
266             num = int(i[0])
267             self.Finger = DealFinger("psDeletChar", num)
268             self.Finger.run()
269         sql = mySqlDeal("delectId", data)   # 刪除
270         sql.run()
271         self.request.send("True".encode("utf8"))  # 發送成功信息
272         pass
273 
274     def databaseBack(self, cmd, data):
275         ch, fileName = dealFile.outPutSql("fingerSql.sql")
276         if ch is False:
277             self.request.send(check["outPutError"].encode("utf8"))  # 發送成功信息
278             return
279         self.request.send("True".encode("utf8"))  # 發送成功信息
280         self.sendData(fileName)
281         pass
282 
283     def updateDatabase(self, cmd, data):
284         buff = data.split("##")
285         fileName = buff[0]
286         fileSize = int(buff[1])
287         self.request.send("True".encode("utf8"))  # 發送成功信息
288         self.getFile(fileName, fileSize)
289         check = dealFile.creatSql(fileName)
290         if check is not True:
291             return None
292         mysql = mySqlDeal("selectAll")
293         check, data = mysql.run()
294         if check is not True:
295             return None
296         """儲存指紋"""
297         self.Finger = DealFinger("creatFinger", data)
298         self.Finger.run()
299 
300         pass
301 
302     def close(self, cmd, data):
303         """客戶端退出"""
304         for i in self.addr:
305             if i is self.client_address[0]:
306                 self.addr.remove(i)
307         pass
308 
309     def sendData(self, path):
310         """發送文件"""
311         fizeSize = os.path.getsize(path)
312         fileName = os.path.basename(path)
313         senddata = "{fileName}##{fileSize}" .format(fileName=fileName, fileSize=fizeSize)  # 拼接發送格式
314         self.request.send(senddata.encode("utf8"))
315         check = self.request.recv(1024).decode("utf8")
316         print("send......")
317         print(check)
318         if check != "True":     # 確定用戶接收到了數據
319             self.request.send("error".encode("utf8"))
320             return
321         print("send......again")
322         with open(path, "rb") as f:   # 開始發送文件
323             num = 0
324             while num < fizeSize:
325                 data = f.read(1024)
326                 self.request.sendall(data)
327                 num += len(data)
328         print("send  ok")
329         pass
330 
331     def getFile(self, path, size):
332         fileName = dealFile.getFilePath(path)
333         fileSize = size
334         with open(fileName, "w") as f:  # 得到上傳的文件
335             num = 0
336             while num < fileSize:
337                 data = self.request.recv(1024)
338                 num = num + len(data)
339                 data = data.decode("utf8")
340                 f.write(data)
341         print("get OK")
342     pass
343 
344 
345 def checkOccupy():
346     global isTcpOccupy
347     while True:
348         if isTcpOccupy == 0:
349             if core.qToTcpOccupy.empty() is not True:
350                 isTcpOccupy = core.qToTcpOccupy.get()
351     pass
352 
353 
354 if __name__ == "__main__":
355 
356     ip_port = ("192.168.137.249", 9090)
357     print("----等待連接.............")
358     s = socketserver.ThreadingTCPServer(ip_port, SeverHandle)
359 
360     s.serve_forever()
Tcpserver.py

 

 下面是服務器可能用到的

  1 # -*- coding:utf8 -*-
  2 
  3 import numpy as np
  4 from PIL import Image
  5 
  6 import os, sys
  7 import configparser
  8 
  9 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 10 sys.path.append(PATH)
 11 
 12 """存放文件的目錄"""
 13 path = PATH + "/static/"
 14 
 15 """
 16 對文件的一下操作
 17 """
 18 
 19 
 20 def readConf(cf):
 21     """讀取conf文件"""
 22     fileName = PATH + "/conf/" + "conf.conf"
 23     cf = configparser.ConfigParser()
 24     cf.read(fileName)
 25     return cf
 26 
 27 
 28 def createImage(data, fileName):
 29     """創建圖像"""
 30     if isinstance(data, list) is not True:
 31         return False
 32     """得到指紋圖像的灰度bmp圖"""
 33     ByteArray = bytearray(data)  # 將數組轉換成 字節數組
 34     NumpyArray = np.array(ByteArray)
 35     grayImage = NumpyArray.reshape(288, 128)  # 得到灰度圖像字節數組
 36     image = Image.fromarray(grayImage)
 37     fileName = path + fileName   # 文件存放路徑
 38     image.save(fileName)  # 得到指紋圖像
 39     return fileName
 40     pass
 41 
 42 
 43 def textLog(data, fileName):
 44     """寫日志"""
 45     fileName = path + fileName  # 文件存放路徑
 46     with open(fileName, "a+") as f:
 47         f.write(data)
 48     return
 49     pass
 50 
 51 def getFilePath(fileName):
 52     """回取文件路徑"""
 53     fileName = path + fileName
 54     if os.path.isfile(fileName) is False:
 55         return False
 56     return fileName
 57     pass
 58 
 59 def createFindFile(data, fileName):
 60     """生成查找文件"""
 61     fileName = path + fileName
 62     with open(fileName, "w+") as f:
 63         for i in data:
 64             id = "id  : " + i[0] + "\r\n"
 65             name = "name: " + i[1] + "\r\n"
 66             date = "date: " + i[2] + "\r\n"
 67             f.write(id + name + date + "\r\n")
 68     return fileName
 69 
 70 
 71 cf = configparser.ConfigParser()
 72 cf = readConf(cf)
 73 host = cf.get("db", "db_host")
 74 port = cf.getint("db", "db_port")
 75 user = cf.get("db", "db_user")
 76 passwd = cf.get("db", "db_pwd")
 77 db = cf.get("db", "db_database")
 78 table = cf.get("db", "db_table")
 79 
 80 """導出數據庫"""
 81 def outPutSql(fileName, host=host, port=port, user=user, passwd=passwd, db=db, table=table):
 82     """導出mysql腳本"""
 83     fileName = path + fileName
 84     sqlStr = "mysqldump -u{user} -p{passwd} {db}> {fileName}"\
 85         .format(user=user, passwd=passwd, db=db, table=table, fileName=fileName)
 86     try:
 87         os.system(sqlStr)
 88     except Exception as e:  # 找不到數據庫
 89         return False, None
 90     # print(os.path.getsize(fileName))
 91     return True, fileName
 92     pass
 93 
 94 
 95 """創建數據庫"""
 96 def creatSql(fileName,  host=host, port=port, user=user, passwd=passwd, db=db, table=table):
 97     """創建數據庫表"""
 98     fileName = path + fileName
 99     sqlStrDelect = "mysqladmin -u{user} -p{passwd} drop {db} -f"\
100         .format(user=user, passwd=passwd, db=db)
101     sqlStrCreat = "mysqladmin -u{user} -p{passwd} create {db}" \
102         .format(user=user, passwd=passwd, db=db, fileName=fileName)
103     sqlStrInsert = "mysql -u{user} -p{passwd} {db} < {fileName}" \
104         .format(user=user, passwd=passwd, db=db, fileName=fileName)
105     try:
106         """刪除數據庫"""
107         a = os.system(sqlStrDelect)
108         print(a)
109         """創建數據庫"""
110         a = os.system(sqlStrCreat)
111         print(a)
112         """插入數據庫"""
113         a = os.system(sqlStrInsert)
114         print(a)
115     except Exception as e:  # 找不到數據庫
116         print(e)
117         return False, None
118     return True
119 
120 
121 def backFile(fileName, backName):
122     """備份文件"""
123     fileName = path + fileName
124     backName = path + backName
125     logcontent = path + "logContent.txt"
126     with open(fileName, "rb") as f1, open(backName, "wb") as f2:
127         data = f1.read()
128         f2.write(data)
129     with open(fileName, "w") as f1:
130         pass
131     """添加log目錄"""
132     with open(logcontent, "a+") as f1:
133         f1.write(backName + "\r\n")
134     return True
135     pass
136 
137 
138 def joinFile():
139     """拼接日志"""
140     log = path + "log.txt"
141     logcontent = path + "logContent.txt"
142     logback = path + "logback.txt"
143     with open(logback, "w") as f2:
144         pass
145     with open(logcontent) as f1, open(logback, "a+") as f2:
146         data = f1.read().strip()
147         num = len(data)
148         if num == 0:   # 判斷文科是否為空
149             with open(log) as f3:
150                 filestream = f3.read()
151                 f2.write(filestream)
152             return
153         data = data.split("\n")
154         print(data)
155         for i in data:
156             with open(i) as f3:
157                 filestream = f3.read()
158                 f2.write(filestream)
159         with open(log) as f3:
160             filestream = f3.read()
161             f2.write(filestream)
162     pass
163 
164 
165 def cleanFile():
166     """清空無用的日志文件"""
167     filename = path + "log_*"
168     logcontent = path + "logContent.txt"
169     with open(logcontent, "w"):  # 文件目錄清空
170         pass
171     cmd = "rm {filename}".format(filename=filename)
172     data = os.system(cmd)
173     pass
174 
175 if __name__ == "__main__":
176     # print(PATH)
177     # print(type(PATH))
178     # print(path)
179     # print(type(path))
180     # print(createImage(123, 456))
181     # fileName = outPutSql("my.sql")
182     # print(fileName)
183     # print(os.path.getsize(fileName[1]))
184 
185     # backFile("simsun.ttc", "backsimsun.ttc")
186     joinFile()
187     # creatSql("123")
188     # cleanFile()
189     # logconvim tent = path + "logContent.txt"
190     # with open(logcontent) as f1:
191     #     data = f1.read().strip()
192     #     print(data)
193     #     num = len(data)
194     #
195     #     data = data.split("\n")
196     #     print(data)
dealFile.py

 

 

服務器完成后就可以寫客戶端端了。(其實是兩個同時進行然后相互補充)

下面是Qt代碼

主要是通訊,其他的界面其實都還好,就按照自己的想法

   1 #include "mainwindow.h"
   2 #include "ui_mainwindow.h"
   3 #include "QDebug"
   4 #include "QPainter"
   5 #include "QBrush"
   6 #include "QPaintDevice"
   7 #include "QMessageBox"
   8 #include "QSqlDatabase"
   9 #include "QSqlError"
  10 #include "QString"
  11 #include "QFileDialog"
  12 
  13 MainWindow::MainWindow(QWidget *parent) :
  14     QMainWindow(parent),
  15     ui(new Ui::MainWindow)
  16 {
  17     ui->setupUi(this);
  18     initData();//初始化數據函數
  19     initTcp();
  20 }
  21 
  22 MainWindow::~MainWindow()
  23 {
  24     delete ui;
  25 }
  26 
  27 
  28 //初始化數據函數
  29 void MainWindow::initData()
  30 {
  31     /* ================== 初始化登陸 ==================*/
  32     showImage = 3;
  33     //設置當前顯示頁面
  34     ui->stackedWidget->setCurrentWidget(ui->pageLog);
  35     //沒登陸不使能菜單,設置密碼不可見
  36     ui->menuO->setEnabled(false);
  37     //設置編輯框模式
  38     ui->lineEditUserName->setEnabled(true);
  39     ui->lineEditPassward->setEnabled(true);
  40     ui->lineEditPassward->setEchoMode(QLineEdit::Password);
  41     ui->pB_logoChangelink->setStyleSheet("#pB_logoChangelink{border: 0px;}"
  42                                          "#pB_logoChangelink:hover{color:rgb(0, 170, 255)};");
  43     isChangeLink=false;
  44     /* ================== 初始化界面1 ==================*/
  45     //顯示文本框
  46     ui->textEdit_1_Show->setEnabled(true);
  47     ui->pushButton_1_get->setEnabled(true);
  48     ui->pushButton_1_show->setEnabled(true);
  49     ui->progressBar_1_get->setValue(0);
  50     ui->progressBar_1_get->hide();
  51     /* ================== 初始化界面2 ==================*/
  52     //button
  53     isOccupy = false;
  54     ui->pushButton_2_Start->setText("開啟");
  55     ui->pushButton_2_Start->setEnabled(true);
  56     ui->pushButtonConcel->setEnabled(false);
  57     ui->pushButtonSure->setEnabled(false);
  58     ui->pushButtoncheckfinger->setEnabled(false);
  59     ui->pushButtonSavefinger1->setEnabled(false);
  60     ui->pushButtonSavefinger2->setEnabled(false);
  61     //label
  62     ui->label_2_info->setText("請放入手指!");
  63     ui->label_2_info->hide();
  64     //progressBar
  65     ui->progressBar_2_fingerImage->hide();
  66 
  67     /* ================ 初始化界面3 ====================== */
  68     findWhat = "id";
  69     ui->pushButton_3_findName->setText("查找id:");
  70     ui->pushButton_3_find->setEnabled(true);
  71     ui->lineEdit_3_findId->setEnabled(true);
  72     ui->pushButton_3_delect->setEnabled(false);
  73     ui->pushButton_3_back->setEnabled(true);  // 備份
  74     ui->pushButton_3_Updata->setEnabled(true); // 上傳
  75     ui->progressBar_3_show->setValue(0);
  76     ui->progressBar_3_show->hide();
  77     ui->pushButton_3_findName->setStyleSheet("#pushButton_3_findName{border: 0px;}"
  78                                          "#pushButton_3_findName:hover{color:rgb(0, 170, 255)};");
  79 
  80 
  81     /*===================== tcp數據 ======================*/
  82     //文件接收
  83     isStart = true;
  84     //初始化tcp登陸
  85     isLoad = false;
  86     callFunc = 0;
  87     recWhat = 0;
  88     showInfo = false; 
  89 }
  90 
  91 //初始化有關tcp connect
  92 void MainWindow::initTcp()
  93 {
  94     //ip和端口
  95 //    ip = "127.0.0.1";
  96 //    port = 8080;
  97 
  98     ip = "192.168.137.249";
  99     port = 9090;
 100     //套接字
 101     tcpSocket = new QTcpSocket(this);
 102     //接收到服務器后發數據
 103     connect(tcpSocket, &QTcpSocket::connected, this, &MainWindow::sendDataToServe);
 104     //收信號
 105     connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::dealReceiveData);
 106     //對話框 × 掉
 107 //    connect(this, &MainWindow::destroyed, this, &MainWindow::on_actionClose_triggered);
 108      connect(this, &MainWindow::destroyed, this,
 109              [=]()
 110              {
 111                  qDebug() << "distory";
 112              }
 113      );
 114 }
 115 
 116 //設置tcp連接
 117 bool MainWindow::tcpLink(int mode)
 118 {
 119     //tcp連接等待超時
 120     tcpSocket->disconnectFromHost();
 121     tcpSocket->close();
 122     tcpSocket->connectToHost(QHostAddress(ip), port);
 123 
 124     if(!tcpSocket->waitForConnected(100))  //等待5s
 125     {
 126         if(0 == mode)
 127         {
 128             recCheck("link_error");
 129         }
 130         return false;
 131     }
 132     return true;
 133 }
 134 
 135 //成功連接服務器后的響應
 136 void MainWindow::sendDataToServe()
 137 {
 138     switch (callFunc) {
 139     case 1: {//登陸請求
 140         //給對方發送數據,使用套接字是tcpSocket;  QString->QByteArray->char*
 141         QString userName = ui->lineEditUserName->text();
 142         QString passWord = ui->lineEditPassward->text();
 143         QString sendData = QString("{'userName':'%1', 'passWord':'%2'}")
 144                 .arg(userName).arg(passWord);
 145         tcpSocket->write(sendData.toUtf8().data());
 146     }
 147         break;
 148     case 2: {//發送錄制指紋1
 149         QString cmd = "finger";
 150         QString data = "1";
 151         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 152         tcpSocket->write(sendData.toUtf8().data());
 153     }
 154         break;
 155     case 3: {//發送錄制指紋2
 156         QString cmd = "finger";
 157         QString data = "2";
 158         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 159         tcpSocket->write(sendData.toUtf8().data());
 160     }
 161         break;
 162     case 4: {//發送校驗信息
 163         QString cmd = "check";
 164         QString data = "None";
 165         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 166         tcpSocket->write(sendData.toUtf8().data());
 167     }
 168         break;
 169     case 5: {//存儲有效指紋數據
 170         QString cmd = "save";
 171         QString name = ui->lineEditname->text();
 172         QString id = ui->lineEditID->text();
 173         QString date = ui->lineEditdate->text();
 174         QString data = QString("%1##%2##%3").arg(id).arg(name).arg(date);
 175         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 176         tcpSocket->write(sendData.toUtf8().data());
 177     }
 178         break;
 179     case 6:{ // 發送占用指紋資源
 180         QString cmd = "occupy";
 181         QString data = "None";
 182         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 183         tcpSocket->write(sendData.toUtf8().data());
 184     }
 185         break;
 186     case 7:{ // 發送釋放指紋資源
 187         QString cmd = "release";
 188         QString data = "None";
 189         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 190         tcpSocket->write(sendData.toUtf8().data());
 191     }
 192         break;
 193     case 8:{ // 界面1獲取log
 194         QString cmd = "getLog";
 195         QString data = "None";
 196         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 197         tcpSocket->write(sendData.toUtf8().data());
 198     }
 199         break;
 200     case 9:{ // 查找人
 201         QString cmd = "findPeople";
 202         QString data = QString("%1:%2").arg(findWhat).arg(ui->lineEdit_3_findId->text());
 203         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 204         tcpSocket->write(sendData.toUtf8().data());
 205     }
 206         break;
 207     case 10:{ // 刪除信息
 208         QString cmd = "delectPeople";
 209         QString data = QString("%1:%2").arg(findWhat).arg(ui->lineEdit_3_findId->text());
 210         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 211         tcpSocket->write(sendData.toUtf8().data());
 212     }
 213         break;
 214     case 11:{ // 備份數據庫
 215         QString cmd = "databaseBack";
 216         QString data = "None";
 217         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 218         tcpSocket->write(sendData.toUtf8().data());
 219     }
 220         break;
 221     case 12:{ // 上傳數據庫
 222         QString cmd = "updateDatabase";
 223         QString data = QString("%1##%2").arg(upDateFileName).arg(upDateFileSize);
 224         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 225         tcpSocket->write(sendData.toUtf8().data());
 226     }
 227         break;
 228     case 20: {//發送退出程序信號
 229         QString cmd = "close";
 230         QString data = "None";
 231         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 232         tcpSocket->write(sendData.toUtf8().data());
 233         tcpSocket->disconnectFromHost(); //關閉tcp
 234         tcpSocket->close();
 235         QMainWindow::close();
 236     }
 237         break;
 238     default:
 239         break;
 240     }
 241 }
 242 
 243 //接收事件槽函數
 244 void MainWindow::dealReceiveData()
 245 {
 246     //接收的數據
 247     switch (callFunc) {
 248     case 1: {// 登陸獲取信息
 249         QByteArray buf = tcpSocket->readAll();
 250         QString check = QString(buf);
 251         tcpSocket->disconnectFromHost(); //關閉tcp
 252         tcpSocket->close();
 253         if(check != "True")  // 登陸失敗或連接錯誤
 254         {
 255             recCheck(check);
 256             return ;
 257         }
 258         //登陸成功
 259         showImage = 1;
 260         isLoad = true;
 261         ui->menuO->setEnabled(true);
 262         ui->stackedWidget->setCurrentWidget(ui->pageShowInfo);
 263 
 264     } break;
 265 
 266     case 2:{ //接收錄制指紋1
 267         QByteArray buf = tcpSocket->readAll();
 268         QString check = QString(buf);
 269         if(check != "True")
 270         {
 271             recCheck(check);
 272             tcpSocket->disconnectFromHost(); //關閉tcp
 273             tcpSocket->close();
 274             break ;
 275         }
 276         ui->label_2_info->setText("請等待---");
 277         ui->label_2_info->show();
 278         ui->progressBar_2_fingerImage->show();
 279         callFunc = 20;
 280     } break;
 281 
 282     case 3:{ //接收錄制指紋2
 283         QByteArray buf = tcpSocket->readAll();
 284         QString check = QString(buf);
 285         if(check != "True")
 286         {
 287             recCheck(check);
 288             tcpSocket->disconnectFromHost(); //關閉tcp
 289             tcpSocket->close();
 290             break ;
 291         }
 292         ui->label_2_info->setText("請等待---");
 293         ui->label_2_info->show();
 294         ui->progressBar_2_fingerImage->show();
 295         callFunc = 20;
 296     } break;
 297 
 298     case 4:{  //兩次指紋對比度
 299         QByteArray buf = tcpSocket->readAll();
 300         QString str = QString(buf);
 301         //解析返回值
 302         QString check = QString(str).section("##", 0, 0);
 303         QString score = QString(str).section("##", 1, 1);
 304         tcpSocket->disconnectFromHost(); //關閉tcp
 305         tcpSocket->close();
 306 
 307         if("True" != check)
 308             return recCheck(check);
 309         //檢驗合格
 310         QMessageBox::information(this, "檢驗", QString("檢驗合格,分數:%1").arg(score));
 311         ui->pushButtonSure->setEnabled(true);
 312     } break;
 313 
 314     case 5:{  //存儲
 315         QByteArray buf = tcpSocket->readAll();
 316         QString check = QString(buf);
 317         tcpSocket->disconnectFromHost(); //關閉tcp
 318         tcpSocket->close();
 319 
 320         if("True" != check)
 321             return recCheck(check);
 322         QMessageBox::information(this, "save", QString("儲存成功!"));
 323 
 324         on_pushButtonConcel_clicked();
 325 
 326     } break;
 327 
 328     case 6:{  // 接收占用指紋資源是否成功
 329         QByteArray buf = tcpSocket->readAll();
 330         QString check = QString(buf);
 331         tcpSocket->disconnectFromHost(); //關閉tcp
 332         tcpSocket->close();
 333 
 334         if("True" != check)
 335             return recCheck(check);
 336         //開啟后使能和顯示提示
 337         ui->label_2_info->show();
 338         ui->label_2_info->setText("開啟成功");
 339         ui->pushButtonSavefinger1->setEnabled(true);
 340         ui->pushButton_2_Start->setText("關閉");
 341     } break;
 342 
 343     case 7:{  // 接收釋放指紋資源是否成功
 344         QByteArray buf = tcpSocket->readAll();
 345         QString check = QString(buf);
 346         tcpSocket->disconnectFromHost(); //關閉tcp
 347         tcpSocket->close();
 348 
 349         if("True" != check)
 350             return recCheck(check);
 351         QMessageBox::information(this, "release", QString("關閉成功!"));
 352         //關閉后隱藏和禁止button
 353         ui->label_2_info->hide();
 354         ui->progressBar_2_fingerImage->hide();
 355         ui->pushButton_2_Start->setText("開啟");
 356 
 357     } break;
 358 
 359     case 8:{  // 獲取接收log
 360         QByteArray buf = tcpSocket->readAll();
 361         QString check = QString(buf);
 362         if("True" != check){
 363             tcpSocket->disconnectFromHost(); //關閉tcp
 364             tcpSocket->close();
 365             return recCheck(check);
 366         }
 367         callFunc = 20;
 368 
 369     } break;
 370 
 371     case 9:{ // 查找人
 372         QByteArray buf = tcpSocket->readAll();
 373         QString check = QString(buf);
 374         if("True" != check){
 375             tcpSocket->disconnectFromHost(); //關閉tcp
 376             tcpSocket->close();
 377             return recCheck(check);
 378         }
 379         callFunc = 20;
 380     } break;
 381 
 382     case 10:{ // 刪除人
 383         QByteArray buf = tcpSocket->readAll();
 384         QString check = QString(buf);
 385         if("True" != check){
 386             tcpSocket->disconnectFromHost(); //關閉tcp
 387             tcpSocket->close();
 388             return recCheck(check);
 389         }
 390         QMessageBox::information(this, "刪除", QString("刪除成功!"));
 391     } break;
 392 
 393     case 11:{ // 備份數據庫
 394         QByteArray buf = tcpSocket->readAll();
 395         QString check = QString(buf);
 396         if("True" != check){
 397             tcpSocket->disconnectFromHost(); //關閉tcp
 398             tcpSocket->close();
 399             return recCheck(check);
 400         }
 401         callFunc = 20;
 402     } break;
 403 
 404     case 12:{  // 上傳數據庫
 405         QByteArray buf = tcpSocket->readAll();
 406         QString check = QString(buf);
 407         if("True" != check){
 408             tcpSocket->disconnectFromHost(); //關閉tcp
 409             tcpSocket->close();
 410             return recCheck(check);
 411         }
 412         qDebug() << buf;
 413         sendDataFile();
 414         //callFunc = 21;
 415     } break;
 416 
 417     case 20:{
 418         recData();
 419         //顯示進度條
 420         switch (recWhat){
 421         case 1:{
 422             ui->progressBar_1_get->setValue((100 * recvSize) / fileSize);
 423         } break;
 424         case 2:{
 425             ui->progressBar_2_fingerImage->setValue((100 * recvSize) / fileSize);
 426         } break;
 427         case 3:{
 428             ui->progressBar_2_fingerImage->setValue((100 * recvSize) / fileSize);
 429         } break;
 430         case 4:{
 431         } break;
 432         case 5:{
 433             ui->progressBar_3_show->setValue((100 * recvSize) / fileSize);
 434         } break;
 435         default: break;
 436         }
 437         //傳輸完成后
 438         if(showInfo == true)
 439         {
 440             showInfo = false;
 441             callFunc = 0;
 442             QMessageBox::information(this, "完成", "接收完成");
 443             switch (recWhat) {
 444             case 1:{
 445                 recWhat = 0;
 446                 ui->pushButton_1_get->setEnabled(true);
 447                 ui->progressBar_1_get->hide();
 448             } break;
 449             case 2:{
 450                 ui->pushButtonSavefinger2->setEnabled(true);
 451                 showImage = 2;
 452                 update();
 453                 recWhat = 0;
 454             } break;
 455             case 3:{
 456                 ui->pushButtoncheckfinger->setEnabled(true);
 457                 showImage = 2;
 458                 update();
 459                 recWhat = 0;
 460             } break;
 461             case 4:{
 462                 ui->textEdit_3_show->clear();
 463                 QString str = showFile("find.txt");
 464                 ui->textEdit_3_show->append(str);
 465                 ui->pushButton_3_find->setEnabled(true);
 466                 ui->lineEdit_3_findId->setEnabled(true);
 467                 ui->pushButton_3_delect->setEnabled(true);
 468                 recWhat = 0;
 469             } break;
 470             case 5:{
 471                 ui->pushButton_3_back->setEnabled(true);
 472                 ui->progressBar_3_show->hide();
 473                 recWhat = 0;
 474             } break;
 475             default: break;
 476             }
 477         }
 478     } break;
 479 
 480 
 481     case 21:{ // 發送文件
 482         sendDataFile();
 483     } break;
 484 
 485 //    case 22:{ // 等待發送文件后的回應
 486 //        QByteArray buf = tcpSocket->readAll();;
 487 //        QString check = QString(buf).section("##", 0, 0);
 488 //        fileSize = QString(buf).section("##", 1, 1).toInt();
 489 //        if("True" != check){
 490 //            tcpSocket->disconnectFromHost(); //關閉tcp
 491 //            tcpSocket->close();
 492 //            return recCheck(check);
 493 //        }
 494 //        callFunc = 23;
 495 //    } break;
 496 
 497 //    case 23:{  //等待對方更新完成
 498 
 499 //    } break;
 500 
 501     default: break;
 502     }
 503 
 504 }
 505 
 506 //獲取文件
 507 void MainWindow::recData()
 508 {
 509     QByteArray buf = tcpSocket->readAll();
 510     QString check = QString(buf);
 511 
 512     if(true == isStart)
 513     {
 514         qDebug() << buf;
 515         isStart = false;
 516         //解析傳回的頭文件
 517         fileName = QString(buf).section("##", 0, 0);
 518         fileSize = QString(buf).section("##", 1, 1).toInt();
 519         recvSize = 0;  //初始化接收數據大小
 520 
 521         qDebug() << fileName << fileSize;
 522         if (0 == fileSize){  // 文件大小為0
 523             tcpSocket->disconnectFromHost();
 524             tcpSocket->close();
 525             return recCheck("fileError");
 526         }
 527 
 528         fileTransport.setFileName(fileName);
 529 
 530         bool isOk = fileTransport.open(QIODevice::WriteOnly);
 531         if(false == isOk)
 532         {
 533             qDebug() << "WriteOnly error 40";
 534         }
 535         tcpSocket->write(QString("True").toUtf8().data());
 536 
 537 
 538     }
 539     else
 540     {
 541         qint64 len = fileTransport.write(buf);
 542         recvSize += len;
 543         if(recvSize == fileSize)  //判斷是否傳輸完成
 544         {
 545             fileTransport.close();
 546             tcpSocket->disconnectFromHost();
 547             tcpSocket->close();
 548             //准備新的傳輸
 549             isStart = true;
 550             showInfo = true;
 551         }
 552     }
 553 }
 554 
 555 //發送文件
 556 void MainWindow::sendDataFile()
 557 {
 558     qint64 len = 0;
 559     do
 560     {
 561         //每次發送數據的大小
 562         char buf[4*1024] = {0};
 563         len = 0;
 564 
 565         //往文件中讀數據
 566         len = fileTransport.read(buf, sizeof(buf));
 567 
 568         //發送數據,讀多少,發多少
 569         len = tcpSocket->write(buf, len);
 570         //發送數據要累加
 571         sendSize += len;
 572         ui->progressBar_3_show->setValue(sendSize*100/upDateFileSize);
 573 
 574     }while(len >0 );
 575     //是否發送文件完畢
 576     if(sendSize == upDateFileSize)
 577     {
 578         QMessageBox::about(this, "傳輸", "文件發送完成");
 579         fileTransport.close();
 580 
 581         //把客戶端關閉
 582         ui->textEdit_3_show->append("連接斷開");
 583         tcpSocket->disconnectFromHost();
 584         tcpSocket->close();
 585 
 586 
 587         ui->pushButton_3_Updata->setEnabled(true);
 588         ui->pushButton_3_back->setEnabled(true);
 589         ui->menuO->setEnabled(true);
 590         ui->pushButton_3_find->setEnabled(true);
 591         ui->progressBar_3_show->setValue(0);
 592         ui->progressBar_3_show->hide();
 593         //callFunc = 22;
 594     }
 595 }
 596 
 597 //接收的信號做檢測
 598 void MainWindow::recCheck(QString check)
 599 {
 600     qDebug() << check;
 601     if ("error" == check){// 連接失敗或者是登陸失敗
 602         if(false == isLoad)
 603             QMessageBox::warning(this, "連接信息", "用戶名或者密碼錯誤!");
 604         else
 605             QMessageBox::warning(this, "連接信息", "連接斷開,重新登陸!");
 606         initData();
 607     }
 608     else if("102" == check){// 沒有檢測到手指
 609         ui->label_2_info->setText("請放入手指!");
 610         ui->label_2_info->show();
 611         switch (callFunc) {
 612         case 2:{
 613             ui->pushButtonSavefinger1->setEnabled(true);
 614         } break;
 615         case 3:{
 616             ui->pushButtonSavefinger2->setEnabled(true);
 617         }break;
 618         default: break;
 619         }
 620     }
 621     else if ("302" == check) { // 校驗失敗
 622         QMessageBox::warning(this, "校驗信息", "兩次指紋不匹配!");
 623         this->on_pushButtonConcel_clicked();
 624     }
 625     else if("link_error" == check) // 找不到服務器
 626     {
 627         QMessageBox::about(this, "連接信息", "連接失敗......");
 628         initData();
 629     }
 630     else if("occupyError" == check) //搶占失敗
 631     {
 632         QMessageBox::about(this, "占用信息", "設備正忙......");
 633         isOccupy = false;
 634     }
 635     else if("getLogError" == check)
 636     {
 637         QMessageBox::about(this, "獲取日志", "失敗!");
 638         ui->progressBar_1_get->hide();
 639         ui->pushButton_1_get->setEnabled(true);
 640     }
 641     else if("findError" == check)
 642     {
 643         QMessageBox::about(this, "查找", "失敗!沒這個人");
 644         ui->pushButton_3_find->setEnabled(true);
 645         ui->lineEdit_3_findId->setEnabled(true);
 646         ui->textEdit_3_show->clear();
 647     }
 648     else if("delectError" == check)
 649     {
 650         QMessageBox::about(this, "刪除", "刪除失敗!");
 651     }
 652     else if("outPutError" == check)
 653     {
 654         QMessageBox::about(this, "導出數據庫", "導出失敗!");
 655         ui->pushButton_3_back->setEnabled(true);
 656     }
 657     else if("fileError" == check)
 658     {
 659         QMessageBox::about(this, "文件錯誤", "文件錯誤!");
 660     }
 661 }
 662 
 663 //繪圖事件
 664 void MainWindow::paintEvent(QPaintEvent *)
 665 {
 666 
 667     QPainter p;
 668     //QPaintDevice pD;
 669     p.begin(this);//指定當前出窗口為繪圖設備
 670 
 671     /* *
 672      * showImage
 673      * 1,顯示頁面顏色繪圖
 674      * 2,指紋頁面繪圖
 675      * 3,查詢頁面繪圖
 676      * */
 677     switch (showImage) {
 678     case 1:      
 679 //        ui->pageShowInfo->setStyleSheet("#pageShowInfo{"
 680 //                                       "border-image:url(:/image/image/car.jpg);"
 681 //                                       "}"
 682 //                                       );
 683 //        break;
 684 
 685     case 2:{
 686         QString str = QString("QWidget{"
 687                       "border-image:url(finger.bmp);"
 688                       "}");
 689         ui->widgetFinger->setStyleSheet(str);
 690     }
 691         break;
 692 
 693     case 3:
 694 
 695         break;
 696 
 697     default:
 698         break;
 699     }
 700 
 701     p.end();
 702 }
 703 
 704 //顯示文本
 705 QString MainWindow::showFile(QString fileName)
 706 {
 707     QFile file(fileName);
 708     ui->textEdit_1_Show->clear();
 709     bool isOk = file.open(QIODevice::ReadOnly);
 710     if(false == isOk)
 711     {
 712         qDebug() << "WriteOnly error 40";
 713     }
 714     QByteArray buff = file.readAll();
 715     QString str = QString(buff);
 716     return str;
 717 }
 718 /***================= 菜單函數 ===================***/
 719 //顯示界面
 720 void MainWindow::on_actionShow_triggered()
 721 {
 722     ui->stackedWidget->setCurrentWidget(ui->pageShowInfo);
 723     showImage = 1;
 724     update();
 725 
 726 }
 727 
 728 //錄指紋界面
 729 void MainWindow::on_actionSave_triggered()
 730 {
 731     ui->stackedWidget->setCurrentWidget(ui->pageSave);
 732     showImage = 2;
 733     update();
 734 }
 735 
 736 //查找界面
 737 void MainWindow::on_actionFind_triggered()
 738 {
 739     ui->stackedWidget->setCurrentWidget(ui->pageFind);
 740     showImage = 3;
 741     update();
 742 }
 743 
 744 //菜單欄退出
 745 void MainWindow::on_actionClose_triggered()
 746 {
 747     /***********連接服務器發送數據***********/
 748     callFunc = 20;
 749     bool check = tcpLink(1);    //不要默認模式 0
 750     if(false == check)
 751     {
 752         MainWindow::close();
 753     }
 754 }
 755 
 756 /*** ===================界面登陸的函數========================== ***/
 757 //登陸函數
 758 void MainWindow::on_pushButtonReg_clicked()
 759 {
 760     //禁止輸入
 761     ui->lineEditUserName->setEnabled(false);
 762     ui->lineEditPassward->setEnabled(false);
 763 
 764     tcpSocket->disconnectFromHost();
 765     tcpSocket->close();
 766     //連接服務器
 767     callFunc = 1;
 768     tcpLink();  //默認模式 0
 769 
 770 }
 771 
 772 
 773 //退出函數
 774 void MainWindow::on_pushButtonClose_clicked()
 775 {
 776     QMainWindow::close();
 777 }
 778 
 779 //改變連接端口
 780 void MainWindow::on_pB_logoChangelink_clicked()
 781 {
 782     if(false == isChangeLink)
 783     {
 784         isChangeLink = true;
 785         ui->pB_logoChangelink->setText("返回?");
 786         //清楚編輯行文本
 787         ui->lineEditUserName->clear();
 788         ui->lineEditPassward->clear();
 789         //設置端口和ip
 790         ui->label_logo_name->setText("ip :");
 791         ui->label_logo_passwd->setText("port :");
 792         ui->lineEditPassward->setEchoMode(QLineEdit::Normal);  //設置正常顯示
 793         //隱藏登陸
 794         ui->pushButtonReg->hide();
 795 
 796         qDebug() << ip << port;
 797     }
 798     else
 799     {
 800         isChangeLink = false;
 801         ui->pB_logoChangelink->setText("更改登陸連接?");
 802         //設置端口和ip
 803         ip = ui->lineEditUserName->text();
 804         port = ui->lineEditPassward->text().toInt();
 805         //清楚編輯行文本
 806         ui->lineEditUserName->clear();
 807         ui->lineEditPassward->clear();
 808         //設置為登陸模式
 809         ui->label_logo_name->setText("用戶名:");
 810         ui->label_logo_passwd->setText("密 碼:");
 811         ui->lineEditPassward->setEchoMode(QLineEdit::Password);
 812         //顯示登陸
 813         ui->pushButtonReg->show();
 814 
 815         qDebug() << ip << port;
 816     }
 817 }
 818 /*** ===================界面1的函數========================== */
 819 //在窗口顯示信息
 820 void MainWindow::on_pushButton_1_show_clicked()
 821 {
 822     QString str = showFile("log.txt");
 823     ui->textEdit_1_Show->append(str);
 824 }
 825 //下載更新log
 826 void MainWindow::on_pushButton_1_get_clicked()
 827 {
 828     ui->pushButton_1_get->setEnabled(false);
 829     //顯示進度條
 830     ui->progressBar_1_get->setValue(0);
 831     ui->progressBar_1_get->show();
 832     /***********連接服務器發送數據***********/
 833     recWhat = 1;
 834     callFunc = 8;
 835     tcpLink();  //默認模式 0
 836 }
 837 /*** ===================界面2的函數========================== */
 838 //開啟錄制,占用資源
 839 void MainWindow::on_pushButton_2_Start_clicked()
 840 {
 841     if(false == isOccupy)  //開啟占用
 842     {
 843         isOccupy = true;
 844         /***********連接服務器發送數據***********/
 845         callFunc = 6;
 846         //tcp連接
 847         tcpLink();
 848     }
 849     else  // 釋放
 850     {
 851         isOccupy = false;
 852         //禁止button
 853         ui->pushButtonSavefinger1->setEnabled(false);
 854         ui->pushButtonConcel->setEnabled(false);
 855         ui->pushButtonSavefinger2->setEnabled(false);
 856         ui->pushButtonSure->setEnabled(false);
 857         ui->pushButtoncheckfinger->setEnabled(false);
 858         //隱藏進度條
 859         ui->progressBar_2_fingerImage->setValue(0);
 860         ui->progressBar_2_fingerImage->hide();
 861         /***********連接服務器發送數據***********/
 862         callFunc = 7;
 863         //tcp連接
 864         tcpLink();
 865     }
 866 }
 867 
 868 //錄制指紋 1 Button
 869 void MainWindow::on_pushButtonSavefinger1_clicked()
 870 {
 871     //使能返回button和禁止錄制button
 872     ui->pushButtonSavefinger1->setEnabled(false);
 873     ui->pushButtonConcel->setEnabled(true);
 874     //禁止輸入
 875     ui->lineEditname->setEnabled(false);
 876     ui->lineEditID->setEnabled(false);
 877     ui->lineEditdate->setEnabled(false);
 878     //隱藏進度條
 879     ui->progressBar_2_fingerImage->setValue(0);
 880     ui->progressBar_2_fingerImage->hide();
 881     /***********連接服務器發送數據***********/
 882     callFunc = 2;
 883     recWhat = 2;
 884     tcpLink();  //默認模式 0
 885 
 886 }
 887 
 888 //錄制指紋 2 Button
 889 void MainWindow::on_pushButtonSavefinger2_clicked()
 890 {
 891     //禁止button
 892     ui->pushButtonSavefinger2->setEnabled(false);
 893     //隱藏進度條
 894     ui->progressBar_2_fingerImage->setValue(0);
 895     ui->progressBar_2_fingerImage->hide();
 896     /***********連接服務器發送數據***********/
 897     callFunc = 3;
 898     recWhat = 3;
 899     tcpLink();  //默認模式 0
 900 
 901 
 902 }
 903 
 904 //檢驗兩次錄取准確度
 905 void MainWindow::on_pushButtoncheckfinger_clicked()
 906 {
 907     ui->pushButtoncheckfinger->setEnabled(false);
 908     /***********連接服務器發送數據***********/
 909     callFunc = 4;    
 910     tcpLink();  //默認模式 0
 911 }
 912 
 913 
 914 //取消錄取操作
 915 void MainWindow::on_pushButtonConcel_clicked()
 916 {
 917     //開啟輸入
 918     ui->lineEditname->setEnabled(true);
 919     ui->lineEditID->setEnabled(true);
 920     ui->lineEditdate->setEnabled(true);
 921     //button功能轉換
 922     ui->pushButtonSavefinger1->setEnabled(true);
 923     ui->pushButtonConcel->setEnabled(false);
 924     ui->pushButtonSavefinger2->setEnabled(false);
 925     ui->pushButtonSure->setEnabled(false);
 926     //隱藏顯示信息
 927     ui->label_2_info->hide();
 928     ui->progressBar_2_fingerImage->hide();
 929     //關閉連接主機
 930     tcpSocket->disconnectFromHost();
 931     tcpSocket->close();
 932     //關閉文件
 933     fileTransport.close();
 934     isStart = true;
 935     showInfo = false;
 936 }
 937 
 938 //更新數據庫
 939 void MainWindow::on_pushButtonSure_clicked()
 940 {
 941     ui->pushButtonSure->setEnabled(false);
 942     //彈出對話框提醒用戶是否更新
 943     QString str = "是否跟新到數據庫";
 944     int isOk = QMessageBox::information(this, "issave", str, QMessageBox::Ok, QMessageBox::Cancel);
 945 
 946     if (QMessageBox::Cancel == isOk)
 947     {
 948         on_pushButtonConcel_clicked();
 949         return;
 950     }
 951 
 952 //    /*================== 數據庫的操作 ==============*/
 953 //    //添加MySql數據庫
 954 //    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
 955 //    //連接數據庫
 956 //    db.setHostName("127.0.0.1"); //數據庫服務器IP
 957 //    db.setUserName("root"); //數據庫用戶名
 958 //    db.setPassword("123456"); //密碼
 959 //    db.setDatabaseName("myinfo"); //使用哪個數據庫
 960 
 961 //    //打開數據庫
 962 //    if(false == db.open()) //數據庫打開失敗
 963 //    {
 964 //        QMessageBox::warning(this, "錯誤", db.lastError().text());
 965 //        return;
 966 
 967 //    }
 968 
 969 //    db.close();
 970     callFunc = 5;
 971     tcpLink();  //默認模式 0
 972 
 973 }
 974 
 975 /*** ===================界面3的函數========================== */
 976 //查找人
 977 void MainWindow::on_pushButton_3_find_clicked()
 978 {
 979     ui->pushButton_3_find->setEnabled(false);
 980     ui->lineEdit_3_findId->setEnabled(false);
 981     /***********連接服務器發送數據***********/
 982     callFunc = 9;
 983     recWhat = 4;
 984     tcpLink();  //默認模式 0
 985 }
 986 
 987 //刪除信息
 988 void MainWindow::on_pushButton_3_delect_clicked()
 989 {
 990     ui->pushButton_3_delect->setEnabled(false);
 991     /***********連接服務器發送數據***********/
 992     callFunc = 10;
 993     tcpLink();  //默認模式 0
 994 }
 995 //輸入框變化
 996 void MainWindow::on_lineEdit_3_findId_textChanged(const QString &arg1)
 997 {
 998     ui->pushButton_3_delect->setEnabled(false);
 999 }
1000 
1001 //備份數據庫
1002 void MainWindow::on_pushButton_3_back_clicked()
1003 {
1004     ui->pushButton_3_back->setEnabled(false);
1005     ui->progressBar_3_show->setValue(0);
1006     ui->progressBar_3_show->show();
1007     /***********連接服務器發送數據***********/
1008     callFunc = 11;
1009     recWhat = 5;
1010     tcpLink();  //默認模式 0
1011 
1012 }
1013 //按查找的名字
1014 void MainWindow::on_pushButton_3_findName_clicked()
1015 {
1016     ui->lineEdit_3_findId->setEnabled(true);
1017     QString txt = ui->pushButton_3_findName->text();
1018     if("查找id:" == txt)
1019     {
1020         ui->pushButton_3_findName->setText("查找name:");
1021         findWhat = "name";
1022     }
1023     else if("查找name:" == txt)
1024     {
1025         ui->pushButton_3_findName->setText("查找date:");
1026         findWhat = "time";
1027     }
1028     else if("查找date:" == txt)
1029     {
1030         ui->pushButton_3_findName->setText("查找all:");
1031         findWhat = "id";
1032 //        ui->lineEdit_3_findId->setEnabled(false);
1033     }
1034 //    else if("查找all:" == txt)
1035 //    {
1036 //        ui->pushButton_3_findName->setText("查找id:");
1037 //        findWhat = "id";
1038 //    }
1039 }
1040 
1041 //上傳.sql 文件 並更新模塊
1042 void MainWindow::on_pushButton_3_Updata_clicked()
1043 {
1044     QString filePath = QFileDialog::getOpenFileName(this, "open", "./");
1045     //如果路徑有效
1046     if(false == filePath.isEmpty()){
1047         upDateFileName.clear(); // 上傳文件名字
1048         upDateFileSize = 0;//文件大小
1049         sendSize = 0; // 發送文件的大小
1050         //獲取信息
1051         QFileInfo info(filePath);
1052         upDateFileName = info.fileName();
1053         upDateFileSize = info.size();
1054 
1055         //打開文件
1056         fileTransport.setFileName(filePath);
1057         bool isOk = fileTransport.open(QIODevice::ReadOnly);
1058         if(false == isOk){
1059             qDebug() << "打開失敗 62";
1060         }
1061 
1062         ui->textEdit_3_show->setText(filePath);
1063 
1064         ui->pushButton_3_Updata->setEnabled(false);
1065         ui->pushButton_3_back->setEnabled(false);
1066         ui->menuO->setEnabled(false);
1067         ui->pushButton_3_delect->setEnabled(false);
1068         ui->pushButton_3_find->setEnabled(false);
1069         ui->progressBar_3_show->setValue(0);
1070         ui->progressBar_3_show->show();
1071 
1072     }
1073     else{
1074         qDebug() << "選擇文件路徑出錯 62";
1075 
1076 
1077     }
1078 
1079 
1080     /***********連接服務器發送數據***********/
1081     callFunc = 12;
1082     recWhat = 6;
1083     tcpLink();  //默認模式 0
1084 }
Qt客戶端  .cpp文件

 

  1 #ifndef MAINWINDOW_H
  2 #define MAINWINDOW_H
  3 
  4 #include <QMainWindow>
  5 #include "QTcpServer"
  6 #include "QTcpSocket"
  7 #include "QPaintEvent"
  8 
  9 namespace Ui {
 10 class MainWindow;
 11 }
 12 
 13 class MainWindow : public QMainWindow
 14 {
 15     Q_OBJECT
 16 
 17 public:
 18     explicit MainWindow(QWidget *parent = 0);
 19     ~MainWindow();
 20 
 21     //初始化數據
 22     void initData();
 23     //初始化tcp
 24     void initTcp();
 25     //設置tcp連接
 26     bool tcpLink(int mode = 0);
 27 
 28     //發送數據給服務器
 29     void sendDataToServe();
 30     //處理接收的數據
 31     void dealReceiveData();
 32     //接收文件
 33     void recData();
 34     //處理接收的返回值檢測
 35     void recCheck(QString check);
 36     //畫圖事件
 37     void paintEvent(QPaintEvent *);
 38     //顯示文本
 39     QString showFile(QString fileName);
 40     //發送文件
 41     void sendDataFile();
 42 
 43 signals:
 44     void connectSuccess();
 45 
 46 private slots:
 47     //菜單顯示事件
 48     void on_actionShow_triggered();
 49 
 50     void on_actionSave_triggered();
 51 
 52     void on_actionFind_triggered();
 53 
 54     void on_actionClose_triggered();  // 菜單退出
 55 
 56     //button事件
 57     void on_pushButtonSavefinger1_clicked(); //錄指紋1
 58 
 59     void on_pushButtonConcel_clicked(); //取消錄指紋
 60 
 61     void on_pushButtonSure_clicked(); //確定錄取
 62 
 63     void on_pushButtonReg_clicked(); //登陸服務器
 64 
 65     void on_pushButtonClose_clicked(); //關閉窗口
 66 
 67     void on_pushButtonSavefinger2_clicked(); //錄制指紋 2
 68 
 69     void on_pushButtoncheckfinger_clicked(); //檢驗兩次錄取准確度
 70 
 71     void on_pB_logoChangelink_clicked();  // 登陸界面改變link
 72 
 73     void on_pushButton_2_Start_clicked();  //申請資源
 74 
 75     void on_pushButton_1_get_clicked();   //獲取日志
 76 
 77     void on_pushButton_1_show_clicked();  //顯示日志
 78 
 79     void on_pushButton_3_find_clicked();  //查找人
 80 
 81     void on_lineEdit_3_findId_textChanged(const QString &arg1);
 82 
 83     void on_pushButton_3_delect_clicked(); //刪除信息
 84 
 85     void on_pushButton_3_back_clicked(); //備份數據庫
 86 
 87     void on_pushButton_3_findName_clicked();  // 更改查找選項
 88 
 89     void on_pushButton_3_Updata_clicked();  // 上傳數據庫
 90 
 91 private:
 92     Ui::MainWindow *ui;
 93 
 94     //tcp套接字指針
 95     QTcpSocket *tcpSocket;
 96     QString ip;
 97     quint16 port;
 98 
 99     int showImage; //顯示哪個界面
100     bool isLoad; //是否登陸
101     bool isChangeLink;
102     int recWhat; //接收的什么數據
103     bool isOccupy; //是否占用指紋資源
104     /* *
105      * 哪個函數發送的tcp請求
106      * 1,登陸
107      * */
108     int callFunc;
109 
110     QString filePath; //文件路徑
111     QFile fileTransport;//文件對象
112     QString fileName;//文件名字
113     qint64 fileSize;//文件大小
114     qint64 recvSize;//已經發送的文件的大小
115     bool isStart;  //接收頭文件
116     bool showInfo; //接收完成后
117 
118     QString upDateFileName; // 上傳文件名字
119     qint64 upDateFileSize;//文件大小
120     qint64 sendSize; // 發送文件的大小
121 
122     QString findWhat; //按什么查找數據庫
123 };
124 
125 #endif // MAINWINDOW_H
客戶端頭文件 .h

 

3.然后就是數據庫儲存了

 就是一些簡單的mysql語句

  1 #!/usr/local/opt/python-3.5.2/bin/python3.5
  2 #-*- coding:utf8 -*-
  3 
  4 import pymysql
  5 import os, sys
  6 import configparser
  7 
  8 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  9 sys.path.append(PATH)
 10 
 11 from core import dealFile
 12 
 13 
 14 class mySqlDeal:
 15     """數據庫的操作"""
 16     def __init__(self, cmd=None, data=None, host="127.0.0.1", port=3306, user="root", passwd="123456", db="finger", table="test"):
 17         cf = configparser.ConfigParser()
 18         cf = dealFile.readConf(cf)
 19         host = cf.get("db", "db_host")
 20         port = cf.getint("db", "db_port")
 21         user = cf.get("db", "db_user")
 22         passwd = cf.get("db", "db_pwd")
 23         db = cf.get("db", "db_database")
 24         table = cf.get("db", "db_table")
 25         """初始化數據"""
 26         self.cmd = cmd
 27         self.data = data
 28         self.host = host
 29         self.port = port
 30         self.user = user
 31         self.passwd = passwd
 32         self.db = db
 33         self.table = table
 34         pass
 35 
 36     def link(self):
 37         """連接數據庫"""
 38         self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.passwd, db=self.db)
 39         self.cursor = self.conn.cursor()
 40         pass
 41 
 42     def run(self, cmd=None, table=None):
 43         """執行cmd"""
 44         self.link()
 45         if hasattr(self, self.cmd):
 46             func = getattr(self, self.cmd)
 47             return func(data=self.data, table=self.table)
 48         self.endSql()
 49         return False, None
 50 
 51     def creatDatabase(self, data, table):
 52         """創建數據庫"""
 53         pass
 54 
 55     def creatTable(self, data, table):
 56         """創建表"""
 57         pass
 58 
 59     def insertData(self, data, table):
 60         """插入數據到數據庫"""
 61         if isinstance(data, dict) is not True:   # 判斷data是不是字典類型
 62             return False, None
 63         # 拼接sql語句  執行
 64         sqlStr = "INSERT INTO {table} VALUES ('{num}', '{id}', '{name}', '{date}', '{finger}');"\
 65             .format(table=table, num=data['num'], id=data["id"], name=data["name"], date=data["date"], finger=data["finger"])
 66         self.cursor.execute(sqlStr)
 67 
 68         self.endSql()  # 結束sql
 69         return True, None
 70         pass
 71 
 72     def selectAll(self, data=None, table=None):
 73         """選擇數據庫中的數據  所有"""
 74         # 拼接sql語句  執行
 75         sqlStr = "SELECT * FROM {table};".format(table=table)
 76         self.cursor.execute(sqlStr)
 77         data = self.cursor.fetchall()   # 尋找所有數據
 78 
 79         self.endSql()   # 結束sql
 80         return True, data
 81         pass
 82 
 83     def selectData(self, data=None, table=None):
 84         """選擇數據庫中的數據"""
 85         # 拼接sql語句  執行
 86         data = data.split(":")
 87         sqlStr = "SELECT * FROM {table} WHERE {what}={find};".format(table=table, what=data[0], find=data[1])
 88         self.cursor.execute(sqlStr)
 89         data = self.cursor.fetchall()   # 尋找所有數據
 90 
 91         self.endSql()   # 結束sql
 92         return True, data
 93         pass
 94 
 95     def selectId(self, data, table):
 96         """
 97         :param data: 固定格式必須要  what:find
 98         :param table:
 99         :return:
100         """
101         # 拼接sql語句  執行
102         data = data.split(":")
103         if data[0] == "all":
104             sqlStr = "SELECT id, name, time FROM {table};".format(table=table)
105         else:
106             sqlStr = "SELECT id, name, time FROM {table} WHERE {what} REGEXP '^{find}';"\
107                 .format(table=table, what=data[0], find=data[1])
108         self.cursor.execute(sqlStr)
109         data = self.cursor.fetchall()   # 尋找所有數據
110         self.endSql()  # 結束sql
111         if len(data) is 0:
112             return False, None
113         return True, data
114 
115     def selectNum(self, data, table):
116         data = data.split(":")
117         sqlStr = "SELECT num FROM {table} WHERE {what} REGEXP '^{find}';"\
118             .format(table=table, what=data[0], find=data[1])
119         self.cursor.execute(sqlStr)
120         data = self.cursor.fetchall()  # 尋找所有數據
121         self.endSql()  # 結束sql
122         if len(data) is 0:
123             return False, None
124         return True, data
125         pass
126 
127     def delectId(self, data, table):
128         """
129         :param data: 固定格式必須要  what:find
130         :param table:
131         :return:
132         """
133         # 拼接sql語句  執行
134         data = data.split(":")
135         if data[0] == "all":
136             sqlStr = "DELETE FROM {table};".format(table=table)
137         else:
138             sqlStr = "DELETE FROM {table} WHERE {what} REGEXP '^{find}';".format(table=table, what=data[0], find=data[1])
139         self.cursor.execute(sqlStr)
140         self.endSql()  # 結束sql
141         return True, None
142 
143     def endSql(self):
144 
145         """提交和關閉sql"""
146         self.conn.commit()
147         self.cursor.close()
148         self.conn.close()
149 
150     pass
151 
152 
153 if __name__ == "__main__":
154     # delectId
155     # A = mySqlDeal("selectWhat", "name")
156     A = mySqlDeal("selectId", "name:12")
157     check, data = A.run()
158     # print(check)
159     # for i in data:
160     #     print(i)
161     print(check)
162     print(data)
163 
164     pass
dealSql.py

 

 4.可以用Pycharm遠程調試樹莓派啦

 網上有很多遠程調試的例子,如果還是不會可以留言

首先用編寫打卡的程序,用到樹莓派GPIO口

  1 # -*- coding:utf8 -*-
  2 
  3 import RPi.GPIO as GPIO
  4 
  5 import os,sys
  6 
  7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  8 sys.path.append(PATH)
  9 # import core
 10 from core.dealSql import mySqlDeal
 11 from core import dealFinger
 12 # from core import clockIn
 13 from core import dealFile
 14 from core import oledshow
 15 # from core import Tcpserver
 16 import time
 17 
 18 isOccupy = False
 19 
 20 class ClockCheck:
 21 
 22     def __init__(self, queueOled, queueToTcp, queueToClock, queueIsNewSql):
 23         self.flage = False
 24         self.queueOled = queueOled
 25         self.queueToTcp = queueToTcp
 26         self.queueToClock = queueToClock
 27         self.queueIsNewSql = queueIsNewSql
 28         """初始化GPIO"""
 29         self.GPIO_Pin = 18
 30         GPIO.setmode(GPIO.BCM)
 31         GPIO.setwarnings(False)
 32         GPIO.setup(self.GPIO_Pin, GPIO.IN)
 33         """引入其他模塊"""
 34         # self.mysql = mySqlDeal()
 35         self.myFinger = dealFinger.DealFinger()
 36         self.check = 0
 37 
 38         # check, self.data = self.mysql.run()
 39         pass
 40 
 41     def run(self):
 42         while True:
 43             """判斷是否串口可用"""
 44             check = self.isOk()
 45             if check is not True:
 46                 continue
 47             """獲取數據庫的值"""
 48             self.flage = True
 49 
 50             a = time.time()
 51             check = self.getChar()  # 判斷是否獲取成功
 52             if check is not True:
 53                 print(check)
 54                 self.release()
 55                 continue
 56             """判斷是否有指紋存在"""
 57             check = self.checkFinger(0)
 58             self.release()
 59             print(time.time() - a)
 60             if check is not True:
 61                 print("ERROR")
 62                 continue
 63             print("success!")
 64         pass
 65 
 66     def isOk(self):
 67         """判斷是否串口可用"""
 68         if GPIO.input(self.GPIO_Pin) is GPIO.LOW:
 69             if self.queueIsNewSql.empty() is not True:  # 是否跟新數據
 70                 self.queueIsNewSql.get()
 71                 self.renewData()
 72             """判斷是否有指紋按下"""
 73             if self.flage is True:
 74                 self.flage = False
 75             return False
 76         """有指紋按下判斷是否可搶占"""
 77         check = self.occupy()
 78         if check is not True:
 79             return False
 80 
 81         if self.check is 102:  # 清除沒指紋意外
 82             self.check = 0
 83             self.flage = False
 84         if self.flage is not False:
 85             self.release()  # 釋放
 86             return False
 87         return True
 88         pass
 89 
 90     def occupy(self):
 91         """搶占指紋資源"""
 92         global isOccupy
 93         if self.queueToClock.empty() is not True:
 94             isOccupy = self.queueToClock.get()
 95 
 96         if isOccupy is True:
 97             # print("occupyError")
 98             return False
 99         self.queueToTcp.put(1)
100         return True
101         pass
102 
103     def release(self):
104         """釋放指紋資源"""
105         self.queueToTcp.put(0)
106 
107     def renewData(self):
108         # check, self.data = self.mysql.run()
109         # return check
110         pass
111 
112     def checkFinger(self, data):
113         """和數據庫中的指紋匹配"""
114         self.myFinger.link()
115         check, buff = self.myFinger.checkPSIdentify()
116         if check is True:
117             """獲取數據庫中的相應值"""
118             num = buff[1]*256 + buff[2]
119             numStr = "num:%s" % num
120             print(numStr)
121             mysql = mySqlDeal("selectData", numStr)
122             check, data = mysql.run()
123             for i in data:
124                 fingerData = eval(i[4])
125                 fingerData = dealFinger.DealBuff(fingerData)
126                 fingerData = fingerData.write()
127                 check, score = self.myFinger.isFinger(fingerData)
128                 if check is True:
129                     self.writeLog(i[1] + " " + i[2], "log.txt")
130                     qDir ={
131                         "check": True,
132                         "id": i[1],
133                         "name": i[2]
134                     }
135                     self.queueOled.put(qDir)
136                     time.sleep(0.2)
137                     return True
138         print(check)
139         qDir = {
140             "check": False
141         }
142         self.queueOled.put(qDir)
143         time.sleep(0.2)
144         return False
145 
146     def writeLog(self, data, fileName):
147         date = time.strftime("%Y-%m-%d %X  ")
148         data = date + data + "\r\n\r\n"
149         dealFile.textLog(data, fileName)
150         pass
151 
152     def getChar(self):
153         """獲取現在按下的指紋的信息"""
154         self.myFinger.link()
155         check = self.myFinger.getImage()  # 檢測獲取圖像
156         if check is not True:
157             self.check = check
158             return check
159 
160         self.myFinger.link()
161         check = self.myFinger.genChar("1")  # 檢測生成特征值 放如模塊1
162         if check is not True:
163             return check
164 
165         return True
166     pass
167 
168 
169 if __name__ == "__main__":
170     import core
171     A = ClockCheck(core.qOledClock, core.qToTcpOccupy, core.qToClockOccupy, core.qIsNewSql)
172     A.run()
173     pass
clockIn.py

 

當能夠正常打卡后就需要在液晶屏上顯示了

 1 import time
 2 import Adafruit_GPIO.SPI as SPI
 3 import Adafruit_SSD1306
 4 from PIL import Image, ImageDraw, ImageFont
 5 
 6 import os, sys
 7 
 8 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 9 sys.path.append(PATH)
10 
11 path = PATH + "/static/"
12 
13 # 引腳配置,按照上面的接線來配置
14 RST = 17
15 DC = 27
16 # 因為連的是CE0,這里的PORT和DEVICE也設置為0
17 SPI_PORT = 0
18 SPI_DEVICE = 0
19 disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
20 class Oled:
21     """oled顯示"""
22     def __init__(self, queue):
23         self.queue = queue
24         # 根據自己的oled型號進行初始化,我的是128X64、SPI的oled,使用SSD1306_128_64初始化
25         self.disp = disp
26         self.disp.begin()
27         self.disp.clear()
28         self.disp.display()
29         self.width = self.disp.width
30         self.height = self.disp.height
31         # image ,顯示一些文字
32         self.image = Image.new('1', (self.width, self.height))
33         self.draw = ImageDraw.Draw(self.image)
34 
35         self.fontDate = ImageFont.truetype(path + "simsun.ttc", 16)
36         self.fontTime = ImageFont.truetype(path + "EXEPixelPerfect.ttf", 50)
37         self.fontNum = ImageFont.truetype(path + "EXEPixelPerfect.ttf", 35)
38         self.fontName = ImageFont.truetype(path + "simsun.ttc", 28)
39         pass
40 
41     def run(self):
42         """顯示界面"""
43         while True:
44             date = time.ctime()
45             date = date.split(" ")
46             num = len(date)   # 當日期小於10時  日期為" num"  大於10為"num"
47             self.draw.text((0, 0), date[0], font=self.fontDate, fill=1)  # 星期幾
48             if num == 6:
49                 self.draw.text((80, 0), date[1] + " " + date[3], font=self.fontDate, fill=1)  # 月份
50             else:
51                 self.draw.text((80, 0), date[1] + " " + date[2], font=self.fontDate, fill=1)  # 月份
52             self.draw.text((0, 20), date[-2], font=self.fontTime, fill=1)    # 時間
53             """顯示"""
54             self.disp.image(self.image)
55             self.disp.display()
56             """清屏"""
57             self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)
58             """顯示"""
59             self.showPeple()
60 
61             pass
62 
63     def showPeple(self):
64         """顯示人"""
65         if self.queue.empty() is True:  # 沒有人按
66             # time.sleep(0.2)
67             return
68         data = self.queue.get()
69         if data["check"] is False:    # 有人按匹配錯誤
70             self.draw.text((15, 20), "ERROR", font=self.fontTime, fill=1)
71             """顯示"""
72             self.disp.image(self.image)
73             self.disp.display()
74             """清屏"""
75             self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)
76             time.sleep(2)
77             return
78         self.draw.text((0, 0), data["id"], font=self.fontNum, fill=1)
79         self.draw.text((25, 30), data["name"], font=self.fontName, fill=1)
80         """顯示"""
81         self.disp.image(self.image)
82         self.disp.display()
83         """清屏"""
84         self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)
85         time.sleep(2)
86         pass
87 
88     pass
89 
90 
91 if __name__ == "__main__":
92     from multiprocessing import Queue
93     q = Queue()
94     A = Oled(q)
95     A.run()
oledshow.py

 

 

5.怎么實現物聯呢

這就要用到公網平台了,應為我們都是“私網”,

剛開始想用yeelink的,但是發現好像沒人維護用不了了,我就發現了“樂為物聯”這個平台,操作簡單

你首先得在上面注冊一個用戶,他上面有api的介紹,很容易看懂

再分享一波

我是想在微信上發送命令

  1 # -*- coding:utf8 -*-
  2 
  3 import configparser
  4 from core import dealFile
  5 from core import emailSendReceive
  6 
  7 import optparse
  8 import os, sys
  9 import socket
 10 import json,re
 11 import time
 12 
 13 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 14 sys.path.append(PATH)
 15 
 16 cf = configparser.ConfigParser()
 17 cf = dealFile.readConf(cf)
 18 ip = cf.get("lewei", "ip")
 19 port = cf.getint("lewei", "port")
 20 userKey = cf.get("lewei", "userKey")
 21 gatewayNode = cf.get("lewei", "gatewayNode")
 22 
 23 
 24 # ip = "tcp.lewei50.com"
 25 # port = 9960
 26 # userKey = "9701daf039574b199602b4958252dc19"
 27 # gatewayNode = "02"
 28 
 29 head = "&^!"
 30 
 31 class ClientHandler():
 32 
 33     def __init__(self):
 34 
 35         self.bufsize = 1024
 36         # self.op = optparse.OptionParser()
 37         # option,args = self.op.parse_args()
 38         #
 39         # self.verify_args(option,args)
 40         self.connect()
 41 
 42     def verify_args(self,option,args):
 43         '啟動命令處理'
 44         cmd = args[0]
 45         if hasattr(self,cmd):
 46             func = getattr(self,cmd)
 47             func()
 48         else:
 49             exit("No parameter")
 50 
 51     def connect(self):
 52         '連接網路'
 53         self.loadToServer()
 54         oldTime = time.time()
 55         while True:
 56             nowTime = time.time()
 57             if nowTime - oldTime > 40:
 58                 oldTime = nowTime
 59                 self.loadToServer()
 60             self.interactive()
 61 
 62     def interactive(self):
 63         self.rev_deal()
 64 
 65     def loadToServer(self):
 66         '發送數據登陸服務器'
 67         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 68         self.sock.connect((ip, port))
 69         cmd={
 70             'method': "update",
 71             'gatewayNo': gatewayNode,
 72             'userkey': userKey
 73         }
 74         self.sendData(cmd)
 75 
 76     def rev_deal(self):
 77         '處理接收的數據做命令分類'
 78         """調用該命令時會調用該設備的API地址傳遞參數f=方法名,p1=參數1,p2=參數2......"""
 79         data = self.sock.recv(self.bufsize).decode("gbk")
 80         if data:
 81             print(data)
 82             data = re.split("[&^!]", data) # 去掉數據尾巴
 83             data = eval(data[0]) # 轉換成字典
 84             self.data = data
 85             # print(data)
 86             if hasattr(self, data["f"]):
 87                 func = getattr(self, data["f"])
 88                 func()
 89 
 90     """=======================================  f = message  ==========================================="""
 91     def message(self):
 92         print("message")
 93         pass
 94 
 95     """=======================================  f = sendemail  ==========================================="""
 96     def sendEmail(self):
 97         data = str.lower(self.data["p1"])
 98         if data:
 99             if hasattr(self, data):
100                 func = getattr(self, data)
101                 func()
102         self.sendSuccess()
103         pass
104 
105     def getlog(self):
106         """得到日志"""
107         a = emailSendReceive.SendEmail()
108         a.run(self.data["p1"])
109         self.sendSuccess()
110         pass
111 
112     def backlog(self):
113         """備份日志"""
114         backname = "log_{date}.txt".format(date=time.strftime("%Y.%m.%d.%X"))
115         dealFile.backFile("log.txt", backname)
116         pass
117 
118     def getlogall(self):
119         """得到所有日志"""
120         a = emailSendReceive.SendEmail()
121         a.run(self.data["p1"])
122         self.sendSuccess()
123         pass
124 
125     def clean(self):
126         """清除所有日志"""
127         dealFile.cleanFile()  # 清除日志
128         pass
129 
130     """=======================================  f = getAllSensors  ==========================================="""
131     def getAllSensors(self):
132         '上傳傳感器數據給服務器,讓它知道傳感器狀態'
133         data={
134                  "method": "response",
135                  "result":{
136                      "successful": True,
137                      "message": "xxxx",
138                      "data":[{
139                              "id": "POWER",
140                              "value": 0
141                          },
142                          {
143                              "id": "ledLight",
144                              "value": 0
145                          }
146                      ]
147                  }
148         }  # 固定格式
149         self.sendData(data)
150 
151     """=========================================  f = updateSensor  =============================================="""
152     def updateSensor(self):
153         '區分傳感器標識'
154         data = str.lower(self.data["p1"])
155         if data:
156             if hasattr(self, data):
157                 func = getattr(self, data)
158                 func()
159 
160     def power(self):
161         '傳感器power標識'
162         if self.data["p2"] == "1":
163             self.sendSuccess()
164             # conf.LED_STATUS = 1
165             print("open led")
166         elif self.data["p2"] == "0":
167             self.sendSuccess()
168             # conf.LED_STATUS = 0
169             print("close led")
170 
171     def ledlight(self):
172         '傳感器ledlignt標識'
173         self.sendSuccess()
174         # conf.LED_VALUE = self.data["p2"]
175         print("led亮度為",self.data["p2"])
176 
177     def sendSuccess(self):
178         '返回接收數據成功'
179         data = {
180             "method": "response",
181             "result":
182                 {
183                     "successful": True,
184                     "message": "發送成功!"
185                 }
186         }
187         self.sendData(data)
188 
189     def sendData(self,data):
190         data = json.dumps(data)
191         data += head
192         self.sock.send(data.encode("gbk"))
193 
194 
195 
196 if __name__ == '__main__':
197     ch = ClientHandler()
198 # cd F:\tmp\python_date1\myDevice\bin
199 # python tcp_client.py connect
weChat.py

 

 

如果你不想在注冊或者嫌麻煩也可以通過郵箱來發送命令

郵箱的代碼在下面

  1 # -*- coding:utf8 -*-
  2 
  3 import smtplib
  4 from poplib import POP3_SSL
  5 from email.parser import Parser
  6 from email.header import Header
  7 from email.mime.text import MIMEText
  8 from email.mime.multipart import MIMEMultipart
  9 from email.utils import formataddr
 10 
 11 from core import dealFile
 12 import time
 13 import configparser
 14 import os, sys
 15 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 16 
 17 
 18 cf = configparser.ConfigParser()
 19 cf = dealFile.readConf(cf)
 20 
 21 smtpServer = cf.get("email", "smtpServer")  # 發送請求服務
 22 popServer = cf.get("email", "popServer")     # 接收請求服務
 23 
 24 # smtpSrcAddr = "270176392@qq.com"    # 發送的源郵箱
 25 # smtpSrcAddrPwd = "tromtljvidhgbibj"  # 發送源郵箱的請求碼 密碼
 26 smtpSrcAddr = cf.get("email", "smtpSrcAddr")
 27 smtpSrcAddrPwd = cf.get("email", "smtpSrcAddrPwd")
 28 
 29 smtpDstAddr = cf.get("email", "smtpDstAddr")    # 發送的目的郵箱
 30 smtpPort = cf.get("email", "smtpPort")
 31 
 32 
 33 
 34 def sendEmailTxt(msg):
 35     """發送文本內容"""
 36     massage = MIMEText(msg, "plain", "utf8")
 37     return massage
 38 
 39 
 40 def sendEmailFile(filename):
 41     """發送附件"""
 42     fileName = dealFile.getFilePath(filename)
 43     massage = MIMEText(open(fileName).read(), "base64", "utf8")
 44     massage['Content-Type'] = "application/octet-stream"
 45     massage['Content-Disposition'] = "attachment; filename = {name}".format(name=filename)
 46     return massage
 47 
 48 
 49 class SendEmail:
 50     """發送郵件類"""
 51     def __init__(self):
 52         """初始化"""
 53         self.massage = MIMEMultipart()
 54         self.massage['From'] = formataddr(["實驗室", smtpSrcAddr])
 55         self.massage['To'] = formataddr(["to", smtpDstAddr])
 56         self.massage['Subject'] = Header("回復郵件", "utf8")
 57         self.server = smtplib.SMTP_SSL(smtpServer, smtpPort)
 58         pass
 59 
 60     def run(self, cmd):
 61         """解析命令"""
 62         if isinstance(cmd, str):
 63             if hasattr(self, cmd):
 64                 cmd = cmd.lower()
 65                 func = getattr(self, cmd)
 66                 func()
 67                 self.login(self.massage)
 68             self.quit()
 69         elif isinstance(cmd, list):
 70             for i in cmd:
 71                 if hasattr(self, i):
 72                     i = i.lower()
 73                     func = getattr(self, i)
 74                     func()
 75             if len(self.massage.get_payload())is 0:
 76                 return self.quit()
 77             self.login(self.massage)
 78             self.quit()
 79     pass
 80 
 81     def getlog(self):
 82         """得到日志"""
 83         sendStr = "{date} 最新日志\r\n".format(date=time.strftime("%Y-%m-%d"))
 84         massage = sendEmailTxt(sendStr)
 85         self.massage.attach(massage)
 86         massage = sendEmailFile("log.txt")
 87         print(massage)
 88         self.massage.attach(massage)
 89         pass
 90 
 91     def backlog(self):
 92         """備份日志"""
 93         backname = "log_{date}.txt".format(date=time.strftime("%Y.%m.%d.%X"))
 94         dealFile.backFile("log.txt", backname)
 95         sendStr = "備份成功\r\n"
 96         massage = sendEmailTxt(sendStr)
 97         self.massage.attach(massage)
 98         pass
 99 
100     def getlogall(self):
101         """得到所有日志"""
102         dealFile.joinFile()  # 拼接所有日志
103 
104         sendStr = "{date} 前的所有日志\r\n".format(date=time.strftime("%Y-%m-%d"))
105         massage = sendEmailTxt(sendStr)
106         self.massage.attach(massage)
107         massage = sendEmailFile("logback.txt")
108         print(massage)
109         self.massage.attach(massage)
110         pass
111 
112     def help(self):
113         """幫助文檔"""
114         sendStr = "幫助文檔!\r\n"
115         massage = sendEmailTxt(sendStr)
116         self.massage.attach(massage)
117         massage = sendEmailFile("help.txt")
118         print(massage)
119         self.massage.attach(massage)
120         pass
121 
122     def clean(self):
123         """清除所有日志"""
124         dealFile.cleanFile()   # 清除日志
125 
126         sendStr = "清除成功!\r\n"
127         massage = sendEmailTxt(sendStr)
128         self.massage.attach(massage)
129         pass
130 
131     def login(self, msg):
132         """登陸發送"""
133         self.server.login(smtpSrcAddr, smtpSrcAddrPwd)
134         self.server.sendmail(smtpSrcAddr, smtpDstAddr, msg.as_string())
135         pass
136 
137     def quit(self):
138         """退出"""
139         self.server.quit()
140         pass
141     pass
142 
143 
144 class GetEmail:
145     """獲取郵件並解析"""
146     def __init__(self):
147         self.server = POP3_SSL(popServer)
148         pass
149 
150     def run(self):
151 
152         self.login()
153         cmd = self.getEmail()
154         self.deleEmail()
155         self.quit()
156         return cmd
157 
158     def getEmail(self):
159         """獲取最新消息"""
160         num, size = self.server.stat()
161         if num > 0:
162             resp, list, octets = self.server.retr(num)
163             """分開list, 將信息變為emailMassger"""
164             msg = b"\r\n".join(list).decode("utf8")
165             msg = Parser().parsestr(msg)
166             """解析出命令"""
167             cmd = self.analyze(msg)
168             try:
169                 cmd = cmd.split(",")
170                 return cmd
171             except Exception as e:
172                 print(e)
173         return False
174         pass
175 
176     def deleEmail(self):
177         num, size = self.server.stat()
178         if num > 0:
179             for i in range(num):
180                 self.server.dele(i+1)
181         pass
182 
183     def analyze(self, msg):
184         """解析出msg中的文本內"""
185         if msg.is_multipart():
186             print("is_multipart")
187             parts = msg.get_payload()
188             part = parts[0]    # 得到第一個
189             content = part.get_payload(decode=True)
190             charset = self.gussCharset(part)  # 得到編碼格式
191             if charset:
192                 content = content.decode(charset)
193                 return content
194         else:
195             print("is_not_multipart")
196             content_type = msg.get_content_type()
197             if content_type == 'text/plain' or content_type == 'text/html':
198                 content = msg.get_payload(decode=True)
199                 charset = self.gussCharset(msg)    # 得到編碼格式
200                 if charset:
201                     content = content.decode(charset)
202                     return content
203             else:
204                 print("Attachment.........................")
205         pass
206 
207     def gussCharset(self, msg):
208         """獲取編碼格式"""
209         charset = msg.get_charset()
210         if charset is None:
211             content_type = msg.get("Content-Type", "").lower()
212             pos = content_type.find("charset=")
213             if pos > 0:
214                 charset = content_type[pos+8:]
215             return charset
216         pass
217 
218     def login(self):
219         self.server.user(smtpSrcAddr)
220         self.server.pass_(smtpSrcAddrPwd)
221         pass
222 
223     def quit(self):
224         self.server.quit()
225         pass
226 
227     pass
228 
229 
230 if __name__ == "__main__":
231     while True:
232         A = GetEmail()
233         cmd = A.run()
234         print(cmd)
235         time.sleep(10)
236         if cmd is not False:
237             B = SendEmail()
238             B.run(cmd)
239             time.sleep(10)
240     pass
emailSendReceive.py

 

6.最后看看主程序把

 分別寫兩個腳本運行就好了

 1 # -*- coding:utf8 -*-
 2 
 3 import os,sys
 4 import socketserver
 5 import threading
 6 import time
 7 from multiprocessing import Process
 8 
 9 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
10 sys.path.append(PATH)
11 
12 from core import Tcpserver
13 from core import clockIn
14 from core import oledshow
15 from core import emailSendReceive
16 from core import dealFile
17 import configparser
18 import core
19 
20 def TCP():
21     """tcp進程"""
22     # check = threading.Thread(target=Tcpserver.checkOccupy)
23     # check.start()
24     cf = configparser.ConfigParser()
25     cf = dealFile.readConf(cf)
26     ip = cf.get("TCP", "ip")
27     port = cf.getint("TCP", "port")
28     ip_port = (ip, port)
29     print("----等待連接.............")
30     s = socketserver.ThreadingTCPServer(ip_port, Tcpserver.SeverHandle)
31     s.serve_forever()
32     pass
33 
34 
35 def CLOCK(queueOled, queueToTcp, queueToClock, queueIsNewSql):
36     """檢驗進程"""
37     gpio = clockIn.ClockCheck(queueOled, queueToTcp, queueToClock, queueIsNewSql)
38     gpio.run()
39     pass
40 
41 
42 def OLED(queue):
43     """oled進程"""
44     oled = oledshow.Oled(queue)
45     oled.run()
46     pass
47 
48 
49 def EMAIL():
50     """郵件進程"""
51     while True:
52         A = emailSendReceive.GetEmail()
53         cmd = A.run()
54         print(cmd)
55         time.sleep(10)
56         if cmd is not False:
57             B = emailSendReceive.SendEmail()
58             B.run(cmd)
59             time.sleep(10)
60 
61 
62 def main():
63     # A = Process(target=TCP)
64     # B = Process(target=EMAIL)
65     C = threading.Thread(target=CLOCK, args=(core.qOledClock, core.qToTcpOccupy, core.qToClockOccupy, core.qIsNewSql))
66     D = threading.Thread(target=OLED, args=(core.qOledClock,))
67 
68     # A.start()
69     # B.start()
70     C.start()
71     D.start()
72     # A.join()
73     TCP()
74 
75 
76 if __name__ == "__main__":
77     main()
78     # TCP()
fingerStart.py
 1 # -*- coding:utf8 -*-
 2 
 3 from core import weChat
 4 
 5 def main():
 6     a = weChat.ClientHandler()
 7 
 8 
 9 if __name__ == "__main__":
10     main()
11     # TCP()
weChatClient.py

 邏輯結構圖如下

 

 

 

 

 未經本人許可不得轉載 謝謝!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM