from RPi import GPIO import time import pygame import requests import cv2 import json from pywifi import const,PyWiFi,Profile import pyzbar.pyzbar as pyzbar from apscheduler.schedulers.blocking import BlockingScheduler import webbrowser print("\n***********************自动借书机***********************") webbrowser.open("http://www.pn8v.cn/school/book_machine/list.php?code=000001") def playsound(file_mp3): pygame.mixer.init(frequency=16000, size=-8, channels=2, buffer=2000) pygame.mixer.music.load(file_mp3) pygame.mixer.music.play(loops=1) # 初始化检测================== print('正在启动设备,请稍等...') playsound("/home/pi/voice.mp3") time.sleep(3) # 采用BCM引脚编号 GPIO.setmode(GPIO.BCM) time.sleep(2) GPIO.setwarnings(False) # 关闭警告 # 蜂鸣器27引脚 trig = 27 # LED红灯18引脚输出电平信号端 LED1_ROUT = 16 GPIO.setup(LED1_ROUT, GPIO.OUT) # LED白灯18引脚输出电平信号端 LED1_WOUT = 18 GPIO.setup(LED1_WOUT, GPIO.OUT) # 按钮23引脚 GPIO_IN = 23 GPIO.setup(GPIO_IN, GPIO.IN) # LED绿灯24引脚输出电平信号端 LED_GOUT = 24 GPIO.setup(LED_GOUT, GPIO.OUT) # LED蓝灯12引脚输出电平信号端 LED2_BOUT = 12 GPIO.setup(LED2_BOUT, GPIO.OUT) # 黄灯26引脚输出电平信号端 LED3_yOUT = 26 GPIO.setup(LED3_yOUT, GPIO.OUT) # ============================== GPIO.output(LED1_WOUT, False) # 白灯灭 GPIO.output(LED2_BOUT, False) # 蓝灯灭 GPIO.output(LED3_yOUT, False) # 黄灯灭 GPIO.output(LED_GOUT, False) # 绿灯灭 GPIO.output(LED1_ROUT, True) # 红灯亮 # 从后台读取wifi名和密码,初始化wifi链接,防止wifi更改密后,设备不能用================================= # 本机编码 code = "000001" def mainInit(): global code url = "http://www.pn8v.cn/school/book_machine/init.php" data = {'code': code} # 需要捕获异常的代码(可能会出现异常的代码) try: # 1读取成功,初始化wifi链接 # 2如果比较程序版本号(更新程序) req = requests.post(url, data=data) req_str = req.text # 返回的字符串前面有空格,要去掉 req_str = req.text.strip('') print(req_str) json_str = json.loads(req_str) # 更新wifi用户名和密码(如果wifi连接不上,先用网线连接) wifi_name = json_str["wifi"] wifi_pw = json_str["pw"] wifiLink(wifi_name, wifi_pw) # 读取版本号,判断是否下载更新系统文件 with open("init.json","r") as f: f_str = f.readline() json_str = json.loads(f_str) print(json_str["version"]) f.close() with open("init.json", "w+") as f: f.write(req_str) f.close() # 下载文件,用于更新系统 downFile() except IOError: # 出现异常时才会执行的代码 print('数据上传失败!') #读取不到,说明wifi连接失败,亮红灯 # 下载文件,用于更新系统 def downFile(): url = 'http://www.pn8v.cn/school/book_machine/demo.zip' try: req = requests.get(url) with open("demo.zip", "wb") as code: code.write(req.content) print('文件下成功!') except IOError: # 出现异常时才会执行的代码 print('文件下载败!') def wifiLink(name,pw): wifi = PyWiFi() # 获取无线网卡 ifaces = wifi.interfaces()[1] # wifi配置文件 profile_info=Profile() # 需要密码 profile_info.auth=const.AUTH_ALG_OPEN # 加密类型 profile_info.akm.append(const.AKM_TYPE_WPA2PSK) # 加密单元 profile_info.cipher=const.CIPHER_TYPE_CCMP # 配置wifi名称 profile_info.ssid=name # wifi密码 profile_info.key=pw # 删除其他配置文件 ifaces.remove_all_network_profiles() # 加载配置文件 tmp_profile=ifaces.add_network_profile(profile_info) # 开始连接 ifaces.connect(tmp_profile) time.sleep(5) if ifaces.status()==const.IFACE_CONNECTED: print("link:"+ifaces.name()) else: print("not link "+ifaces.name()) capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) ret, frame = capture.read() time.sleep(2) barcode_old = "" book_obj = "" student_obj = "" numStar = 0 def detection(): global capture,student_obj,book_obj,detection_listen,clearStar,clearFrameStar #capture = cv2.VideoCapture(0) if clearStar and clearFrameStar: time.sleep(0.2) ret, frame = capture.read() if ret: gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) barcodes = pyzbar.decode(gray) for barcode in barcodes: barcode_data = barcode.data.decode("utf-8") barcode_type = barcode.type print(barcode_data) if barcode_type == "QRCODE" and student_obj == "": student_obj = barcode_data GPIO.setup(trig, GPIO.OUT, initial=GPIO.HIGH) time.sleep(0.2) GPIO.output(trig, GPIO.LOW) GPIO.output(LED_GOUT, False) # 绿灯 GPIO.output(LED1_WOUT, True) # 黄灯 if book_obj != "": detection_listen.pause() send_data() elif barcode_type == "EAN13" and book_obj == "": book_obj = barcode_data GPIO.setup(trig, GPIO.OUT, initial=GPIO.HIGH) time.sleep(0.2) GPIO.output(trig, GPIO.LOW) GPIO.output(LED_GOUT, False) # 绿灯 GPIO.output(LED2_BOUT, True) # 蓝灯 if student_obj != "": detection_listen.pause() send_data() else: print(barcode_type) print("else:type已读取*****************") # 将读取到的二维码和条形码发送到后台检查并保存==================== def send_data(): global student_obj,book_obj,clearFrameStar,clearStar # 发送数据时,按钮不能进行清空动作 clearFrameStar=False clearStar=False url = "http://www.pn8v.cn/school/book_machine/up_data.php" data = {'student': student_obj,'isbn':book_obj} #url = "http://www.pn9v.cn/demo/postData.php" #收到数据:*** #data = {'a': student_obj + ":", 'b': "\n[content:" + book_obj + "]"} try: # 需要捕获异常的代码(可能会出现异常的代码) req = requests.post(url, data=data) ############################### #req_str=req.text #print(req_str) #print('借书登记完成!') #playsound("/home/pi/voice4.mp3") ############################### # 返回的字符串前面有空格,要去掉 req_str=req.text.strip('') list_1=req_str.split("§") str_0=list_1[0] str_1=list_1[1] str_2=list_1[2] if str_0=='0': print('借书登记已完成!') playsound("/home/pi/voice4.mp3") else: #二维码或条形码有误 print("扫码识别有错误!") print(str_1) print(str_2) playsound("/home/pi/voice5.mp3") time.sleep(0.2) GPIO.output(LED2_BOUT, False) # 蓝灯 GPIO.output(LED3_yOUT, True) # 黄灯 GPIO.output(LED1_WOUT, False) # 白灯 clearFrameStar=True clearStar=True print('***************完成!') except IOError: # 出现异常时才会执行的代码 print('数据上传失败!') # 清除后台数据(网页显示清空)=========================== clearStar=True def clear_data(): global clearStar,clear_listen clear_listen.pause() #url = "http://www.pn9v.cn/demo/postData.php" #收到数据:*** url = "http://www.pn8v.cn/school/book_machine/clear_data.php" data = {'a': 'student','b':'book'} try: # 需要捕获异常的代码(可能会出现异常的代码) req = requests.post(url, data=data) print('后台登记数据清除成功!') clearStar=True except IOError: # 出现异常时才会执行的代码 print('数据上传失败!') clearStar=True # 清除帧上的图片和变量=========================== clearFrameStar=True def clear_frame(): global capture,student_obj,book_obj,numStar,clearFrameStar,clear_frame_listen ret, frame = capture.read() if numStar>0: ##刷新多次,以删除fram上的图片 numStar=numStar-1 student_obj = "" book_obj="" print(numStar) else: clear_frame_listen.pause() clearFrameStar=True playsound("/home/pi/voice1.mp3") print('相机帧上的图片和变量清除成功!') detection_listen.resume() btnStar=True def btn_gpio(): global student_id,book_id,capture,btnStar,detection_listen,numStar,clearStar,clearFrameStar,clear_listen,clear_frame_listen if GPIO.input(GPIO_IN) == 0 and btnStar == True: btnStar= False print("star") GPIO.output(LED_GOUT, True) # 绿灯亮 GPIO.output(LED1_WOUT, False) # 白灯 GPIO.output(LED2_BOUT, False) # 蓝灯 #detection_listen.resume() if GPIO.input(GPIO_IN) == 1 and btnStar == False: btnStar = True detection_listen.pause() print("clear") GPIO.output(LED3_yOUT, False) GPIO.output(LED_GOUT, False) # 绿灯灭 if clearStar==True and clearFrameStar==True: # 清空数据和清空网页分别开两个侦听线程,可以同时进行,提高效率 clearStar=False clear_listen.resume() clearFrameStar=False numStar=5 clear_frame_listen.resume() #******************************************************* print("设备启动完成,可以开始操作") # ***蜂鸣器*** GPIO.setup(trig, GPIO.OUT, initial=GPIO.HIGH) GPIO.output(LED1_ROUT, False) # 红灯灭 time.sleep(0.35) GPIO.output(trig, GPIO.LOW) GPIO.output(LED1_ROUT, True) # 红灯 time.sleep(0.35) GPIO.output(trig, GPIO.HIGH) GPIO.output(LED1_ROUT, False) # 红灯灭 time.sleep(0.35) GPIO.output(trig, GPIO.LOW) # ***蜂鸣器*** GPIO.output(LED1_ROUT, True) # 红灯 playsound("/home/pi/voice0.mp3") time.sleep(5) GPIO.output(LED1_ROUT, False) # 红灯灭 try: mainInit() scheduler = BlockingScheduler() detection_listen=scheduler.add_job(detection,'interval',seconds=0.5) #(1)间隔0.4秒扫描识别侦听 btn_listen=scheduler.add_job(btn_gpio, 'interval',seconds=0.2) #(2)间隔0.2秒按钮开关侦听 clear_listen=scheduler.add_job(clear_data, 'interval',seconds=0.5) #(3)间隔0.2秒清除后台网页数据侦听 clear_frame_listen=scheduler.add_job(clear_frame, 'interval',seconds=0.5) #(4)间隔0.2秒清除帧上的图片和变量侦听 scheduler.start() #这里的调度任务是独立的一个线程 #[Desktop Entry] #Type=Applicaton #Exec=chromium-browser --disable-popup-blocking --no-first-run --disable-desktop-notifications --kiosk "http://www.pn8v.cn/" #Exec=chromium-browser --disable-popup-blocking --no-first-run --disable-desktop-notifications --kiosk "http://www.pn9v.cn/demo/postData.php" #收到数据: except: scheduler.shutdown() GPIO.cleanup() capture.release() print('Close...') finally: scheduler.shutdown() GPIO.cleanup() capture.release() print('Close...')