Commit 70e3d023 刘韬

1

1 个父辈 e1d50aec
正在显示 74 个修改的文件 包含 2490 行增加149 行删除
此文件太大,无法显示。
......@@ -43,10 +43,11 @@ LANGUAGES = {
"ja": "Japanese"
}
from app import induction_post,induction_test,induction_admin,induction_config,autoback,qr_code,scan_collection
from app import config_ip,induction_post,induction_test,induction_admin,induction_config,autoback,qr_code,scan_collection
from app.induction_config import testCidExists
import time
def s():
time.sleep(10)
data = {'key1':'value1','key2':'value2'}
time.sleep(2)
requests.post("http://127.0.0.1:5000/stoppost",data)
......
......@@ -30,11 +30,12 @@ ss16mm[] = {1,---100}
{"ADDR":"99","setcalibrate":[1,100,600,150],"threshold":45}
{"ADDR":"99","setcalibrate":[1,100,600,150,30]}
{"ADDR":"99","calibrate":"min","threshold":45}
{"ADDR":"99","setcalibrate":"max","threshold":30}
{"ADDR":"99","calibrate":"autotrain"}
{"ADDR":"1","ledtype":[1,1,1,1,1]}
{"ADDR":"99","action":"siteid","hwid":"7cdfa117818","addr":2}
{"ADDR":"99","action":"siteid","addr":11}
{"ADDR":"99","action":"info"}
{"ADDR":"99","action":"report"}
{"ADDR":"99","action":"LedBoardTest"}
......@@ -42,6 +43,8 @@ ss16mm[] = {1,---100}
{"ADDR":"99","action":"ClearCheckList"}
{"ADDR":"99","action":"PrintStatus"}
{"ADDR":"99","action":"factoryModeON"}
{"ADDR":"99","action":"diagnosMode"}
{"ADDR":"99","action":"MirrorMode","hwid":"7cdfa10d4c4","data":1}
{"ADDR":"99","action":"ShelfPart","name":"NLP-00035-82-466-01"}
version 0.3 0708
......@@ -81,7 +84,7 @@ turn on/off all leds:"{"ADDR":"1","colorset":[[1,255,255,255]]}\n{"ADDR":"1","le
{"ADDR":"1","calibrate":"min"}
{"ADDR":"1","calibrate":"max"}
{"ADDR":"1","setcalibrate":[1,100,0,1,20]}
{"ADDR":"99","setcalibrate":[1,100,0,0,15]}
......
import os
from flask import Flask, render_template, request, Response
from app import app
import time
from threading import Thread
netprofilepath = r'/prog/smartshelf/app/netprofile/'
#app = Flask(__name__)
@app.route('/ipconfig')
def shelfconfig():
print("begin ip flask")
return render_template('ipconfig.html')
def Config_DHCP():
netconfigfile = ''
if os.path.exists('/etc/dhcpcd.conf'):
netprofile = netprofilepath+'dhcpcd.conf.bak'
netconfigfile = '/etc/dhcpcd.conf'
else:
netprofile = netprofilepath+'/NEOTEL.nmconnection.bak'
netconfigfile = '/etc/NetworkManager/system-connections/NEOTEL.nmconnection'
with open(netprofile, 'r') as f:
file_lines = f.readlines()
f.close()
with open(netconfigfile, 'w') as f:
# for line in file_lines:
f.writelines(file_lines)
f.flush()
f.close()
def Config_StaticIP(IPAddress, Router_IP):
netconfigfile = ''
if os.path.exists('/etc/dhcpcd.conf'):
netprofile = netprofilepath+'dhcpcd.conf.bak'
netconfigfile = '/etc/dhcpcd.conf'
with open(netprofile, 'r') as f:
file_lines = f.readlines()
f.close()
with open(netconfigfile, 'w') as f:
# for line in file_lines:
f.writelines(file_lines)
# f.write("static ip_address=" + str(request.args.get('new_ip')))
# interface eth0
#IPAddress = str(request.args.get('new_ip')
#Router_IP = str(request.args.get('new_ip')
f.write("interface eth0" + "\n")
if len(IPAddress) > 0:
f.write("static ip_address=" + IPAddress + "\n")
if len(Router_IP) > 0:
f.write("static routers=" + Router_IP + "\n")
# f.write("")
f.flush()
f.close()
else:
netprofile = netprofilepath+'/NEOTEL.nmconnection.bak'
netconfigfile = '/etc/NetworkManager/system-connections/NEOTEL.nmconnection'
with open(netprofile, 'r') as f:
file_lines = f.readlines()
f.close()
with open(netconfigfile, 'w') as f:
# for line in file_lines:
for line in file_lines:
f.write(line)
if line.startswith('[ipv4]') and len(IPAddress) > 0:
if len(Router_IP) > 0:
f.write('address1='+ IPAddress + ','+Router_IP+"\n")
else:
f.write('address1='+ IPAddress + "\n")
# f.write("static ip_address=" + str(request.args.get('new_ip')))
# interface eth0
#IPAddress = str(request.args.get('new_ip')
#Router_IP = str(request.args.get('new_ip')
f.flush()
f.close()
def reboot_after_delay():
# Wait for 5 seconds before rebooting
time.sleep(5)
os.system('sudo reboot')
def Reenable_NetworkService():
#os.system('sudo systemctl stop networking')
#os.system('sudo systemctl start networking')
#os.system('sudo systemctl stop dhcpcd.service')
#print("services stop")
#os.system('sudo ip addr flush dev eth0')
#os.system('sudo systemctl start dhcpcd.service')
# Wait for 3 seconds before rebooting
reboot_thread = Thread(target=reboot_after_delay)
reboot_thread.start()
return "Apply Successfully, System will reboot in 5 seconds"
#return "Raspberry Pi will reboot in 3 seconds"
#os.system('sudo reboot')
def netmask_to_length(netmask):
# Convert the netmask to a list of integers
netmask = [int(x) for x in netmask.split(".")]
# Count the number of set bits in the netmask
length = 0
for octet in netmask:
while octet > 0:
length += octet & 1
octet >>= 1
return length
@app.route('/ip_config',methods=['POST'])
def IP_Config():
dhcp_enabled = request.form.get('dhcp')
if dhcp_enabled:
Config_DHCP()
print("DHCP ENABLED")
else:
IP_ADDR = str(request.form.get('new_ip'))
print("input:",str(request.form.get('new_ip')))
Router_ADDR = str(request.form.get('router_ip'))
NET_MASK = str(request.form.get('new_mask'))
IP_ADDR +="/"+str(netmask_to_length(NET_MASK))
print(IP_ADDR)
print(Router_ADDR)
Config_StaticIP(IP_ADDR,Router_ADDR)
print(IP_ADDR,Router_ADDR)
print("IP CHANGED")
#Reenable_NetworkService()
#Response('Apply Successfully', status=200, mimetype='text/plain')
return Reenable_NetworkService()
#return #'Apply Successfully ' #{} with DHCP enabled: {}'.format(IP_ADDR, 'True' if dhcp_enabled else 'False')
#Config_StaticIP("192.168.1.59/24", "192.168.1.1")
#Reenable_NetworkService()
......@@ -12,6 +12,8 @@ import re
import logging
import requests
from app.induction_post import COLORS
import app.utils.g as gg
from app.utils.g import shelfconfig
from config import Config
from werkzeug.utils import secure_filename
from app.utils.serial_communication import SerialCommunication
......@@ -20,7 +22,14 @@ from app.induction_config import read_addrs,ip_config,testCidExists
from app.utils.location import Location
config_dict,convert_dict = Location().read_location_file()
sensorindex={}
for k,v in convert_dict.items():
d=k.split('@')
if d[1] not in sensorindex:
sensorindex[d[1]] = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
s=sensorindex[d[1]]
n =int(d[0])-1
sensorindex[d[1]] = s[:n] + '1' + s[n+1:]
ser = SerialCommunication()
print('admin open serial')
@app.route('/adminaddr_test', methods=['POST'])
......@@ -42,6 +51,19 @@ def adminaddr_test():
c_dict = {'msg':'所有传感器通信成功'}
return json.dumps(c_dict)
@app.route('/restart', methods=['GET','POST'])
def restart():
c_dict = {'msg':'开始重启...'}
import _thread
_thread.start_new_thread(dorestart)
return json.dumps(c_dict)
def dorestart():
logging.warning("手动触发重启")
time.sleep(2)
import os
os.system('sudo reboot')
@app.route('/adminled_test', methods=['POST'])
def adminled_test():
addrs = read_addrs()
......@@ -156,8 +178,7 @@ def threshold():
@app.route('/writeserial', methods=['POST'])
def writeserial():
current_state = read_state()
if current_state=='on':
if gg.current_state=='on':
return json.dumps({'msg':"请先停止系统"})
data = request.get_json()
command = data['command']+'\n'
......@@ -180,8 +201,8 @@ def writeserial():
@app.route('/readserial')
def readserial():
current_state = read_state()
if current_state=='off':
#current_state = read_state()
if gg.current_state=='off':
ser = SerialCommunication()
msg = ser.read_alldata()
if msg is not None:
......@@ -191,8 +212,8 @@ def readserial():
@app.route('/sitereport', methods=['POST'])
def sitereport():
current_state = read_state()
if current_state=='on':
#current_state = read_state()
if gg.current_state=='on':
return json.dumps({'msg':"请先停止系统"})
ser.read_alldata()
ser.send_data("report")
......@@ -202,7 +223,7 @@ def sitereport():
@app.route('/getledcount', methods=['POST','GET'])
def getledcount():
if read_state()=='on':
if gg.current_state=='on':
return json.dumps({'msg':"请先停止系统"})
ser.read_alldata()
time.sleep(0.1)
......@@ -252,7 +273,7 @@ last_sensor_dict={}
@app.route('/getshelfstate', methods=['POST','GET'])
def getshelfstate():
global last_sensor_dict
if read_state()=='on':
if gg.current_state=='on':
return json.dumps({'msg':"请先停止系统"})
dataaddrs = request.get_json()
command="";
......@@ -279,27 +300,32 @@ def getshelfstate():
return json.dumps(cur_dict)
def ProcessLastSensor(cur_dict,last_sensor_dict):
global sensorindex
if len(last_sensor_dict)>0:
for k,v in cur_dict.items():
lightlist=[]
closelist=[]
lv = last_sensor_dict.get(k)
if lv:
hv= sensorindex.get(k)
ledcount=0;
if lv and len(lv)==len(v):
for i in range(0,len(lv)):
if v[i]=='1' and v[i]!=lv[i]:
lightlist.append(i+1)
elif v[i]=='0' and v[i]!=lv[i]:
closelist.append(i+1)
if hv[i]=='1':
ledcount=ledcount+1
if v[i]=='1' and v[i]!=lv[i]:
lightlist.append(ledcount)
elif v[i]=='0' and v[i]!=lv[i]:
closelist.append(ledcount)
list=[]
if len(lightlist)>0:
lightlist.insert(0,COLORS.get('white')[0])
lightlist.insert(0,COLORS.get(shelfconfig.after_induction_preshow_color)[0])
list.append(lightlist)
if len(closelist)>0:
closelist.insert(0,COLORS.get('off')[0])
list.append(closelist)
if len(list)>0:
command = '{{"ADDR":{},"color":{}}}\n'.format(k[1:],list)
print("ProcessLastSensor",command)
print("ProcessLastSensor",command,len(list))
ser.send_data(command,False)
return True
else:
......@@ -317,8 +343,8 @@ def buildstore():
return json.dumps({'msg':"服务器还未支持本功能"})
if cidExists:
return json.dumps({'msg':"Cid相关库位已存在服务器,请先删除"})
current_state = read_state()
if current_state=='on':
#current_state = read_state()
if gg.current_state=='on':
return json.dumps({'msg':"请先停止系统"})
#data = request.get_json()
addrs = read_addrs()
......@@ -339,8 +365,11 @@ def buildstore():
#msg='ADDR=1//ShelfPartName=NLP-00030-10-330-01//BoardIsOK=1//ReadLedType 0=2//ReadLedType 1=2//ReadLedType 2=0//ReadLedType 3=0//ReadLedType 4=0//LedType=7,7,7,6,0,0,0,0,0,0,//Led Count=27//Led List=1,2,3,4,5,6,7,11,12,13,14,15,16,17,21,22,23,24,25,26,27,31,32,33,34,35,36,//RowWidth=13//'
if msg is not None:
msg=bytes.decode(msg)
if msg.find("timeout"):
if msg.find("timeout")>=0:
return json.dumps({'msg':'库位建立失败,地址:'+addr+' 通讯失败,请检查后重试.'})
if msg.find("LedType=")<=0:
return json.dumps({'msg':'库位建立失败,地址:'+addr+' 通讯失败,请检查后重试.'})
ledcount=getinfo(msg,'Led Count=')
_LedType = getinfo(msg,'LedType=').split(',')
ShelfPartName=getinfo(msg,'ShelfPartName=')
......@@ -378,6 +407,68 @@ def buildstore():
return json.dumps({'msg':'库位更新成功'})
@app.route('/downloadstore', methods=['GET'])
def downloadstore():
cid = ip_config['cid']
#current_state = read_state()
if gg.current_state=='on':
return json.dumps({'msg':"请先停止系统"})
#data = request.get_json()
addrs = read_addrs()
addrs = addrs.split('@')
ledcountdict={}
title = '位置,address,led,sensor,优先级,高度,宽度'
contents=title+'\r\n'
body=[]
for addr in addrs:
command = '{"ADDR":"'+ addr[1:] +'","action":"info"}'+'\r\n'
ser.send_data(command)
time.sleep(0.5)
msg = ser.read_alldata()
print(msg)
addr=re.sub('A1(\d)',r'B\1',addr)
if msg is None:
return json.dumps({'msg':'库位建立失败,地址:'+addr+' 通讯失败,请检查后重试.'})
#msg='ADDR=1//ShelfPartName=NLP-00030-10-330-01//BoardIsOK=1//ReadLedType 0=2//ReadLedType 1=2//ReadLedType 2=0//ReadLedType 3=0//ReadLedType 4=0//LedType=7,7,7,6,0,0,0,0,0,0,//Led Count=27//Led List=1,2,3,4,5,6,7,11,12,13,14,15,16,17,21,22,23,24,25,26,27,31,32,33,34,35,36,//RowWidth=13//'
if msg is not None:
msg=bytes.decode(msg)
if msg.find("timeout")>=0:
return json.dumps({'msg':'库位建立失败,地址:'+addr+' 通讯失败,请检查后重试.'})
if msg.find("LedType=")<=0:
return json.dumps({'msg':'库位建立失败,地址:'+addr+' 通讯失败,请检查后重试.'})
ledcount=getinfo(msg,'Led Count=')
_LedType = getinfo(msg,'LedType=').split(',')
ShelfPartName=getinfo(msg,'ShelfPartName=')
RowWidth=getinfo(msg,'RowWidth=')
LedType=[]
LedTypeCopy=[]
for i in range(0,5):
ll=int(_LedType[i*2])+int(_LedType[i*2+1])
LedType.append(ll)
LedTypeCopy.append(ll)
LedTypeindex=0
ledcountdict[addr]=ledcount
print(addr+' ledcount:'+ledcount);
for num in range(1,int(ledcount)+1):
#ledh=plateh[getinfo(msg,'ReadLedType '+str(LedTypeindex)+'=')]
ledh=plateh[str(LedTypeCopy[0])]
if RowWidth is None:
RowWidth = plateWidth[ShelfPartName+'-'+addr]
data = {"addr":addr,'index':num,'width':RowWidth,'height':ledh}
contents+=cid+'-{addr}-{index:0>3d},{addr},{index},{index},10,{height},{width}\r\n'.format(**data)
body.append({'pos':cid+'-{addr}-{index:0>3d}'.format(**data),'pri':10,'h':data['height'],'w':data['width']})
LedType[LedTypeindex]=LedType[LedTypeindex]-1
if LedType[LedTypeindex]==0:
LedTypeindex=LedTypeindex+1
with open(Config.UPLOAD_FOLDER+"//linePositions.csv","w",newline='',encoding='gbk') as f:
f.write(contents)
return '/static/uploads/linePositions.csv'
def getinfo(msg,key):
if msg.find(key)<0:
return None
......
......@@ -16,6 +16,7 @@ from werkzeug.utils import secure_filename
from app.utils.serial_communication import SerialCommunication
#from serial_config import ReadConfig
from flask_babel import Babel, gettext
import app.utils.g as gg
basepath = os.path.dirname(__file__)
ip_config = {'post':'wait'}
......@@ -32,7 +33,6 @@ except Exception as e:
@app.route('/getstate',methods=['POST'])
def getstate():
current_state = read_state()
state_info = []
version = read_version()
ser = SerialCommunication()
......@@ -43,7 +43,7 @@ def getstate():
serial_num = read_com()
ad_serial = "{}:{},{}:{}".format(gettext("串口号"),serial_num,gettext("地址"),addrs)
c_dict = {
'state':current_state,
'state':gg.current_state,
'msg':'未进行测试动作',
'ipconfig':ip_config,
'version':version,
......@@ -79,6 +79,8 @@ def read_state():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + "state.txt","r") as f:
state=f.readline()
if state.isspace():
state='off'
return state
from app.utils.g import ver,shelfconfig
......@@ -90,9 +92,9 @@ def confirm_ip(data):
sipconfig = read_ip()
with open(uploads_path + 'ipconfig.csv','w') as f:
if data['ip'] and not data['cid']:
data['cid'] = sipconfig[0][1]
data['cid'] = sipconfig[0][1].strip()
elif data['cid'] and not data['ip']:
data['ip'] = sipconfig[0][0]
data['ip'] = sipconfig[0][0].strip()
fieldnames = ['ip', 'cid']
writer = csv.DictWriter(f,fieldnames=fieldnames)
writer.writerow(data)
......@@ -131,20 +133,26 @@ def confirm_autostart():
f.write("{}\n".format(i))
f.close()
else:
os.mknod(filename)
cmd = "chmod 777 " + filename
run = pexpect.spawn('su -c "%s" root' %cmd)
time.sleep(0.5)
run.sendline('123')
time.sleep(0.1)
with open("/home/pi/.config/autostart/auto.desktop","a") as f:
for i in strs:
f.write("{}\n".format(i))
f.close()
try:
os.mknod(filename)
cmd = "chmod 777 " + filename
run = pexpect.spawn('su -c "%s" root' %cmd)
time.sleep(0.5)
run.sendline('123')
time.sleep(0.1)
with open("/home/pi/.config/autostart/auto.desktop","a") as f:
for i in strs:
f.write("{}\n".format(i))
f.close()
except Exception as e:
logging.warning(e)
logging.warning("自启动脚本更新成功")
def read_ip():
uploads_path = basepath + Config.STATE_PATH
if not os.path.exists(uploads_path + 'ipconfig.csv'):
return [['','']]
with open(uploads_path + 'ipconfig.csv','r') as f:
reader = csv.reader(f)
sipconfig = [row for row in reader]
......@@ -288,10 +296,13 @@ def get_towerstate():
tower_state = {
'1@4':{'action':False,'status':'off'},
'2@5':{'action':False,'status':'off'},
'3@6':{'action':True,'status':'on'}
# '4':{'action':False,'status':'off'},
# '5':{'action':False,'status':'off'},
# '6':{'action':True,'status':'on'}
'3@6':{'action':True,'status':'on'},
'1':{'action':False,'status':'off'},
'2':{'action':False,'status':'off'},
'3':{'action':True,'status':'on'},
'4':{'action':False,'status':'off'},
'5':{'action':False,'status':'off'},
'6':{'action':True,'status':'on'}
}
return tower_state
......
......@@ -133,7 +133,9 @@ def process_linetest(data):
# addr_list = map(remove_a,addrs)
if new_channel_nums == 'all':
# addr = "99"
texts = deal_allcommand(color)
#texts = deal_allcommand(color)
for i in range(1, 21):
texts += '{"ADDR":"'+str(i)+'","ledrange":[16,1,100]}\n'
else:
addr = new_channel_nums
color_index = color[0]
......@@ -183,6 +185,29 @@ def indlineledoff():
c_dict = {'msg':msg}
return json.dumps(c_dict)
@app.route('/single_calibrate', methods=['POST'])
def single_calibrate():
ser=SerialCommunication();
data = request.get_json()
light_led = data['light_led']
Aaddr = config_dict.get(light_led).split('@')[1]
addr = re.findall("\d+",Aaddr)[0]
led_index = config_dict.get(light_led).split('@')[0]
text = {"ADDR":addr,"calibrate":"autotrain","pin":led_index}
texts = str(json.dumps(text)) + '\n'
logging.info("指令:{}".format(texts))
if isinstance(texts,list):
for line in texts:
ser.send_data(line)
time.sleep(0.1)
else:
ser.send_data(texts)
msg = "addr:{},led:{},send single calibrate ok.".format(addr,led_index)
logging.warning(msg)
c_dict = {'msg':msg}
return json.dumps(c_dict)
# 处理库位操作测试>>亮灯/灭灯操作
def process_lightindex(data):
color = COLORS.get(data['light_led_color'],[15,255,255,255])
......@@ -239,7 +264,7 @@ def indresetled():
if isinstance(texts,list):
for line in texts:
ser.send_data(line)
time.sleep(0.1)
time.sleep(0.01)
else:
ser.send_data(texts)
msg = '灯条已重置'
......
# Translations template for PROJECT.
# Copyright (C) 2022 ORGANIZATION
# Copyright (C) 2023 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2022-04-19 13:57+0800\n"
"POT-Creation-Date: 2023-03-16 12:39+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -17,51 +17,53 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: induction_config.py:44 induction_config.py:193
#: induction_config.py:44 induction_config.py:202
#: templates/induction_config.html:120
msgid "串口号"
msgstr ""
#: induction_config.py:44 induction_config.py:193
#: induction_config.py:44 induction_config.py:202
#: templates/induction_config.html:125 templates/induction_test.html:58
msgid "地址"
msgstr ""
#: induction_post.py:57
#: induction_post.py:62
msgid "启动成功"
msgstr ""
#: induction_post.py:98
#: induction_post.py:104
msgid "关闭成功"
msgstr ""
#: induction_post.py:101
#: induction_post.py:107
msgid "无需关闭"
msgstr ""
#: templates/head.html:11
#: templates/head.html:29
msgid "感应式料架"
msgstr ""
#: templates/head.html:16
#: templates/head.html:34
msgid "控制"
msgstr ""
#: templates/head.html:17
#: templates/head.html:35
msgid "测试"
msgstr ""
#: templates/head.html:18
#: templates/head.html:36
msgid "料架配置"
msgstr ""
#: templates/induction_admin.html:7 templates/induction_config.html:6
#: templates/induction_control.html:6 templates/induction_test.html:6
#: templates/induction_control.html:6 templates/induction_debug.html:7
#: templates/induction_test.html:6
msgid "感应式料架系统"
msgstr ""
#: templates/induction_admin.html:22 templates/induction_config.html:78
#: templates/induction_control.html:25 templates/induction_test.html:23
#: templates/induction_control.html:25 templates/induction_debug.html:67
#: templates/induction_test.html:23
msgid "料架系统"
msgstr ""
......@@ -85,45 +87,54 @@ msgstr ""
msgid "随机亮灯"
msgstr ""
#: templates/induction_admin.html:50 templates/induction_admin.html:129
#: templates/induction_admin.html:50 templates/induction_admin.html:149
msgid "发送"
msgstr ""
#: templates/induction_admin.html:58
#: templates/induction_admin.html:58 templates/induction_test.html:124
msgid "标定"
msgstr ""
#: templates/induction_admin.html:84
#: templates/induction_admin.html:85
msgid "参数"
msgstr ""
#: templates/induction_admin.html:94
#: templates/induction_admin.html:95
msgid "自动标定"
msgstr ""
#: templates/induction_admin.html:101
#: templates/induction_admin.html:102
msgid "地址检测"
msgstr ""
#: templates/induction_admin.html:106
#: templates/induction_admin.html:107
msgid "亮灯检测"
msgstr ""
#: templates/induction_admin.html:113
#: templates/induction_admin.html:114
msgid "传感器地址"
msgstr ""
#: templates/induction_admin.html:117
#: templates/induction_admin.html:118
msgid "重建库位"
msgstr ""
#: templates/induction_admin.html:124
#: templates/induction_admin.html:122
msgid "重启控制器"
msgstr ""
#: templates/induction_admin.html:126
msgid "下载库位表"
msgstr ""
#: templates/induction_admin.html:133
msgid "串口调试"
msgstr ""
#: templates/induction_admin.html:172 templates/induction_admin.html:213
#: templates/induction_admin.html:240 templates/induction_admin.html:262
#: templates/induction_admin.html:297 templates/induction_admin.html:336
#: templates/induction_admin.html:192 templates/induction_admin.html:233
#: templates/induction_admin.html:260 templates/induction_admin.html:282
#: templates/induction_admin.html:317 templates/induction_admin.html:335
#: templates/induction_admin.html:376 templates/induction_debug.html:304
msgid "请谨慎操作"
msgstr ""
......@@ -178,22 +189,22 @@ msgid "teamview"
msgstr ""
#: templates/induction_config.html:148 templates/induction_control.html:86
#: templates/induction_test.html:180
#: templates/induction_test.html:181
msgid "运行日志&状态信息"
msgstr ""
#: templates/induction_config.html:154 templates/induction_control.html:42
#: templates/induction_test.html:186
#: templates/induction_test.html:187
msgid "提醒消息"
msgstr ""
#: templates/induction_config.html:159 templates/induction_control.html:47
#: templates/induction_test.html:191
#: templates/induction_test.html:192
msgid "运行状态"
msgstr ""
#: templates/induction_config.html:164 templates/induction_control.html:52
#: templates/induction_test.html:201
#: templates/induction_test.html:202
msgid "配置文件加载状态"
msgstr ""
......@@ -212,23 +223,24 @@ msgstr ""
#: templates/induction_config.html:208 templates/induction_config.html:246
#: templates/induction_config.html:285 templates/induction_control.html:128
#: templates/induction_control.html:152 templates/induction_control.html:175
#: templates/induction_test.html:234 templates/induction_test.html:250
#: templates/induction_test.html:277 templates/induction_test.html:302
#: templates/induction_test.html:325 templates/induction_test.html:349
#: templates/induction_test.html:374 templates/induction_test.html:400
#: templates/induction_test.html:421 templates/induction_test.html:443
#: templates/induction_test.html:466 templates/induction_test.html:490
#: templates/induction_test.html:514
#: templates/induction_test.html:235 templates/induction_test.html:251
#: templates/induction_test.html:278 templates/induction_test.html:306
#: templates/induction_test.html:329 templates/induction_test.html:353
#: templates/induction_test.html:378 templates/induction_test.html:407
#: templates/induction_test.html:433 templates/induction_test.html:454
#: templates/induction_test.html:476 templates/induction_test.html:499
#: templates/induction_test.html:523 templates/induction_test.html:547
msgid "运行中"
msgstr ""
#: templates/induction_config.html:208 templates/induction_config.html:246
#: templates/induction_test.html:250 templates/induction_test.html:277
#: templates/induction_test.html:302 templates/induction_test.html:325
#: templates/induction_test.html:349 templates/induction_test.html:374
#: templates/induction_test.html:400 templates/induction_test.html:421
#: templates/induction_test.html:443 templates/induction_test.html:466
#: templates/induction_test.html:490 templates/induction_test.html:514
#: templates/induction_test.html:251 templates/induction_test.html:278
#: templates/induction_test.html:306 templates/induction_test.html:329
#: templates/induction_test.html:353 templates/induction_test.html:380
#: templates/induction_test.html:407 templates/induction_test.html:433
#: templates/induction_test.html:454 templates/induction_test.html:476
#: templates/induction_test.html:499 templates/induction_test.html:523
#: templates/induction_test.html:547
msgid "料架运行中,请关闭后再进行配置"
msgstr ""
......@@ -254,13 +266,13 @@ msgstr ""
#: templates/induction_config.html:286 templates/induction_control.html:129
#: templates/induction_control.html:153 templates/induction_control.html:176
#: templates/induction_test.html:235
#: templates/induction_test.html:236
msgid "已关闭"
msgstr ""
#: templates/induction_config.html:287 templates/induction_control.html:130
#: templates/induction_control.html:154 templates/induction_control.html:177
#: templates/induction_test.html:236
#: templates/induction_test.html:237
msgid "未初始化"
msgstr ""
......@@ -285,7 +297,7 @@ msgstr ""
msgid "服务器连接状态"
msgstr ""
#: templates/induction_control.html:72 templates/induction_test.html:206
#: templates/induction_control.html:72 templates/induction_test.html:207
msgid "串口状态"
msgstr ""
......@@ -309,10 +321,26 @@ msgstr ""
msgid "启动失败"
msgstr ""
#: templates/induction_control.html:159
#: templates/induction_control.html:159 templates/induction_debug.html:298
msgid "停止失败"
msgstr ""
#: templates/induction_debug.html:72
msgid "料架状态显示"
msgstr ""
#: templates/induction_debug.html:76
msgid "开始扫描库位"
msgstr ""
#: templates/induction_debug.html:78
msgid "停止扫描库位"
msgstr ""
#: templates/induction_debug.html:156
msgid "开始顺序测试"
msgstr ""
#: templates/induction_test.html:27
msgid "串口连接状态"
msgstr ""
......@@ -346,7 +374,7 @@ msgid "灯条测试"
msgstr ""
#: templates/induction_test.html:82 templates/induction_test.html:111
#: templates/induction_test.html:143
#: templates/induction_test.html:144
msgid "颜色"
msgstr ""
......@@ -366,11 +394,11 @@ msgstr ""
msgid "库位"
msgstr ""
#: templates/induction_test.html:121 templates/induction_test.html:152
#: templates/induction_test.html:121 templates/induction_test.html:153
msgid "亮灯"
msgstr ""
#: templates/induction_test.html:122 templates/induction_test.html:153
#: templates/induction_test.html:122 templates/induction_test.html:154
msgid "灭灯"
msgstr ""
......@@ -378,35 +406,39 @@ msgstr ""
msgid "重置"
msgstr ""
#: templates/induction_test.html:129
#: templates/induction_test.html:130
msgid "状态灯测试"
msgstr ""
#: templates/induction_test.html:132
#: templates/induction_test.html:133
msgid "编号"
msgstr ""
#: templates/induction_test.html:160
#: templates/induction_test.html:161
msgid "下载库位二维码"
msgstr ""
#: templates/induction_test.html:172
#: templates/induction_test.html:173
msgid "下载二维码"
msgstr ""
#: templates/induction_test.html:174
#: templates/induction_test.html:175
msgid "单个二维码尺寸(含白色底框)尺寸为16*16mm,黑码尺寸为10*10mm"
msgstr ""
#: templates/induction_test.html:196
#: templates/induction_test.html:197
msgid "测试消息"
msgstr ""
#: utils/serial_collection.py:64 utils/serial_communication.py:113
#: templates/induction_test.html:384
msgid "操作前请确保该库位中没有物料"
msgstr ""
#: utils/serial_collection.py:64
msgid "串口连接正常"
msgstr ""
#: utils/serial_collection.py:66 utils/serial_communication.py:115
#: utils/serial_collection.py:66 utils/serial_communication.py:121
msgid "串口连接失败"
msgstr ""
[connection]
id=NEOTEL
uuid=527c1020-2fdf-45c5-a3f5-1af22cbfdc70
type=ethernet
permissions=
[ethernet]
mac-address-blacklist=
[ipv4]
dns-search=
method=manual
[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.
# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel
# Inform the DHCP server of our hostname for DDNS.
hostname
# Use the hardware address of the interface for the Client ID.
clientid
# or
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
# Some non-RFC compliant DHCP servers do not reply with this set.
# In this case, comment out duid and enable clientid above.
#duid
# Persist interface configuration when dhcpcd exits.
persistent
# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit
# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Respect the network MTU. This is applied to DHCP routes.
option interface_mtu
# Most distributions have NTP support.
#option ntp_servers
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# Generate SLAAC address using the Hardware Address of the interface
#slaac hwaddr
# OR generate Stable Private IPv6 Addresses based from the DUID
slaac private
#interface wlan0
#static ip_address =10.174.92.33/24
#static routers=10.174.92.1
#static domain_name_servers=10.8.136.21
# Example static IP configuration:
#interface eth0
#static ip_address=192.168.10.100/24
#static ip6_address=fd51:42f8:caae:d92e::ff/64
#static routers=192.168.10.2
#static domain_name_servers=192.168.10.2 114.114.114.114 fd51:42f8:caae:d92e::1
# It is possible to fall back to a static IP if DHCP fails:
# define static profile
#profile static_eth0
#static ip_address=192.168.1.23/24
#static routers=192.168.1.1
#static domain_name_servers=192.168.1.1
# fallback to static profile on eth0
#interface eth0
#fallback static_eth0
import re
import time
import functools
# from app.induction_test import config_dict,convert_dict
import logging
import traceback
from app.utils.g import shelfconfig
s_detail = {}
test_state = False
......@@ -28,27 +29,43 @@ def production_filter(origin_value):
def transfer(origin_value):
cur_dict = {}
addrs=shelfconfig.addrs.split('@')
if origin_value:
# receive_data=origin_value.split("\n")
receive_data=origin_value.decode().split("\r\n")
for item in receive_data[::-1]:
if not (item.startswith("A") and item.endswith("]")):
receive_data.remove(item)
print (item)
print("筛选后的数据:", receive_data)
if receive_data:
for line in receive_data:
# print ("-----------------line",line)
addr = re.search("(?<=A)\d+",line)
led = re.search("\[.*?\]", line)
if led is None:
continue
c_list = list(led.group())
# print ("-------------------c_list",c_list)
c_list.pop(0)
c_list.pop(-1)
keyword = 'A' + addr.group()
cur_dict[keyword] = c_list
try:
receive_data=origin_value.decode().split("\n")
for item in receive_data[::-1]:
if re.search('^A\d{1,2}\[[0-1]{100}\]$',item.strip())==None:
receive_data.remove(item)
print (item)
print("筛选后的数据:", receive_data)
if receive_data:
for line in receive_data:
line=line.strip()
# print ("-----------------line",line)
addr = re.search("(?<=A)\d{1,2}",line)
led = re.search("\[[0-1]{100}\]", line)
if led is None:
continue
if len(addr.group())==2:
if "B"+addr.group()[1] in addrs:
addrs.remove("B"+addr.group()[1])
else:
if "A"+addr.group() in addrs:
addrs.remove("A"+addr.group())
c_list = list(led.group())
# print ("-------------------c_list",c_list)
c_list.pop(0)
c_list.pop(-1)
keyword = 'A' + addr.group()
cur_dict[keyword] = c_list
except Exception as e:
logging.warning("读取传感器状态出错:{}".format(repr(e)))
logging.warning("当前解析值:{}".format(receive_data))
msg = traceback.format_exc()
logging.warning(msg)
if len(addrs)>0:
logging.warning("当前解析值2:{},{}".format(len(addrs),origin_value))
return None
return cur_dict
def change_deatil(old_dict):
......
/dev/ttyUSBneotel
\ No newline at end of file
/dev/ttyUSBN
\ No newline at end of file
on
\ No newline at end of file
off
\ No newline at end of file
......@@ -31,9 +31,9 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li{{ " class=active" if index==1 }}><a href="{{ url_for('induction_control') }}">{{ _('控制') }}</a></li>
<li{{ " class=active" if index==1 }}><a href="{{ url_for('induction_control') }}">{{ _('通用') }}</a></li>
<li{{ " class=active" if index==2 }}><a href="{{ url_for('induction_test') }}">{{ _('测试') }}</a> </li>
<li{{ " class=active" if index==3 }}><a href="{{ url_for('induction_config') }}">{{ _('料架配置') }}</a> </li>
<li{{ " class=active" if index==3 }}><a href="{{ url_for('induction_config') }}">{{ _('配置') }}</a> </li>
</ul>
<ul class="nav navbar-nav navbar-right" style="font-size: 14px;"">
<li>
......
......@@ -118,6 +118,14 @@
<input type="button" value="{{ _('重建库位') }}" class="btn btn-warning"
onclick="buildstore()" />
</div>
<div class="col-sm-2">
<input type="button" value="{{ _('重启控制器') }}" class="btn btn-warning"
onclick="restart()" />
</div>
<div class="col-sm-2">
<input type="button" value="{{ _('下载库位表') }}" class="btn btn-warning"
onclick="location.href='/downloadstore'" />
</div>
</div>
</div>
<div class="panel panel-info">
......@@ -133,6 +141,7 @@
<option>A1</option>
<option>{"ADDR":"1","action":"info"}</option>
<option>{"ADDR":"1","action":"PrintStatus"}</option>
<option>{"ADDR":"99","action":"diagnosMode"}</option>
</select>
</div>
<div class="col-sm-12">
......@@ -245,7 +254,7 @@
})
}
}
// 获取阈值
function getcalibrate() {
if (confirm("{{ _('请谨慎操作') }}")) {
......@@ -322,6 +331,24 @@
})
}
}
function restart() {
if (confirm("{{ _('请谨慎操作') }}")) {
$.ajax({
url: "/restart",
type: "post",
// data:JSON.stringify(data),
contentType: "application/json",
dataType: 'json',
success: function (data) {
// $("#testinfo").html(data.msg)
alert(data.msg);
},
error: function (e) {
alert("error");
}
})
}
}
function command_test() {
var data = {
"command": document.getElementById("command").value
......
......@@ -75,7 +75,6 @@
<div class="row">
<div class="col-md-6">
<h2>{{ _('料架系统') }}</h2>
<hr class="divider">
<!-- 上传文件 -->
<div class="panel panel-primary">
......@@ -114,7 +113,7 @@
</div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">{{ _('更新串口&地址') }}</h3>
<h3 class="panel-title">{{ _('设置串口&地址') }}</h3>
</div>
<div class="panel-body">
<label for="stock_cha1" class="col-sm-3">{{ _('串口号') }}</label>
......@@ -129,7 +128,7 @@
<div class="col-sm-12">
<input type="button" value={{ _('保存') }} class="btn btn-warning" onclick="updateserial()"/>
<input type="button" value={{ _('同步颜色信息') }} class="btn btn-info" onclick="sendcolor()"/>
<!-input type="button" value={{ _('同步颜色信息') }} class="btn btn-info" onclick="sendcolor()"/-->
</div><!-- /.col-sm-4 -->
</div>
</div>
......@@ -145,13 +144,12 @@
</div-->
</div>
<div class="col-md-6">
<h2>{{ _('运行日志&状态信息') }}</h2>
<hr class="divider">
<div id="panel-group">
<!-- 1 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{{ _('提醒消息') }}</h3>
<h3 class="panel-title">{{ _('消息') }}</h3>
</div>
<div class="panel-body">
<div class="alert alert-info" role="alert">
......
......@@ -39,7 +39,7 @@
<!-- 1 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{{ _('提醒消息') }}</h3>
<h3 class="panel-title">{{ _('消息') }}</h3>
</div>
<div class="panel-body">
<div class="alert alert-info" role="alert">
......@@ -74,7 +74,7 @@
</div>
<div class="alert alert-info" role="alert">
<p>
{{ _('server connect') }}:<span id="serverstate"></span>
{{ _('服务器连接状态') }}:<span id="serverstate"></span>
</p>
</div>
</div>
......
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="/static/js/ipvalidate.js"></script>
<script>
function validateForm() {
var ipAddress = document.getElementById("new_ip").value;
var netmask = document.getElementById("new_mask").value;
var router = document.getElementById("router_ip").value;
var dhcp_check = document.getElementById("dhcp").checked
if (dhcp_check)
{
return true
}
// Check if the IP address and netmask are valid
if (!isValidIpAddress(ipAddress)) {
alert("Invalid IP address");
return false;
}
if (!isValidNetmask(netmask)) {
alert("Invalid netmask");
return false;
}
if (!isValidIpAddress(router)) {
alert("Invalid router address");
return false;
}
return true;
}
</script>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
}
form {
display: flex;
flex-direction: column;
margin:50px auto
}
div p {
font-size: 24px;
#font-weight: bold;
display: block;
margin: 20px auto;
}
input[type="text"], textarea {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
}
input[type="submit"] {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
display: block;
margin: 0 auto;
}
label, input, textarea {
margin-bottom: 10px;
}
label.remark-label {
font-size: 14px;
color: #999;
}
</style>
<title> </title>
</head>
<body>
<div >
<p> Network Configure</p>
<form action="/ip_config" method="post" onsubmit="return validateForm()">
IP Address: <input type="text" id="new_ip" name="new_ip"><label class="remark-label">For Example:192.168.10.10</label><br>
Network Mask: <input type="text" id="new_mask" name="new_mask"><label class="remark-label">For Example:255.255.255.0</label><br>
Default GateWay: <input type="text" id="router_ip" name="router_ip"><label class="remark-label">For Example:192.168.10.1</label><br>
<label for="dhcp">Enable DHCP:
<input type="checkbox" name="dhcp" id="dhcp"></label><br>
<div style="margin:50px auto;width:200px;">
<input type="submit" value="Submit">
</div>
</form>
</div>
</body>
</html>
\ No newline at end of file
import pickle
import os
import string
from config import Config
current_state: string
current_state='off'
Serl = None
basepath = os.path.dirname(__file__)
shelfconfigfile = basepath+"/../" + Config.STATE_PATH+'shelfconfig.pkl'
def ver():
return "1.6"
return "1.873"
class _shelfconfig:
......@@ -19,14 +22,23 @@ class _shelfconfig:
self.addrs="not_config"
self.after_instore_close_light=False
self.after_instore_light_color='orange'
self.comport_carsh_timeout=30
self.comport_carsh_reboot=False
self.after_induction_preshow_color='white'
self.inok_blink_times=4;
def Save(self):
with open(shelfconfigfile, 'wb') as f:
pickle.dump(self, f)
shelfconfig:_shelfconfig
shelfconfig = _shelfconfig()
if os.path.exists(shelfconfigfile):
with open(shelfconfigfile, 'rb') as f:
shelfconfig = pickle.load(f)
a = pickle.load(f)
for it in a.__dict__.items():
if it[0].find('__')>=0 or it[0]=='Save':
continue
if shelfconfig.__dict__.get(it[0]) is not None:
shelfconfig.__dict__[it[0]]=a.__dict__[it[0]]
print("shelfconfig",shelfconfig.__dict__.items())
......@@ -11,9 +11,9 @@ import serial
import logging
from config import Config
import app.utils.g as gg
from app.utils.g import shelfconfig
from flask_babel import Babel, gettext as _
class SerialCommunication():
def __init__(self):
# print(gg.Serl)
......@@ -24,6 +24,7 @@ class SerialCommunication():
# self.timeout = float(serial_cf.get_serial("DEFAULT_TIMEOUT"))
# self.port = read_com()
# self.uploads_path = Config.UPLOAD_FOLDER
self.serialstate="串口连接正常"
with open(Config.IP_PATH + "/serialcom.txt", "r") as f:
serialcom = f.read()
self.port = serialcom.strip("\n")
......@@ -51,12 +52,15 @@ class SerialCommunication():
log("main_engine 关闭失败")
if not self.findSerial(self.port.strip('n').strip('N')):
log("无法定位串口,系统重启.")
shelfconfig.comport_carsh_reboot=True
shelfconfig.Save()
time.sleep(1)
import os
os.system('sudo reboot')
def findSerial(self, portpre):
trytimes = 0
while trytimes < 120/5:
while trytimes < shelfconfig.comport_carsh_timeout /5:
for i in range(0, 5):
try:
currentport = portpre+str(i)
......@@ -68,9 +72,11 @@ class SerialCommunication():
gg.Serl.write(bytes("A1\n".encode('utf-8')))
self.main_engine=gg.Serl
log("成功打开串口:{}".format(currentport))
self.serialstate="串口连接正常"
return True
except Exception as e:
log("串口打开失败:", currentport, e)
self.serialstate=e
trytimes += 1
time.sleep(5)
log("串口打开失败,第{}次重试".format(trytimes))
......@@ -110,7 +116,7 @@ class SerialCommunication():
def check_serial(self):
try:
if (self.main_engine.is_open):
return _('串口连接正常')
return _(self.serialstate)
else:
return _('串口连接失败')
except Exception as e:
......@@ -140,11 +146,12 @@ class SerialCommunication():
data=bytes(bytes("".encode('utf-8')))
while self.main_engine.in_waiting:
data=data+ self.main_engine.read_all()
time.sleep(0.05)
time.sleep(0.06)
return data
except Exception as e:
log('串口读取数据错误,{}'.format(e))
self.TryConnectSerial()
self.serialstate=e
return bytes(bytes("".encode('utf-8')))
# 未使用
......@@ -160,10 +167,16 @@ class SerialCommunication():
# text = '{"ADDR":"99","colorset:[[1,255,0,0],[2,0,255,255],[5,132,142,110]]}\n{"ADDR":"1","color":[[1,10,20,30],[2,31,37,49],[5,1,3,5,7,9,11,14,18]]}\n{"ADDR":"3","color":[[1,10,20,30],[2,31,37,49],[5,1,3,5,7,9,11,14,18]]}\n'
try:
print("out_waiting",self.main_engine.out_waiting,'send_data:'+data.replace('\n','\\n')+"EOF")
data = bytes(data.encode('utf-8'))
self.main_engine.write(data)
if wait:
self.main_engine.flush()
commands = data.split("\n")
for cmd in commands:
if len(cmd)==0:
continue;
cmd=cmd+"\n"
cmd = bytes(cmd.encode('utf-8'))
self.main_engine.write(cmd)
time.sleep(0.03)
if wait:
self.main_engine.flush()
except Exception as e:
log('串口发送数据错误,{}'.format(e))
self.TryConnectSerial()
......
......@@ -40,8 +40,28 @@ class Config(object):
'forestgreen':[11,34,139,34],
'lightblue':[12,132,112,255],
'indianred':[13,139,58,58],
'darkgreen':[14,85,107,47],
'darkgreen':[14,0,90,0],
'white':[15,125,125,125],
'off':[16,0,0,0],
'magenta':[17,125,125,0]
'magenta':[17,125,125,0],
'#ff0000':[51,255,0,0],
'#ffc0cb':[52,255,192,203],
'#c71585':[53,199,21,133],
'#ff8c00':[54,255,140,0],
'#ffff00':[55,255,255,0],
'#bdb76b':[56,189,183,107],
'#e6e6fa':[57,230,230,250],
'#9370db':[58,147,112,219],
'#800080':[59,128,0,128],
'#adff2f':[60,173,255,47],
'#98fb98':[61,52,251,152],
'#008000':[62,0,128,0],
'#808000':[63,128,128,0],
'#00ffff':[64,0,255,255],
'#7fffd4':[65,127,255,212],
'#b0c4de':[66,176,196,222],
'#0000ff':[67,0,0,255],
'#ffe4c4':[68,255,228,196],
'#f4a460':[69,244,164,96]
}
\ No newline at end of file
此文件的差异太大,无法显示。
cd /d %~dp0
set zip="C:\Program Files\7-Zip\7z.exe"
set zipname=../app.zip
del app.zip /y
cd app
%zip% a %zipname% *.py
%zip% a -xr"!__pycache__" %zipname% utils
%zip% a %zipname% templates
%zip% a %zipname% translations
pause
\ No newline at end of file
此文件太大,无法显示。
此文件太大,无法显示。
<?xml version="1.0" encoding="UTF-8"?>
<config ver="10">
<item key="ipstart" ver="10" value="192.168.101.111" />
<item key="ipend" ver="10" value="118" />
</config>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<config ver="10">
<item key="ipstart" ver="10" value="192.168.101.111" />
<item key="ipend" ver="10" value="118" />
</config>
\ No newline at end of file
{"192.168.101.222":{"IP":"192.168.101.222","Mac":"","Host":null,"BoardType":0,"Ver":0.0,"MCAddr":null,"PingDelay":70,"shelfState":{"isupdate":false,"state":"off","msg":"未进行测试动作","ipconfig":{"post":"wait","ip":"http://192.168.101.58/smf-core","cid":"1245-02"},"version":"1.871","serial_state":"串口连接正常","ad_serial":"串口号:/dev/ttyUSBN,地址:A1@A2@A3@A4@A5@B1@B2@B3"},"memo":null},"192.168.101.221":{"IP":"192.168.101.221","Mac":"","Host":null,"BoardType":0,"Ver":0.0,"MCAddr":null,"PingDelay":71,"shelfState":{"isupdate":false,"state":"na","msg":null,"ipconfig":null,"version":null,"serial_state":"na","ad_serial":null},"memo":null},"192.168.101.111":{"IP":"192.168.101.111","Mac":"","Host":null,"BoardType":0,"Ver":0.0,"MCAddr":null,"PingDelay":34,"shelfState":{"isupdate":false,"state":"na","msg":null,"ipconfig":null,"version":null,"serial_state":"na","ad_serial":null},"memo":null},"192.168.101.113":{"IP":"192.168.101.113","Mac":"","Host":null,"BoardType":0,"Ver":0.0,"MCAddr":null,"PingDelay":25,"shelfState":{"isupdate":false,"state":"on","msg":"未进行测试动作","ipconfig":{"post":"failed","ip":"http://192.168.10.200/smf-core","cid":"001"},"version":"1.4","serial_state":null,"ad_serial":null},"memo":null},"192.168.101.115":{"IP":"192.168.101.115","Mac":"","Host":null,"BoardType":0,"Ver":0.0,"MCAddr":null,"PingDelay":9,"shelfState":{"isupdate":true,"state":"off","msg":"未进行测试动作","ipconfig":{"post":"failed","ip":"http://192.168.101.77/smf-core","cid":"01"},"version":"1.872","serial_state":"串口连接正常","ad_serial":"串口号:/dev/ttyUSB0,地址:A1@A2@A3@A4@A5@A6@A7@B1@B2@B3@B4@B5@B6@B7"},"memo":null},"192.168.101.116":{"IP":"192.168.101.116","Mac":"","Host":null,"BoardType":0,"Ver":0.0,"MCAddr":null,"PingDelay":72,"shelfState":{"isupdate":true,"state":"off","msg":"未进行测试动作","ipconfig":{"post":"failed","ip":"http://192.168.101.77/smf-core","cid":"01"},"version":"1.872","serial_state":"串口连接正常","ad_serial":"串口号:/dev/ttyUSB0,地址:A1@A2@A3@A4@A5@B1@B2"},"memo":null},"192.168.101.117":{"IP":"192.168.101.117","Mac":"","Host":null,"BoardType":0,"Ver":0.0,"MCAddr":null,"PingDelay":20,"shelfState":{"isupdate":true,"state":"off","msg":"未进行测试动作","ipconfig":{"post":"failed","ip":"http://192.168.101.77/smf-core","cid":"01"},"version":"1.872","serial_state":"Error,'NoneType' object has no attribute 'is_open'","ad_serial":"串口号:/dev/ttyUSB0,地址:A1@A2@A3@A4@A5@B1@B2@B3@B4@B5"},"memo":null}}
\ No newline at end of file
此文件类型无法预览
此文件类型无法预览
<?xml version="1.0"?>
<doc>
<assembly>
<name>ConfigHelper</name>
</assembly>
<members>
<member name="F:ConfigHelper.AdvanceConfigEdit.CustomEditor">
<summary>
自定义编辑器
</summary>
</member>
<member name="F:ConfigHelper.AdvanceConfigEdit.components">
<summary>
必需的设计器变量。
</summary>
</member>
<member name="M:ConfigHelper.AdvanceConfigEdit.Dispose(System.Boolean)">
<summary>
清理所有正在使用的资源。
</summary>
<param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
</member>
<member name="M:ConfigHelper.AdvanceConfigEdit.InitializeComponent">
<summary>
设计器支持所需的方法 - 不要修改
使用代码编辑器修改此方法的内容。
</summary>
</member>
<member name="M:ConfigHelper.AdvanceConfigForm.AddCustomEditor``1(System.String)">
<summary>
添加自定义编辑器
</summary>
<typeparam name="T"></typeparam>
<param name="name"></param>
</member>
<member name="M:ConfigHelper.AdvanceConfigForm.ShowEditDialog(System.Windows.Forms.IWin32Window,System.Boolean)">
<summary>
显示配置界面,2秒内调用约6次后显示
</summary>
<param name="owner"></param>
<param name="TopMost"></param>
</member>
<member name="F:ConfigHelper.AdvanceConfigForm.components">
<summary>
Required designer variable.
</summary>
</member>
<member name="M:ConfigHelper.AdvanceConfigForm.Dispose(System.Boolean)">
<summary>
Clean up any resources being used.
</summary>
<param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
</member>
<member name="M:ConfigHelper.AdvanceConfigForm.InitializeComponent">
<summary>
Required method for Designer support - do not modify
the contents of this method with the code editor.
</summary>
</member>
<member name="T:ConfigHelper.Config">
<summary>
自定义配置存取
</summary>
</member>
<member name="F:ConfigHelper.Config.hasChange">
<summary>
指示配置文件是否存在变化
</summary>
</member>
<member name="P:ConfigHelper.Config.SaveToAppdata">
<summary>
将设置保存至appdata目录
</summary>
</member>
<member name="M:ConfigHelper.Config.ReloadConfig">
<summary>
重载配置
</summary>
</member>
<member name="M:ConfigHelper.Config.SetComment(System.String,System.String)">
<summary>
设置备注
</summary>
<param name="key"></param>
<param name="Comment"></param>
</member>
<member name="M:ConfigHelper.Config.Get(System.String)">
<summary>
读取配置
</summary>
<param name="key"></param>
<returns></returns>
</member>
<member name="M:ConfigHelper.Config.Get(System.Object)">
<summary>
读取配置
</summary>
<param name="key">传入一个枚举值</param>
<returns></returns>
</member>
<member name="M:ConfigHelper.Config.Get``1(System.Object,``0)">
<summary>
读取配置
</summary>
<typeparam name="T">返回类型</typeparam>
<param name="key">传入一个枚举值</param>
<param name="defaultvalue">失败默认值</param>
<returns></returns>
</member>
<member name="M:ConfigHelper.Config.Get``1(System.String,``0)">
<summary>
读取配置
</summary>
<typeparam name="T">返回类型</typeparam>
<param name="key">key</param>
<param name="defaultvalue">失败默认值</param>
<returns></returns>
</member>
<member name="M:ConfigHelper.Config.Set(System.String,System.String)">
<summary>
设置配置
</summary>
<param name="key"></param>
<param name="value"></param>
</member>
<member name="M:ConfigHelper.Config.Set(System.Object,System.String)">
<summary>
设置配置
</summary>
<param name="key">配置枚举值</param>
<param name="value"></param>
</member>
<member name="M:ConfigHelper.Config.Set``1(System.Object,``0)">
<summary>
设置配置
</summary>
<param name="key">配置枚举值</param>
<param name="value"></param>
</member>
<member name="M:ConfigHelper.Config.Set``1(System.String,``0)">
<summary>
设置配置
</summary>
<typeparam name="T">值类型</typeparam>
<param name="key"></param>
<param name="value"></param>
</member>
<member name="M:ConfigHelper.Config.SaveChangeDebounce">
<summary>
保存设置
</summary>
</member>
<member name="M:ConfigHelper.Config.SaveChange">
<summary>
保存设置
</summary>
</member>
<member name="P:ConfigHelper.Config.Configlist">
<summary>
获取所有配置文本
</summary>
</member>
<member name="M:ConfigHelper.Config.FileSave(System.String,System.String)">
<summary>
不通过系统缓存立刻写入磁盘
</summary>
<param name="content"></param>
<param name="destfilename"></param>
</member>
<member name="M:ConfigHelper.Config.PropertyBind(System.Object,System.Object,System.String,System.String,System.String)">
<summary>
绑定UI属性
</summary>
<param name="key">配置key</param>
<param name="uiobj">ui对象</param>
<param name="Property">绑定属性</param>
<param name="SaveEvent">绑定事件(object s, EventArgs x),可以为空</param>
<param name="defaultvalue">默认值</param>
</member>
<member name="M:ConfigHelper.Config.PropertyBind``1(System.Object,System.Object,System.String,System.String,``0)">
<summary>
绑定UI属性
</summary>
<param name="key">配置key</param>
<param name="uiobj">ui对象</param>
<param name="Property">绑定属性</param>
<param name="SaveEvent">绑定事件(object s, EventArgs x),可以为空</param>
<param name="defaultvalue">默认值</param>
</member>
<member name="M:ConfigHelper.Config.LoadMyConfig(System.Type)">
<summary>
转换自定义配置类
</summary>
<param name="ConfigClassType"></param>
<returns>加载到的配置Key数量</returns>
</member>
<member name="T:ConfigHelper.ICustEditor">
<summary>
自定义编辑器接口
</summary>
</member>
<member name="M:ConfigHelper.ICustEditor.ValueEdit(System.Object)">
<summary>
自己的编辑方法或界面
</summary>
<param name="value">传入的值</param>
<returns>传出的值</returns>
</member>
<member name="T:ConfigHelper.MyConfig`1">
<summary>
自动化我的配置
</summary>
</member>
<member name="F:ConfigHelper.MyConfig`1.Key">
<summary>
配置的Key
</summary>
</member>
<member name="P:ConfigHelper.MyConfig`1.Val">
<summary>
配置的值
</summary>
</member>
<member name="M:ConfigHelper.MyConfig`1.ToString">
<summary>
获取配置数据的文本
</summary>
<returns></returns>
</member>
<member name="M:ConfigHelper.MyConfig`1.op_Implicit(ConfigHelper.MyConfig{`0})~`0">
<summary>
隐式转换,读值
</summary>
<param name="m1"></param>
</member>
<member name="M:ConfigHelper.MyConfig`1.op_Implicit(`0)~ConfigHelper.MyConfig{`0}">
<summary>
隐式转换,写值
</summary>
<param name="v1"></param>
</member>
<member name="T:ConfigHelper.MyConfigComment">
<summary>
自定义配置描述
</summary>
</member>
<member name="M:ConfigHelper.MyConfigComment.#ctor(System.String)">
<summary>
配置的说明
</summary>
<param name="comment"></param>
</member>
</members>
</doc>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
\ No newline at end of file
此文件类型无法预览
此文件的差异太大,无法显示。
此文件类型无法预览
此文件的差异太大,无法显示。
此文件太大,无法显示。
import requests
import threading
from flask import Flask
from flask_babel import Babel
from config import Config
import logging
from logging.handlers import RotatingFileHandler,TimedRotatingFileHandler
#from flask_cors import CORS
global Serl
Serl=None
def setup_log():
# 设置日志的记录等级
logging.basicConfig(level=Config.LOG_LEVEL) # 调试debug级
# 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
file_log_handler = RotatingFileHandler(Config.LOG_FOLDER, maxBytes=1024 * 1024 * 100, backupCount=10)
# 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
# log_file_handler = TimedRotatingFileHandler(filename='logs/smartshelf.log', when="D", interval=1, backupCount=3)
formatter = logging.Formatter('%(asctime)s - %(levelname)s : %(message)s')
# 为刚创建的日志记录器设置日志记录格式
file_log_handler.setFormatter(formatter)
file_log_handler.setLevel(logging.WARNING)
# 为全局的日志工具对象(flask app使用的)添加日志记录器
logging.getLogger().addHandler(file_log_handler)
def add_header(response):
response.cache_control.no_store = True
response.cache_control.no_cache = True
#if 'Cache-Control' not in response.headers:
# response.headers['Cache-Control'] = 'no-cache'
return response
setup_log()
app = Flask(__name__)
#CORS(app, resources=r'/*')
babel = Babel(app)
app.config.from_object(Config)
app.after_request(add_header)
LANGUAGES = {
"zh": "Chinese",
"en": "English",
"ja": "Japanese"
}
from app import config_ip,induction_post,induction_test,induction_admin,induction_config,autoback,qr_code,scan_collection
from app.induction_config import testCidExists
import time
def s():
time.sleep(10)
data = {'key1':'value1','key2':'value2'}
time.sleep(2)
requests.post("http://127.0.0.1:5000/stoppost",data)
#if testCidExists():
time.sleep(2)
requests.post("http://127.0.0.1:5000/startpost",data)
t =threading.Thread(target=s)
t.start()
# return app
\ No newline at end of file
# codinf:utf-8
import os
import time
from flask import render_template, Response, request,redirect,url_for
from werkzeug.utils import secure_filename
from app import app
import logging
import pexpect
import json
import zipfile
import shutil
import csv
import requests
import re
from config import Config
basepath = os.path.dirname(__file__)
def backup():
try:
source_dir = '/prog/backup/'
today = source_dir + time.strftime('%Y%m%d')
if not os.path.exists(today):
os.mkdir(today)
cmd = "cp -rf /prog/smartshelf/* /prog/backup/{}/".format(time.strftime('%Y%m%d'))
run = pexpect.spawn('su -c "%s" root' %cmd)
time.sleep(2)
run.sendline('xxx')
logging.warning("备份成功")
except Exception as e:
logging.warning("备份失败:{}".format(e))
def read_ip():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + 'ipconfig.csv','r') as f:
reader = csv.reader(f)
current = [row for row in reader]
ip = current[0][0]
return ip
from app.utils.g import ver
def read_version():
return ver()
@app.route('/upgrade',methods=['POST'])
def upgrade():
ip = read_ip()
ip = ip.replace('/myproject', '')
# ip = 'http://192.168.1.99'
download_url = '{}/download/version.txt'.format(ip)
logging.warning("服务器最新版本信息:{}".format(download_url))
try:
response = requests.get(download_url)
if response.status_code == 200:
version = response.json()
s_version = read_version()
logging.warning("当前版本:{},最新版本:{}".format(s_version,version))
if str(s_version) == str(version):
info = {'operation':'当前版本已是最新版本!'}
else:
download_zip(ip,version)
backup()
time.sleep(2)
process_file()
time.sleep(2)
reboot()
info = {'operation':'已升级到最新版本'}
else:
info = {'operation':'服务器地址错误'}
except Exception as e:
logging.warning("发生错误:{}".format(e))
info = {'operation':'Error'}
return json.dumps(info)
def download_zip(ip,version):
zip_url = '{}/download/{}.zip'.format(ip,version)
logging.warning("服务器最新文件:{}".format(zip_url))
target_path = '/prog/upgrade_cach/smartshelf.zip'
File=requests.get(zip_url, stream=True)
with open(target_path,'wb+') as f:
for chunk in File.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
f.close()
def process_file():
zfile = zipfile.ZipFile('/prog/upgrade_cach/smartshelf.zip','r')
path2 = '/prog/update/smartshelf/'
n_train = 0
for filename in zfile.namelist():
if filename.endswith('/'):
n_train += 1
os.makedirs(os.path.join(path2, filename))
else:
data = zfile.read(filename)
file = open(os.path.join(path2, filename), 'w+b')
file.write(data)
file.close()
time.sleep(5)
py_source = '/prog/update/smartshelf/app/'
templates_source = '/prog/update/smartshelf/app/templates/'
py_target = '/prog/smartshelf/app/'
template_target = '/prog/smartshelf/app/templates/'
templates_lis = os.listdir(path=templates_source)
py_lis = os.listdir(path=py_source)
logging.warning("待更新文件:{},{}".format(py_lis,templates_lis))
for t_file in templates_lis:
t_filename = os.path.join(templates_source,t_file)
if os.path.isfile(t_filename):
try:
shutil.copy(t_filename, template_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
# print("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
for p_file in py_lis:
p_filename = os.path.join(py_source,p_file)
if os.path.isfile(p_filename):
try:
shutil.copy(p_filename, py_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
shutil.rmtree(path2)
os.remove('/prog/upgrade_cach/smartshelf.zip')
# shutil.rmtree('/prog/upgrade_cach/')
logging.warning("templates upgrade success")
def reboot():
os.system('/prog/./restart.sh')
def openteam():
# os.system('/usr/bin/./teamviwer')
cmd = "nohub /opt/teamviewer/tv_bin/TeamViewer"
run = pexpect.spawn('su -c "%s" root' %cmd)
time.sleep(0.5)
run.sendline('xxx')
# cmd1 = "./teamviwer"
# run1 = pexpect.spawn('su -c "%s" root' %cmd1)
# time.sleep(0.5)
# run1.sendline('xxx')
logging.warning("teamview open")
@app.route('/openteamview',methods=['POST'])
def openteamview():
openteam()
info = {'operation':'已打开teamview'}
return json.dumps(info)
import os
from flask import Flask, render_template, request, Response
from app import app
import time
from threading import Thread
netprofilepath = r'/prog/smartshelf/app/netprofile/'
#app = Flask(__name__)
@app.route('/ipconfig')
def shelfconfig():
print("begin ip flask")
return render_template('ipconfig.html')
def Config_DHCP():
netconfigfile = ''
if os.path.exists('/etc/dhcpcd.conf'):
netprofile = netprofilepath+'dhcpcd.conf.bak'
netconfigfile = '/etc/dhcpcd.conf'
else:
netprofile = netprofilepath+'/NEOTEL.nmconnection.bak'
netconfigfile = '/etc/NetworkManager/system-connections/NEOTEL.nmconnection'
with open(netprofile, 'r') as f:
file_lines = f.readlines()
f.close()
with open(netconfigfile, 'w') as f:
# for line in file_lines:
f.writelines(file_lines)
f.flush()
f.close()
def Config_StaticIP(IPAddress, Router_IP):
netconfigfile = ''
if os.path.exists('/etc/dhcpcd.conf'):
netprofile = netprofilepath+'dhcpcd.conf.bak'
netconfigfile = '/etc/dhcpcd.conf'
with open(netprofile, 'r') as f:
file_lines = f.readlines()
f.close()
with open(netconfigfile, 'w') as f:
# for line in file_lines:
f.writelines(file_lines)
# f.write("static ip_address=" + str(request.args.get('new_ip')))
# interface eth0
#IPAddress = str(request.args.get('new_ip')
#Router_IP = str(request.args.get('new_ip')
f.write("interface eth0" + "\n")
if len(IPAddress) > 0:
f.write("static ip_address=" + IPAddress + "\n")
if len(Router_IP) > 0:
f.write("static routers=" + Router_IP + "\n")
# f.write("")
f.flush()
f.close()
else:
netprofile = netprofilepath+'/NEOTEL.nmconnection.bak'
netconfigfile = '/etc/NetworkManager/system-connections/NEOTEL.nmconnection'
with open(netprofile, 'r') as f:
file_lines = f.readlines()
f.close()
with open(netconfigfile, 'w') as f:
# for line in file_lines:
for line in file_lines:
f.write(line)
if line.startswith('[ipv4]') and len(IPAddress) > 0:
if len(Router_IP) > 0:
f.write('address1='+ IPAddress + ','+Router_IP+"\n")
else:
f.write('address1='+ IPAddress + "\n")
# f.write("static ip_address=" + str(request.args.get('new_ip')))
# interface eth0
#IPAddress = str(request.args.get('new_ip')
#Router_IP = str(request.args.get('new_ip')
f.flush()
f.close()
def reboot_after_delay():
# Wait for 5 seconds before rebooting
time.sleep(5)
os.system('sudo reboot')
def Reenable_NetworkService():
#os.system('sudo systemctl stop networking')
#os.system('sudo systemctl start networking')
#os.system('sudo systemctl stop dhcpcd.service')
#print("services stop")
#os.system('sudo ip addr flush dev eth0')
#os.system('sudo systemctl start dhcpcd.service')
# Wait for 3 seconds before rebooting
reboot_thread = Thread(target=reboot_after_delay)
reboot_thread.start()
return "Apply Successfully, System will reboot in 5 seconds"
#return "Raspberry Pi will reboot in 3 seconds"
#os.system('sudo reboot')
def netmask_to_length(netmask):
# Convert the netmask to a list of integers
netmask = [int(x) for x in netmask.split(".")]
# Count the number of set bits in the netmask
length = 0
for octet in netmask:
while octet > 0:
length += octet & 1
octet >>= 1
return length
@app.route('/ip_config',methods=['POST'])
def IP_Config():
dhcp_enabled = request.form.get('dhcp')
if dhcp_enabled:
Config_DHCP()
print("DHCP ENABLED")
else:
IP_ADDR = str(request.form.get('new_ip'))
print("input:",str(request.form.get('new_ip')))
Router_ADDR = str(request.form.get('router_ip'))
NET_MASK = str(request.form.get('new_mask'))
IP_ADDR +="/"+str(netmask_to_length(NET_MASK))
print(IP_ADDR)
print(Router_ADDR)
Config_StaticIP(IP_ADDR,Router_ADDR)
print(IP_ADDR,Router_ADDR)
print("IP CHANGED")
#Reenable_NetworkService()
#Response('Apply Successfully', status=200, mimetype='text/plain')
return Reenable_NetworkService()
#return #'Apply Successfully ' #{} with DHCP enabled: {}'.format(IP_ADDR, 'True' if dhcp_enabled else 'False')
#Config_StaticIP("192.168.1.59/24", "192.168.1.1")
#Reenable_NetworkService()
[connection]
id=NEOTEL
uuid=527c1020-2fdf-45c5-a3f5-1af22cbfdc70
type=ethernet
permissions=
[ethernet]
mac-address-blacklist=
[ipv4]
dns-search=
method=manual
[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.
# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel
# Inform the DHCP server of our hostname for DDNS.
hostname
# Use the hardware address of the interface for the Client ID.
clientid
# or
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
# Some non-RFC compliant DHCP servers do not reply with this set.
# In this case, comment out duid and enable clientid above.
#duid
# Persist interface configuration when dhcpcd exits.
persistent
# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit
# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Respect the network MTU. This is applied to DHCP routes.
option interface_mtu
# Most distributions have NTP support.
#option ntp_servers
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# Generate SLAAC address using the Hardware Address of the interface
#slaac hwaddr
# OR generate Stable Private IPv6 Addresses based from the DUID
slaac private
#interface wlan0
#static ip_address =10.174.92.33/24
#static routers=10.174.92.1
#static domain_name_servers=10.8.136.21
# Example static IP configuration:
#interface eth0
#static ip_address=192.168.10.100/24
#static ip6_address=fd51:42f8:caae:d92e::ff/64
#static routers=192.168.10.2
#static domain_name_servers=192.168.10.2 114.114.114.114 fd51:42f8:caae:d92e::1
# It is possible to fall back to a static IP if DHCP fails:
# define static profile
#profile static_eth0
#static ip_address=192.168.1.23/24
#static routers=192.168.1.1
#static domain_name_servers=192.168.1.1
# fallback to static profile on eth0
#interface eth0
#fallback static_eth0
import os
import sys
import qrcode
# from PIL import Image
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import numpy
from app import app
from flask import jsonify,render_template,request,send_from_directory
import matplotlib.font_manager as fm
import logging
code_path = '/prog/smartshelf/app/static/uploads'
def make_qrcode(file_code):
# for line in all_data:
# A_NUMBER = line[0]
# c_start = int(line[1])
# c_stop = int(line[2])
# dirs_str = deal_line_code(project_number,A_NUMBER,c_start,c_stop)
# resize(project_number,dirs_str)
# current_path_file=os.path.join(code_path,t_file)
qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=0)
qr.add_data(file_code)
qr.make(fit=True)
img = qr.make_image()
file = "{}/{}.png".format(code_path,file_code)
img.save(file)
# img1.save("./{}_qr_jpg/{}/{}.jpg".format(project_number,dirs_str,filename[:-4]))
return True
def resize(file_code):
# path = './{}_qr_png/{}'.format(project_number,dirs_str)
# path_list = os.listdir(path)
img1 = Image.open("{}/{}.png".format(code_path,file_code))
# img1 = Image.open("E:/qr_png/code/0/{}.png".format(filename))
img1 = img1.resize((300, 300),Image.ANTIALIAS)
# print (filename[:-4])
img1.save("{}/{}.jpg".format(code_path,file_code))
def deal_number(file_code):
print (file_code)
color = "White"
img_str = Image.new("RGB",(480,90),color)
img_str.save("{}/temp_number.jpg".format(code_path))
im = Image.open("{}/temp_number.jpg".format(code_path))
# font = ImageFont.truetype('simsun.ttc',55)
# font = ImageFont.truetype(fm.findfont(fm.FontProperties(family='DejaVu Sans')),63)
if os.path.isfile("/usr/share/fonts/truetype/dejavu/simsun.ttf"):
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/simsun.ttf",75)
draw = ImageDraw.Draw(im)
draw.text((50,20), file_code, font=font, fill='#000')
else:
font = ImageFont.truetype(fm.findfont(fm.FontProperties(family='DejaVu Sans')),75)
draw = ImageDraw.Draw(im)
draw.text((30,20), file_code, font=font, fill='#000')
# draw.text((60,13), filename, font=font, fill='#000') #602项目改动
im.save("{}/temp_number.jpg".format(code_path))
def paste(file_code):
color = 'white'
target = Image.new("RGB",(300,390),color)
# qr = Image.open("E:/qr_png/jpg_code/B/{}".format(filename))
# qr = Image.open("E:/code_tool/{}/{}/{}.jpg".format(source_path,path_str,filename))
qr = Image.open('{}/{}.jpg'.format(code_path,file_code))
im = Image.open('{}/temp_number.jpg'.format(code_path))
a = 0 # 图片距离左边的大小
b = 0 # 图片距离上边的大小
c = 300 # 图片距离左边的大小 + 图片自身宽度
d = 300 # 图片距离上边的大小 + 图片自身高度
target.paste(qr, (a, b, c, d))
e = 0
f = 300
# target.paste(im, (e, f))
target.save("{}/code_img_str.jpg".format(code_path))
targeta = Image.new("RGB",(480,480),color)
targetb = Image.open("{}/code_img_str.jpg".format(code_path))
targeta.paste(targetb, (90, 60))
targeta.paste(im, (0, 360))
targeta.save("{}/{}.jpg".format(code_path,file_code))
logging.warning("库位二维码生成成功:{}".format(file_code))
@app.route('/downqrcode/', methods=['GET','POST'], strict_slashes=False)
def downqrcode():
# file_code = '001-01-001'
file_code = str(request.args.get("code"))
make_qrcode(file_code)
resize(file_code)
deal_number(file_code)
paste(file_code)
c_path = '/prog/smartshelf/app/static/uploads/'
filename = '{}.jpg'.format(file_code)
if request.method == "GET":
if os.path.isfile(os.path.join(c_path, filename)):
return send_from_directory(c_path, filename, as_attachment=True)
\ No newline at end of file
import re
import time
import functools
import logging
import traceback
from app.utils.g import shelfconfig
s_detail = {}
test_state = False
def logtime(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
res = func(*args, **kwargs)
end = time.perf_counter()
print(f'函数 {func.__name__} 耗时 {(end - start) * 1000} ms')
return res
return wrapper
@logtime
def first_filter(origin_value):
cur_dict = transfer(origin_value)
return cur_dict,s_detail
def production_filter(origin_value):
cur_dict = transfer(origin_value)
return cur_dict
def transfer(origin_value):
cur_dict = {}
addrs=shelfconfig.addrs.split('@')
if origin_value:
try:
receive_data=origin_value.decode().split("\n")
for item in receive_data[::-1]:
if re.search('^A\d{1,2}\[[0-1]{100}\]$',item.strip())==None:
receive_data.remove(item)
print (item)
print("筛选后的数据:", receive_data)
if receive_data:
for line in receive_data:
line=line.strip()
# print ("-----------------line",line)
addr = re.search("(?<=A)\d{1,2}",line)
led = re.search("\[[0-1]{100}\]", line)
if led is None:
continue
if len(addr.group())==2:
if "B"+addr.group()[1] in addrs:
addrs.remove("B"+addr.group()[1])
else:
if "A"+addr.group() in addrs:
addrs.remove("A"+addr.group())
c_list = list(led.group())
# print ("-------------------c_list",c_list)
c_list.pop(0)
c_list.pop(-1)
keyword = 'A' + addr.group()
cur_dict[keyword] = c_list
except Exception as e:
logging.warning("读取传感器状态出错:{}".format(repr(e)))
logging.warning("当前解析值:{}".format(receive_data))
msg = traceback.format_exc()
logging.warning(msg)
if len(addrs)>0:
logging.warning("当前解析值2:{},{}".format(len(addrs),origin_value))
return None
return cur_dict
def change_deatil(old_dict):
global s_detail
if old_dict:
s_detail = old_dict
# print ('------------------------',s_detail)
def reset_value():
s_detail = {}
print (s_detail)
\ No newline at end of file
<script>
function switchLanguage(language){
$.ajax({
url: "/language/"+language,
type: "get",
//data: JSON.stringify(ionum),
//contentType: "application/json",
//dataType: 'json',
success: function (data) {
location.reload();
},
error: function (e) {
window.reload();
}
});
return false;
}
</script>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand" href="#">{{ _('感应式料架') }}</span>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li{{ " class=active" if index==1 }}><a href="{{ url_for('induction_control') }}">{{ _('通用') }}</a></li>
<li{{ " class=active" if index==2 }}><a href="{{ url_for('induction_test') }}">{{ _('测试') }}</a> </li>
<li{{ " class=active" if index==3 }}><a href="{{ url_for('induction_config') }}">{{ _('配置') }}</a> </li>
</ul>
<ul class="nav navbar-nav navbar-right" style="font-size: 14px;"">
<li>
<a href="#" onclick="return switchLanguage('zh');">简体中文</a>
</li>
<li>
<a href="#" onclick="return switchLanguage('en');">English</a>
</li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
</nav>
<div style="clear:both;"></div>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ _('感应式料架系统') }}</title>
<!-- <link rel="icon" href="/static/favicon.ico"> -->
<!-- <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> -->
<link rel="icon" href="/static/favicon.ico">
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
</head>
<body style="font-size:18px;">
{% set index=1 %}
{% import 'head.html' as head with context%}
{{ head }}
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<h2>{{ _('料架系统') }}</h2>
<hr class="divider">
<!-- 料架启动关闭 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">{{ _('开关') }}</h3>
</div>
<div class="panel-body">
<input type="button" value={{ _('启动') }} class="btn btn-info" onclick="startpost()"/>
<input type="button" value={{ _('停止') }} class="btn btn-warning" onclick="stoppost()"/>
</div>
</div>
<div id="panel-group">
<!-- 1 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{{ _('消息') }}</h3>
</div>
<div class="panel-body">
<div class="alert alert-info" role="alert">
<p>
{{ _('运行状态') }}:<span id="shelfstate"></span>
</p>
</div>
<!-- <div class="alert alert-info" role="alert">
<p>
{{ _('配置文件加载状态') }}:<span id="testinfo">{{ config_state }}</span>
</p>
</div> -->
<div class="alert alert-info" role="alert">
<p>
{{ _('服务器地址') }}:<span id="ipconfig"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
{{ _('料架序列号') }}:<span id="ccid"></span>
</p>
</div>
<!-- <div class="alert alert-info" role="alert">
<p>
{{ _('服务器连接状态') }}:<span id="poststate"></span>
</p>
</div> -->
<div class="alert alert-info" role="alert">
<p>
{{ _('串口状态') }}:<span id="serialstate"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
{{ _('服务器连接状态') }}:<span id="serverstate"></span>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<h2>{{ _('运行日志&状态信息') }}</h2>
<hr class="divider">
<!-- 日志下载 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">{{ _('日志下载') }}</h3>
</div>
<div class="panel-body">
<a type="button" class="btn btn-warning" href="{{ url_for('download') }}">{{ _('下载日志') }}</a>
</div>
</div>
<!-- 日志显示 -->
<!-- <div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">{{ _('日志') }}</h3>
</div>
<div class="panel-body">
<div id="logmsg" style="overflow:auto;height: 400px;background:#000; color:green"></div>
</div>
</div> -->
</div>
</div>
</div>
<script>
$(document).ready(function () {
getstate();
getauto();
console.log('success');
});
function startpost(){
$.ajax({
url:"/startpost",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
if (data[0].state == 'on') {$("#shelfstate").html("{{_('运行中')}}");}
else if (data[0].state == 'off') {$("#shelfstate").html("{{_('已关闭')}}");}
else {$("#shelfstate").html("{{_('未初始化')}}");}
// console.log(data)
alert (data[0].msg)
},
error:function(e){
alert("{{_('启动失败')}}");
}
})
}
function stoppost(){
// var form= new FormData(document.getElementById("test_form"));
var shelfstate = document.getElementById("shelfstate").value
console.log(shelfstate)
$.ajax({
url:"/stoppost",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
if (data[0].state == 'on') {$("#shelfstate").html("{{_('运行中')}}");}
else if (data[0].state == 'off') {$("#shelfstate").html("{{_('已关闭')}}");}
else {$("#shelfstate").html("{{_('未初始化')}}");}
console.log(data)
alert (data[0].msg)
},
error:function(e){
alert("{{_('停止失败')}}");
}
})
}
// 获取开机关机状态
function getstate(){
// var form= new FormData(document.getElementById("test_form"));
$.ajax({
url:"/getstate",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
console.log(data)
if (data[0].state == 'on') {$("#shelfstate").html("{{_('运行中')}}");}
else if (data[0].state == 'off') {$("#shelfstate").html("{{_('已关闭')}}");}
else {$("#shelfstate").html("{{_('未初始化')}}");}
// $("#gpioconfig").html(data[0].gpio)
$("#ipconfig").html(data[0].ipconfig['ip'])
$("#ccid").html(data[0].ipconfig['cid'])
$("#serialstate").html(data[0].serial_state)
},
error:function(e){
alert("{{_('未获取到状态信息')}}");
}
})
}
// 获取开机关机状态
function taillog(){
// var form= new FormData(document.getElementById("test_form"));
$.ajax({
url:"/taillog",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
$("#logmsg").html(data.msg)
// $("#poststate").html(data.poststate)
},
error:function(e){
}
})
}
// 获取服务器连接状态状态
function getauto(){
// var form= new FormData(document.getElementById("test_form"));
$.ajax({
url:"/getauto",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
$("#serverstate").html(data.msg)
console.log(data)
},
error:function(e){
//alert("{{_('未获取到状态信息')}}");
}
})
}
setInterval(function(){
// taillog();
getauto();
}, 3000);
</script>
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="/static/js/ipvalidate.js"></script>
<script>
function validateForm() {
var ipAddress = document.getElementById("new_ip").value;
var netmask = document.getElementById("new_mask").value;
var router = document.getElementById("router_ip").value;
var dhcp_check = document.getElementById("dhcp").checked
if (dhcp_check)
{
return true
}
// Check if the IP address and netmask are valid
if (!isValidIpAddress(ipAddress)) {
alert("Invalid IP address");
return false;
}
if (!isValidNetmask(netmask)) {
alert("Invalid netmask");
return false;
}
if (!isValidIpAddress(router)) {
alert("Invalid router address");
return false;
}
return true;
}
</script>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
}
form {
display: flex;
flex-direction: column;
margin:50px auto
}
div p {
font-size: 24px;
#font-weight: bold;
display: block;
margin: 20px auto;
}
input[type="text"], textarea {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
}
input[type="submit"] {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
display: block;
margin: 0 auto;
}
label, input, textarea {
margin-bottom: 10px;
}
label.remark-label {
font-size: 14px;
color: #999;
}
</style>
<title> </title>
</head>
<body>
<div >
<p> Network Configure</p>
<form action="/ip_config" method="post" onsubmit="return validateForm()">
IP Address: <input type="text" id="new_ip" name="new_ip"><label class="remark-label">For Example:192.168.10.10</label><br>
Network Mask: <input type="text" id="new_mask" name="new_mask"><label class="remark-label">For Example:255.255.255.0</label><br>
Default GateWay: <input type="text" id="router_ip" name="router_ip"><label class="remark-label">For Example:192.168.10.1</label><br>
<label for="dhcp">Enable DHCP:
<input type="checkbox" name="dhcp" id="dhcp"></label><br>
<div style="margin:50px auto;width:200px;">
<input type="submit" value="Submit">
</div>
</form>
</div>
</body>
</html>
\ No newline at end of file
import pickle
import os
import string
from config import Config
current_state: string
current_state='off'
Serl = None
basepath = os.path.dirname(__file__)
shelfconfigfile = basepath+"/../" + Config.STATE_PATH+'shelfconfig.pkl'
def ver():
return "1.873"
class _shelfconfig:
def __init__(self):
self.server_addr ="not_config"
self.serial_port="not_config"
self.cid="not_config"
self.addrs="not_config"
self.after_instore_close_light=False
self.after_instore_light_color='orange'
self.comport_carsh_timeout=30
self.comport_carsh_reboot=False
self.after_induction_preshow_color='white'
self.inok_blink_times=4;
def Save(self):
with open(shelfconfigfile, 'wb') as f:
pickle.dump(self, f)
shelfconfig:_shelfconfig
shelfconfig = _shelfconfig()
if os.path.exists(shelfconfigfile):
with open(shelfconfigfile, 'rb') as f:
a = pickle.load(f)
for it in a.__dict__.items():
if it[0].find('__')>=0 or it[0]=='Save':
continue
if shelfconfig.__dict__.get(it[0]) is not None:
shelfconfig.__dict__[it[0]]=a.__dict__[it[0]]
print("shelfconfig",shelfconfig.__dict__.items())
'''
@ author: jie
@ tools: pycharm
@ content: 库位操作类
@ date: 2021.6.02
'''
import logging
import os
import csv
from config import Config
class Location():
def __init__(self):
# self.basepath = os.path.dirname(__file__)
self.uploads_path = Config.UPLOAD_FOLDER
def read_location_file(self):
config_dict = {}
convert_dict = {}
try:
with open(self.uploads_path +'/linePositions.csv', 'r',encoding='gbk') as f:
reader = csv.reader(f)
head = next(reader)
# lines = f.readlines()[1:]
for row in reader:
row[1]=row[1].replace('B','A1')
config_dict[row[0]] = row[2]+'@'+row[1]+'@'+row[3]
convert_dict[row[3]+'@'+row[1]] = row[2]+'@'+row[1]+'@'+row[0]
# led_addr_dict[row[2]+'@'+row[1]] = row[0]+'@'+row[3]
# option_list.append(row[0])
# logging.warning("配置文件加载成功...")
except Exception as e:
print (e)
# logging.warning("配置文件加载失败,请上传配置文件")
return config_dict,convert_dict
def init_location_option(self):
config_location,covert = self.read_location_file()
option_list = list(config_location.keys())
return option_list
def production_location_init(self):
locations = {}
print (locations)
config_location,convert_dict = self.read_location_file()
print (config_location)
print (convert_dict)
# 从配置表获取库位,初始化库位
for loc,values in config_location.items():
c_value = {
'addr':values.split('@')[1],
'led_index':int(values.split('@')[0]),
'sensor_index':int(values.split('@')[2]),
'in_blink':False,
'out_blink':False,
# 'loc_inlocation':False,
'inloc_ng':False,
'outloc_ng':False,
'color':'off',
# 'guide_locin':False,
'blink':False,
'blink_num':0,
'action':False
}
locations[loc] = c_value
return locations
......@@ -8,7 +8,7 @@ import serial
import serial.tools.list_ports
import logging
from config import Config
from serial_config import ReadConfig
#from serial_config import ReadConfig
from flask_babel import Babel, gettext as _
class Communication():
......
'''
@ author: jie
@ tools: pycharm
@ content: 串口通讯实现类
@ date: 2021.5.10
'''
import imp
import time
import serial
#import serial.tools.list_ports
import logging
from config import Config
import app.utils.g as gg
from app.utils.g import shelfconfig
from flask_babel import Babel, gettext as _
class SerialCommunication():
def __init__(self):
# print(gg.Serl)
#global serl
# serial_cf = ReadConfig()
# self.port = serial_cf.get_serial("DEFAULT_COM")
# self.bps = int(serial_cf.get_serial("DEFAULT_BAUDRATE"))
# self.timeout = float(serial_cf.get_serial("DEFAULT_TIMEOUT"))
# self.port = read_com()
# self.uploads_path = Config.UPLOAD_FOLDER
self.serialstate="串口连接正常"
with open(Config.IP_PATH + "/serialcom.txt", "r") as f:
serialcom = f.read()
self.port = serialcom.strip("\n")
self.bps = 115200
self.timeout = 1
if gg.Serl is None:
try:
if self.port.lower().endswith("n"):
self.TryConnectSerial()
else:
gg.Serl = serial.Serial(port=self.port, baudrate=self.bps, timeout=self.timeout)
#if not gg.Serl.is_open:
# gg.Serl.open()
log("串口已打开1")
except Exception as e:
log("---异常---:", e)
self.main_engine = gg.Serl
def TryConnectSerial(self):
if not self.port.lower().endswith("n"):
return
try:
self.main_engine.close()
except:
log("main_engine 关闭失败")
if not self.findSerial(self.port.strip('n').strip('N')):
log("无法定位串口,系统重启.")
shelfconfig.comport_carsh_reboot=True
shelfconfig.Save()
time.sleep(1)
import os
os.system('sudo reboot')
def findSerial(self, portpre):
trytimes = 0
while trytimes < shelfconfig.comport_carsh_timeout /5:
for i in range(0, 5):
try:
currentport = portpre+str(i)
log("尝试打开串口:{}".format(currentport))
gg.Serl = serial.Serial(port=currentport, baudrate=self.bps, timeout=self.timeout)
#if not gg.Serl.is_open:
# gg.Serl.open()
# 判断是否打开成功
gg.Serl.write(bytes("A1\n".encode('utf-8')))
self.main_engine=gg.Serl
log("成功打开串口:{}".format(currentport))
self.serialstate="串口连接正常"
return True
except Exception as e:
log("串口打开失败:", currentport, e)
self.serialstate=e
trytimes += 1
time.sleep(5)
log("串口打开失败,第{}次重试".format(trytimes))
return False
# 打印设备基本信息
def print_name(self):
print(self.main_engine.name) # 设备名字
print(self.main_engine.port) # 读或者写端口
print(self.main_engine.baudrate) # 波特率
print(self.main_engine.bytesize) # 字节大小
print(self.main_engine.parity) # 校验位
print(self.main_engine.stopbits) # 停止位
print(self.main_engine.timeout) # 读超时设置
print(self.main_engine.writeTimeout) # 写超时
print(self.main_engine.xonxoff) # 软件流控
print(self.main_engine.rtscts) # 软件流控
print(self.main_engine.dsrdtr) # 硬件流控
print(self.main_engine.interCharTimeout) # 字符间隔超时
# 打开串口
def Open_Engine(self):
self.main_engine.open()
# 关闭串口
def Close_Engine(self):
self.main_engine.close()
print(self.main_engine.is_open) # 检验串口是否打开
# 打印可用串口列表
def get_used_port(self):
port_list = list(serial.tools.list_ports.comports())
# print(port_list)
return port_list
# 检查串口连接状态
def check_serial(self):
try:
if (self.main_engine.is_open):
return _(self.serialstate)
else:
return _('串口连接失败')
except Exception as e:
error_msg = 'Error,{}'.format(e)
return error_msg
# 接收指定大小的数据
# 从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。
def read_Size(self, size):
return self.main_engine.read(size=size)
# 接收一行数据
# 使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。
# 如果没有超时,readline会报异常。
def read_Line(self):
line = self.main_engine.readline().decode('utf-8').rstrip()
return line
# 未使用
def read_Lines(self):
line = self.main_engine.readlines()
return line
def read_alldata(self):
try:
print("in_waiting",self.main_engine.in_waiting)
data=bytes(bytes("".encode('utf-8')))
while self.main_engine.in_waiting:
data=data+ self.main_engine.read_all()
time.sleep(0.06)
return data
except Exception as e:
log('串口读取数据错误,{}'.format(e))
self.TryConnectSerial()
self.serialstate=e
return bytes(bytes("".encode('utf-8')))
# 未使用
def read_hex_data(self):
if self.main_engine.in_waiting:
data = self.main_engine.read_all()
# data= str(binascii.b2a_hex(t.read(num)))[2:-1] #十六进制显示方法2
# 发数据
def send_data(self, data, wait=True):
# self.main_engine.flushInput()
# self.main_engine.flushOutput()
# text = '{"ADDR":"99","colorset:[[1,255,0,0],[2,0,255,255],[5,132,142,110]]}\n{"ADDR":"1","color":[[1,10,20,30],[2,31,37,49],[5,1,3,5,7,9,11,14,18]]}\n{"ADDR":"3","color":[[1,10,20,30],[2,31,37,49],[5,1,3,5,7,9,11,14,18]]}\n'
try:
print("out_waiting",self.main_engine.out_waiting,'send_data:'+data.replace('\n','\\n')+"EOF")
commands = data.split("\n")
for cmd in commands:
if len(cmd)==0:
continue;
cmd=cmd+"\n"
cmd = bytes(cmd.encode('utf-8'))
self.main_engine.write(cmd)
time.sleep(0.03)
if wait:
self.main_engine.flush()
except Exception as e:
log('串口发送数据错误,{}'.format(e))
self.TryConnectSerial()
# 十六进制数据发送
# 未使用
def send_hex_data(self, data):
data = bytes(data.encode('utf-8')) # 先将输入的字符串转化成字节码
hexstring = data.hex()
self.main_engine.write(hexstring)
# 更多示例
# self.main_engine.write(chr(0x06).encode("utf-8")) # 十六制发送一个数据
# print(self.main_engine.read().hex()) # # 十六进制的读取读一个字节
# print(self.main_engine.read())#读一个字节
# print(self.main_engine.read(10).decode("gbk"))#读十个字节
# print(self.main_engine.readline().decode("gbk"))#读一行
# print(self.main_engine.readlines())#读取多行,返回列表,必须匹配超时(timeout)使用
# print(self.main_engine.in_waiting)#获取输入缓冲区的剩余字节数
# print(self.main_engine.out_waiting)#获取输出缓冲区的字节数
# print(self.main_engine.readall())#读取全部字符。
# 未使用
def Recive_data(self, way):
# 循环接收数据,此为死循环,可用线程实现
print("开始接收数据:")
while True:
try:
# 一个字节一个字节的接收
if self.main_engine.in_waiting:
if(way == 0):
for i in range(self.main_engine.in_waiting):
print("接收ascii数据:"+str(self.Read_Size(1)))
data1 = self.Read_Size(1).hex() # 转为十六进制
# 转为十进制print("收到数据十六进制:"+data1+" 收到数据十进制:"+str(data2))
data2 = int(data1, 16)
if(way == 1):
# 整体接收
# data = self.main_engine.read(self.main_engine.in_waiting).decode("utf-8")#方式一
data = self.main_engine.read_all() # 方式二print("接收ascii数据:", data)
except Exception as e:
print("异常报错:", e)
def log(*values: object):
print(values)
logging.warning(values)
# if __name__ == '__main__':
# myser = Communication("/dev/ttyUSB0",115200,1)
# myser.print_name()
# myser.get_used_port()
# myser.delete_port()
# myser.show_port()
'''
@ author: jie
@ tools: pycharm
@ content: 服务器通讯实现类
@ date: 2021.6.3
'''
import logging
from config import Config
import requests
class ServerCommunication():
def __init__(self):
self.ip_path = Config.IP_PATH
self.ip_config = {}
try:
with open(self.ip_path + 'ipconfig.csv', 'r') as f:
reader = csv.reader(f)
current = [row for row in reader]
self.ip_config['ip'] = current[0][0]
self.ip_config['cid'] = current[0][1]
logging.warning("ip&cid...:{}".format(self.ip_config))
except Exception as e:
logging.warning("ip,cid配置失败:{}".format(e))
def server_post(self,body):
ip_config = self.ip_config
url = ip_config['ip']
cid = ip_config['cid']
headers = {'content-type': "application/json"}
try:
response = requests.post(url, data = json.dumps(data), headers = headers,timeout=2)
json_data = response.json()
except Exception as e:
logging.warning("服务器通信失败:{}".format(e))
import functools
def logtime(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
res = func(*args, **kwargs)
end = time.perf_counter()
print(f'函数 {func.__name__} 耗时 {(end - start) * 1000} ms')
return res
return wrapper
\ No newline at end of file
import os
import logging
from datetime import timedelta
# 实例化configParser对象
# from dotenv import load_dotenv
basedir = os.path.abspath(os.path.dirname(__file__))
# load_dotenv(os.path.join(basedir, '.env'))
class Config(object):
#SEND_FILE_MAX_AGE_DEFAULT = timedelta(seconds=-1)
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
URL = 'http://192.168.1.100:8080/service/store/communication'
UPLOAD_FOLDER = '/prog/smartshelf/app/static/uploads'
IP_PATH = '/prog/smartshelf/app/state'
STATE_PATH = '/state/'
ALLOWED_EXTENSIONS = set(['csv']) #限制上传文件格式
LOG_LEVEL = logging.WARNING
LOG_FOLDER = 'logs/smart.log'
DEFAULT_COLOR = 'red'
DEFAULT_COM = "/dev/ttyUSB0"
DEFAULT_BAUDRATE = 115200
DEFAULT_TIMEOUT = 0.5
COLORS = {
'red':[1,125,0,0],
'yellow':[2,125,125,0],
'blue':[3,0,0,125],
'green':[4,0,125,0],
'orange':[5,255,97,0],
'cyan':[6,0,125,125],
'firebrick':[7,116,22,22],
'purple':[8,155,48,255],
'skyblue':[9,108,166,205],
'pink':[10,255,20,147],
'forestgreen':[11,34,139,34],
'lightblue':[12,132,112,255],
'indianred':[13,139,58,58],
'darkgreen':[14,0,90,0],
'white':[15,125,125,125],
'off':[16,0,0,0],
'magenta':[17,125,125,0],
'#ff0000':[51,255,0,0],
'#ffc0cb':[52,255,192,203],
'#c71585':[53,199,21,133],
'#ff8c00':[54,255,140,0],
'#ffff00':[55,255,255,0],
'#bdb76b':[56,189,183,107],
'#e6e6fa':[57,230,230,250],
'#9370db':[58,147,112,219],
'#800080':[59,128,0,128],
'#adff2f':[60,173,255,47],
'#98fb98':[61,52,251,152],
'#008000':[62,0,128,0],
'#808000':[63,128,128,0],
'#00ffff':[64,0,255,255],
'#7fffd4':[65,127,255,212],
'#b0c4de':[66,176,196,222],
'#0000ff':[67,0,0,255],
'#ffe4c4':[68,255,228,196],
'#f4a460':[69,244,164,96]
}
\ No newline at end of file
此文件类型无法预览
此文件太大,无法显示。
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!