轻量级按(安)灯系统python实现
按灯系统是精益生产常用的工具之一
传统使用软件+硬件搭建系统,本案例使用python的标准库纯软件实现。
python主要标准库及功能
tkinter UI界面
socket 服务端/客户端通信
sqlite 数据保存
本案例实现了按灯的基本功能,后续可进行扩展:
如可以根据按灯保存的数据使用python第三方库matplotlib实现可视化功能。
统计:机器异常种类,异常持续时间,间隔等
客户端代码:
from tkinter import *
import os
from random import randint
import socket, threading
import tkinter.ttk
from datetime import datetime
root = Tk()
width = 600
height =470
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2)
root.geometry(alignstr)
root.title("MyAndon")
root.resizable(0,0)
root.iconbitmap(".\\pic\\smart.ico")
one = Label(root, text="© Powered by Will Wu "+"2020-"+str(datetime.now().year), width=30, height=2, font=("Arial", 10))
one.pack(side=BOTTOM)
f1=LabelFrame(root,text="CNC_状态",labelanchor="n" )
f1.place(x=30,y=10,width=215,height=400)
cv = Canvas(f1)
cv.place(x=0,y=10,width=200,height=200)
green_button = PhotoImage(file = ".\\pic\\greenlight.png")
red_button = PhotoImage(file = ".\\pic\\redlight.png")
btn = cv.create_image(150, 0, anchor=NE, image=green_button)
def flashr():
global c
cv.itemconfigure(btn, image=[red_button,green_button][randint(0,1)])
c=root.after(500, flashr)
def combine():
send_content("N")
flashr()
def cancel_red():
send_content("Y")
root.after_cancel(c)
cv.itemconfigure(btn, image=green_button)
def get_local_ip(): #获取当前计算机的IP地址
local_ip = ""
try:
socket_objs = [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]
#print(socket_objs[0][1])
ip_from_ip_port = [(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in socket_objs][0][1]
ip_from_host_name = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1]
local_ip = [l for l in (ip_from_ip_port, ip_from_host_name) if l][0]
except (Exception) as e:
print("get_local_ip found exception : %s" % e)
return local_ip if("" != local_ip and None != local_ip) else socket.gethostbyname(socket.gethostname())
def connectServer():
global ck
#ipStr = eip.get()
ipStr = termhost.get()
print(ipStr)
portStr = eport.get()
userStr = comboNO.get()
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#socked所遵守ipv4或ipv6,和相关协议的
client.connect((ipStr, int(portStr)))#连接ip和端口号!!!1:注意输入的端口号是str型而这里的要传入int型 #是服务器地址
client.send(userStr.encode("utf-8"))
ck = client
t = threading.Thread(target=getInfo)
t.start()
def getInfo(): #后续使用
while True:
data = ck.recv(1024)#用于接收服务器发送的信息
text.insert(tkinter.INSERT, data.decode("utf-8"))#显示在信息框上
def send_content(signal):
userStr = comboNO.get()
sendStr = combo_abnormal.get()
sendStr = userStr+ ":" +signal+":" + sendStr+"\n"
ck.send(sendStr.encode("utf-8"))
photo1 = PhotoImage(file=os.getcwd()+".\\pic\\machine.png")
theLabel = Label(f1,justify=CENTER,image=photo1,compound=CENTER,fg="white")
theLabel.place(x=0,y=130,width=200,height=200)
photog = PhotoImage(file=os.getcwd()+".\\pic\\green.png")
photor = PhotoImage(file=os.getcwd()+".\\pic\\red.png")
buttonGeen=Button(f1,image=photog,command=cancel_red)
buttonGeen.place(relx=0,rely=0.85)
buttonRed=Button(f1,image=photor,command=combine)
buttonRed.place(relx=0.66,rely=0.85)
f2=LabelFrame(root,text="信息传递",labelanchor="n")
f2.place(x=300,y=10,width=230,height=400)
labelName = Label(f2, text='机器编号').place(relx=0,rely=0.01,width=60,height=20)
labelIp = Label(f2, text='本机ip').place(relx=0,rely=0.1,width=40,height=20)
labelPort = Label(f2, text='port').place(relx=0,rely=0.2,width=40,height=20)
TermIp = Label(f2, text='终端ip').place(relx=0,rely=0.3,width=40,height=20)
labeltext = Label(f2, text='发送消息').place(relx=0.0,rely=0.5,width=60,height=30)
eip =Variable()
eip.set(get_local_ip())
eport = Variable()
eport.set("9999")
var_NO=["M001","M002","M003","M004","M005","M006","M007","M008"]
termhost=Variable()
termhost.set(get_local_ip())
var_abnormal=["机器不工作","尺寸超差","缺料"]
comboNO = tkinter.ttk.Combobox(f2,value=tuple(var_NO))
comboNO.place(relx=0.3,rely=0.01,width=150,height=20)
comboNO.set("M001")
combo_abnormal=tkinter.ttk.Combobox(f2,value=tuple(var_abnormal))
combo_abnormal.place(relx=0,rely=0.6,relwidth=0.99,height=20)
combo_abnormal.set("正常")
entryIp = Entry(f2, textvariable=eip).place(relx=0.3,rely=0.1,width=150,height=20)
entryPort = Entry(f2, textvariable=eport).place(relx=0.3,rely=0.2,width=150,height=20)
entryterm = Entry(f2, textvariable=termhost).place(relx=0.3,rely=0.3,width=150,height=20)
button = Button(f2, text="连接服务器", command=connectServer).place(relx=0.3,rely=0.8,width=100,height=30) #1启动服务器按钮
text = Text(f2, height=5, width=30)
root.mainloop()
服务端代码:
kinter
import socket, threading
import datetime
import time
import sqlite3
import os
root = tkinter.Tk() # 创建主窗口
root.title('模拟服务器')
root.geometry("400x300+200+20")
root.resizable(0,0)
root.iconbitmap(".\\pic\\smart.ico")
users = {}#用户字典,也可以连接数据库
class lightFrame: #构造灯类,每个灯代表一台机器
def __init__(self,name,pic,x,y):
self.name=name
self.pic=pic
self.x=x-0.1
self.y=y+0.4
fx=tkinter.LabelFrame(root,text=self.name)
fx.place(relx=self.x,rely=self.y,relwidth=0.2,relheight=0.23)
self.photo0 = tkinter.PhotoImage(file=self.pic)
theLabel = tkinter.Label(fx,image=self.photo0,fg="white")
theLabel.pack()
def create_db(tablename):
conn=sqlite3.connect(".\\db\\abnormal_log.db")
c=conn.cursor()
content="id INTEGER PRIMARY KEY AUTOINCREMENT ,Keyindate DATE,Machine TEXT,Signal TEXT,Description TEXT" #拼接字段语句
sql="CREATE TABLE IF NOT EXISTS"+chr(32)+tablename+chr(32) +"("+content+")"
c.execute(sql)
conn.commit()
conn.close()
def insert_to_db(table_name,value):
conn=sqlite3.connect(".\\db\\abnormal_log.db")
c=conn.cursor()
content="Keyindate,Machine,Signal,Description"
sql="INSERT INTO"+chr(32)+ table_name +chr(32)+ "("+content+")"+"VALUES"+"("+value+")"
#print(sql)
c.execute(sql)
conn.commit()
conn.close()
def get_local_ip(): #获取当前计算机的IP地址
local_ip = ""
try:
socket_objs = [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]
ip_from_ip_port = [(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in socket_objs][0][1]
ip_from_host_name = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1]
local_ip = [l for l in (ip_from_ip_port, ip_from_host_name) if l][0]
except (Exception) as e:
print("get_local_ip found exception : %s" % e)
return local_ip if("" != local_ip and None != local_ip) else socket.gethostbyname(socket.gethostname())
def run(ck, ca):
userName = ck.recv(1024)#接收客户端发送的信息以1k作为单位这里接受到的信息为byte类型,收到用户名(发起用户)
users[userName.decode("utf-8")] = ck#解码并储存用户的信息
printStr = "" + userName.decode("utf-8") + "连接\n"#在连接显示框中显示是否连接成功
text.insert(tkinter.INSERT, printStr)
while True:
rData = ck.recv(1024)#接收客户端发送的信息以1k作为单位这里接受到的信息为byte类型
dataStr = rData.decode("utf-8")
infolist = dataStr.split(":") #将接收的内容分割
text.insert(tkinter.INSERT,dataStr)
date=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
value="'"+date+"','"+userName.decode("utf-8")+"','"+infolist[1]+"','"+infolist[2] +"'"
create_db("abnormal_log")
insert_to_db("abnormal_log",value)
#print("ck",ck)
if infolist[1]=="N":
if 0.2*int(userName.decode("utf-8")[3])<0.9:
f=lightFrame(userName.decode("utf-8"),".\\pic\\red.png",0.2*int(userName.decode("utf-8")[3]),0) #M001[3]
else:
f=lightFrame(userName.decode("utf-8"),".\\pic\\red.png",0.2*int(userName.decode("utf-8")[3])-0.8,0.25)
else:
if 0.2*int(userName.decode("utf-8")[3])<0.9:
f=lightFrame(userName.decode("utf-8"),".\\pic\\green.png",0.2*int(userName.decode("utf-8")[3]),0)
else:
f=lightFrame(userName.decode("utf-8"),".\\pic\\green.png",0.2*int(userName.decode("utf-8")[3])-0.8,0.25)
def start():#3
ipStr = eip.get()#从输入端中获取ip
portStr = eport.get()#从输入端中获取端口,注意端口取得时候不能被占用(可以取8080,9876,等)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#socked
server.bind((ipStr, int(portStr)))#绑定ip和端口号
server.listen(10)#设置监听,和设置连接的最大的数量
printStr = "服务器启动成功\n"#,是否连接成功
text.insert(tkinter.INSERT, printStr)#显示在信息窗口中
while True:#这里用死循环是因为模拟的服务器要一直运行
ck, ca = server.accept()
t = threading.Thread(target=run, args=(ck, ca))
t.start()
def startSever():
s = threading.Thread(target=start)#启用一个线程开启服务器
s.start()
labelIp = tkinter.Label(root, text='ip').place(relx=0.1,rely=0.01,width=30,height=20)
labelPort = tkinter.Label(root, text='port').place(relx=0.1,rely=0.1,width=30,height=20)
eip =tkinter.Variable()
eip.set(get_local_ip())
eport = tkinter.Variable()
eport.set("9999")
scr=tkinter.Scrollbar(root)
#scr.grid(row=7)
scr.place(relx=0.8,rely=0.2)
entryIp = tkinter.Entry(root, textvariable=eip).place(relx=0.2,rely=0.01,width=100,height=20)
entryPort = tkinter.Entry(root, textvariable=eport).place(relx=0.2,rely=0.1,width=100,height=20)
button = tkinter.Button(root, text="启动", command=startSever).place(relx=0.5,rely=0.03,width=60,height=30) #1启动服务器按钮
labeltext = tkinter.Label(root, text='连接消息').place(relx=0.05,rely=0.2,width=60,height=20)
text = tkinter.Text(root,yscrollcommand=scr.set)
text.place_configure(relx=0.2,rely=0.2,width=230,height=60)
'''text = tkinter.Text(root, height=5, width=5,yscrollcommand=scr.set)
text.grid(row=7, column=1)'''
root.mainloop()

6442

被折叠的 条评论
为什么被折叠?



