import face_recognition
import cv2
import numpy as np
import os
import os.path
import itertools
import multiprocessing
from PIL import Image,ImageDraw,ImageFont
from face_recognition.face_recognition_cli import image_files_in_folder
import time
import datetime
import re
import face_recognition.api as face_recognition
import sys
import json
# 初始化一些变量
face_locations = []
face_encodings = []
face_names = []
known_people_folder = r'/home/simon/mqtt/picture'
known_face_names = []
known_face_encodings = []
b = []#role:1(Admin管理员)2(User用户)3(Guest访客)
c = []#userid
t = []#存进门的时间戳
doorState = "close"#门的状态
idrole = 0#初始化由userid查找出的对应role
with open("/home/simon/mqtt/"+"shadow.ini","r") as mj:
mess = mj.read()
mess_parsed = json.loads(mess)
state_f = mess_parsed['payload']['state']['reported']['state']
state = int(state_f) #门禁状态state=0(正常)1(常开)2(常闭)3(仅管理员模式)4(禁止访客开门)
facelist = mess_parsed['payload']['state']['reported']['faceList']
start = time.time()
for i in facelist:
role = i['role']
userid = i['userId']
b.append(int(role))
c.append(int(userid))#将role和userid对应存起来
t.append(int(0))#将进门的时间戳和userid对应存起来,初始时间戳都设为int(0)
#加载文件夹中的图片
def scan_known_people(known_people_folder,known_face_names,known_face_encodings):
with open("/home/simon/mqtt/"+"connect.txt","r") as a:
connect = a.read()
if(connect==str(1)):
known_face_names = []
known_face_encodings = []
with open("/home/simon/mqtt/"+"connect.txt","w") as b:
b.write(str(5))
for file in os.listdir(known_people_folder):
d = os.path.basename(file)#图片名加后缀
basename = os.path.splitext(d)[0]#图片名
#print(basename)
if basename in known_face_names:
continue
img = cv2.imread(known_people_folder+"/"+file)
encodings = face_recognition.face_encodings(img)
known_face_names.append(basename)#任务名称的集合
print(known_face_names)
known_face_encodings.append(encodings[0])#已知人脸的编码集合
#print(known_face_names)
return known_face_names, known_face_encodings
def cv2ImgAddText(img,text,left,top,textColor,textSize):
if(isinstance(img,np.ndarray)):
img=Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
draw =ImageDraw.Draw(img)
ttf="/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc" #linux中的中文字体格式一般在/usr/share/fonts/opentype/noto下
fontStyle=ImageFont.truetype(ttf,textSize,encoding="utf-8")
draw.text((left,top),text,textColor,font=fontStyle)
return cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)
def face():
#获取对网络摄像头 #0 的引用(默认)
video_capture = cv2.VideoCapture(0)
#global idrole
namestart = "未知"
fangdouname = "未知"
show_num = 0
start = time.time()
process_this_frame = True
shibie_frame = False#用来在屏幕上显示开门
global known_face_names
global known_face_encodings
print("state:")
print(state)
while True:
ret, frame = video_capture.read()# 抓取一帧视频
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)# 将视频帧调整为 1/4 大小以加快人脸识别处理
rgb_small_frame = small_frame[:, :, ::-1] # 将图像从 BGR 颜色(OpenCV 使用的)转换为 RGB 颜色(face_recognition 使用的)
# 只处理每隔一帧的视频以节省时间
known_face_names, known_face_encodings = scan_known_people(known_people_folder,known_face_names,known_face_encodings)#加载文件夹中的图片
#print(known_face_names)
#print(known_face_names)
if process_this_frame:
# 查找当前视频帧中的所有人脸和人脸编码/根据encoding来判断是不是同一个人,是就输出true,不是为false
face_locations = face_recognition.face_locations(rgb_small_frame)#获得所有人脸位置
if face_locations:
face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)#获得人脸特征值
face_names = []#存储出现在画面中人脸的名字
for face_encoding in face_encodings:
# 查看人脸是否与已知人脸匹配/默认为unknown
matches = face_recognition.compare_faces(known_face_encodings, face_encoding,tolerance=0.4)
facename = "未知"
name = facename.encode("utf-8").decode("utf-8") #转为汉字
# 如果在 known_face_encodings 中找到匹配,则使用与新人脸距离最小的已知人脸
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
facename = known_face_names[best_match_index]
name = facename.encode("utf-8").decode("utf-8") #转为汉字
if(facename==fangdouname):
fangdouname = facename
face_names.append(facename)
now_time=datetime.datetime.now()
nowtime = datetime.datetime.strftime(now_time,'%Y-%m-%d %H:%M:%S')
if(state==0):#正常
now = time.time()
namestart = facename
timenow = int(round(now*1000))#ms级时间戳
namenum = re.sub("\D","",name)#只传id
#识别出的人脸已知时保存数据
if(namenum):
#循环userid的数组确定对应的时间戳
key1 = len(c)-1
while(key1>=0):
if(c[key1]==int(namenum)):
if(t[key1]==int(0)):#第一次进门
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:#不是第一次进门
itime = t[key1]
#判断当前人员与前一次进门是否相差规定时间
if((timenow-itime)>=360000):#5分钟内不能重复识别#1秒相差1200左右
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:
doorState = "close"
#shibie_frame = False
break
key1 =key1-1
else:
doorState = "close"
#shibie_frame = False
if(state==1):#常开
doorState = "open"
start = time.time()
namestart = facename
timenow = int(round(start*1000))
namenum = re.sub("\D","",name)#只传id
#识别出的人脸已知时保存数据
if(namenum):namenum = namenum
else:namenum = 0#识别出未知传送0
#循环userid的数组确定对应的时间戳
key1 = len(c)-1
while(key1>=0):
if(c[key1]==int(namenum)):
if(t[key1]==int(0)):#第一次进门
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:#不是第一次进门
itime = t[key1]
#判断当前人员与前一次进门是否相差规定时间
if((timenow-itime)>=360000):
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:
pass
#shibie_frame = False
break
key1 =key1-1
if(state==2):#常闭
doorState = "close"
shibie_frame = False
if(state==3):#仅管理员可开门
start = time.time()
namestart = facename
timenow = int(round(start*1000))
namenum = re.sub("\D","",name)#只传id
#识别出的人脸已知时保存数据
if(namenum):
#循环userid的数组确定对应的role和时间戳
key1 = len(c)-1
while(key1>=0):
if(c[key1]==int(namenum)):
idrole = b[key1]
itime = t[key1]
if(idrole==int(1)):
if(itime==int(0)):#第一次进门
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:#不是第一次进门
#判断当前人员与前一次进门是否相差规定时间
if((timenow-itime)>=360000):
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:
doorState = "close"
#shibie_frame = False
else:
doorState = "close"
#shibie_frame = False
break
key1 =key1-1
else:
doorState = "close"
#shibie_frame = False
if(state==4):#禁止访客开门
start = time.time()
namestart = facename
timenow = int(round(start*1000))
namenum = re.sub("\D","",name)#只传id
#识别出的人脸已知时保存数据
if(namenum):
#循环userid的数组确定对应的role
key1 = len(c)-1
while(key1>=0):
if(c[key1]==int(namenum)):
idrole = b[key1]
itime = t[key1]
if(idrole==int(1) or int(2)):
if(itime==int(0)):#第一次进门
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:#不是第一次进门
#判断当前人员与前一次进门是否相差规定时间
if((timenow-itime)>=360000):
nameandtime = {"name":namenum,"timestamp":timenow}
with open("/home/simon/mqtt/"+"FaceAndTime.json","a+") as p:
p.write(json.dumps(nameandtime)+"\n")
doorState = "open"
shibie_frame = True
t[key1] = timenow#更新时间戳
else:
doorState = "close"
#shibie_frame = False
else:
doorState = "close"
#shibie_frame = False
break
key1 =key1-1
else:
doorState = "close"
#shibie_frame = False
else:
doorState = "close"
#shibie_frame = False
# 显示结果
for (top, right, bottom, left), facename in zip(face_locations, face_names):
# 缩放人脸位置,因为我们检测到的帧被缩放到 1/4 大小
top *= 4
right *= 4
bottom *= 4
left *= 4
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)# 在脸部周围画一个框
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) # 在人脸下方画一个带有名字的标签
namec = ''.join(re.findall('[\u4e00-\u9fa5]',name))#只显示名字不显示id
nameAndtime = namec + ' ' + nowtime + ' '
img = cv2ImgAddText(frame, nameAndtime, (left + 6), (bottom - 30), (255, 255, 255), 20)#调用的函数
if(shibie_frame):
if(show_num==0):
show_num+=1
show_name = namec
else:
if(show_num==2):
show_num=0
shibie_frame = False
else:
show_num+=1
(H,W) = frame.shape[:2]
rec = (H,W)
width = 1000#框的大小
height = 150
(w,h) = (width,height)
(x,y) = (int((rec[1]-width)/2),int((rec[0]-height)/2))
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), cv2.FILLED)
image1=cv2ImgAddText(frame,("欢迎"+show_name+"!已开门!"),(int((rec[1]-width)/2)+100),int((rec[0]-height)/2),(0,0,255),100)
cv2.imshow('Video',image1)
else:
cv2.imshow('Video', img)# 显示结果图像
else:fangdouname = facename
else:
cv2.imshow("Video",frame)
process_this_frame = not process_this_frame#只处理每隔一帧的视频以节省时间
if cv2.waitKey(1) & 0xFF == ord('q'):# 按键盘上的“q”退出!
break
# 释放网络摄像头的句柄
video_capture.release()
cv2.destroyAllWindows()
if __name__=="__main__":
while(True):
try:
face()
time.sleep(1000)
except:
pass
import paho.mqtt.client as mqtt
import json
import base64
import uuid
import time
import sys
import multiprocessing
import re
import os
from face_recognition.face_recognition_cli import image_files_in_folder
import glob
HOST = "api.yumik.top"
PORT = 1883
client_id="414ce45bde0a4bc1949fec75a7d2f699"
clientToken=uuid.uuid4()
class Data(object):
def __init__(self,name,timestamp):
self.timestamp = timestamp
self.name = name
def dict2Data(d):
return Data(d['name'],d['timestamp'])
#publish shadow/operation
data1 = {
"type":"get",
"clientToken":str(clientToken)
}
param1 = json.dumps(data1)
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
def file_circle(dirs5,houzhui,i,picture):
global picture2
for dirs4 in dirs5:
d2 = os.path.basename(dirs4)#图片名加后缀
num2 = os.path.splitext(d2)[0]#图片名
basename2 = os.path.splitext(d2)[1] #后缀名
if(int(num2)==i):
with open("/home/simon/mqtt/picture_recieve/"+str(num2)+basename2,"rb") as p1:
picture2 = picture + str(base64.b64encode(p1.read()),encoding="utf-8")#bytes
break
return(picture2)
picture = ""
houzhui = ""
u = []#存用户的id
v = []#存每个用户的图片数量,递增
a = []#获取userId
jishu = 1
gg = 0#记录人脸收集数
def on_message(client, userdata, msg):
global picture
global i
global houzhui
global jishu
global gg
recieve = msg.payload.decode("utf-8")
recieve_parsed = json.loads(recieve)
msg_type = recieve_parsed['type']
if(msg.topic=="414ce45bde0a4bc1949fec75a7d2f699/control" and msg_type=="history"):
print("topic:"+msg.topic+" message:"+str(msg.payload.decode('utf-8')))
if(msg.topic=="$shadow/operation/result/414ce45bde0a4bc1949fec75a7d2f699"):
if(msg_type=="get"):
print("topic:"+msg.topic+" message:"+str(msg.payload.decode('utf-8')))
print("get achieve!")
shadow_desired = recieve_parsed['payload']['state']['desired']
shadow_reported = recieve_parsed['payload']['state']['reported']
shadow_version = recieve_parsed['payload']['version']#字符串
if(shadow_desired!={}):
if('faceList' in shadow_desired):
s_d_facelist = shadow_desired['faceList']#数组
if('state' in shadow_desired):
state = shadow_desired['state']
data_delta = {
"type":"delta",
"state":{
"reported":{
"state":state,
"faceList":s_d_facelist
}
},
"version":shadow_version,
"clientToken":str(clientToken)
}
else:
data_delta = {
"type":"delta",
"state":{
"reported":{
"faceList":s_d_facelist
}
},
"version":shadow_version,
"clientToken":str(clientToken)
}
else:
state = shadow_desired['state']
data_delta = {
"type":"delta",
"state":{
"reported":{
"state":state
}
},
"version":shadow_version,
"clientToken":str(clientToken)
}
data_delta_param = json.dumps(data_delta)
client.publish("$shadow/operation/414ce45bde0a4bc1949fec75a7d2f699", payload=data_delta_param,qos=2,retain=False)#delta
else:#desired内没有内容需要完成时
with open("/home/simon/mqtt/"+"shadow.ini","r") as ud:
mes = ud.read()
mes_parsed = json.loads(mes)
if('payload' in mes_parsed):
meslist = mes_parsed['payload']['state']['reported']['faceList']
for i in meslist:
userid = i['userId']
a.append(int(userid))
#publish event
data_in = {
"type":"face",
"payload":{"userList":a,},
#"payload":{"userList":[2,3,4,5],},
"clientToken":str(clientToken)
}
param_in = json.dumps(data_in)
jishu = 1
client.publish("414ce45bde0a4bc1949fec75a7d2f699/event", payload=param_in,qos=2,retain=False)#获得图片
else:print("The device is disconnected!")
if(msg_type=="delta"):
if('payload' in recieve_parsed):
print("topic:"+msg.topic+" message:"+str(msg.payload.decode('utf-8')))
print("delta achieve!")
root3 = "/home/simon/mqtt/picture_recieve/"
root4 = "/home/simon/mqtt/picture/"
ls3 = os.listdir(root3)
ls4 = os.listdir(root4)
for i in ls3:
del_file3 = root3 + i
os.remove(del_file3)
for j in ls4:
del_file4 = root4 + j
os.remove(del_file4)
with open("/home/simon/mqtt/"+"shadow.ini","w") as sd:
sd.write(msg.payload.decode('utf-8'))
shadow_desired = recieve_parsed['payload']['state']['desired']
shadow_reported = recieve_parsed['payload']['state']['reported']
shadow_version = recieve_parsed['payload']['version']#字符串
if(shadow_desired!={}):
if('faceList' in shadow_desired):
s_d_facelist = shadow_desired['faceList']#数组
if('state' in shadow_desired):
state = shadow_desired['state']
data_delta = {
"type":"delta",
"state":{
"reported":{
"state":state,
"faceList":s_d_facelist
}
},
"version":shadow_version,
"clientToken":str(clientToken)
}
else:
data_delta = {
"type":"delta",
"state":{
"reported":{
"faceList":s_d_facelist
}
},
"version":shadow_version,
"clientToken":str(clientToken)
}
else:
state = shadow_desired['state']
data_delta = {
"type":"delta",
"state":{
"reported":{
"state":state
}
},
"version":shadow_version,
"clientToken":str(clientToken)
}
data_delta_param = json.dumps(data_delta)
client.publish("$shadow/operation/414ce45bde0a4bc1949fec75a7d2f699", payload=data_delta_param,qos=2,retain=False)#delta
else:#desired为空
with open("/home/simon/mqtt/"+"shadow.ini","w") as sd:
sd.write(msg.payload.decode('utf-8'))
meslist = recieve_parsed['payload']['state']['reported']['faceList']
print("meslist")
print(meslist)
a.clear()
for i in meslist:
userid = i['userId']
a.append(int(userid))
#publish event
data_in = {
"type":"face",
"payload":{"userList":a,},
#"payload":{"userList":[2,3,4,5],},
"clientToken":str(clientToken)
}
param_in = json.dumps(data_in)
client.publish("414ce45bde0a4bc1949fec75a7d2f699/event", payload=param_in,qos=2,retain=False)#获得图片
print("a")
print(a)
jishu = 1
with open("/home/simon/mqtt/"+"connect.txt","w") as co:
co.write(str(1))
else:
print("topic:"+msg.topic+" message:"+str(msg.payload.decode('utf-8')))
print("delete device achieve!")
root3 = "/home/simon/mqtt/picture_recieve/"
root4 = "/home/simon/mqtt/picture/"
ls3 = os.listdir(root3)
ls4 = os.listdir(root4)
for i in ls3:
del_file3 = root3 + i
os.remove(del_file3)
for j in ls4:
del_file4 = root4 + j
os.remove(del_file4)
with open("/home/simon/mqtt/"+"shadow.ini","w") as sd:
sd.write(msg.payload.decode('utf-8'))
if(msg.topic=="414ce45bde0a4bc1949fec75a7d2f699/control" and msg_type=="imageUpdate"):
print("topic:"+msg.topic+" message:"+str(msg.payload.decode('utf-8')))
gguserid = recieve_parsed['payload']['userId']
houzhui1 = "."+str(gguserid)
rootdir = "/home/simon/mqtt/picture_recieve/"
file_delete = os.listdir(rootdir)
for file in file_delete:
if houzhui1 in file:
del_file = rootdir + file#当代码和要删除的文件不在同一个文件夹时,必须使用绝对路径
os.remove(del_file)#删除文件
#publish event
data_in1 = {
"type":"face",
"payload":{"userList":[gguserid],},
"clientToken":str(clientToken)
}
param_in1 = json.dumps(data_in1)
client.publish("414ce45bde0a4bc1949fec75a7d2f699/event", payload=param_in1,qos=2,retain=False)#获得图片
if(msg.topic=="414ce45bde0a4bc1949fec75a7d2f699/control" and msg_type=="face"):
#print("topic:"+msg.topic+" message:"+str(msg.payload.decode('utf-8')))
print("control achieve!")
g = len(a)
packetnum = recieve_parsed['payload']['packet']
packettotal = recieve_parsed['payload']['totalPacket']
picture = recieve_parsed['payload']['userImageBase64']
temp = base64.b64decode(picture)#bytes
useridnum = str(recieve_parsed['payload']['user'])
houzhui = "."+str(recieve_parsed['payload']['user'])
if(jishu==1):
root1 = "/home/simon/mqtt/picture_recieve/"
root2 = "/home/simon/mqtt/picture/"
ls1 = os.listdir(root1)
ls2 = os.listdir(root2)
for i in ls1:
del_file1 = root1 + i
os.remove(del_file1)
for j in ls2:
del_file2 = root2 + j
os.remove(del_file2)
jishu+=1
with open("/home/simon/mqtt/picture_recieve/"+str(packetnum)+"."+str(recieve_parsed['payload']['user']),"wb") as f:
f.write(temp)#int
#判断一张图片是否全部接收
key = len(u)-1
if(key<0):#接收第一张图片
u.append(useridnum)
v.append(1)
else:
while(key>=0):
if(useridnum==u[key]):
v[key]+=1
else:
u.append(useridnum)
v.append(1)
if(v[key]==packettotal):
break
key = key-1
#一张图片全部接收后进行组装
if(v[key]==packettotal):
i=1
v.clear()
u.clear()
bool_flag2 = False#大循环跳出标志
dirs2 = []#大循环的数组
dirs0 = []#小循环的数组
for dirs1 in glob.glob('/home/simon/mqtt/picture_recieve'+"/*"+houzhui):
dirs2.append(dirs1)
dirs0.append(dirs1)
for dirs3 in dirs2:
d1 = os.path.basename(dirs3)#图片名加后缀
num1 = os.path.splitext(d1)[0]#图片名
basename1 = os.path.splitext(d1)[1] #后缀名
if(int(num1)==1):#找到序号为1的照片部分
with open("/home/simon/mqtt/picture_recieve/"+str(num1)+basename1,"rb") as p1:
picture1 = str(base64.b64encode(p1.read()),encoding="utf-8")#bytes
i=i+1
bool_flag1 = False#跳出小循环标志
while True:
if(i!=packettotal):#不是最后一部分就一直组装照片
picture1 = file_circle(dirs0,houzhui,i,picture1)
i=i+1
if(i==packettotal):#找到照片的最后一部分
picture1 = file_circle(dirs0,houzhui,i,picture1)
i=1
bool_flag1 = True
break
if(bool_flag1):
bool_flag2 = True
temp = base64.b64decode(picture1)#bytes
with open("/home/simon/mqtt/picture/"+str(recieve_parsed['payload']['user'])+str(recieve_parsed['payload']['userName'])+".jpg","wb") as o:
o.write(temp)
if(bool_flag2):
gg+=1
if(gg==g):
gg = 0
with open("/home/simon/mqtt/"+"connect.txt","w") as co:
co.write(str(1))
break
def on_publish(client,userdata,mid):
print("On onPublish: qos = %d" % mid)
def on_subscribe(client, userdata, mid, granted_qos):
print("On Subscribed: qos = %d" % granted_qos)
def on_disconnect(client, userdata, rc):
if rc != 0:
print("Unexpected disconnection %s" % rc)
def client_loop():
while True:
with open('/home/simon/mqtt/'+'FaceAndTime.json','r',encoding="utf-8") as old_f:
#读取所有行,每行会是一个字符串
for j in old_f.readlines():
if(j):
print(j)
face = json.loads(j,object_hook=dict2Data)
data_face = {
"type":"history",
"payload":{
"history":[
{
"timestamp":face.timestamp,
"history":{"name":face.name}
}]
},
"clientToken":str(clientToken)
}
client.publish("414ce45bde0a4bc1949fec75a7d2f699/event", payload=str(data_face), qos=0,retain=False)#发送人脸数据
with open('/home/simon/mqtt/'+'FaceAndTime.json','w+',encoding="utf-8") as new_f:
seek_point = old_f.tell()#光标在被删除行的行首,记录该位置
new_f.seek(seek_point,0)#设置光标位置
old_f.readline()#读需要删除的行,光标移动到下一行行首
next_line=old_f.readline()#被删除行的下一行读给next_line
while next_line:#连续覆盖剩余行,后面所有行上移一行
new_f.write(next_line)
next_line=old_f.readline()
new_f.truncate()
if __name__ == '__main__':
client = mqtt.Client(client_id)
client.on_connect = on_connect
client.connect(HOST, PORT, 60)
client.on_subscribe = on_subscribe
client.on_publish = on_publish
client.subscribe("414ce45bde0a4bc1949fec75a7d2f699/control",qos=1)
client.subscribe("$shadow/operation/result/414ce45bde0a4bc1949fec75a7d2f699",qos=1)
client.publish("$shadow/operation/414ce45bde0a4bc1949fec75a7d2f699", payload=param1,qos=2,retain=False)#get
client.on_message = on_message
client.loop_start()
client_loop()