from misc import Power,USB,PowerKey
import ntptime
import machine
+import dataCall
+import constants
+import versions
+
+dev_type = "G10"
+#dev_type = "7PIN_BK"#小瑞
+#dev_type = "7PIN"#柒牌
+#dev_type = 'momo'#食梦貘
+#dev_type = 'sjgq'#四季甘泉
class AI_led(Abstract):
def __init__(self):
- self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
- self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
- self.led_white = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1)
+ if dev_type == "G10":
+ self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
+ self.led_green = Pin(Pin.GPIO44, Pin.OUT, Pin.PULL_PD, 1)
+ self.led_blue = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
+ else:
+ self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
+ self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
+ self.led_blue = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1)
+
+ #=1 红灯闪,=2白灯闪,=3绿灯闪,=4全部灯闪
+ self.led_flicker_flag = 0
+ self.led_flicker_on_off_flag = 0
+ self.led_flicker_timer = osTimer()
+
EventMesh.subscribe("open_led_red",self.open_led_red)
- EventMesh.subscribe("open_led_white",self.open_led_white)
+ EventMesh.subscribe("open_led_blue",self.open_led_blue)
EventMesh.subscribe("open_led_green",self.open_led_green)
EventMesh.subscribe("open_led_all",self.open_led_all)
+ EventMesh.subscribe("open_led_red_blue",self.open_led_red_blue)
+ EventMesh.subscribe("open_led_red_green",self.open_led_red_green)
+ EventMesh.subscribe("flicker_led_red",self.flicker_led_red)
+ EventMesh.subscribe("flicker_led_blue",self.flicker_led_blue)
+ EventMesh.subscribe("flicker_led_green",self.flicker_led_green)
+ EventMesh.subscribe("flicker_led_all",self.flicker_led_all)
EventMesh.subscribe("close_led",self.close_led)
EventMesh.publish("open_led_red")
+
+ def flicker_led_red(self,event,msg):
+ self.led_flicker_flag = 1
+ self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb)
+
+ def flicker_led_blue(self,event,msg):
+ self.led_flicker_flag = 2
+ self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb)
+
+ def flicker_led_green(self,event,msg):
+ self.led_flicker_flag = 3
+ self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb)
+
+ def flicker_led_all(self,event,msg):
+ self.led_flicker_flag = 4
+ self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb)
+
+ def led_flicker_timer_cb(self, *args, **kwargs):
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.led_flicker_timer_cb_})
+ def led_flicker_timer_cb_(self):
+ if self.led_flicker_flag == 0:
+ self.led_flicker_timer.stop()
+ return
+ if self.led_flicker_on_off_flag == 0:
+ self.led_red.write(0)
+ self.led_blue.write(0)
+ self.led_green.write(0)
+ self.led_flicker_on_off_flag = 1
+ else:
+ self.led_flicker_on_off_flag = 0
+ if self.led_flicker_flag == 1:
+ self.led_blue.write(0)
+ self.led_green.write(0)
+ self.led_red.write(1)
+ elif self.led_flicker_flag == 2:
+ self.led_red.write(0)
+ self.led_green.write(0)
+ self.led_blue.write(1)
+ elif self.led_flicker_flag == 3:
+ self.led_red.write(0)
+ self.led_blue.write(0)
+ self.led_green.write(1)
+ elif self.led_flicker_flag == 4:
+ self.led_blue.write(1)
+ self.led_green.write(1)
+ self.led_red.write(1)
+
def open_led_red(self,event,msg):
+ #print("open_led_red")
+ self.led_flicker_flag = 0
#self.led_red.write(0)
- self.led_white.write(0)
+ self.led_blue.write(0)
self.led_green.write(0)
self.led_red.write(1)
- def open_led_white(self,event,msg):
+ def open_led_blue(self,event,msg):
+ #print("open_led_blue")
+ self.led_flicker_flag = 0
self.led_red.write(0)
- #self.led_white.write(0)
+ #self.led_blue.write(0)
self.led_green.write(0)
- self.led_white.write(1)
+ self.led_blue.write(1)
def open_led_green(self,event,msg):
+ #print("open_led_green")
+ self.led_flicker_flag = 0
self.led_red.write(0)
- self.led_white.write(0)
+ self.led_blue.write(0)
#self.led_green.write(0)
self.led_green.write(1)
+ def open_led_red_blue(self,event,msg):
+ #print("open_led_blue")
+ self.led_flicker_flag = 0
+ self.led_red.write(1)
+ #self.led_blue.write(0)
+ self.led_green.write(0)
+ self.led_blue.write(1)
+
+ def open_led_red_green(self,event,msg):
+ #print("open_led_blue")
+ self.led_flicker_flag = 0
+ self.led_red.write(1)
+ #self.led_blue.write(0)
+ self.led_green.write(1)
+ self.led_blue.write(0)
+
def open_led_all(self,event,msg):
+ #print("open_led_all")
+ self.led_flicker_flag = 0
#self.led_red.write(0)
- self.led_white.write(1)
+ self.led_blue.write(1)
self.led_green.write(1)
self.led_red.write(1)
def close_led(self,event,msg):
+ #print("close_led")
+ self.led_flicker_flag = 0
self.led_red.write(0)
- self.led_white.write(0)
+ self.led_blue.write(0)
self.led_green.write(0)
-audio_buf = ['dianliangshengyu10', 'dianliangshengyu100', 'dianliangshengyu20', 'dianliangshengyu40', 'dianliangshengyu60', 'dianliangshengyu80', 'dianliangshengyu90', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'peizhichenggong', 'qiehuanchenggong', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_POWER_OFF_1', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_SIM_FAILE', 'xianyikaiji', 'xinhaoruo1', 'xinhaoruo2', 'yinliangyizuida', 'yinliangyizuixiao', 'zhengzaiguanji']
+audio_buf = ['chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_READ_TIME_A', 'R_READ_TIME_B', 'R_READ_TIME_C', 'R_READ_TIME_D', 'R_READ_TIME_E', 'R_READ_TIME_F', 'R_READ_TIME_G', 'R_READ_TIME_H', 'R_READ_TIME_I', 'R_READ_TIME_J', 'R_READ_TIME_K', 'R_READ_TIME_L', 'R_READ_TIME_M', 'R_READ_TIME_N', 'R_READ_TIME_O', 'R_READ_TIME_P', 'R_READ_TIME_Q', 'R_READ_TIME_R', 'R_READ_TIME_S', 'R_READ_TIME_T', 'R_READ_TIME_U', 'R_READ_TIME_V', 'R_READ_TIME_W', 'R_READ_TIME_X', 'R_READ_TIME_Y', 'R_READ_TIME_Z', 'send_tone', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji']
class AI_dev(Abstract):
# AI
def __init__(self):
- self.VBATT_tab = {"charge_full":4300,100 :4250 , 90:3994 , 80:3883, 60: 3707, 40:3604, 20:3537, 10:3486,}
+ self.is_wdt = 0 #是否开启看门狗
+
+ self.VBATT_tab = {"charge_full":4300,"100" :4250 , "90":4179 , "80":4070, "60": 3883, "40":3770, "20":3699, "10":3652,"5":3600,}
self.KeyAI_status = 0
self.KeyAI_timer_count = 0
self.KeyAI_long_press = 0
self.KeyAI_press = 0
+ if self.is_wdt == 1:
+ self.wdt = WDT(30) #开启看门狗
+ # self.wdt_timer = osTimer()
+ # self.wdt_timer.start(5000, 1, self.wdt_timer_cb)
+ count = 0
+ while True:
+ count += 1
+ if count > 20 :
+ break
+ data = dataCall.getInfo(1, 0)
+ print("data call INFO {}".format(data))
+ if data[2][0]:
+ self.network_state = 1
+ break
+ print("等待网络 {}...".format(count))
+ utime.sleep_ms(500)
self.KeyAI_timer = osTimer()
- #self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
- self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
+ if dev_type == "G10":
+ self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
+ self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+ else:
+ self.pwk_key = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+ #self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
+ self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
self.extint_AI.enable()
self.pwk_key_status = 0
self.pwk_key_timer_count = 0
self.pwk_key_press = 0
self.pwk_key_timer = osTimer()
#self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_DISABLE, self.pwk_extint_cb)
- self.pwk_key = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+
self.pwk_key.enable()
- self.btnInfo_queue = Queue()
- _thread.stack_size(10*1024)
- _thread.start_new_thread(self.btnInfo_queue_thread, ())
+ print("AI_dev:1")
+ self.btnInfo_queue = Queue(100)
+ self.btnInfo_queue_count = 0
+ _thread.stack_size(16*1024)
+ self.btnInfo_queue_thread_id = _thread.start_new_thread(self.btnInfo_queue_thread, ())
_thread.stack_size(8*1024)
EventMesh.subscribe("publish_AI_btnInfo",self.publish_AI_btnInfo)
EventMesh.subscribe("get_battery",self.get_battery)
EventMesh.subscribe("audio_montage_play",self.audio_montage_play)
EventMesh.subscribe("paly_iccid_imei",self.paly_iccid_imei)
EventMesh.subscribe("paly_device_res_error",self.paly_device_res_error)
-
- self.wdt = WDT(30) #开启看门狗
- # self.wdt_timer = osTimer()
- # self.wdt_timer.start(10000, 1, self.wdt_timer_cb)
+ print("AI_dev:2")
self.pk = PowerKey()
self.pk.powerKeyEventRegister(self.powerKey_callback)
self.usb = USB()
self.usb.setCallback(self.usb_event_cb)
self.usb_status = self.usb.getStatus()
self.usb_charge_flag = 0
+ self.Low_power_warning_timer = 0
self.AI_dev_timer = osTimer()
self.AI_dev_timer.start(10000, 1, self.AI_dev_timer_cb)
+ print("AI_dev:AI_dev_timer")
self.aud = audio.Audio(0)
-
+ self.Low_power_warning_flag = 0
+ self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
+ if self.VC_TTS_volume == None:
+ self.VC_TTS_volume = 100
+ self.aud.setVolume(self.VC_TTS_volume //10)
#self.aud.play(1,0,'U:/static/xianyikaiji.mp3')#开机音频
#EventMesh.publish("audio_montage_play",["xianyikaiji.mp3"])
#EventMesh.publish("publish_AI_btnInfo",{"func":self.ntptime_cb})
+ self.check_rest_timer_count = 0
+ print("AI_dev:end")
def ntptime_cb(self):
#ntptime.settime(8)
print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
def usb_event_cb(self, state):
EventMesh.publish("publish_AI_btnInfo",{"func":self.usb_event,"data":state})
+
def usb_event(self, state):
status = state
self.usb_charge_flag = 0
if status == 1:#插入USB
print("charge R_CHARGE_in")
self.usb_status = 1
- self.aud.stop()
- #self.aud.play(1,1,'U:/static/R_CHARGE_IN.mp3')
- EventMesh.publish("audio_montage_play",["R_CHARGE_IN.mp3"])
+ VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行
+ if VC_satrt_flag == None:
+ VC_satrt_flag = 0
+ if VC_satrt_flag == 0:
+ self.aud.stop()
+ #EventMesh.publish("flicker_led_red")#充电闪灯
+ #self.aud.play(1,1,'U:/static/R_CHARGE_IN.mp3')
+ EventMesh.publish("open_led_red")#充电红灯常亮
+ EventMesh.publish("audio_montage_play",["R_CHARGE_IN.mp3"])
+ self.Low_power_warning_flag = 0
pass
elif status == 0:#拨出usbs
self.usb_status = 0
- self.aud.stop()
- EventMesh.publish("audio_montage_play",["R_CHARGE_OUT.mp3"])
- #self.aud.play(1,1,'U:/static/R_CHARGE_OUT.mp3')
+ VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行
+ if VC_satrt_flag == None:
+ VC_satrt_flag = 0
+ if VC_satrt_flag == 0:
+ self.aud.stop()
+ EventMesh.publish("close_led")
+ EventMesh.publish("audio_montage_play",["R_CHARGE_OUT.mp3"])
+ #self.aud.play(1,1,'U:/static/R_CHARGE_OUT.mp3')
def btnInfo_queue_thread(self):
while True:
data = self.btnInfo_queue.get()
+ self.btnInfo_queue_count-=1
#EventMesh.debug_log("Info_queue:data = {}".format(data))
if data != None:
try:
#EventMesh.debug_log("btnInfo_queue:ERROR:{}".format(e))
usys.print_exception(e)
def publish_AI_btnInfo(self,event,msg):
+ #print("publish_AI_btnInfo 1")
self.btnInfo_queue.put(msg)
+ self.btnInfo_queue_count+=1
+ if self.btnInfo_queue_count > 80:
+ self.btnInfo_queue_count =0
+ print("事件处理线程队列出问题,重启!!!!!!!!!!!!!!")
+ print("线程:{} 队列:{}".format(_thread.threadIsRunning(self.btnInfo_queue_thread_id),self.btnInfo_queue.size()))
+ # if _thread.threadIsRunning(self.btnInfo_queue_thread_id):
+ # _thread.stop_thread(self.btnInfo_queue_thread_id)
+ # _thread.stack_size(10*1024)
+ # self.btnInfo_queue_thread_id = _thread.start_new_thread(self.btnInfo_queue_thread, ())
+ # _thread.stack_size(8*1024)
+ # self.btnInfo_queue.clear()
+ # self.btnInfo_queue = Queue(100)
+ EventMesh.publish("VC_error") #播放报错
+ utime.sleep_ms(1000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ Power.powerRestart()
+ EventMesh.publish("set_storage_config",["powerRestart",1])
+ #print("publish_AI_btnInfo 2")
def powerKey_callback(self, status):
print("powerKey_callback:{}".format(status))
self.pwk_key_status = 0
pass
if self.pwk_key_status == 0:#按下
+
if self.pwk_key_press == 0 :
self.pwk_key.disable()
self.pwk_key_press = 1
self.pwk_key_timer.start(100, 1, self.pwk_key_timer_cb)
self.pwk_key_timer_count = 0
#EventMesh.publish("AI_key_press")
-
except Exception as e:
usys.print_exception(e)
def pwk_key_timer_cb(self, *args, **kwargs):
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_timer_cb_})
+ # def pwk_key_timer_cb_(self) :
try:
self.pwk_key_status = self.pwk_key.read_level()
self.pwk_key_timer_count +=1
if self.pwk_key_long_press == 0:
self.pwk_key_long_press = 1
#EventMesh.publish("AI_key_long_press")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_Long_Press})
+ EventMesh.publish("audio_montage_play",["zhengzaiguanji.mp3"])
+ #self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频
+ EventMesh.publish("open_led_red")
+ utime.sleep_ms(2000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ Power.powerDown()
+ #print("AI_key_release")
+ EventMesh.publish("pwk_key_long_press")
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_Long_Press})
if self.pwk_key_status == 1:#松开
#print("pwk_key_timer_cb:{}".format(self.pwk_key_timer_count))
- if self.pwk_key_timer_count >= 5: #防抖200ms
+ key_count = 5
+ if dev_type == "7PIN_BK":
+ key_count = 3
+ if self.pwk_key_timer_count >= key_count: #防抖200ms
#EventMesh.publish("AI_key_release")
EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release})
self.pwk_key.enable()
if self.KeyAI_status == 0:#按下
if self.KeyAI_press == 0 :
+ EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
self.extint_AI.disable()
self.KeyAI_press = 1
self.KeyAI_long_press = 0
self.KeyAI_timer.start(100, 1, self.KeyAI_timer_cb)
self.KeyAI_timer_count = 0
#EventMesh.publish("AI_key_press")
+ if dev_type == "7PIN" :
+ self.aud.aud_tone_play(10,200)#播放按键音
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})
except Exception as e:
usys.print_exception(e)
def KeyAI_timer_cb(self, *args, **kwargs):
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.KeyAI_timer_cb_})
+ # def KeyAI_timer_cb_(self):
try:
self.KeyAI_status = self.extint_AI.read_level()
self.KeyAI_timer_count +=1
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_long_press})
if self.KeyAI_status == 1:#松开
#print("KeyAI_timer_cb:{}".format(self.KeyAI_timer_count))
- if self.KeyAI_timer_count >= 5: #防抖200ms
+ key_count = 5
+ if dev_type == "7PIN_BK":
+ key_count = 3
+ if self.KeyAI_timer_count >= key_count: #防抖200ms
#EventMesh.publish("AI_key_release")
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_release})
self.extint_AI.enable()
usys.print_exception(e)
def AI_key_press(self):
- #print("AI_key_press")
+ self.check_rest_timer_count = 0
+ print("AI_key_press")
EventMesh.publish("AI_key_press")
+
def AI_key_long_press(self):
- #print("AI_key_long_press")
+ self.check_rest_timer_count = 0
+ print("AI_key_long_press")
EventMesh.publish("AI_key_long_press")
def AI_key_release(self):
- #print("AI_key_release")
+ print("AI_key_release")
EventMesh.publish("AI_key_release")
+
def pwk_key_Long_Press(self):
+ self.check_rest_timer_count = 0
print("pwk_key_long_press!!!!!!!")
print("pwk_key_long_press!!!!!!!")
#self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频
EventMesh.publish("open_led_red")
utime.sleep_ms(3000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
Power.powerDown()
#print("AI_key_release")
EventMesh.publish("pwk_key_long_press")
def pwk_key_release(self):
+ self.check_rest_timer_count = 0
#print("pwk_key_release")
EventMesh.publish("pwk_key_release")
+
+ def wdt_timer_cb(self, *args, **kwargs):
+ if self.is_wdt == 1:
+ self.wdt.feed()
+
def AI_dev_timer_cb(self, *args, **kwargs):
+ #print("AI_dev_timer_cb")
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_dev_timer_event})
def AI_dev_timer_event(self):
- self.wdt.feed()
+ if self.is_wdt == 1:
+ self.wdt.feed()
+ VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行
+ if VC_satrt_flag == None:
+ VC_satrt_flag = 0
Vbatt = Power.getVbatt()
- if self.usb_charge_flag == 0 and self.usb_status == 1 and Vbatt>=self.VBATT_tab["charge_full"]:#充电充满
- EventMesh.publish("audio_montage_play",["R_CHARGE_FULL.mp3"])
- #self.aud.play(1,0,'U:/static/R_CHARGE_FULL.mp3')#充电已满
- self.usb_charge_flag = 1
- if self.usb_charge_flag == 0 and self.usb_status == 0 and Vbatt<self.VBATT_tab[10]:#低电报警
+ if self.usb_status == 1 and VC_satrt_flag == 0:
+ EventMesh.publish("open_led_red")#充电红灯常亮
+ if self.usb_status == 1 and Vbatt>=self.VBATT_tab["charge_full"]and VC_satrt_flag == 0:#充电充满
+ EventMesh.publish("open_led_green")
+ if self.usb_charge_flag == 0 :
+ EventMesh.publish("audio_montage_play",["R_CHARGE_FULL.mp3"])
+ #self.aud.play(1,0,'U:/static/R_CHARGE_FULL.mp3')#充电已满
+ self.usb_charge_flag = 1
+ if self.usb_status == 0 and Vbatt<self.VBATT_tab["20"]and VC_satrt_flag == 0 and self.Low_power_warning_flag ==0:#低电报警
+ self.Low_power_warning_flag = 1
+ EventMesh.publish("flicker_led_red")
#self.aud.play(1,0,'Low_power_warning.mp3')
+ # self.Low_power_warning_timer+=1
+ # if self.Low_power_warning_timer >= 2:
+ # self.Low_power_warning_timer = 0
EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"])
- self.usb_charge_flag = 1
- pass
+
+ if self.usb_status == 0 and Vbatt<self.VBATT_tab["5"]:
+ EventMesh.publish("audio_montage_play",["didianguanji.mp3"])
+ utime.sleep_ms(4500)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ Power.powerDown()
+
+ self.check_rest_timer_count += 1
+ if self.check_rest_timer_count >= 8640:#24小时没按键,则关机
+ self.pwk_key_Long_Press()
+
def get_battery(self, event=None, msg=None):
Vbatt = Power.getVbatt()
- if Vbatt>self.VBATT_tab[90]:
+ if Vbatt>self.VBATT_tab["90"]:
return 100
- if Vbatt>self.VBATT_tab[80]:
+ if Vbatt>self.VBATT_tab["80"]:
return 90
- if Vbatt>self.VBATT_tab[60]:
+ if Vbatt>self.VBATT_tab["60"]:
return 80
- if Vbatt>self.VBATT_tab[40]:
+ if Vbatt>self.VBATT_tab["40"]:
return 60
- if Vbatt>self.VBATT_tab[20]:
+ if Vbatt>self.VBATT_tab["20"]:
return 40
- if Vbatt>self.VBATT_tab[10]:
+ if Vbatt>self.VBATT_tab["10"]:
return 20
- if Vbatt<=self.VBATT_tab[10]:
+ if Vbatt<=self.VBATT_tab["10"]:
return 10
def audio_montage_play(self,event,msg):
self.aud.stopPlayStream()
+ self.aud.stopAll()
str_data='mp3files='
for i in msg:
try:
str_data = str_data[:-1]
print("audio_montage_play:{}".format(str_data))
self.aud.montage_play('U:/static/audio.bin',1,1,str_data)
+
def paly_iccid_imei(self,event,msg):
str_data = 'mp3files={}.mp3+'.format(audio_buf.index("liuliangtishi"))#流量提示
imei = modem.getDevImei()
iccid = sim.getIccid()
- if len(iccid) > 5:
- str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+'.format(audio_buf.index("R_READ_TIME_{}".format(iccid[0]))\
+ print("paly_iccid_imei:ICCID:{}".format(iccid))
+ if iccid != -1 and len(iccid) > 5:
+ iccid = iccid.upper()
+ if len(iccid) <20:
+ for i in range(20-len(iccid)):
+ iccid = "0"+iccid
+ str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+'.format(audio_buf.index("R_READ_TIME_{}".format(iccid[0]))\
,audio_buf.index("R_READ_TIME_{}".format(iccid[1])),audio_buf.index("R_READ_TIME_{}".format(iccid[2])),audio_buf.index("R_READ_TIME_{}".format(iccid[3])),\
audio_buf.index("R_READ_TIME_{}".format(iccid[4])),audio_buf.index("R_READ_TIME_{}".format(iccid[5])),audio_buf.index("R_READ_TIME_{}".format(iccid[6])),audio_buf.index("R_READ_TIME_{}".format(iccid[7])),\
audio_buf.index("R_READ_TIME_{}".format(iccid[8])),audio_buf.index("R_READ_TIME_{}".format(iccid[9])),audio_buf.index("R_READ_TIME_{}".format(iccid[10])),audio_buf.index("R_READ_TIME_{}".format(iccid[11])),\
- audio_buf.index("R_READ_TIME_{}".format(iccid[12])),audio_buf.index("R_READ_TIME_{}".format(iccid[13])),audio_buf.index("R_READ_TIME_{}".format(iccid[14])))
- str_data += '{}.mp3+'.format(audio_buf.index("IMEIhao"))#IMEI号为:
- str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3'.format(audio_buf.index("R_READ_TIME_{}".format(imei[0]))\
- ,audio_buf.index("R_READ_TIME_{}".format(imei[1])),audio_buf.index("R_READ_TIME_{}".format(imei[2])),audio_buf.index("R_READ_TIME_{}".format(imei[3])),\
- audio_buf.index("R_READ_TIME_{}".format(imei[4])),audio_buf.index("R_READ_TIME_{}".format(imei[5])),audio_buf.index("R_READ_TIME_{}".format(imei[6])),audio_buf.index("R_READ_TIME_{}".format(imei[7])),\
- audio_buf.index("R_READ_TIME_{}".format(imei[8])),audio_buf.index("R_READ_TIME_{}".format(imei[9])),audio_buf.index("R_READ_TIME_{}".format(imei[10])),audio_buf.index("R_READ_TIME_{}".format(imei[11])),\
- audio_buf.index("R_READ_TIME_{}".format(imei[12])),audio_buf.index("R_READ_TIME_{}".format(imei[13])),audio_buf.index("R_READ_TIME_{}".format(imei[14])))
- #print("str_data:{}".format(str_data))
+ audio_buf.index("R_READ_TIME_{}".format(iccid[12])),audio_buf.index("R_READ_TIME_{}".format(iccid[13])),audio_buf.index("R_READ_TIME_{}".format(iccid[14])),audio_buf.index("R_READ_TIME_{}".format(iccid[15])),\
+ audio_buf.index("R_READ_TIME_{}".format(iccid[16])),audio_buf.index("R_READ_TIME_{}".format(iccid[17])),audio_buf.index("R_READ_TIME_{}".format(iccid[18])),audio_buf.index("R_READ_TIME_{}".format(iccid[19])))
+ str_data += '{}.mp3+'.format(audio_buf.index("shouhou"))#可联系售后解决,联系方式见售后客服电话是400-886-8777或到微信公众号柒牌SEVENBRAND自行充值:
self.aud.montage_play('U:/static/audio.bin',1,1,str_data)
#鉴权出错,播放imei号
def paly_device_res_error(self,event,msg):
str_data = 'mp3files={}.mp3+'.format(audio_buf.index("jianquancuowu"))#AI功能异常,请联系客户查询,设备号为:
imei = modem.getDevImei()
+ imei = imei.upper()
str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3'.format(audio_buf.index("R_READ_TIME_{}".format(imei[0]))\
,audio_buf.index("R_READ_TIME_{}".format(imei[1])),audio_buf.index("R_READ_TIME_{}".format(imei[2])),audio_buf.index("R_READ_TIME_{}".format(imei[3])),\
audio_buf.index("R_READ_TIME_{}".format(imei[4])),audio_buf.index("R_READ_TIME_{}".format(imei[5])),audio_buf.index("R_READ_TIME_{}".format(imei[6])),audio_buf.index("R_READ_TIME_{}".format(imei[7])),\
audio_buf.index("R_READ_TIME_{}".format(imei[12])),audio_buf.index("R_READ_TIME_{}".format(imei[13])),audio_buf.index("R_READ_TIME_{}".format(imei[14])))
#print("str_data:{}".format(str_data))
self.aud.montage_play('U:/static/audio.bin',1,1,str_data)
+
#存储信息
class getStorageDataManager(Abstract):#获取内存数据
def __init__(self):
class device_res_author(Abstract):
def __init__(self) :
+ print("device_res_author __init__ start !!!!!!!!!!!!!!!!!")
self.deviceId = modem.getDevImei()#"876226002022574"
self.SHA1_BLOCK_SIZE = 64
self.PAD_BLOCK_SIZE = 16
self.pid = "cqxJZi5CNgzjS3mX21Zw"
self.dev_res_timer = osTimer()
- self.dev_res_timer.start(10000, 1, self.dev_timer_cb)
+ self.dev_res_timer.start(20000, 1, self.dev_timer_cb)
self.dev_res_timerCount = 0
self.ud_token_timer = osTimer()
- self.ud_token_timer.start(30000, 1, self.ud_token_timer_cb)
+ self.ud_token_timer.start(10000, 1, self.ud_token_timer_cb)
self.ud_token_timer_Count = 0
self.dev_token = None
self.res_error_count = 0
+ self.ntptime_flag = 0
EventMesh.subscribe("get_dev_token", self.get_dev_token)
EventMesh.subscribe("update_dev_token", self.update_dev_token)
+ EventMesh.subscribe("dev_active", self.dev_active)
+ EventMesh.subscribe("dev_sign_in", self.dev_sign_in)
+ EventMesh.subscribe("dev_NTP", self.dev_NTP)
+ #EventMesh.publish_async("dev_NTP",thread_size = 8192)
+
+ # count = 0
+ # while True:
+ # if self.ntptime_flag == 1:
+ # break
+ # utime.sleep_ms(1)
+ # count+=1
+ # if count>600:
+ # break
+ # EventMesh.publish_async("dev_active",thread_size = 8192)
+ # EventMesh.publish_async("dev_sign_in",thread_size = 8192)
+
+ self.dev_NTP()#获取时间
self.dev_active() #设备激活
self.dev_sign_in() #设备登入
- self.ntptime_flag = 0
+ print("device_res_author __init__ end !!!!!!!!!!!!!!!!!")
def get_dev_token(self, event, msg):
return self.dev_token
#网络校时
- def dev_NTP(self):
- url = "http://dmp.raisound.com/bz-api/dev/time"
- response = request.get(url)
- data = response.json()
- print("dev_NTP:{}".format(data))
- if data:
- try:
- timeSecond = data["data"]["timestamp"]//1000
-
- next_alarm_time = utime.localtime(timeSecond)
- print("timeSecond {} next_alarm_time {}".format(timeSecond,next_alarm_time))
- machine.RTC().datetime((next_alarm_time[0],next_alarm_time[1],next_alarm_time[2],next_alarm_time[6],next_alarm_time[3],next_alarm_time[4],next_alarm_time[5],0))
- except Exception as e:
- usys.print_exception(e)
+ def dev_NTP(self, event=None, msg=None):
+ response = None
+ try:
+ print("dev_NTP1")
+ url = "http://dmp.raisound.com/bz-api/dev/time"
+ response = request.get(url,timeout=5)
+ data = response.json()
+ print("dev_NTP:{}".format(data))
+ if data:
+ try:
+ timeSecond = data["data"]["timestamp"]//1000
+
+ next_alarm_time = utime.localtime(timeSecond)
+ print("timeSecond {} next_alarm_time {}".format(timeSecond,next_alarm_time))
+ machine.RTC().datetime((next_alarm_time[0],next_alarm_time[1],next_alarm_time[2],next_alarm_time[6],next_alarm_time[3],next_alarm_time[4],next_alarm_time[5],0))
+ self.ntptime_flag = 1
+ except Exception as e:
+ usys.print_exception(e)
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+ print("dev_NTP end")
def dev_timer_cb(self, *args): #设备资源管理鉴权平台定时器
EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_timer_cb_})
def dev_timer_cb_(self):
#if EventMesh.DEV_RES_MANAGE_AUTHEN_PLATFORM == 1:
- if self.dev_token == None:
- if self.ntptime_flag == 0:
- self.ntptime_flag = 1
- EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_NTP})
- print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
- self.dev_active() #设备激活
- self.dev_sign_in() #设备登入
- self.dev_res_timerCount+=1
- if self.dev_res_timerCount > 6: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程
- self.dev_res_timerCount=0
- self.dev_res_timer.stop()
+ try:
+ if self.dev_token == None:
+ if self.ntptime_flag == 0:
+ self.ntptime_flag = 1
+ EventMesh.publish_async("dev_NTP",thread_size = 8192)
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_NTP})
+ print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
+ EventMesh.publish_async("dev_active",thread_size = 8192)
+ EventMesh.publish_async("dev_sign_in",thread_size = 8192)
+ # self.dev_active() #设备激活
+ # self.dev_sign_in() #设备登入
+ self.dev_res_timerCount+=1
+ if self.dev_res_timerCount > 3: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程
+ self.dev_res_timerCount=0
+ self.dev_res_timer.stop()
+ except Exception as e:
+ usys.print_exception(e)
def ud_token_timer_cb(self, *args):
EventMesh.publish("publish_AI_btnInfo",{"func":self.ud_token_timer_cb_})
def ud_token_timer_cb_(self):
- #print("ud_token_timer_!!!!")
- self.ud_token_timer_Count+=1
- if self.ud_token_timer_Count >= 20: #定时30*200s时更新token
- self.ud_token_timer_Count = 0
- EventMesh.publish("update_dev_token")
-
+ try:
+ #print("ud_token_timer_!!!!")
+ self.ud_token_timer_Count+=1
+ if self.ud_token_timer_Count >= 720: #定时10*3000s时更新token
+ self.ud_token_timer_Count = 0
+ EventMesh.publish_async("dev_sign_in",thread_size = 8192)
+ except Exception as e:
+ usys.print_exception(e)
def get_sim_Status(self):
return sim.getStatus()
def HMAC(self,k, m):
result = self.unpad(result) # 除去补16字节的多余字符
return str(result, 'utf-8') # 以字符串的形式返回
#激活接口 没有密码走激活
- def dev_active(self):
+ def dev_active(self, event=None, msg=None):
signal = net.csqQueryPoll()
if signal == -1 or self.get_sim_Status() != 1:#网络不正常
print("dev_active 无 SIM卡!!!!!!!!\r\n")
return
+ print("dev_active 1\r\n")
# 签名内容: = deviceId+pid+timeStamp
dev_pass = ""
dev_pass = EventMesh.publish("get_storage_config","dev_pass")
if dev_pass == None:
dev_pass = ""
if dev_pass == "" or dev_pass == None:
- date_tmp = utime.localtime() #获取当前时间
- print("date_tmp:{}\r\n".format(date_tmp)) #转换时间戳s
- timeStamp = (utime.mktime(date_tmp))*1000#获取时间戳ms
- deviceId = self.deviceId #"876226002022574" #以imei号
- pid = self.pid
- key = self.key
- sign_data = "{}{}{}".format(deviceId,pid,timeStamp) #签名内容
- print("sign_data:{}\r\n".format(sign_data))
- sha256_hex = self.get_hmac_sha256(key,sign_data)
- print("sha256_hex:{}\r\n".format(sha256_hex))
-
- data = {
- "deviceId":"{}".format(deviceId), #设备名
- "pid":pid, #产品PID
- "sign":"{}".format(sha256_hex), #HMACSHA256签名后的数据
- "timeStamp":timeStamp, #要以ms的形式
- "signMethod":"HMACSHA256" #签名方式 HMACSHA256
- }
- print(ujson.dumps(data))
- headers_T ={"Content-Type":"application/json"}
- url = "http://dmp.raisound.com/bz-api/dev/auth/active"
- data =ujson.dumps(data)
- response = 0
- response_result = 0
try:
- response = request.put(url,data=data,headers = headers_T)
- response_result = 1
- except Exception as e:
- print("put error!!!!!\r\n")
+ date_tmp = utime.localtime() #获取当前时间
+ print("date_tmp:{}\r\n".format(date_tmp)) #转换时间戳s
+ timeStamp = (utime.mktime(date_tmp))*1000#获取时间戳ms
+ deviceId = self.deviceId #"876226002022574" #以imei号
+ pid = self.pid
+ key = self.key
+ sign_data = "{}{}{}".format(deviceId,pid,timeStamp) #签名内容
+ print("sign_data:{}\r\n".format(sign_data))
+ sha256_hex = self.get_hmac_sha256(key,sign_data)
+ print("sha256_hex:{}\r\n".format(sha256_hex))
+
+ data = {
+ "deviceId":"{}".format(deviceId), #设备名
+ "pid":pid, #产品PID
+ "sign":"{}".format(sha256_hex), #HMACSHA256签名后的数据
+ "timeStamp":timeStamp, #要以ms的形式
+ "signMethod":"HMACSHA256" #签名方式 HMACSHA256
+ }
+ print(ujson.dumps(data))
+ headers_T ={"Content-Type":"application/json"}
+ url = "http://dmp.raisound.com/bz-api/dev/auth/active"
+ data =ujson.dumps(data)
+ response = None
response_result = 0
-
- IV = "" #偏移量
- PASSWORD= "" #服务器返回后的加密内容 密码
- if response_result == 1: #访问成功ip
- if response.status_code == 200:
- print("headers:{}".format(response.headers))
- content = response.content
- c = next(content)
- # "api.xcloudtech.com"
- # d_server_port = 9000
- data = ujson.loads(c)
- # data = response.json()
- print("data-{}".format(data))
- if data != None:
- if "success" in data:
- if data['success'] == True:
- if "data" in data:
- data_tmp = data["data"]
- if "nonce" in data_tmp: #偏移量
- IV = data_tmp["nonce"]
- if "password" in data_tmp:
- PASSWORD = data_tmp["password"]
- # EventMesh.publish("set_storage_config",["dev_pass",PASS])
- if data["code"] == 20001:#鉴权成功
- pass
- elif data["code"] > 50000:#时间错误
- self.res_error_count+=1
- if self.res_error_count>=3:
- self.res_error_count = 0
- #EventMesh.publish("paly_device_res_error")
- if data["code"] == 50003:#时间错误
- self.ntptime_flag = 0
- if PASSWORD != None and IV != None:
- if len(PASSWORD) != 0 and len(IV) != 0:
- password = PASSWORD
- iv = IV
- #解密 之后保存本地下一次登入做使用
- decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密
- print("decrypt_data {}".format(decrypt_data))
- EventMesh.publish("set_storage_config",["dev_pass",decrypt_data])
-
-
- print("IV:{}\r\n PASS:{}".format(IV,PASSWORD))
+ try:
+ response = request.put(url,data=data,headers = headers_T,timeout=5)
+ response_result = 1
+ except Exception as e:
+ usys.print_exception(e)
+ print("put error!!!!!\r\n")
+ response_result = 0
+
+ IV = "" #偏移量
+ PASSWORD= "" #服务器返回后的加密内容 密码
+ if response_result == 1: #访问成功ip
+ if response.status_code == 200:
+ print("headers:{}".format(response.headers))
+ content = response.content
+ c = next(content)
+ # "api.xcloudtech.com"
+ # d_server_port = 9000
+ data = ujson.loads(c)
+ # data = response.json()
+ print("data-{}".format(data))
+ if data != None:
+ if "success" in data:
+ if data['success'] == True:
+ if "data" in data:
+ data_tmp = data["data"]
+ if "nonce" in data_tmp: #偏移量
+ IV = data_tmp["nonce"]
+ if "password" in data_tmp:
+ PASSWORD = data_tmp["password"]
+ # EventMesh.publish("set_storage_config",["dev_pass",PASS])
+ if data["code"] == 20001:#鉴权成功
+ pass
+ elif data["code"] > 50000:#时间错误
+ self.res_error_count+=1
+ if self.res_error_count>=3:
+ self.res_error_count = 0
+ #EventMesh.publish("paly_device_res_error")
+ if data["code"] == 50003:#时间错误
+ self.ntptime_flag = 0
+ if PASSWORD != None and IV != None:
+ if len(PASSWORD) != 0 and len(IV) != 0:
+ password = PASSWORD
+ iv = IV
+ #解密 之后保存本地下一次登入做使用
+ decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密
+ print("decrypt_data {}".format(decrypt_data))
+ EventMesh.publish("set_storage_config",["dev_pass",decrypt_data])
+ print("IV:{}\r\n PASS:{}".format(IV,PASSWORD))
+ if response != None:
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ print("dev_active end\r\n")
return [response_result,PASSWORD,IV]
#随机生成16个字节的字符串作为加密的IV 偏移量
def generate_random_string(self,length=16):
return random_str
#设备登入 没有Token 走登入获取token
- def dev_sign_in(self):
+ def dev_sign_in(self, event=None, msg=None):
signal = net.csqQueryPoll()
if signal == -1 or self.get_sim_Status() != 1:#网络不正常
print("dev_sign_in 无 SIM卡!!!!!!!!\r\n")
return
+ print("dev_sign_in 1")
token = ""
- token = self.dev_token
- dev_pass = EventMesh.publish("get_storage_config","dev_pass")
- #print("token:{}\r\n".format(token))
- if token == None:
- token = ""
- if dev_pass == None:
- dev_pass = ""
- if len(dev_pass) == 0:#没有密码
- return
- if token == None or token == "":
+ try:
+ token = self.dev_token
+ dev_pass = EventMesh.publish("get_storage_config","dev_pass")
+ #print("token:{}\r\n".format(token))
+ if token == None:
+ token = ""
+ if dev_pass == None:
+ dev_pass = ""
+ if len(dev_pass) == 0:#没有密码
+ return
+ #if token == None or token == "":
if 1: #返回结果成功
#获取本地保存的密码
decrypt_data=EventMesh.publish("get_storage_config","dev_pass")
response_result = 0
response = 0
try:
- response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T)
+ response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T,timeout=5)
response_result = 1
except Exception as e:
+ usys.print_exception(e)
print("post error!!!!!\r\n")
response_result = 0
# {'msg': '', 'code': 20001, 'success': True,
# 'data': {'deviceId': '876226002022574',
# 'token': '95436a9e09fd0ff89feb8825257dca982f'}
# }
- token = ""
+
+ #self.dev_token = ""
if response_result == 1:
if response.status_code == 200:
content = response.content
self.dev_token = data_tmp["token"]
if data["code"] == 50003:#时间错误
self.ntptime_flag = 0
- print("token:{}\r\n".format(token))
+ print("token:{}\r\n".format(self.dev_token))
+ if response != None:
+ response.close()
pass
+ except Exception as e:
+ print("post error!!!!!\r\n")
+ response_result = 0
+ print("dev_sign_in end")
#获取新的令牌 更新token
- def update_dev_token(self, event, msg):
+ def update_dev_token(self, event=None, msg=None):
print("update_dev_token")
- dev_pass = ""
- dev_pass = EventMesh.publish("get_storage_config","dev_pass")
-
- if dev_pass == None:
+ try:
dev_pass = ""
- if len(dev_pass) == 0: #没有密码走激活
- print("no dev_pass:{}\r\n".format(dev_pass))
- self.dev_active()
- token = self.dev_token
- if token == None:
- token = ""
- if len(token) == 0: #没有token走登入
- print("no dev_token:{}\r\n".format(token))
- self.dev_sign_in()
-
- dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
- token = self.dev_token
- if token == None:
- token = ""
- if len(token) != 0:
- response_result=0
- response = 0
- headers_T = {"bz-dt":"{}".format(token)}
- try:
- response = request.get(dev_tokenip,headers = headers_T)
- response_result = 1
- except Exception as e:
- print("get error!!!!!\r\n")
- response_result = 0
- if response_result == 1:
- if response.status_code == 200:
+ dev_pass = EventMesh.publish("get_storage_config","dev_pass")
+
+ if dev_pass == None:
+ dev_pass = ""
+ if len(dev_pass) == 0: #没有密码走激活
+ print("no dev_pass:{}\r\n".format(dev_pass))
+ EventMesh.publish("dev_active")
+ token = self.dev_token
+ if token == None:
+ token = ""
+ if len(token) == 0: #没有token走登入
+ print("no dev_token:{}\r\n".format(token))
+ #self.dev_sign_in()
+ EventMesh.publish("dev_sign_in")
+ dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
+ token = self.dev_token
+ if token == None:
+ token = ""
+ if len(token) != 0:
+ response_result=0
+ response = None
+ headers_T = {"bz-dt":"{}".format(token)}
+ try:
+ response = request.get(dev_tokenip,headers = headers_T,timeout=5)
+ response_result = 1
+ except Exception as e:
+ print("get error!!!!!\r\n")
+ response_result = 0
+ if response_result == 1:
+ if response.status_code == 200:
+ try:
+ headers_data = response.headers
+ # print("headers_data!!!!! headers_data:{}\r\n".format(headers_data))
+ if "bz-dt" in headers_data: #bz-dt字段是否在头部数据里面 如果有就需要更新
+ bz_dt = headers_data["bz-dt"]
+ self.dev_token = bz_dt.replace(" ", "") #去掉所有的空格符
+ print("update_dev_token:{}".format(self.dev_token))
+ except Exception as e:
+ print("headers_data!!!!! error\r\n")
+ if response != None:
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ print("update_dev_token end")
+
+#OTA升级
+class OTA():
+ def __init__(self):
+ #EventMesh.subscribe("min_sys_ota",self.min_sys_ota)
+ self.downloadFileVoURL1= ""
+ self.downloadFileVoURL2= ""
+ #小系统升级,返回0,没有升级;返回,1有升级,正在执行升级;返回2,电压不够
+ def min_sys_ota(self,event=None,msg=None):
+ print("min_sys_ota")
+ signal = net.csqQueryPoll()
+ if signal == -1 or sim.getStatus() != 1:#网络不正常
+ print("min_sys_ota 无 SIM卡!!!!!!!!\r\n")
+ return 0
+ # return 0
+ response = None
+ ret_str =0
+ self.downloadFileVoURL1= ""
+ self.downloadFileVoURL2= ""
+ try:
+ sourceVersion = versions.Build_Time
+ sourceVersion = "7PIN-"+sourceVersion[:10]+"-"+sourceVersion[11:-3]
+ print("sourceVersion:{}".format(sourceVersion))
+ sourceVersion = sourceVersion.replace(" ", "0")
+ print("sourceVersion2:{}".format(sourceVersion))
+ #url = "http://iot.api.thisiot.com/ota/task?deviceId=860132060348836&sourceVersion=2024-12-20-15:35-1"
+ url = "http://dmp.raisound.com/bz-api/ota/task?deviceId={}&sourceVersion={}".format(modem.getDevImei(),sourceVersion)
+ print(url)
+ response = request.get(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("min_sys_ota1:{}".format(data))
+
+ if data:
try:
- headers_data = response.headers
- # print("headers_data!!!!! headers_data:{}\r\n".format(headers_data))
- if "bz-dt" in headers_data: #bz-dt字段是否在头部数据里面 如果有就需要更新
- bz_dt = headers_data["bz-dt"]
- self.dev_token = bz_dt.replace(" ", "") #去掉所有的空格符
- print("update_dev_token:{}".format(self.dev_token))
+ if data["code"] == 20007:#有新版本
+ if "fileList"in data["data"]:
+ if len(data["data"]["fileList"]) == 2:
+ for fileList in data["data"]["fileList"]:
+ if fileList["fileName"] == "dfota_2.bin":
+ self.downloadFileVoURL2 = fileList["url"]
+ elif fileList["fileName"] == "dfota_1.bin":
+ self.downloadFileVoURL1 = fileList["url"]
+
+ if data["code"] == 20006:#已是最新版本
+ ret_str = 0
+
except Exception as e:
- print("headers_data!!!!! error\r\n")
+ usys.print_exception(e)
+ else:
+ print("min_sys_ota get error")
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
- pass
-
-
-
-
-#阿里voice_chat状态枚举
+ print("min_sys_ota:downloadFileVoURL1:{},\ndownloadFileVoURL2:{}".format(self.downloadFileVoURL1,self.downloadFileVoURL2))
+ print("min_sys_ota end")
+ if self.downloadFileVoURL2!="" and self.downloadFileVoURL1!="":
+ battery = EventMesh.publish("get_battery")
+ if battery>=40:
+ self.ota_timer = osTimer()
+ self.ota_timer.start(15000, 0, self.ota_timer_cb)
+ ret_str = 1
+ else:
+ ret_str = 2
+ return ret_str
+
+ def ota_timer_cb(self, *args, **kwargs):
+ import fota
+ fota_obj = fota()
+ fota_obj.httpDownload(url1=self.downloadFileVoURL1,url2=self.downloadFileVoURL2)
+ #ota升级结果返回,开机时调用一次即可
+ def ota_result(self,event=None,msg=None):
+ response = None
+ try:
+ currentVersion = versions.Build_Time
+ currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3]
+ print("currentVersion1:{}".format(currentVersion))
+ currentVersion = currentVersion.replace(" ", "0")
+ print("currentVersion2:{}".format(currentVersion))
+ url = "http://dmp.raisound.com/bz-api/ota/result?deviceId={}¤tVersion={}".format(modem.getDevImei(),currentVersion)
+ print(url)
+ response = request.post(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("ota_result:{}".format(data))
+ else:
+ print("ota_result error!!!!")
+ for i in response.text:
+ print(i)
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+ #ICCID上传
+ def pots_ICCID(self,event=None,msg=None):
+ response = None
+ try:
+ iccid = sim.getIccid()
+ if iccid != -1 and len(iccid) > 5:
+ print("pots_ICCID:{}".format(iccid))
+ #Headers = {'Transfer-Encodong':'chunked'}
+ #http://dmp.raisound.com/bz-api/dev/iccid?deviceId=866610001099679&iccid=89860002192307889057
+ url = "http://dmp.raisound.com/bz-api/dev/iccid?deviceId={}&iccid={}".format(modem.getDevImei(),iccid)
+ print(url)
+ response = request.post(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("pots_ICCID:{}".format(data))
+ else:
+ print("pots_ICCID error!!!!")
+ for i in response.text:
+ print(i)
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+#阿里VC状态枚举
VC_State_None=0
VC_State_Listening=1#听
VC_State_SpeechStart=2#说开始
-VC_State_SpeechEnd=3#说结束
-VC_State_Thinking=4#想(chat)
-VC_State_Responding=5#音频播放
-VC_State_TTSStart=6
-VC_State_TTSData=7
-VC_State_TTSFinish=8
-VC_State_TTSEnd=9
-VC_State_TTSError=10
-VC_State_DialogError=11
-VC_State_End=12
+VC_State_SpeechIng=3#正在说
+VC_State_SpeechEnd=4#说结束
+VC_State_RequestToRespond=5 #TTS请求或者chat请求
+VC_State_Thinking=6#想(chat)
+VC_State_Responding=7#音频播放
+VC_State_TTSStart=8
+VC_State_TTSData=9
+VC_State_TTSFinish=10
+VC_State_TTSEnd=11
+VC_State_TTSError=12
+VC_State_DialogError=13
+VC_State_End=14
VC_record_TYPE_PCM = 0
VC_record_TYPE_AMR = 1
# AI_client_asr_num = 0
# AI_client_chat_num = 1
# AI_client_tts_num = 2
-AI_client_voice_chat_num = 3
+AI_client_VC_num = 3
+AI_client_asr_num = 4
+
+
class AI_VC(Abstract):
# AI
def __init__(self):
-
+ try:
+ self.http_get_config()#获取/更新配置参数
+ except Exception as e:
+ usys.print_exception(e)
+ self.VC_30S_timer = osTimer()
+ self.VC_30S_timer.start(30000, 1, self.VC_30S_timer_cb)
+ self.get_config_timer_count = 0
+ self.record_data_save_flag = 0 #是否保存录音文件
+ self.play_data_save_flag = 0 #是否保存tts数据到文件
+ self.record_fd = None
+ self.play_fd = None
+ self.is_VC_ACK = 0 #是否开启ack应答模式
+ self.is_long_record = 0 #是否开启长录音模式(语音打断模式)
+ self.ai_OTA = OTA()
+ self.is_auth = 0 #是否开启dmp鉴权
#self.VC_mode = 0 #0:短按连续问答模式 1:长按录音模式
- self.VC_mode = EventMesh.publish("get_storage_config","VC_mode")#音色配置
+ self.VC_mode = EventMesh.publish("get_storage_config","VC_mode")#
if self.VC_mode == None :
self.VC_mode = 0
+ self.is_up_error= 0 #是否上传错误id
+ self.error_data = []
+ self.asr_taskid = ""
+ self.VC_taskid = ""
+ self.VC_server = 2 #0柒牌正式服务器,1:测试服务器1,2:测试服务器2
+
+ self.server_ip = EventMesh.publish("get_storage_config","server_ip")#
+ if self.server_ip == None:
+ if self.VC_server == 1:#
+ self.server_ip="118.145.158.207:22083"
+ elif self.VC_server == 2:#
+ self.server_ip="118.145.158.207:22082"
+ elif self.VC_server == 4:#
+ self.server_ip="118.145.158.207:22084"
+ elif self.VC_server == 5:#
+ self.server_ip="amp-wss.raisound.com"
+ elif self.VC_server == 6:#
+ self.server_ip="118.145.158.207:22080"
+ else:
+ self.server_ip="sevenpin.qipai.com.cn"
+
+ if dev_type == 'momo':#
+ self.server_ip="118.145.158.207:22080"
+ elif dev_type == "7PIN":
+ self.server_ip="sevenpin.qipai.com.cn"
+ elif dev_type == "sjgq":
+ self.server_ip="118.145.158.207:22084"
+ #开机提示音
+ self.power_on_tone = EventMesh.publish("get_storage_config","power_on_tone")#
+ if dev_type != "7PIN":
+ self.power_on_tone = None
+ if self.power_on_tone == None:
+ if dev_type == "G10":
+ self.power_on_tone = "已开机,您好!我是北科瑞讯智能 AI bot_name"
+ elif dev_type == "7PIN_BK":
+ self.power_on_tone = "小瑞来了!我们一起来愉快地聊天吧!"
+ elif dev_type == "momo":
+ self.power_on_tone = "DuloDulo,我是上古神兽食梦貘,主人可以叫我momo,我来自《山海经》,是一只以梦为食的神秘灵兽,每当颜色朦胧、人们入睡时,我就会悄悄飞到人们的床头,用我长长的鼻子把噩梦统统吞噬掉,只留下甜甜的美梦。从今往后,就由我守护在主人身边,一起度过每一个星河璀璨的夜晚。"
+ elif dev_type == "sjgq":
+ self.power_on_tone = "您好!我是巴马四季甘泉的智能助手。我可以为你解答各种各样的问题,像是有关巴马四季甘泉知识库、中基长寿科学产品、卫斯曼院士国际先进医疗中心的问题,还有日常生活与工作、旅游信息、健康咨询、教育与学习、情感交流、全球资讯、世界文化等方面的问题哦。你有没有这方面的问题想要问我呀?"
+ else:
+ self.power_on_tone = "您好!我是世界首创柒牌男装AI生活好帮手-bot_name, 很高兴为您服务,我可以帮您解答柒牌公司知识库、日常生活与工作、旅游信息、健康与运动咨询、教育与学习、情感交流、全球资讯、世界文化等问题!请问您有什么需要我帮忙的吗?"
+
- self.VC_server = 2 #0正式服务器,1:测试服务器1,2:测试服务器2
self.VC_record_TYPE = VC_record_TYPE_PCM #0:PCM 1:AMR
self.VC_play_TYPE = VC_play_TYPE_PCM #0:PCM 1:mp3
self.VC_record_samplerate = 16000
self.VC_play_samplerate = 16000
- #女,男,童,粤,川
- self.VC_TTS_voice_type = {0:"huoshan::zh_female_xinlingjitang_moon_bigtts",1:"huoshan::zh_male_wennuanahu_moon_bigtts",2:"huoshan::ICL_zh_female_huoponvhai_tob",
- 3:"aliyun::longjiaxin",4:"huoshan::zh_female_daimengchuanmei_moon_bigtts"}
- #self.VC_TTS_voice_type = ["aliyun::longxiaoxia","aliyun::longnan","aliyun::longling"]
- self.VC_TTS_voice_num = EventMesh.publish("get_storage_config","VC_TTS_voice_num")#音色配置
- if self.VC_TTS_voice_num == None or self.VC_TTS_voice_num>=len(self.VC_TTS_voice_type):
- self.VC_TTS_voice_num = 0
-
- self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
+
+ self.VC_TTS_voice_type = EventMesh.publish("get_storage_config","VC_TTS_voice_type")#音色配置
+ if self.VC_TTS_voice_type == None or ("男" in self.VC_TTS_voice_type) == False:
+ if dev_type == "G10" or dev_type == "7PIN_BK":
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"小瑞",
+ "voice":"zh_female_wanwanxiaohe_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"小瑞",
+ "voice":"zh_male_wennuanahu_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"小瑞",
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ "粤":{
+ "bot_name":"小瑞",
+ "voice":"zh_female_wanqudashu_moon_bigtts" ,
+ "lang":"zh-hk"
+ },
+ "四川":{
+ "bot_name":"小瑞",
+ "voice":"zh_female_daimengchuanmei_moon_bigtts",
+ "lang":"&lang=zh-cn-sc"
+ },
+ "个性":{
+ "bot_name":"小瑞",
+ "voice":"zh_male_sunwukong_mars_bigtts" ,
+ "lang":"zh-cn"
+ }
+
+ }
+ elif dev_type == 'momo':
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"食梦貘",
+ "voice":"zh_female_shaoergushi_mars_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"食梦貘",
+ "voice":"zh_male_yangguangqingnian_mars_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"食梦貘",
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ }
+ elif dev_type == 'sjgq':
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"小巴",
+ "voice":"zh_female_wanwanxiaohe_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"小巴",
+ "voice":"zh_male_wennuanahu_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"小巴",
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ }
+ else:
+ #女,男,童,粤,川,个性声
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"柒妹妹",
+ "voice":"huoshan::zh_female_wanwanxiaohe_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::zh_male_wennuanahu_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"柒乐乐",
+ "voice":"huoshan::ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ "粤":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::zh_female_wanqudashu_moon_bigtts" ,
+ "lang":"zh-hk"
+ },
+ "四川":{
+ "bot_name":"柒妹妹",
+ "voice":"huoshan::zh_female_daimengchuanmei_moon_bigtts",
+ "lang":"&lang=zh-cn-sc"
+ },
+ "个性":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::zh_male_sunwukong_mars_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "英语":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::en_male_smith_mars_bigtts" ,
+ "lang":"zh-cn"
+ }
+
+
+ }
+
+ # self.VC_TTS_voice_type = {0:"zh_female_xinlingjitang_moon_bigtts",1:"zh_male_wennuanahu_moon_bigtts",2:"ICL_zh_female_huoponvhai_tob",
+ # 3:"aliyun::longjiaxin",4:"zh_female_daimengchuanmei_moon_bigtts"}
+ #self.VC_TTS_voice_type = ["aliyun::longxiaoxia","aliyun::longnan","aliyun::longling"]
+
+ #EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type])
+
+ try:
+ self.VC_TTS_voice_key = EventMesh.publish("get_storage_config","VC_TTS_voice_key")#音色配置
+ if self.VC_TTS_voice_key == None :
+ if dev_type == "7PIN_BK":
+ self.VC_TTS_voice_key = "童"
+ elif dev_type == "momo":
+ self.VC_TTS_voice_key = "男"
+ else:
+ self.VC_TTS_voice_key = "男"
+ if self.VC_TTS_voice_key in self.VC_TTS_voice_type:
+ pass
+ else:
+ self.VC_TTS_voice_key = list(self.VC_TTS_voice_type.keys())[0]
+ print("音色配置:{}:{}\r\n\r\n".format(self.VC_TTS_voice_key,self.VC_TTS_voice_type[self.VC_TTS_voice_key]))
+ self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
+ except Exception as e:
+ usys.print_exception(e)
+
if self.VC_TTS_volume == None:
self.VC_TTS_volume = 100
self.AI_audio_queue_thread_id = 0
- self.AI_send_data_queue_thread_id = 0
-
+ self.AI_audio_queue_thread_lock = 0
+ self.AI_VC_send_data_queue_thread_id = 0
+ self.AI_VC_send_data_queue_thread_lock = 0
+ self.AI_ASR_send_data_queue_thread_id = 0
+ self.AI_ASR_send_data_queue_thread_lock = 0
self.AI_record_tmp_queue = Queue(100)
- self.AI_send_data_queue = Queue(100)
+ self.AI_ASR_send_data_queue = Queue(200)
+ self.AI_VC_send_data_queue = Queue(100)
self.AI_audio_queue = Queue(100)
+ #self.AI_WS_connect_Queue = Queue(100) #释放用
self.AI_TTS_str = ""
+ self.AI_ASR_str = ""
+ self.AI_ASR_flag = 0
+ self.AI_ASR_str_tmp = ""
+ self.AI_ASR_send_buf_len = 0
+ self.AI_ASR_text_tmp = ""
+ self.AI_ASR_text_repet_count = 0
# #开始线程
# if self.AI_audio_queue_thread_id ==0:
# self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ())
# else:
# print("AI_VC_start :AI_audio_queue_thread_id != 0 ")
- # if self.AI_send_data_queue_thread_id == 0:
- # self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ())
+ # if self.AI_VC_send_data_queue_thread_id == 0:
+ # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ())
- self.voice_chat_state = VC_State_None #阿里ai voice_chat状态
- self.VC_dialog_id = ""
+ self.VC_state = VC_State_None #阿里ai VC状态
+ self.VC_dialog_id = ""#
self.VC_message_id=None
self.VC_task_id =None
- self.AI_client_voice_chat = None
- self.AI_client_voice_chat_recv_id = 0
- self.AI_client_voice_chat_isconnect =0
+ self.AI_client_VC = None
+ self.AI_client_VC_recv_id = 0
+ self.AI_client_VC_recv_lock = 0
+ self.AI_client_VC_isconnect =0
+ self.AI_client_VC_debug =0
+
+ self.asr_state = VC_State_None #阿里VC_ASR VC状态
+ self.key_state = 0
- self.AI_client_ASR = None
- self.AI_client_ASR_recv_id = 0
- self.AI_client_ASR_isconnect =0
+ self.AI_client_asr = None
+ self.AI_client_asr_recv_id = 0
+ self.AI_client_asr_recv_lock = 0
+ self.AI_client_asr_isconnect =0
+ self.AI_ASR_timer = osTimer()
+ self.AI_ASR_timer_count = 0
+ self.AI_client_asr_debug =0
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
+ self.VC_Thinking_timerout = 0
+ self.VC_Speech_end_timerout = 0
self.record_pcm = None
self.play_pcm = None
self.VC_record_thread_id = 0
- self.pingping_timerout = 0
-
+ self.VC_record_thread_lock = 0
+ self.VC_pingping_timerout = 0
+ self.asr_pingping_timerout = 0
self.factory_timer = osTimer()
self._1S_timer = osTimer()
self.Audio_buf_size = 16*1024
self.record = audio.Record()
#self.record.end_callback(self.record_callback)
self.record.gain_set(4,10)
+ #self.record.gain_set(4,12)
self.aud = audio.Audio(0)
self.aud.setCallback(self.audio_cb)
- self.aud.setVolume(self.VC_TTS_volume //10)
+ #self.aud.setVolume(self.VC_TTS_volume //10)
self.audio_play_state = 1 #音频播放完状态
self.close_timerout = 0
self.LocalRespondingEnded_timerout = 0
self.play_flag = 0
self.VC_record_state_flag = 0
self.AI_key_long_press_flag = 0
- self.websocket_error_voice_chat_count = 0
- self.play_data_len = 0
+ self.websocket_error_count = 0
+
+ self.tts_in_data_len = 0
+ self.tts_out_data_len = 0
+ self.VC_satrt_flag = 0
+ self.session_id = ""
EventMesh.subscribe("AI_key_press", self.AI_key_press)
EventMesh.subscribe("AI_key_release", self.AI_key_release)
EventMesh.subscribe("AI_key_long_press", self.AI_key_long_press)
EventMesh.subscribe("pwk_key_release", self.pwk_key_release)
EventMesh.subscribe("get_AI_audio_queue", self.get_AI_audio_queue)
+ EventMesh.subscribe("get_VC_satrt_flag", self.get_VC_satrt_flag)
+ EventMesh.subscribe("VC_error", self.VC_error)
EventMesh.publish("close_led")
- #开机提示语,如果联网失败,直接提示信号弱
- #女,男,童,粤,川
+
self.bot_name = "柒先生"
- if self.VC_TTS_voice_num == 0 or self.VC_TTS_voice_num == 3 or self.VC_TTS_voice_num == 4:
- self.bot_name = "柒妹妹"
- elif self.VC_TTS_voice_num == 1:
- self.bot_name = "柒先生"
- elif self.VC_TTS_voice_num == 2:
- self.bot_name = "柒思思"
- self.AI_TTS_str = "您好!我是柒牌 AI 智能男装生活好帮手-{}, 很高兴为您服务,我可以帮您解答日常生活、工作,旅游信息、健康咨询、教育与学习、情感交流、全球资讯等问题!请问您有什么需要我帮忙的吗?".format(self.bot_name )
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ try:
+ if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]:
+ self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"]
+ else:
+ print("not bot_name!!!!!!!!!!!!!!!!!!!!!!")
+ except Exception as e:
+ usys.print_exception(e)
+ try:
+ if self.ai_OTA.min_sys_ota()==1:
+ #if 0:
+ self.AI_TTS_str = "检测到有新版本需要升级啦!升级时可千万别断电或乱按哦,升级完成后设备会自动重启,重启就代表升级成功"
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ # if self.ai_OTA.min_sys_ota()==2:
+ # self.AI_TTS_str = "检测到有新版本需要升级啦!电量低于40%,无法保证升级正常执行,请充满电后重启设备再次升级!"
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ else:
+ try:
+ self.ai_OTA.ota_result()
+ self.ai_OTA.pots_ICCID()
+ except Exception as e:
+ usys.print_exception(e)
+ #开机提示语,如果联网失败,直接提示信号弱
+
+ #"voice":{"女":"柒妹妹-huoshan::zh_female_wanwanxiaohe_moon_bigtts","男":"柒先生-huoshan::zh_male_wennuanahu_moon_bigtts","童":"柒乐乐huoshan::ICL_zh_female_huoponvhai_tob","广东":"柒先生-huoshan::zh_female_wanqudashu_moon_bigtts","四川":"柒妹妹-huoshan::zh_female_daimengchuanmei_moon_bigtts","个性":"柒先生-zh_male_sunwukong_mars_bigtts"}
+ #EventMesh.publish("get_storage_config",["powerRestart",1])
+ powerRestart = EventMesh.publish("get_storage_config","powerRestart")#=1非正常重启
+ if powerRestart == None:
+ powerRestart = 0
+ if powerRestart == 1:
+ EventMesh.publish("set_storage_config",["powerRestart",0])
+
+ else:
+
+ self.AI_TTS_str = self.power_on_tone.replace("bot_name", self.bot_name)
+ print("开机提示:{}".format(self.AI_TTS_str))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
+
+
+ except Exception as e:
+ usys.print_exception(e)
+
def post_processor_after_instantiation(self):
pass
def get_AI_audio_queue(self, event, msg):
return self.AI_audio_queue
+ def get_VC_satrt_flag(self, event, msg):
+ return self.VC_satrt_flag
+
+
+ def VC_30S_timer_cb(self, *args): #
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_30S_timer_cb_})
+
+ def VC_30S_timer_cb_(self):
+ self.get_config_timer_count += 1
+ if self.get_config_timer_count >= 2*60*2:#2小时更新配置参数
+ self.get_config_timer_count = 0
+ try:
+ self.http_get_config()#获取/更新配置参数
+ except Exception as e:
+ usys.print_exception(e)
+ #提交错误id
+ def ud_error(self,error_data):
+ response = None
+ if self.is_up_error == 1:
+ try:
+ # currentVersion = versions.Build_Time
+ # currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3]
+ url = "http://{}/health?task_id={}".format(self.server_ip,error_data[0]+error_data[1])
+ print(url)
+ response = request.get(url,timeout=5)
+ if response.status_code == 200:
+
+ print("ud_error:ok")
+ else:
+ print("ud_error error!!!!")
+ for i in response.text:
+ print(i)
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+ #获取配置参数
+ def http_get_config(self, event=None, msg=None):
+ print("http_get_config")
+
+ response = None
+ #http://180.184.206.142/bz-api/dev/config?deviceId=xxx
+ try:
+ url = "http://dmp.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei())
+ print(url)
+ response = request.get(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("http_get_config:{}".format(data))
+
+ if data:
+ try:
+ if data["code"] == 20000:#有配置
+ if data["data"] :
+ if "version" in data["data"]:
+ config_version = EventMesh.publish("get_storage_config","config_version")#音量配置
+ if config_version != data["data"]["version"]:
+ config_version = data["data"]["version"]
+ EventMesh.publish("set_storage_config",["config_version",config_version])
+ if "VC_TTS_voice_type" in data["data"]:
+ self.VC_TTS_voice_type = data["data"]["VC_TTS_voice_type"]
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type])
+ print("配置VC_TTS_voice_type成功")
+ if "server_ip" in data["data"]:
+ self.server_ip = data["data"]["server_ip"]
+ EventMesh.publish("set_storage_config",["server_ip",self.server_ip])
+ print("配置server_ip成功")
+ if "power_on_tone" in data["data"]:
+ self.power_on_tone = data["data"]["power_on_tone"]
+ EventMesh.publish("set_storage_config",["power_on_tone",self.power_on_tone])
+ print("配置power_on_tone成功")
+
+ except Exception as e:
+ usys.print_exception(e)
+ else:
+ print("status_code:{}".format(response.status_code))
+ print("http_get_config:error!!!!!!!!!!")
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+
def audio_cb(self,event):
if event == 0:
self.audio_play_state =1
print('audio-play finish.!!!!!!')
def AI_key_press(self, event, msg):#按键按下
- print("AI_key_press voiceCall")
- self.aud.aud_tone_play(16,200)#播放按键音
- # import voiceCall
- # voiceCall.callStart("10086")
- # return
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ print("AI_key_press")
+ self.get_config_timer_count = 0
+ self.key_state = 1
+ #self.aud.aud_tone_play(10,200)#播放按键音
+ self.AI_TTS_str = ""#"你好,有什么吩咐"
+ self.AI_ASR_str = ""
+ self.AI_ASR_str_tmp = ""
+ self.VC_state = VC_State_None
+ # if self.VC_state != VC_State_None:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ # EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(10)})
+ #if self.VC_record_state_flag >1:#如果在录音,就先停止录音
+ self.VC_Speech_End()
+
+ self.VC_Speech_Start()
+ self.AI_VC_start()
+ # self.Close()
+ # self.AI_VC_start()
self.AI_key_long_press_flag = 0
def AI_key_release(self, event, msg):#按键弹起
print("AI_key_release123")
+ self.key_state = 0
if self.AI_key_long_press_flag == 1 :#有长按
- self.AI_client_voice_chat_end_speech()
+ #self.AI_client_VC_end_speech()
+ EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_asr_StopTranscription_requset})
+ #self.AI_client_asr_StopTranscription_requset()#请求停止
+ if self.VC_mode == 1 :#长按单次问答模式
+ if self.AI_ASR_str_tmp != "":
+ print("AI_key_release:asr_str:{}".format(self.AI_ASR_str))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
else :
if self.VC_mode == 1 :#长按单次问答模式
- EventMesh.publish("audio_montage_play",["key_prompt.mp3"])
- #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可
- self.AI_send_data_queue.clear()
- try:
- self.websocket_deconnect_voice_chat()
- except Exception as e:
- usys.print_exception(e)
- self.VC_Speech_End()
+ # try:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ # except Exception as e:
+ # usys.print_exception(e)
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.key_prompt}) #提示请您按住中间的按钮开始讲话,讲完松开即可
+ self.AI_TTS_str = "请您按住中间的按钮开始讲话,讲完松开即可 "
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
+
+ #self.VC_Speech_End()
def AI_key_long_press(self, event, msg):#按键长按
print("AI_key_long_press")
self.AI_key_long_press_flag = 1
def pwk_key_release(self, event, msg):#电源键短按,关闭
print("pwk_key_release")
EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
-#**********************************ASR连接**********************************************************
- def websocket_connect_ASR(self):
- print("websocket_connect_ASR:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_ASR_isconnect))
- if self.AI_client_ASR_isconnect == 1:
+
+ def key_prompt(self):
+ EventMesh.publish("audio_montage_play",["key_prompt.mp3"])
+ #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可
+ def VC_error(self, event, msg):#错误播报
+ self.websocket_error()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
+#****************************************ASR连接**********************************************************************
+ def websocket_connect_asr(self):
+ print("websocket_connect_asr:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_asr_isconnect,self.AI_client_asr_debug))
+ self.AI_ASR_text_repet_count = 0
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
+ self.AI_ASR_text_tmp = ""
+ if self.AI_client_asr_isconnect == 1:
return
- # 创建VC客户端
+ # 创建ASR客户端
try:
signal = net.csqQueryPoll()
if signal == -1 or sim.getStatus() != 1:#网络正常
- self.websocket_error_ASR()
+ self.websocket_error()
return
- # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
- # self.AI_client_ASR = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
- if self.VC_server == 1 or self.VC_server == 2:#
- self.AI_client_ASR = uwebsocket.Client.connect('ws://amp.raisound.com/asr/ws', debug=False)#测试环境
- else:
- token = EventMesh.publish("get_dev_token")
- print("token:{}".format(token))
- if token != None:
- self.AI_client_ASR = uwebsocket.Client.connect('ws://amp.raisound.com/asr/ws?dt={}'.format(token), debug=False)
+
+ # self.AI_client_asr = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
+ req_str = ""
+ platform = "platform=huoshan"
+ #platform= "platform=xfyun-ita"
+ platform= "platform=xfyun-bigmodel-ita"
+ lang = "lang=zh-cn"#普通话测试环境
+ try:
+ if "loang" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]:
+ lang = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["lang"]
else:
- self.websocket_error_ASR()
+ print("not lang!!!!!!!!!!!!!!!!!!!!!!")
+ except Exception as e:
+ usys.print_exception(e)
+ req_str = "asr/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
+ print("req_str:{}".format(req_str))
+ token = EventMesh.publish("get_dev_token")
+ print("token:{}".format(token))
+ url = 'ws://{}/{}&dt={}'.format(self.server_ip,req_str,token)
+ print("websocket_connect_asr URL:{}".format(url))
+ self.AI_client_asr = uwebsocket.Client.connect(url, debug=True)#
+ #self.AI_WS_connect_Queue.put(self.AI_client_asr)
+
except Exception as e: #网络连接异常
usys.print_exception(e)
- print("websocket_connect_ASR error!!!\r\n")
- #self.connect_timerout_popup(2)
+ print("websocket_connect_asr error!!!\r\n")
+ #self.connect_timerout_popup(2)
+ str_error = str(e)
+ if str_error.find("[Errno 22] EINVAL")!= -1:
+ self.websocket_error()
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ EventMesh.publish("set_storage_config",["powerRestart",1])#调试临时关闭
+ utime.sleep_ms(1000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ Power.powerRestart()
+
+ self.websocket_error()
- if self.AI_client_ASR == None:
- EventMesh.publish("update_dev_token")#获取token
return
-
- # 线程接收数据
- if self.AI_client_ASR_recv_id != 0:
- try:
- _thread.stop_thread(self.AI_client_ASR_recv_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_client_ASR_recv_id = 0
+ if self.AI_client_asr == None:
+ EventMesh.publish_async("update_dev_token",thread_size = 8192)#获取token
+ return
+ self.AI_client_asr_debug+=1
+ utime.sleep_ms(10)
+ #self.AI_client_asr.settimeout(5)
+ #开启发送线程
+ if self.AI_ASR_send_data_queue_thread_id == 0:
+ _thread.stack_size(self.Audio_buf_size+8*1024)
+ self.AI_ASR_send_data_queue_thread_id = _thread.start_new_thread(self.AI_ASR_send_data_queue_thread, ())
+ _thread.stack_size(8*1024)
+ print("AI_VC_start :AI_ASR_send_data_queue_thread_id :{} ".format(self.AI_ASR_send_data_queue_thread_id))
+ print("websocket_connect_asr 222!!!\r\n")
+ self.AI_client_asr_recv_thread_close()#关闭读线程
+ # 创建线程接收数据
_thread.stack_size(self.Audio_buf_size+8*1024)
- self.AI_client_ASR_recv_id = _thread.start_new_thread(self.AI_client_ASR_recv, (self.AI_client_ASR,))
+ self.AI_client_asr_recv_id = _thread.start_new_thread(self.AI_client_asr_recv, (self.AI_client_asr,))
_thread.stack_size(8*1024)
- self.AI_client_ASR_isconnect = 1
- def websocket_error_ASR(self):
- print("websocket_error_ASR!!!!")
- print("websocket_error_ASR!!!!")
- EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"])
- #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3')
- self.AI_send_data_queue.clear()
- self.AI_audio_queue.clear()
- self.VC_Speech_End()
- EventMesh.publish("close_led")
- try:
- self.websocket_deconnect_ASR()
- except Exception as e:
- usys.print_exception(e)
+ self.AI_client_asr_isconnect = 1
+ self.AI_ASR_timer.start(1000, 1, self.AI_ASR_timer_cb)
+ self.AI_client_asr_start_requset()#开始请求
+ print("websocket_connect_asr:OK!!!!!!!!!!!!!!!!!!!!!")
- def websocket_deconnect_ASR(self):
- print("websocket_deconnect_ASR {}!!!!!!!".format(self.AI_client_ASR_isconnect))
- print("websocket_deconnect_ASR!!!!!!!")
- if self.AI_client_ASR_recv_id != 0:#关闭线程
+ def websocket_deconnect_asr(self):
+ print("websocket_deconnect_asr {}!!!!!!!".format(self.AI_client_asr_isconnect))
+ print("websocket_deconnect_asr!!!!!!!")
+ self.AI_ASR_text_repet_count = 0
+ self.AI_ASR_text_tmp = ""
+ self.AI_ASR_timer.stop()
+ #self.AI_ASR_send_data_queue_thread_close()#关闭发送线程
+ self.AI_client_asr_recv_thread_close()#关闭读线程
+ if self.AI_client_asr_isconnect == 1 or self.AI_client_asr!= None:
try:
- _thread.stop_thread(self.AI_client_ASR_recv_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_client_ASR_recv_id = 0
- if self.AI_client_ASR_isconnect == 1:
- self.AI_client_ASR_isconnect = 0
- self.AI_client_ASR.close()
- print("websocket_deconnect_ASR {}!!!!!!!".format(self.AI_client_ASR_isconnect))
- #Ai ASR websocket返回数据
- def AI_client_ASR_recv(self,cli):
- while True:
- try:
- # 死循环接收数据
- utime.sleep_ms(1)
- recv_data = cli.recv()
- self.close_timerout = 0#服务器有返回清零退出时间
- if not recv_data:
- # 服务器关闭连接或客户端关闭连接
- print("AI_client_ASR_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- #self.AI_client_ASR_isconnect = 0
- #self.websocket_deconnect_ASR()
- break
+ self.AI_client_asr_isconnect = 0
+ count = 500
+ while True:#等待发完数据
+ count-=1
+ if count <=0 or self.AI_ASR_send_data_queue_thread_lock == 0:
+ break
+ print("等待发送完成:{}".format(count))
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ utime.sleep_ms(1)
+
try:
- if isinstance(recv_data, str):#返回的是字符串
- print("ASR:recv_data:{}".format(recv_data))
- jsload_data = ujson.loads(recv_data)
+ self.AI_client_asr_StopTranscription_requset()#发送停止ASR
+ self.AI_client_asr.close()
+ except Exception as e:
+ usys.print_exception(e)
+ utime.sleep_ms(200)#再尝试关闭一次
+ try:
+ self.AI_client_asr.close()
-
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_asr_debug-=1
+ try:
+ self.AI_client_asr._close()
except Exception as e:
usys.print_exception(e)
-
+ self.AI_client_asr = None
except Exception as e:
- usys.print_exception(e)
- #self.websocket_error_ASR()
-
- break
- self.AI_client_ASR_isconnect = 0
- self.AI_client_ASR_recv_id = 0
-
-#****************************************VC连接**********************************************************************
- def websocket_connect_voice_chat(self):
- print("websocket_connect_voice_chat:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_voice_chat_isconnect))
- if self.AI_client_voice_chat_isconnect == 1:
- return
- # 创建VC客户端
- try:
- signal = net.csqQueryPoll()
- if signal == -1 or sim.getStatus() != 1:#网络正常
- self.websocket_error_voice_chat()
- return
- # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
- # self.AI_client_voice_chat = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
- if self.VC_server == 1:#
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws', debug=False)#测试环境
- elif self.VC_server == 2:#
- if self.VC_TTS_voice_num <= 2:
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-cn', debug=False)#普通话测试环境
- elif self.VC_TTS_voice_num == 3:
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-hk', debug=False)#粤语测试环境
- elif self.VC_TTS_voice_num == 4:
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-cn-sc', debug=False)#四川话测试环境
+ usys.print_exception(e)
+ print("websocket_deconnect_asr {}!!!!!!!".format(self.AI_client_asr_isconnect))
+
+ #websocket发送数据
+ def AI_client_asr_send(self,data_str):
+ # if isinstance(data_str, str):#是字符串
+ # print("ASR ASR AI_client_asr_send:{}".format(data_str))
+ # pass
+ # else:
+ # pass
+ # #print("ASR ASR AI_client_asr_send:len:{}".format(len(data_str)))
+ self.AI_ASR_send_data_queue.put([AI_client_asr_num,data_str])
+
+ def AI_client_asr_ping(self):
+ pass
+ if self.AI_client_asr_isconnect == 1:
+ #self.AI_client_asr.write_frame(0x09,b'ping ping')
+ self.AI_client_asr_send("ping")
+ def set_AI_ASR_flag(self,data):
+ self.AI_ASR_flag = data
+ def AI_ASR_timer_cb(self, *args): #
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_ASR_timer_cb_})
+
+ def AI_ASR_timer_cb_(self):
+ if self.AI_ASR_check_timeout > 0:
+ print("AI_ASR_check_timeout:{}".format(self.AI_ASR_check_timeout))
+ self.AI_ASR_check_timeout-=1
+ if self.AI_ASR_check_timeout <=0:
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 3#发送停止后3秒后没正式结果就提示
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_asr_StopTranscription_requset})
+
+ if self.AI_ASR_error_timeout>0:
+ self.AI_ASR_error_timeout-=1
+ print("AI_ASR_error_timeout:{}".format(self.AI_ASR_error_timeout))
+ if self.AI_ASR_error_timeout <= 0:
+ self.AI_ASR_error_timeout = 0
+ #if self.AI_ASR_str == "":
+ if self.AI_ASR_str_tmp == "" and self.AI_ASR_str == "" and self.AI_ASR_text_tmp == "":
+ self.AI_TTS_str = "没有识别到您说话,请重试"
else :
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-cn', debug=False)#普通话测试环境
- else:
- token = EventMesh.publish("get_dev_token")
- print("token:{}".format(token))
- if token != None:
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://amp.raisound.com/voice-chat/ws?dt={}'.format(token), debug=False)
+ self.AI_ASR_str = self.AI_ASR_str_tmp + self.AI_ASR_str+self.AI_ASR_text_tmp
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
+ print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
+ print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连ASR
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) #重连ASR
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.set_AI_ASR_flag,"data":1})#设置以打断过一次
+ if self.VC_record_state_flag > 1:
+ self.VC_record_state_flag =1
+ pass
+ #关闭ASR数据发送线程
+ def AI_ASR_send_data_queue_thread_close(self):
+ if self.AI_ASR_send_data_queue_thread_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_ASR_send_data_queue_thread_lock == 0 or count <=0:
+ break
else:
- self.websocket_error_voice_chat()
- return
- except Exception as e: #网络连接异常
- usys.print_exception(e)
- print("websocket_connect_voice_chat error!!!\r\n")
- #self.connect_timerout_popup(2)
- self.websocket_error_voice_chat()
- return
- if self.AI_client_voice_chat == None:
- EventMesh.publish("update_dev_token")#获取token
- self.websocket_error_voice_chat()
- return
-
- # 线程接收数据
- if self.AI_client_voice_chat_recv_id != 0:
+ self.AI_ASR_send_data_queue_thread_lock = 2
+ print("AI_ASR_send_data_queue_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_ASR_send_data_queue_thread_lock = 0
+ print("AI_ASR_send_data_queue_thread_close")
try:
- _thread.stop_thread(self.AI_client_voice_chat_recv_id)
+ _thread.stop_thread(self.AI_ASR_send_data_queue_thread_id)
except Exception as e:
- usys.print_exception(e)
- self.AI_client_voice_chat_recv_id = 0
- _thread.stack_size(self.Audio_buf_size+8*1024)
- self.AI_client_voice_chat_recv_id = _thread.start_new_thread(self.AI_client_voice_chat_recv, (self.AI_client_voice_chat,))
- _thread.stack_size(8*1024)
- self.AI_client_voice_chat_isconnect = 1
- def websocket_error_voice_chat(self):
- print("websocket_error_voice_chat!!!!")
- print("websocket_error_voice_chat!!!!")
- print("websocket_error_voice_chat!!!!")
- print("websocket_error_voice_chat!!!!")
- self.websocket_error_voice_chat_count+=1
- if self.websocket_error_voice_chat_count <=3:
- EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
- elif self.websocket_error_voice_chat_count <10 :
- EventMesh.publish("audio_montage_play",["xinhaoruo2.mp3"])
- elif self.websocket_error_voice_chat_count >=10:
- EventMesh.publish("paly_iccid_imei")
- else:
- EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"])
- #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3')
- self.AI_send_data_queue.clear()
- self.AI_audio_queue.clear()
- self.VC_Speech_End()
- EventMesh.publish("close_led")
- try:
- self.websocket_deconnect_voice_chat()
- except Exception as e:
usys.print_exception(e)
+ self.AI_ASR_send_data_queue_thread_id = 0
+ #发送数据队列
+ def AI_ASR_send_data_queue_thread(self):
+ print("AI_ASR_send_data_queue_thread:start")
+ count_t = 0
+ while True:
+ if self.AI_ASR_send_data_queue_thread_lock == 2:
+ print("AI_ASR_send_data_queue_thread:该退出了")
+ break
+ if self.AI_ASR_send_data_queue.empty() :#不能去掉,去掉会卡死
+ self.AI_ASR_send_data_queue_thread_lock = 0
+ count_t+=1
+ utime.sleep_ms(1)
+ else:
+ #data[0]是websocket连接对象编号,data[1]是数据
+ #print("AI_ASR_send_data_queue_thread:get")
+
+ self.AI_ASR_send_data_queue_thread_lock = 1
+ data = self.AI_ASR_send_data_queue.get()
+ #print("AI_ASR_send_data_queue_thread:num{} len{}".format(data[0],len(data[1])))
+ if data != None:
+ try:
+ # 发送数据
+ if data[0] == AI_client_asr_num:
+ self.AI_ASR_send_buf_len -= len(data[1])
+ self.asr_pingping_timerout = 0
+ if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
+ self.AI_client_asr.send(data[1])
+ if isinstance(data[1], str):#是字符串
+ print("ASR ASR: send_data:{}".format(data[1]))
+ # else:
+ # print("ASR ASR: send_data!:{}".format(len(data[1])))
+ else:
+ if isinstance(data[1], str):#是字符串
+ print("ASR ASR: send_data error!!!:{}".format(data[1]))
+ else:
+ print("ASR ASR: send_data error!!!:{}".format(len(data[1])))
+
+ except Exception as e:
+ usys.print_exception(e)
+ if data[0] == AI_client_asr_num:
+ if self.AI_client_asr_isconnect != 0:
+ print("ASR发送数据错误,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR发送出错了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连
+ utime.sleep_ms(1)
+ self.AI_ASR_send_data_queue_thread_lock = 0
- def websocket_deconnect_voice_chat(self):
- print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
- print("websocket_deconnect_voice_chat!!!!!!!")
- if self.AI_client_voice_chat_recv_id != 0:#关闭线程
+ #ASR关闭读线程
+ def AI_client_asr_recv_thread_close(self):
+ if self.AI_client_asr_recv_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_client_asr_recv_lock == 1:
+ self.AI_client_asr_recv_lock = 2
+ if self.AI_client_asr_recv_lock == 0 or count <=0:
+ break
+ else:
+ print("AI_client_asr_recv_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_client_asr_recv_lock = 0
+ print("AI_client_asr_recv_thread_close")
try:
- _thread.stop_thread(self.AI_client_voice_chat_recv_id)
+ _thread.stop_thread(self.AI_client_asr_recv_id)
except Exception as e:
usys.print_exception(e)
- self.AI_client_voice_chat_recv_id = 0
- if self.AI_client_voice_chat_isconnect == 1:
- self.AI_client_voice_chat_isconnect = 0
- self.AI_client_voice_chat.close()
- print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
- #websocket发送ping
- def AI_client_voice_chat_ping(self):
- pass
- if self.AI_client_voice_chat_isconnect == 1:
- #self.AI_client_voice_chat.write_frame(0x09,b'ping ping')
- self.AI_client_voice_chat_send("ping")
- #print("websocket ping ping")
+ self.AI_client_asr_recv_id = 0
- #websocket发送数据
- def AI_client_voice_chat_send(self,data_str):
- if isinstance(data_str, str):#是字符串
- print("AI_client_voice_chat_send:{}".format(data_str))
- pass
- # else:
- # print("AI_client_voice_chat_send:len{}".format(len(data_str)))
- self.AI_send_data_queue.put([AI_client_voice_chat_num,data_str])
-
- #Ai VC websocket返回数据
- def AI_client_voice_chat_recv(self,cli):
+ #Ai ASR websocket返回数据
+ def AI_client_asr_recv(self,cli):
while True:
try:
# 死循环接收数据
+ self.AI_client_asr_recv_lock = 0
utime.sleep_ms(1)
recv_data = cli.recv()
+ if self.AI_client_asr_recv_lock == 2:#要关闭线程了
+ print("AI_client_asr_recv 该退出了")
+ break
+ self.AI_client_asr_recv_lock = 1
self.close_timerout = 0#服务器有返回清零退出时间
- if not recv_data:
- # 服务器关闭连接或客户端关闭连接
- print("AI_client_voice_chat_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- #self.AI_client_voice_chat_isconnect = 0
- #self.websocket_deconnect_voice_chat()
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error_voice_chat})
- EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ if recv_data == "websocket close":
+ # 服务器关闭连接
+ print("ASR 服务器主动关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR连接断开了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
+ break
+ elif recv_data == "":#客户端关闭连接
+ print("ASR ASR :客户端关闭连接")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR连接断开了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
break
try:
- self.websocket_error_voice_chat_count = 0
- print("AI_client_voice_chat_recv 1")
- if isinstance(recv_data, str):#返回的是字符串
- print("VC:recv_data:{}".format(recv_data))
+ if isinstance(recv_data, str):
jsload_data = ujson.loads(recv_data)
- #print("AI_client_voice_chat_recv jsload_data = {}".format(jsload_data))
+ print("ASR ASR recv_data: {}".format(jsload_data))
if jsload_data["status"] != 20000000:#返回错误
- self.websocket_error_voice_chat()
+ print("ASR返回非20000000状态码,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
break
- if jsload_data["event"] == "Started" :#会话开始
- payload = jsload_data["payload"]
- self.VC_dialog_id = payload["dialog_id"]
- self.VC_task_id = jsload_data["task_id"]
- print("VC:Started!!!!!!!!\r\n")
- if jsload_data["event"] == "SpeechContent" :#asr转译
- print("VC:SpeechContent!!!!!!!!\r\n")
- payload = jsload_data["payload"]
-
-
- if(payload['finished'] == True):#asr结束
- self.voice_chat_state = VC_State_SpeechEnd
- self.VC_Speech_End()#停止录音
- text = payload["text"]
- if self.check_text(text) == 0:
- print("check_text ok:{}".format(text))
- self.AI_send_data_queue.clear()
- EventMesh.publish("open_led_all")
- try:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat})
- #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- except Exception as e:
- usys.print_exception(e)
+
+ if jsload_data["task_id"] != None:
+ self.asr_taskid = jsload_data["task_id"]
+ if jsload_data["event"] != None:
+ if jsload_data["event"] == "TranscriptionStarted": #开始录音
+ self.VC_record_state_flag = 2
+ self.VC_state = VC_State_SpeechStart
+ EventMesh.publish("open_led_blue")
+ self.AI_ASR_error_timeout = 0
pass
- else:
- self.AI_listen_end = 0
-
- if jsload_data["event"] == "SpeechEnded" :#服务器下发ASR说话结束
- self.voice_chat_state = VC_State_SpeechEnd
- if jsload_data["event"] == "RespondingContent" :#chat回答
-
- payload = jsload_data["payload"]
- self.AI_label_str=str(payload['text'])#chat文本
- self.AI_client_chat_play_str=str(payload['text'])
- self.AI_client_tts_str_sen = str(payload['text'])
- if(payload['finished'] == True):#chat回答 结束,开始tts
- pass
- #utime.sleep_ms(5)
-
- if jsload_data["event"] == "RespondingStarted" :#音频开始下发
- self.play_flag = 0
- self.voice_chat_state = VC_State_TTSStart
- self.VC_Play_Start()
- self.play_data_len = 0
- #self.tts_fd = open('/usr/tts_tesr.pcm','w')
- pass
- if jsload_data["event"] == "RespondingEnded" :#音频下发结束
- if self.voice_chat_state == VC_State_TTSStart:
- self.voice_chat_state = VC_State_TTSEnd
- #self.tts_fd.close()
- pass
- elif jsload_data["event"] == "DialogStateChanged" :#状态切换事件
- payload = jsload_data["payload"]
- if payload["state"] == "Listening":
- self.voice_chat_state = VC_State_Listening
- if self.AI_TTS_str != "":#有tts数据,则请求TTS数据,没有就请求开始上传语音
- self.AI_client_voice_chat_RequestToRespond(self.AI_TTS_str)
- self.AI_TTS_str = ""
- else:
- self.AI_client_voice_chat_send_speech()#开始上传语音
- EventMesh.publish("open_led_red")
- if payload["state"] == "Thinking":#准备开始TTS
- self.voice_chat_state = VC_State_Thinking
+ elif jsload_data["event"] == "Changed" or jsload_data["event"] == "SentenceEnd" : #开始录音Changed
+ # if self.VC_record_state_flag == 2:
+ #
- self.AI_label_str = ""
- EventMesh.publish("open_led_all")
- if payload["state"] == "Responding":
- self.voice_chat_state = VC_State_Responding
- EventMesh.publish("open_led_green")
- elif jsload_data["event"] == "RequestAccepted" :#请求上传语音被允许
- #self.voice_chat_state = VC_State_Responding
- #self.AI_client_voice_chat_send_speech()#开始上传语音
- pass
- else:#下发音频数据
- self.play_data_len += len(recv_data)
- print("下发音频数据1:{} all:{}".format(len(recv_data),self.play_data_len))
- if self.voice_chat_state >= VC_State_TTSStart:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]})
- print("AI_client_voice_chat_recv 2")
+ self.AI_ASR_timer_count = 0
+ if jsload_data["result"]["result"]:
+ #self.AI_listen_text = str(jsload_data["result"]["result"])
+ text= str(jsload_data["result"]["result"])
+ print("ASR recv self.VC_state :{}".format(self.VC_state))
+ if self.is_long_record == 0:
+ if self.VC_state >= VC_State_TTSStart:#开始播音后不响应asr结果
+ print("asr continue")
+ continue
+ EventMesh.publish("open_led_blue")
+
+ if jsload_data["result"]["is_end"] == True: #asr结束
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
+ self.AI_ASR_text_repet_count = 0
+ self.AI_ASR_text_tmp = ""
+ self.VC_record_state_flag = 4
+ ret= self.check_text(text)
+ if ret == 0:#配置指令
+
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ self.AI_ASR_send_buf_len = 0
+ EventMesh.publish("open_led_all")
+ try:
+
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+ #print("AI_client_asr_recv VC_Speech_End")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ except Exception as e:
+ usys.print_exception(e)
+ continue
+ elif ret == 1:#不处理
+ pass
+ else:#正常asr
+ if self.VC_mode == 0 :#连续问答模式
+ self.AI_ASR_str = text#
+ if self.AI_ASR_flag == 0:#d第一次识别,没有打断
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ else:#第二次识别,打断了
+ self.AI_ASR_str = self.AI_ASR_str_tmp+text
+ print("ASR ASR 打断 续集 AI_ASR_str {}".format(self.AI_ASR_str))
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ if self.is_long_record != 0:
+ #if self.VC_state >= VC_State_TTSStart:#如果已经播放了,关闭VC连接,重新打开,处理音频数据太多问题
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})#关闭vc连接
+ self.AI_ASR_flag = 1
+ print("asr recv :asr_str:{}".format(self.AI_ASR_str))
+ #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,"data":(500)}) #等一秒
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ elif self.VC_mode == 1:#单对话模式
+ self.AI_ASR_str += text#
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ if self.key_state == 0:#按键已经弹起
+ self.AI_ASR_str_tmp =""
+ print("asr recv :asr_str:{}".format(self.AI_ASR_str))
+ #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,"data":(500)}) #等一秒
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ self.VC_state = VC_State_SpeechEnd
+ elif jsload_data["result"]["is_end"] == False:
+
+ self.VC_state = VC_State_SpeechIng
+ if self.AI_ASR_text_tmp != "" and self.AI_ASR_text_tmp == text:
+ pass
+ # self.AI_ASR_text_repet_count+=1
+ # if self.AI_ASR_text_repet_count>=40:#重复30次下发一样结果,就报错
+ # print("asr 错误,无正式结果:{}".format(text))
+ # #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})#
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})
+ else:
+ self.AI_ASR_check_timeout = 5 #5秒没更新结果,强制stop
+ self.AI_ASR_error_timeout = 0
+ self.AI_ASR_text_repet_count = 0
+ if self.VC_mode == 0 :#连续问答模式
+ self.AI_ASR_text_tmp = text
+ self.VC_record_state_flag = 3
+ if self.AI_ASR_flag ==1 :#如果已经识别过一次asr
+ self.AI_ASR_flag = 2
+ print("asr 打断,关闭VC连接")
+ self.AI_ASR_str = ""
+ if self.is_long_record != 0:
+ self.VC_Play_End()
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})#关闭vc连接
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_VC})#连接服务器
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_start_requset})#请求
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ EventMesh.publish("publish_AI_btnInfo",{"func":EventMesh.publish,"data":"open_led_blue"})#
+ elif self.VC_mode ==1:#单对话模式
+ self.AI_ASR_str_tmp =""
+
except Exception as e:
usys.print_exception(e)
except Exception as e:
- usys.print_exception(e)
- #self.websocket_error_voice_chat()
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error_voice_chat})
- break
- self.AI_client_voice_chat_isconnect = 0
- self.AI_client_voice_chat_recv_id = 0
- print("AI_client_voice_chat_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- def put_record_data(self,data):
- ret=self.AI_audio_queue.put(data)
- print("下发音频数据2:{}".format(len(data[0])))
- def check_text(self,text):
- if len(text)>60:
- return -1
- try:
- if isinstance(text, str):
- if text.find("更改声音") != -1:
- self.VC_TTS_voice_num += 1
- if self.VC_TTS_voice_num >= len(self.VC_TTS_voice_type):
- self.VC_TTS_voice_num = 0
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音改为") != -1 and (text.find("男声") != -1 or text.find("男生") != -1 ):
- self.VC_TTS_voice_num = 1
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音改为") != -1 and (text.find("女声") != -1 or text.find("女生") != -1 ):
- self.VC_TTS_voice_num = 0
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音改为") != -1 and (text.find("同声") != -1 or text.find("童声") != -1 ):
- self.VC_TTS_voice_num = 2
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音改为") != -1 and (text.find("粤语") != -1 or text.find("越野") != -1 ):
- self.VC_TTS_voice_num = 3
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音改为") != -1 and text.find("四川话") != -1 :
- self.VC_TTS_voice_num = 4
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("切换对话模式") != -1:
- if self.VC_mode == 0:
- self.VC_mode = 1
- self.AI_TTS_str = "已切换到单对话模式"
+ error_str = str(e)
+ print("ASR ASR:e:{}".format(error_str))
+ #usys.print_exception(e)
+ if error_str.find("[Errno 110]")!= -1:
+ #print("ASR ASR:recv TIMEDOUT 正常")
+ pass
else:
- self.VC_mode = 0
- self.AI_TTS_str = "已切换到长对话模式"
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_mode])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ usys.print_exception(e)
+ print("{}".format(cli))
+ #self.websocket_error()
+ print("ASR读数据报错,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})#
+ self.ud_error(["asr",self.asr_taskid])
+ break
+ self.AI_client_asr_isconnect = 0
+ self.AI_client_asr_recv_id = 0
+ self.AI_client_asr_recv_lock = 0
+ print("AI_client_asr_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ #ASR开始会话
+ def AI_client_asr_start_requset(self):
+ self.session_id = self.get_session_id()
+ json_data = \
+ {
+ "header":{
+ "event":"StartTranscription",
+ "trace_id":self.get_trace_id()
+ },
+ "payload":{
+ "format":"pcm",
+ "sample_rate":self.VC_record_samplerate,
+ "session_id": self.session_id ,
+ }
+
+ }
+ if self.VC_record_TYPE == VC_record_TYPE_AMR :
+ json_data["payload"]["format"]='amr'
+ pass
+
+ self.AI_ASR_error_timeout = 5
+ self.AI_client_asr_send(ujson.dumps(json_data))
+ #ASR终止
+ def AI_client_asr_StopTranscription_requset(self):
+ print("AI_client_asr_StopTranscription_requset!!!!!")
+ json_data = \
+ {
+ "header":{
+ "event":"StopTranscription",
+ "trace_id":self.get_trace_id()
+ }
+ }
- return 0
- if text.find("音量") != -1 and text.find("加大") != -1 :
- self.VC_TTS_volume += 10
- if self.VC_TTS_volume > 100:
- #EventMesh.publish("audio_montage_play",["yinliangyizuida.mp3"])
- #self.aud.play(1,0,'U:/static/yinliangyizuida.mp3')#音量已最大
- self.AI_TTS_str = "音量已最大"
- self.VC_TTS_volume = 100
- else:
- self.aud.setVolume(self.VC_TTS_volume //10)
- EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
- #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
- self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
-
- return 0
- if text.find("音量") != -1 and text.find("减小") != -1:
- self.VC_TTS_volume -= 10
- if self.VC_TTS_volume < 0:
- self.VC_TTS_volume = 0
- #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"])
- #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小
- self.AI_TTS_str = "音量已最小"
- else:
- self.aud.setVolume(self.VC_TTS_volume //10)
- EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
- #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
- self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
- return 0
- if text.find("电量") != -1 and text.find("查询") != -1:
- battery = EventMesh.publish("get_battery")
- #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
- #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
- self.AI_TTS_str = "电量剩余百分之{}".format(battery)
- return 0
- if text.find("电压") != -1 and text.find("查询") != -1:
- Vbatt = Power.getVbatt()
- #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
- #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
- self.AI_TTS_str = "当前电池电压{}".format(Vbatt)
- return 0
- if text.find("进入工厂模式") != -1 :
- self.factory_mode()
- return -1
- if text.find("信号") != -1 and text.find("查询") != -1:
- signal = net.csqQueryPoll()
-
- self.AI_TTS_str = "当前信号{}".format(signal)
- return 0
+ #self.AI_client_asr_send(ujson.dumps(json_data))
+ if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
+ self.AI_client_asr.send(ujson.dumps(json_data))
- if text.find("再见") != -1 or text.find("拜拜") != -1:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
- except Exception as e:
- usys.print_exception(e)
- return -1
- #获取trace_id
- def get_trace_id(self):
- t = utime.mktime(utime.localtime())
- t = t*1000+urandom.randint(0, 1000)
- md5_data = "{}".format(t)#md5签名
- sign_data = ""
- hash_obj = uhashlib.md5(md5_data)
- res = hash_obj.digest()
-
- # 转成十六进制表示
- sign_data = ubinascii.hexlify(res)
- sign_data = sign_data.decode('ascii')
- return sign_data
- def get_new_message_id(self):
- message_id = self.get_trace_id()+"aaa"+self.get_trace_id()
- self.VC_message_id=message_id[:32]
- return self.VC_message_id
-
- def get_new_task_id(self):
- task_id = self.get_trace_id()+"aaa"+self.get_trace_id()
- self.VC_task_id=task_id[:32]
- return self.VC_task_id
- #开始播放声音
- def VC_Play_Start(self):
-
- if self.VC_play_TYPE == VC_play_TYPE_PCM:
- if self.VC_play_samplerate == 8000:
- pass
- elif self.VC_play_samplerate == 16000:
- if self.play_pcm == None:
- self.play_pcm = audio.Audio.PCM(0,1,16000,1,1,2)
- #self.play_pcm.setVolume(11)
- ret = self.play_pcm.stream_write_start()
- print("self.record_pcm.stream_write_start:ret:{}".format(ret))
- elif self.VC_play_TYPE == VC_play_TYPE_MP3:
- pass
- #停止播放声音
- def VC_Play_End(self):
- if self.VC_play_TYPE == VC_play_TYPE_PCM:
- if self.VC_play_samplerate == 8000:
- self.aud.stopPlayStream()
- self.aud.stopAll()
- elif self.VC_play_samplerate == 16000:
- if self.play_pcm != None:
- print("Close:play_pcm.close()!!!!!!!!!!!!!!!!!!")
- try:
- self.play_pcm.stream_stop()
- self.play_pcm.close()
- except Exception as e:
- usys.print_exception(e)
- self.play_pcm=None
- self.aud.stopPlayStream()
- self.aud.stopAll()
- elif self.VC_play_TYPE == VC_play_TYPE_MP3:
- self.aud.stopPlayStream()
- self.aud.stopAll()
- #开始录音
+ #开始录音
def VC_Speech_Start(self):
- #self.voice_chat_state = VC_State_SpeechStart
- print("VC_Speech_Start VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))
- if self.VC_record_state_flag == 0:
- if self.VC_record_thread_id != 0:
+ try:
+
+ #self.VC_state = VC_State_SpeechStart
+ print("VC_Speech_Start VC_record_state_flag:{} self.AI_ASR_flag:{}!!!!!!!!".format(self.VC_record_state_flag,self.AI_ASR_flag))
+ if self.AI_ASR_flag != 0:
+ return
+
+ if self.VC_record_state_flag == 0:
+ # if dev_type != "7PIN" :
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.chenggong_tone})
+ #self.websocket_connect_asr()
+ self.VC_record_thread_close()#关闭录音线程
+ _thread.stack_size(self.Audio_buf_size+8*1024)
+ self.VC_record_thread_id = _thread.start_new_thread(self.VC_record_thread,())
+ _thread.stack_size(8*1024)
+ print("self.VC_record_thread_id:{}".format(self.VC_record_thread_id))
try:
- _thread.stop_thread(self.VC_record_thread_id)
- except Exception as e:
- usys.print_exception(e)
- self.VC_record_thread_id = 0
- _thread.stack_size(self.Audio_buf_size+8*1024)
- self.VC_record_thread_id = _thread.start_new_thread(self.VC_record_thread,())
- _thread.stack_size(8*1024)
- print("self.VC_record_thread_id:{}".format(self.VC_record_thread_id))
- if self.VC_record_TYPE == VC_record_TYPE_AMR :
- try :
- self.record.stream_start(audio.Record.AMRNB, self.VC_record_samplerate, 0)
+
+ if self.VC_record_TYPE == VC_record_TYPE_AMR :
+ try :
+ self.record.stream_start(audio.Record.AMRNB, self.VC_record_samplerate, 0)
+ except Exception as e:
+ usys.print_exception(e)
+ elif self.VC_record_TYPE == VC_record_TYPE_PCM:
+ print("record_pcm.stream_read_start()!!!!!!!!!!!!")
+ self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0)
+ # if self.record_pcm != None:
+ # try:
+ # self.record_pcm.stream_stop()
+ # self.record_pcm.close()
+ # self.record_pcm = None
+ # except Exception as e:
+ # usys.print_exception(e)
+ # if self.record_pcm == None:
+ # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2)
+ # print("audio.Audio.PCM:ret:{}".format(ret))
+ # ret = self.record_pcm.stream_read_start()
+ # print("self.record_pcm.stream_read_start:ret:{}".format(ret))
except Exception as e:
- usys.print_exception(e)
- elif self.VC_record_TYPE == VC_record_TYPE_PCM:
- print("record_pcm.stream_read_start()!!!!!!!!!!!!")
- self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0)
- # if self.record_pcm != None:
- # try:
- # self.record_pcm.stream_stop()
- # self.record_pcm.close()
- # self.record_pcm = None
- # except Exception as e:
- # usys.print_exception(e)
- # if self.record_pcm == None:
- # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2)
- # print("audio.Audio.PCM:ret:{}".format(ret))
- # ret = self.record_pcm.stream_read_start()
- # print("self.record_pcm.stream_read_start:ret:{}".format(ret))
+ usys.print_exception(e)
+
+ self.VC_record_state_flag = 2
+ except Exception as e:
+ self.websocket_error()
self.VC_record_state_flag = 1
+ self.VC_Speech_End()#关闭录音
+ usys.print_exception(e)
+
#停止录音
def VC_Speech_End(self):
try:
+ self.AI_ASR_flag = 0
+ self.AI_ASR_str_tmp = ""
+ self.AI_ASR_str = ""
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+
+ if self.VC_record_state_flag == 0:
+ return
+ #self.AI_client_asr_StopTranscription_requset()#请求停止
if self.VC_record_TYPE == VC_record_TYPE_AMR:
self.record.stream_stop()
self.record.stop()#关闭录音
# usys.print_exception(e)
except Exception as e:
usys.print_exception(e)
- self.voice_chat_state = VC_State_SpeechEnd
+ self.VC_record_thread_close()#关闭录音线程
+ if self.AI_record_tmp_queue.empty() != True:
+ self.AI_record_tmp_queue.clear()
+ # try:
+ # self.websocket_deconnect_asr()
+ # except Exception as e:
+ # usys.print_exception(e)
+ self.VC_record_state_flag = 0
+ print("VC_Speech_End VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))
+ #关闭录音线程
+ def VC_record_thread_close(self):
if self.VC_record_thread_id != 0:
+ count =50
+ while True:
+ count -= 1
+ if self.VC_record_thread_lock == 1:
+ self.VC_record_thread_lock = 2
+ if self.VC_record_thread_lock == 0 or count <=0:
+ break
+ else:
+ print("VC_record_thread_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.VC_record_thread_lock = 0
+ print("VC_record_thread_thread_close")
try:
_thread.stop_thread(self.VC_record_thread_id)
except Exception as e:
- usys.print_exception(e)
- self.VC_record_thread_id = 0
-
- self.VC_record_state_flag = 0
- print("VC_Speech_End VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))
+ usys.print_exception(e)
+ self.VC_record_thread_id = 0
#获取录音数据
def VC_record_thread(self):
##return
# if self.VC_record_TYPE == 1:
# h_data= [0x23,0x21 ,0x41 ,0x4D ,0x52 ,0x0A ]
# h_data_b = bytes(h_data)
- # self.AI_client_voice_chat_send(h_data_b)
+ # self.AI_client_VC_send(h_data_b)
+ AI_record_tmp_queue_len = 0
while True:
try:
+ if self.VC_record_thread_lock == 2:
+ break
+ self.VC_record_thread_lock = 1
# 死循环接收数据
- #if self.voice_chat_state == VC_State_SpeechStart:
+ #if self.VC_state == VC_State_SpeechStart:
Record_read_buf = bytearray(self.Audio_buf_size)
Record_len = 0
if self.VC_record_TYPE == VC_record_TYPE_PCM:#pcm
Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
- # if self.record_pcm ==None:
- # break
- # Record_len = self.record_pcm.stream_read(Record_read_buf, self.Audio_buf_size)
- # if Record_len <= 0:
- # try:
- # if self.record_pcm != None:
- # try:
- # self.record_pcm.stream_stop()
- # self.record_pcm.close()
- # self.record_pcm = None
- # except Exception as e:
- # usys.print_exception(e)
- # if self.record_pcm == None:
- # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2)
- # print("audio.Audio.PCM:ret:{}".format(ret))
- # ret = self.record_pcm.stream_read_start()
- # print("self.record_pcm.stream_read_start:ret:{}".format(ret))
- # except Exception as e:
- # usys.print_exception(e)
utime.sleep_ms(20)
else :
Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
- utime.sleep_ms(1000)
+ utime.sleep_ms(600)
+
+ #Record_len = 1024*2
+ #print("VC_record_thread:{}".format(Record_len))
+ if Record_len > 0:
+ read_buf = bytes(Record_read_buf[:Record_len])
+ if self.record_data_save_flag == 1:
+ if self.record_fd == None:
+ try:
+ uos.remove('/usr/record_data.pcm')
+ except Exception as e:
+ usys.print_exception(e)
+ self.record_fd = open('/usr/record_data.pcm','w')
+ if self.record_fd != None:
+ self.record_fd.write(read_buf)
+ print("write record:{}".format(len(read_buf)))
+ # count+=Record_len
+ # if count >150*1024:
+ # self.record_fd.close()
+ #self.record_fd = None
+ # if self.VC_record_state_flag >= 2:
+ # self.AI_client_asr_send(read_buf)
+
+ if self.VC_record_state_flag <=1 :#没发送前先存起来
+ self.AI_record_tmp_queue.put(read_buf)
+ AI_record_tmp_queue_len += len(read_buf)
+ else:
+ AI_record_tmp_queue_len = 0
+ while True:
+ if self.AI_record_tmp_queue.empty() == True:
+ break
+ else:
+ self.AI_client_VC_input_audio_buffer_append(self.AI_record_tmp_queue.get())
+ #self.AI_client_asr_send(self.AI_record_tmp_queue.get()) #发送之前存的数据
+ #self.AI_client_asr_send(read_buf)
+ self.AI_client_VC_input_audio_buffer_append(read_buf)
+ #print("VC_record_thread:{}".format(len(read_buf)))
+ #count+=len(read_buf)
+ # if count>=500*1024:#结束
+ # self.AI_client_VC_end_speech()
+ # break
+ # count+=1
+ # if count %10 == 0:
+ # print("VC_record_thread on line {} asr recv :{} send:{}".format(self.VC_record_state_flag,_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_VC_send_data_queue_thread_id)))
+
+ # if self.VC_state >= VC_State_SpeechEnd:
+ # break
+
+ except Exception as e:
+ usys.print_exception(e)
+ #break
+ self.VC_record_thread_lock = 0
+ utime.sleep_ms(100)
+ #fd.close()
+ print("VC_record_thread:exit")
+ self.VC_record_thread_id = 0#线程退出
+ self.VC_record_thread_lock = 0
+###################################################### VC ###################################################################################
+ def websocket_connect_VC(self):
+ print("websocket_connect_VC:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_VC_isconnect,self.AI_client_VC_debug))
+ if self.AI_client_VC_isconnect == 1:
+ return
+ # 创建VC客户端
+ try:
+ signal = net.csqQueryPoll()
+ if signal == -1 or sim.getStatus() != 1:#网络正常
+ self.websocket_error()
+ return
+ try:
+ if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]:
+ self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"]
+ else:
+ print("not bot_name!!!!!!!!!!!!!!!!!!!!!!")
+ except Exception as e:
+ usys.print_exception(e)
+
+ # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
+ # self.AI_client_VC = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
+
+ url="ws://ws.coze.cn/v1/chat?bot_id=7462617881076351002"
+ url="ws://ws.coze.cn/v1/chat?bot_id=7486697248416989193"
+
+ print("VC VC:url{}".format(url))
+ Headers = {"Authorization":"Bearer pat_PtSpw6ODvy7nDm2NZQsnFzbArzOji5Hev09VfZSLFWBkMXuFrXmAriqlXw5h0I6i"}
+ self.AI_client_VC = uwebsocket.Client.connect(url, headers=Headers,debug=True)
+ #self.AI_WS_connect_Queue.put(self.AI_client_VC)
+
+
+ print("websocket_connect_VC:OK!!!!!!!!!!!!!!!!!!!!!")
+ except Exception as e: #网络连接异常
+ usys.print_exception(e)
+ print("websocket_connect_VC error!!!\r\n")
+ str_error = str(e)
+ if str_error.find("[Errno 22] EINVAL")!= -1:
+ print("websocket_connect_VC:str_error:{}".format(str_error))
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ self.websocket_error()
+ EventMesh.publish("set_storage_config",["powerRestart",1])#调试临时关闭
+ utime.sleep_ms(1000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ Power.powerRestart()
+
+ self.websocket_error()
+ return
+ #print("AI_client_VC:{}".format(self.AI_client_VC))
+ if self.AI_client_VC == None:
+ EventMesh.publish("update_dev_token")#获取token
+ self.websocket_error()
+ return
+ self.AI_client_VC_debug+=1
+ utime.sleep_ms(10)
+ #self.AI_client_VC.settimeout(5)
+ #self.AI_VC_send_data_queue_thread_close()#关闭发送线程
+ if self.AI_VC_send_data_queue_thread_id == 0:
+ _thread.stack_size(self.Audio_buf_size+8*1024)
+ self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ())
+ _thread.stack_size(8*1024)
+ print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id))
+ self.AI_client_VC_recv_thread_close()#关闭读线程
+ # 线程接收数据
+ _thread.stack_size(self.Audio_buf_size+8*1024)
+ self.AI_client_VC_recv_id = _thread.start_new_thread(self.AI_client_VC_recv, (self.AI_client_VC,))
+ _thread.stack_size(8*1024)
+ self.AI_client_VC_isconnect = 1
+ print("websocket_connect_VC end")
+
+ def websocket_error(self,TTS_str=None):
+ print("websocket_error1!!!!")
+ self.Close()
+ print("websocket_error1.1!!!!")
+ print("websocket_error!!!!")
+ print("websocket_error!!!!")
+ self.VC_Thinking_timerout = 0
+ self.VC_satrt_flag = 0
+ self.AI_TTS_str = ""
+ self.AI_ASR_str = ""
+ self.AI_ASR_str_tmp = ""
+ self.AI_ASR_flag = 0
+ self.VC_Speech_End()
+ EventMesh.publish("close_led")
+ if TTS_str == None:
+ self.websocket_error_count+=1
+ # if self.websocket_error_count <=3:
+ # EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
+ if self.websocket_error_count <10 :
+ EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
+ elif self.websocket_error_count >=10:
+ EventMesh.publish("paly_iccid_imei")
+ # else:
+ # EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"])
+ #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3')
+ if self.websocket_error_count <3 :
+ utime.sleep_ms(3000)
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ else:
+ print("websocket_error:tts:{}".format(TTS_str))
+ self.AI_TTS_str = TTS_str
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ print("websocket_error2")
+
+
+ print("websocket_error4")
+
+
+ def websocket_deconnect_VC(self):
+ #print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect))
+ print("websocket_deconnect_VC!!!!!!!")
+ self.AI_client_VC_recv_thread_close()#关闭读线程
+ self.AI_client_VC_recv_id = 0
+ if self.AI_client_VC_isconnect == 1 or self.AI_client_VC!=None:
+ try:
+ self.AI_client_VC_isconnect = 0
+ count = 500
+ while True:#等待发完数据
+ count-=1
+ if count <=0 or self.AI_VC_send_data_queue_thread_lock == 0:
+ break
+ utime.sleep_ms(1)
+
+ try:
+ self.AI_client_VC.close()
+ self.AI_client_VC_debug -=1
+ #self.AI_client_VC=None
+ except Exception as e:
+ usys.print_exception(e)
+ try :
+ self.AI_client_VC.close()
+ self.AI_client_VC_debug -=1
+ #self.AI_client_VC=None
+ except Exception as e:
+ usys.print_exception(e)
+ try :
+ self.AI_client_VC._close()
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_VC = None
+ except Exception as e:
+ usys.print_exception(e)
+ print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect))
+ #websocket发送ping
+ def AI_client_VC_ping(self):
+ pass
+ if self.AI_client_VC_isconnect == 1:
+ #self.AI_client_VC.write_frame(0x09,b'ping ping')
+ self.AI_client_VC_send("ping")
+ #print("websocket ping ping")
+
+ #websocket发送数据
+ def AI_client_VC_send(self,data_str):
+ # if isinstance(data_str, str):#是字符串
+ # print("AI_client_VC_send:{}".format(data_str))
+ # pass
+ # else:
+ # print("AI_client_VC_send:len{}".format(len(data_str)))
+ self.AI_VC_send_data_queue.put([AI_client_VC_num,data_str])
+ #关闭数据发送线程
+ def AI_VC_send_data_queue_thread_close(self):
+ if self.AI_VC_send_data_queue_thread_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_VC_send_data_queue_thread_lock == 0 or count <=0:
+ break
+ else:
+ self.AI_VC_send_data_queue_thread_lock = 2
+ print("AI_VC_send_data_queue_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ self.AI_VC_send_data_queue_thread_lock = 0
+ print("AI_VC_send_data_queue_thread_close")
+ try:
+ _thread.stop_thread(self.AI_VC_send_data_queue_thread_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_VC_send_data_queue_thread_id = 0
+ #发送数据队列
+ def AI_VC_send_data_queue_thread(self):
+ print("AI_VC_send_data_queue_thread:start")
+ count_t = 0
+ while True:
+ if self.AI_VC_send_data_queue_thread_lock == 2:
+ print("AI_VC_send_data_queue_thread,该退出了")
+ break
+ if self.AI_VC_send_data_queue.empty() :#不能去掉,去掉会卡死
+ self.AI_VC_send_data_queue_thread_lock = 0
+ count_t+=1
+ # if count_t%200 == 0:
+ # print("self.AI_VC_send_data_queue.empty")
+ utime.sleep_ms(1)
+ else:
+ #data[0]是websocket连接对象编号,data[1]是数据
+ #print("AI_VC_send_data_queue_thread:get")
+
+ self.AI_VC_send_data_queue_thread_lock = 1
+ data = self.AI_VC_send_data_queue.get()
+
+
+ #print("AI_VC_send_data_queue_thread:num{} len{}".format(data[0],len(data[1])))
+ if data != None:
+ try:
+ #data["func"](data["data"])
+ # 发送数据
+ #bytes_data = bytes(data[1])
+ #data[0].send(data[1])
+ #print("AI_VC_send_data_queue_thread:len:{}".format(len(data[1])))
+ #print("AI_VC_send_data_queue_thread on line asr recv :{} vc recv:{}".format(_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_client_VC_recv_id)))
+ if data[0] == AI_client_VC_num:
+ self.VC_pingping_timerout = 0
+ if isinstance(data[1], str):#是字符串
+ if len(data[1])<900:
+ print("VC VC: send_data:{}".format(data[1]))
+ else:
+ print("VC VC: send_data:{}".format(len(data[1])))
+ pass
+ #print("VC VC: send_data:{}...".format(data[1][:300]))
+ #print("VC: send_data len:{}".format(len(data[1])))
+ if self.AI_client_VC != None and self.AI_client_VC_isconnect == 1:
+ self.AI_client_VC.send(data[1])
+ else:
+ print("VC VC: send_data:ERROR:{}".format(data[1]))
+ #print("VC: send_data end")
+
+ #print("VC: send_data end")
+ except Exception as e:
+ print("DeviceInfo_queue_thread:ERROR:{}".format(e))
+ usys.print_exception(e)
+ if data[0] == AI_client_VC_num:
+ #self.websocket_error()
+ pass
+
+
+ try:
+ if self.AI_client_VC_isconnect != 0:
+ print("VC发送数据错误,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC发送出错了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
+ except Exception as e: #网络连接异常
+ usys.print_exception(e)
+
+ utime.sleep_ms(1)
+ self.AI_VC_send_data_queue_thread_lock = 0
+ #VC关闭读线程
+ def AI_client_VC_recv_thread_close(self):
+ if self.AI_client_VC_recv_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_client_VC_recv_lock == 1:
+ self.AI_client_VC_recv_lock = 2
+ if self.AI_client_VC_recv_lock == 0 or count <=0:
+ break
+ else:
+ print("AI_client_VC_recv_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_client_VC_recv_lock = 0
+ print("AI_client_VC_recv_thread_close")
+ try:
+ _thread.stop_thread(self.AI_client_VC_recv_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_VC_recv_id = 0
+ #Ai VC websocket返回数据
+ def AI_client_VC_recv(self,cli):
+ count = 0
+
+ while True:
+ try:
+ # 死循环接收数据
+ self.AI_client_VC_recv_lock = 0
+ if self.is_VC_ACK == 1:
+ self.AI_client_VC_Read()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_Read})
+ count+=1
+ if self.VC_state >= VC_State_TTSStart and (self.tts_in_data_len - self.tts_out_data_len > 64*1024 or count>5):
+ count = 0
+ utime.sleep_ms(1)
+ if self.VC_state < VC_State_TTSStart:
+ utime.sleep_ms(1)
+ recv_data = cli.recv()
+ if self.AI_client_VC_recv_lock == 2:
+ print("AI_client_VC_recv 该退出了")
+ break
+ self.AI_client_VC_recv_lock = 1
+ self.close_timerout = 0#服务器有返回清零退出时间
+ if recv_data == "websocket close":
+ # 服务器关闭连接
+ print("VC 服务器关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ #self.AI_client_VC_isconnect = 0
+ #self.websocket_deconnect_VC()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ # #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
+ break
+ elif recv_data == "":#客户端关闭连接
+ print("VC VC :客户端关闭连接")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
+ break
+ try:
+ self.websocket_error_count = 0
+ if isinstance(recv_data, str):#返回的是字符串
+ if len(recv_data)<800:
+ print("VC VC:recv_data:{}".format(recv_data))
+ else:
+ print("VC VC:recv_data long :{}".format(recv_data[:300]))
+ jsload_data = ujson.loads(recv_data)
+ #print("AI_client_VC_recv jsload_data = {}".format(jsload_data))
+
+ if jsload_data["event_type"] == "chat.created" :#会话开始
+ self.AI_client_VC_start_requset()
+ self.AI_client_VC_send_speech()#开始上传语音
+ elif jsload_data["event_type"] == "chat.updated" :#会话开始
+ print("VC:Started!!!!!!!!\r\n")
+ print("VC:Started!!!!!!!!\r\n")
+ print("VC:Started!!!!!!!!\r\n")
+
+ #self.AI_client_VC_send_speech()#开始上传语音
+ elif jsload_data["event_type"] == "conversation.audio_transcript.update" :#音频转译
+ self.VC_Speech_end_timerout = 2
+ # self.AI_ASR_str = jsload_data["data"]['content']
+ # if self.AI_ASR_str.find("。") != -1 or self.AI_ASR_str.find("?") != -1 or self.AI_ASR_str.find("!") != -1:
+ # self.VC_Speech_end_timerout = 0
+ # self.AI_client_VC_end_speech()#发送说话终止
+
+ elif jsload_data["event_type"] == "conversation.chat.created" :#开始对话
+ self.open_play_flag = 0
+ if self.play_data_save_flag == 1:
+ try:
+ uos.remove('/usr/play_data.pcm')
+ except Exception as e:
+ usys.print_exception(e)
+ self.play_fd = open('/usr/play_data.pcm','w')
+
+ elif jsload_data["event_type"] == "conversation.message.delta":#返回大模型回答数据
+ if self.open_play_flag == 0:
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})#打开播放
+ self.open_play_flag =1
+ elif jsload_data["event_type"] == "conversation.audio.delta":#下发音频数据
+
+ audio_data = ubinascii.a2b_base64(jsload_data["data"]['content'])
+ print("下发音频数据1:{}".format(len(audio_data)))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[audio_data,""]})
+ if self.play_data_save_flag == 1:
+ if self.play_fd !=None:
+ self.play_fd.write(audio_data)
+ elif jsload_data["event_type"] == "conversation.audio.completed":#结束播放
+ if self.play_data_save_flag == 1:
+ if self.play_fd !=None:
+ print("输出音频文件关闭")
+ self.play_fd.close()
+ elif jsload_data["event_type"] == "conversation.chat.completed":#对话结束
+ self.LocalRespondingEnded_timerout = 8
+
+ # elif jsload_data["event"] == "SpeechContent" :#asr转译
+ # print("VC:SpeechContent!!!!!!!!\r\n")
+ # payload = jsload_data["payload"]
+
+
+ # if(payload['finished'] == True):#asr结束
+ # self.VC_state = VC_State_SpeechEnd
+ # #self.VC_Speech_End()#停止录音
+ # text = payload["text"]
+ # if self.check_text(text) == 0:
+ # if self.AI_VC_send_data_queue.empty()!=True:
+ # self.AI_VC_send_data_queue.clear()
+ # if self.AI_ASR_send_data_queue.empty()!=True:
+ # self.AI_ASR_send_data_queue.clear()
+ # self.AI_ASR_send_buf_len = 0
+ # EventMesh.publish("open_led_all")
+ # try:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+
+ # # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ # except Exception as e:
+ # usys.print_exception(e)
+
+ # pass
+ # else:
+ # pass
+
+ # elif jsload_data["event"] == "SpeechEnded" :#服务器下发ASR说话结束
+ # self.VC_state = VC_State_SpeechEnd
+ # elif jsload_data["event"] == "RespondingContent" :#chat回答
+ # pass
+
+ # elif jsload_data["event"] == "RespondingStarted" :#音频开始下发
+ # self.play_flag = 0
+ # self.VC_state = VC_State_TTSStart
+ # if self.is_long_record == 0:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})#
+ # else:
+ # self.AI_ASR_str_tmp = ""
+ # self.AI_ASR_str = ""
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
+ # self.VC_Thinking_timerout = 0#关闭超时重试
+ # # self.VC_Play_Start()
+ # EventMesh.publish("open_led_green")#绿色
+ # #self.tts_fd = open('/usr/tts_tesr.pcm','w')
+ # if self.play_data_save_flag == 1:
+ # try:
+ # uos.remove('/usr/play_data.pcm')
+ # except Exception as e:
+ # usys.print_exception(e)
+ # self.play_fd = open('/usr/play_data.pcm','w')
+
+ # pass
+ # elif jsload_data["event"] == "RespondingEnded" :#音频下发结束
+ # #if self.VC_state == VC_State_TTSStart:
+
+ # print("RespondingEnded!!!!!!" )
+ # self.VC_state = VC_State_TTSEnd
+ # self.LocalRespondingEnded_timerout = 10 #最长倒数10秒发送音频结束或者终止对话
+ # if self.VC_mode == 0 :#连续问答模式
+ # #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})#调试临时打开
+ # if dev_type != "7PIN_BK":
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音
+ # pass
+ # if self.play_data_save_flag == 1:
+ # if self.play_fd !=None:
+ # self.play_fd.close()
+ # #self.tts_fd.close()
+ # #pass
+ # elif jsload_data["event"] == "DialogStateChanged" :#状态切换事件
+ # payload = jsload_data["payload"]
+ # if payload["state"] == "Listening":#可以说了
+ # self.VC_state = VC_State_Listening
+ # if self.AI_TTS_str != "" or self.AI_ASR_str != "":#有tts数据,则请求TTS数据,没有就请求开始上传语音
+ # self.AI_client_VC_RequestToRespond()
+ # else:
+ # pass
+ # #self.VC_Speech_Start()#开启线程获取录音数据
+ # if self.is_long_record == 0:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#
+ # #self.AI_client_VC_send_speech()#开始上传语音
+
+ # #EventMesh.publish("open_led_red")
+ # if payload["state"] == "Thinking":#思考
+ # self.VC_state = VC_State_Thinking
+ # if self.VC_Thinking_timerout == 0:
+ # self.VC_Thinking_timerout = 15#倒计时15秒,如果没有音频数据返回就重试
+ # EventMesh.publish("open_led_red_green")#黄色
+ # if payload["state"] == "Responding":#开始音频播放
+ # #self.VC_state = VC_State_Responding#
+ # pass
+ # elif jsload_data["event"] == "RequestAccepted" :#请求上传语音被允许
+ # #self.VC_state = VC_State_Responding
+ # #self.AI_client_VC_send_speech()#开始上传语音
+ # pass
+ else:#下发音频数据
+ #self.AI_ASR_str = ""#下发音频后清掉asr结果
+
+ print("下发音频数据1:{}".format(len(recv_data)))
+
+ if self.play_data_save_flag == 1:
+ if self.play_fd !=None:
+ self.play_fd.write(recv_data)
+ # print("下发音频数据2:{}".format(len(recv_data)))
+ if self.VC_state >= VC_State_TTSStart:
+ #self.put_record_data([recv_data,""])
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]})
+ utime.sleep_ms(1)
+ except Exception as e:
+ usys.print_exception(e)
+
+ except Exception as e:
+
+ error_str = str(e)
+ #print("VC VC:e:{}".format(error_str))
+ if error_str.find("[Errno 110] ETIMEDOUT")!= -1:
+ #print("VC VC:recv TIMEDOUT 正常")
+ pass
+ else:
+ usys.print_exception(e)
+ #self.websocket_error()
+ print("VC VC :读数据报错,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC出错了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
+ break
+ self.AI_client_VC_isconnect = 0
+ self.AI_client_VC_recv_id = 0
+ self.AI_client_VC_recv_lock = 0
+ print("AI_client_VC_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ def put_record_data(self,data):
+ #print("下发音频数据1:{}".format(len(data[0])))
+ ret=self.AI_audio_queue.put(data)
+ self.tts_in_data_len += len(data[0])
+ #print("下发音频数据2:{},{}".format(len(data[0]),self.tts_in_data_len))
+ def check_text(self,text):
+ if len(text)>60:
+ return -1
+ try:
+ if isinstance(text, str):
+ if text.find("声音") != -1 and text.find("改") != -1:
+ try:
+ for key in self.VC_TTS_voice_type:
+ if text.find(key) != -1 :
+ self.VC_TTS_voice_key = key
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ self.AI_TTS_str = "更改成功"
+ return 0
+ except Exception as e:
+ usys.print_exception(e)
+ if text.find("男") != -1 :
+ if "男" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "男"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("女") != -1 :
+ if "女" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "女"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("同声") != -1 or text.find("童") != -1 :
+ if "童" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "童"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("粤") != -1 or text.find("越野") != -1 or text.find("广东话") != -1:
+ if "粤" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "粤"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("四川") != -1 :
+ if "四川" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "四川"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("个性") != -1 :
+ if "个性" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "个性"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("英语") != -1 :
+ if "英语" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "英语"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ self.AI_TTS_str = "更改失败,没找到对应声音"
+ return 0
+ if text.find("切换对话模式") != -1:
+ if self.VC_mode == 0:
+ self.VC_mode = 1
+ self.AI_TTS_str = "已切换到单对话模式"
+ else:
+ self.VC_mode = 0
+ self.AI_TTS_str = "已切换到长对话模式"
+ EventMesh.publish("set_storage_config",["VC_mode",self.VC_mode])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+
+ return 0
+ if text.find("音量") != -1:
+ if text.find("加") != -1 :
+ self.VC_TTS_volume += 10
+ if self.VC_TTS_volume > 100:
+ #EventMesh.publish("audio_montage_play",["yinliangyizuida.mp3"])
+ #self.aud.play(1,0,'U:/static/yinliangyizuida.mp3')#音量已最大
+ self.AI_TTS_str = "音量已最大"
+ self.VC_TTS_volume = 100
+ else:
+ self.aud.setVolume(self.VC_TTS_volume //10)
+ EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
+ #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
+ self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
+
+ return 0
+ if text.find("减") != -1:
+ self.VC_TTS_volume -= 10
+ if self.VC_TTS_volume < 0:
+ self.VC_TTS_volume = 0
+ #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"])
+ #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小
+ self.AI_TTS_str = "音量已最小"
+ else:
+ self.aud.setVolume(self.VC_TTS_volume //10)
+ EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
+ #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
+ self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
+ return 0
+
+ if text.find("进入工厂模式") != -1 :
+ self.factory_mode()
+ return 1
+ if text.find("查询") != -1:
+
+ if text.find("信号") != -1 :
+ signal = net.csqQueryPoll()
+
+ self.AI_TTS_str = "当前信号{}".format(signal)
+ return 0
+ if text.find("电量") != -1 :
+ battery = EventMesh.publish("get_battery")
+ print("电量查询:{}".format(battery))
+ #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
+ #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
+ self.AI_TTS_str = "电量剩余百分之{}".format(battery)
+ return 0
+ if text.find("电压") != -1 :
+ Vbatt = Power.getVbatt()
+ #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
+ #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
+ self.AI_TTS_str = "当前电池电压{}".format(Vbatt)
+ return 0
- #Record_len = 1024*2
- #print("VC_record_thread:{}".format(Record_len))
- if Record_len > 0:
- read_buf = bytes(Record_read_buf[:Record_len])
- #fd.write(read_buf)
- #record_data_queue.put(read_buf)
-
- if self.voice_chat_state != VC_State_SpeechStart:#没发送前先存起来
- self.AI_record_tmp_queue.put(read_buf)
+ if text.find("卡号") != -1 :
+ iccid = sim.getIccid()
+ if iccid != -1 and len(iccid) > 5:
+ print("iccid{}".format(iccid))
+ self.AI_TTS_str = "当前卡号为:{}".format(iccid)
+ else:
+ self.AI_TTS_str = "卡号查询失败"
+ return 0
+ if text.find("设备号") != -1 :
+ imei = modem.getDevImei()
+ if imei != -1 and len(imei) > 5:
+ print("IMEI:{}".format(imei))
+ self.AI_TTS_str = "当前设备号为:{}".format(imei)
+ else:
+ self.AI_TTS_str = "设备号查询失败"
+ return 0
+ if text.find("版本") != -1 :
+ sourceVersion = versions.Build_Time
+ self.AI_TTS_str ="Mr-Seven-"+sourceVersion
+ return 0
+ if text.find("服务器地址") != -1 :
+ self.AI_TTS_str ="服务器地址"+self.server_ip
+ return 0
+ if text.find("升级") != -1 and (text.find("OTA") != -1 or text.find("ota") != -1):
+ if self.ai_OTA.min_sys_ota()==1:
+ self.AI_TTS_str = "有新版本,准备开始升级,升级过程会多次重启设备,请保证流量充足及电量充足"
else:
- while True:
- if self.AI_record_tmp_queue.empty() == True:
- break
- else:
- self.AI_client_voice_chat_send(self.AI_record_tmp_queue.get()) #发送之前存的数据
- self.AI_client_voice_chat_send(read_buf)
- #print("VC_record_thread:{}".format(len(read_buf)))
- count+=len(read_buf)
- # if count>=500*1024:#结束
- # self.AI_client_voice_chat_end_speech()
- # break
- utime.sleep_ms(40)
- if self.voice_chat_state >= VC_State_SpeechEnd:
- break
- except Exception as e:
- usys.print_exception(e)
- break
- # while True:
- # if record_data_queue.empty()!=True:
- # self.AI_client_voice_chat_send(record_data_queue.get())
- # else:
- # break
- #self.AI_client_voice_chat_end_speech()
- #fd.close()
+ self.AI_TTS_str = "当前已是最新版本"
+ return 0
+
+ if len(text)<12 and (text.find("再见") != -1 or text.find("拜拜") != -1):
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ return 1
+ except Exception as e:
+ usys.print_exception(e)
+ return -1
+ #获取trace_id
+ def get_trace_id(self):
+ t = utime.mktime(utime.localtime())
+ t = t*1000+urandom.randint(0, 1000)
+ md5_data = "{}".format(t)#md5签名
+ sign_data = ""
+ hash_obj = uhashlib.md5(md5_data)
+ res = hash_obj.digest()
- #if self.AI_TYPE == AI_TYPE_voice_chat:
-
- print("VC_record_thread:exit")
- self.VC_record_thread_id = 0#线程退出
+ # 转成十六进制表示
+ sign_data = ubinascii.hexlify(res)
+ sign_data = sign_data.decode('ascii')
+ return sign_data
+
+ def get_session_id(self,data = "session_id"):
+ t = utime.mktime(utime.localtime())
+ t = t*1000+urandom.randint(0, 1000)
+ md5_data = "{}{}".format(data,t)#md5签名
+ sign_data = ""
+ hash_obj = uhashlib.md5(md5_data)
+ res = hash_obj.digest()
+
+ # 转成十六进制表示
+ sign_data = ubinascii.hexlify(res)
+ sign_data = sign_data.decode('ascii')
+ return sign_data
+
+ def get_new_message_id(self):
+ message_id = self.get_trace_id()+"aaa"+self.get_trace_id()
+ self.VC_message_id=message_id[:32]
+ return self.VC_message_id
+ def get_new_task_id(self):
+ task_id = self.get_trace_id()+"aaa"+self.get_trace_id()
+ self.VC_task_id=task_id[:32]
+ return self.VC_task_id
+ #开始播放声音
+ def VC_Play_Start(self):
+ self.tts_in_data_len = 0
+ self.tts_out_data_len = 0
+ if self.VC_Play_flag == 0:
+ try:
+ if self.VC_play_TYPE == VC_play_TYPE_PCM:
+ if self.play_pcm == None:
+ self.play_pcm = audio.Audio.PCM(0,1,self.VC_play_samplerate,1,1,2)
+ #self.play_pcm.setVolume(11)
+ ret = self.play_pcm.stream_write_start()
+ print("self.record_pcm.stream_write_start:ret:{}".format(ret))
+ elif self.VC_play_TYPE == VC_play_TYPE_MP3:
+ pass
+ self.VC_Play_flag = 1
+ except Exception as e:
+ self.VC_Play_End()
+ usys.print_exception(e)
+ #暂停/继续声音播放 Pause_flag = 1暂停
+ def VC_Play_Pause(self,Pause_flag):
+ try:
+ if self.VC_play_TYPE == VC_play_TYPE_PCM:
+ if self.play_pcm != None:
+ self.play_pcm.stream_pause(Pause_flag)
+ except Exception as e:
+ self.VC_Play_End()
+ usys.print_exception(e)
+ #停止播放声音
+ def VC_Play_End(self):
+ self.VC_Play_flag = 0
+ if self.VC_play_TYPE == VC_play_TYPE_PCM:
+ if self.VC_play_samplerate == 8000:
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ elif self.VC_play_samplerate == 16000:
+ if self.play_pcm != None:
+ print("Close:play_pcm.close()!!!!!!!!!!!!!!!!!!")
+ try:
+ self.play_pcm.stream_stop()
+ self.play_pcm.close()
+ except Exception as e:
+ usys.print_exception(e)
+ self.play_pcm=None
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ elif self.VC_play_TYPE == VC_play_TYPE_MP3:
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ if self.AI_audio_queue.empty()!=True:
+ self.AI_audio_queue.clear()
+
def _1S_timer_cb(self,*argc):
+ EventMesh.publish("publish_AI_btnInfo",{"func":self._1S_timer_cb_})
+
+ def _1S_timer_cb_(self):
+
EventMesh.publish("system_sleep_rest")#防止黑屏
self.close_timerout += 1
- if self.close_timerout > 30:#20秒没数据就close
- EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
- # print("get_audio_state !!!!!{} {} {}\r\n".format(self.play_end,EventMesh.publish("get_audio_state"),self.play_flag))
- #self.LocalRespondingEnded_timerout+=1
- if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
- self.LocalRespondingEnded_timerout += 1
- if self.LocalRespondingEnded_timerout >= 3:
- self.LocalRespondingEnded_timerout = 0
- if self.VC_mode == 1 :#长按单次问答模式
- EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ if self.close_timerout > 60:#20秒没数据就close
+
+ if self.VC_state >= VC_State_SpeechIng:
+ print("接口无响应,超时退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"接口超时了。请重试"})
+ self.ud_error(["VC",self.VC_taskid])
else:
- #通知服务器播放结束
- self.AI_client_voice_chat_LocalRespondingEnded()
- self.pingping_timerout+=1
- if self.pingping_timerout>5:
- self.pingping_timerout=0
- self.AI_client_voice_chat_ping()
-
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ # print("get_audio_state !!!!!{} {} {}\r\n".format(self.play_end,EventMesh.publish("get_audio_state"),self.play_flag))
+ if self.LocalRespondingEnded_timerout>0 :#
+ self.LocalRespondingEnded_timerout -= 1
+ print("LocalRespondingEnded_timerout:{}".format(self.LocalRespondingEnded_timerout))
+ if self.LocalRespondingEnded_timerout <= 0 or (self.play_pcm != None and self.play_pcm.stream_is_empty() == 1) :#超时或者音频播放完,
+ self.LocalRespondingEnded_timerout = 0
+ if self.VC_mode == 1 :#长按单次问答模式
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ else:
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音
+ #通知服务器播放结束
+ self.AI_client_VC_LocalRespondingEnded()
+ self.VC_pingping_timerout+=1
+ if self.VC_pingping_timerout>3:
+ self.VC_pingping_timerout=0
+ #self.AI_client_VC_ping()
+ self.asr_pingping_timerout += 1
+ if self.asr_pingping_timerout>3:
+ self.asr_pingping_timerout=0
+ self.AI_client_asr_ping()
+ if self.VC_Thinking_timerout > 0 and self.VC_Thinking_timerout < 100:#VC Thinking超时后重新开始
+ print("VC_Thinking_timerout:{}!!!!!!!!!!!!!!!!!!!!!".format(self.VC_Thinking_timerout))
+ self.VC_Thinking_timerout -=1
+ if self.VC_Thinking_timerout == 0:
+ self.VC_Thinking_timerout = 100
+ print("Thinking重试,重试!!!!!!!!!!!!!!!!!!!!!")
+ self.VC_state = VC_State_None
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ pass
+ if self.VC_Speech_end_timerout >0:
+ self.VC_Speech_end_timerout-=1
+ if self.VC_Speech_end_timerout <=0:
+ self.VC_Speech_end_timerout = 0
+ #self.AI_client_VC_end_speech()#发送说话终止
#VC开始
def AI_VC_start(self):
-
+ print("AI_VC_start1")
+ self.VC_satrt_flag = 1
+ if self.VC_Thinking_timerout < 100:
+ self.VC_Thinking_timerout = 0
+ EventMesh.publish("open_led_all")
self.VC_Play_End()#关闭音频播放
- #self.VC_init()#关闭一些资源
- if self.VC_mode == 1:
- if self.AI_TTS_str == "":
- self.VC_init2()#关闭一些资源
-
+ print("AI_VC_start2")
#self.aud.aud_tone_play(16,200)#播放按键音
self.LocalRespondingEnded_timerout = 0
self.close_timerout = 0
+
- #utime.sleep_ms(50)
- if self.AI_client_voice_chat_isconnect == 0:#没连接的时候请求开始
- self.websocket_connect_voice_chat()#连接服务器
- self.AI_client_voice_chat_start_requset()
+ #
+ if self.AI_client_VC_isconnect == 0:#没连接的时候请求开始
+ self.websocket_connect_VC()#连接服务器
+
+ #utime.sleep_ms(50)
else:
- print("self.voice_chat_state :{}".format(self.voice_chat_state ))
- if self.voice_chat_state > VC_State_SpeechStart:
+ print("self.VC_state :{}".format(self.VC_state ))
+ if self.VC_state > VC_State_SpeechStart:
#客户端打断对话
- self.AI_client_voice_chat_RequestToSpeak()
- else:#本身处于录音状态
- return
-
- self.voice_chat_state = VC_State_None
+ print("打断对话")
+ # self.websocket_deconnect_VC()
+ # self.websocket_connect_VC()#连接服务器
+ # self.AI_client_VC_start_requset()
+ self.AI_client_VC_RequestToSpeak()
+ elif self.VC_state == VC_State_Listening:
+ #直接chat
+ print("直接chat")
+ self.AI_client_VC_RequestToRespond()
+ return
+ else:
+ print("异常状态")
+ #self.AI_client_VC_RequestToSpeak()
+ self.websocket_deconnect_VC()
+ self.websocket_connect_VC()#连接服务器
+ self.AI_client_VC_start_requset()
+ if self.AI_client_VC_isconnect == 0:
+ return
+ print("AI_VC_start3")
+
+ self.VC_state = VC_State_None
if self.AI_TTS_str == "":#没有tts要播放的时候才开始录音
- #开始录音
+ #开始asr录音
self.VC_Speech_Start()
- #self.websocket_connect_voice_chat()#连接服务器
- #self.AI_client_voice_chat_start_requset()
-
+ # pass
+ print("AI_VC_start4")
#开始线程
+
+ # if self.AI_VC_send_data_queue_thread_id == 0:
+ # _thread.stack_size(self.Audio_buf_size+8*1024)
+ # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ())
+ # _thread.stack_size(8*1024)
+ # print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id))
+
if self.AI_audio_queue_thread_id ==0:
_thread.stack_size(24*1024)
self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ())
print("AI_VC_start :AI_audio_queue_thread_id :{} ".format(self.AI_audio_queue_thread_id))
else:
print("AI_VC_start :AI_audio_queue_thread_id != 0 ")
- if self.AI_send_data_queue_thread_id == 0:
- _thread.stack_size(self.Audio_buf_size+8*1024)
- self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ())
- _thread.stack_size(8*1024)
- print("AI_VC_start :AI_send_data_queue_thread_id :{} ".format(self.AI_send_data_queue_thread_id))
self._1S_timer.start(1000,1,self._1S_timer_cb)
- self.pingping_timerout = 0
-
-
+ # self.VC_pingping_timerout = 0
+ # self.asr_pingping_timerout = 0
+ print("AI_VC_start5")
#开始会话
- def AI_client_voice_chat_start_requset(self):
-
- json_data = \
- {
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"Start"
+ def AI_client_VC_start_requset(self):
+ voice="huoshan::zh_male_wennuanahu_moon_bigtts"
+ try:
+ voice = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["voice"]
+ except Exception as e:
+ usys.print_exception(e)
+ json_data =\
+ {
+ "id": "event_id",
+ "event_type": "chat.update",
+ "data": {
+ "chat_config": {
+ "auto_save_history": True, #保存历史记录。默认 true
+ #"conversation_id": "", #按需配置,conversation_id
+ "user_id": modem.getDevImei(), #标识当前与智能体的用户,由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户,不同的 user_id,其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离,可将此参数固定为一个任意字符串
+ "meta_data": {}, #附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。
+ "custom_variables": {}, #智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。
+ "extra_params": {}, #附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。
+ "parameters": {"custom_var_1": "测试"}
+ },
+ "input_audio": { #输入音频格式
+ "format": "pcm", #输入音频格式,支持 pcm/wav/ogg。默认 wav
+ "codec": "pcm", #输入音频编码。 pcm/opus。默认 pcm
+ "sample_rate": 16000, #采样率
+ "channel": 1, #通道数
+ "bit_depth": 16 #位深
+ },
+ "output_audio": { #输出音频格式
+ "codec": "pcm",
+ "pcm_config": {
+ "sample_rate": 16000, #默认 24000
+ "frame_size_ms": 200,
+ "limit_config": {
+ "period": 1,
+ "max_frame_num": 6
+ }
+ },
+ "speech_rate": 0, #回复的语速,取值范围 [-50, 100],默认为 0,-50 表示 0.5 倍速,100 表示 2倍速
+ "voice_id": "7426720361733046281"
},
- "payload":{
- "dialog_id":self.VC_dialog_id,
- "device_id":modem.getDevImei(),
- "user_agent":"python",
- "in_format":"pcm",
- "out_format":"mp3",
- "in_sample_rate":self.VC_record_samplerate,
- "sample_rate":self.VC_play_samplerate,
- "space_time": 100,
- "volume": str(self.VC_TTS_volume),
- "voice":self.VC_TTS_voice_type[self.VC_TTS_voice_num],
- "voice_detection":"enabled",
- "simple_response":True,
- "custom_variables":{
- "bot_name":"{}".format(self.bot_name)
+ "turn_detection": {
+ "type": "server_vad"
},
-
- }
+ "event_subscriptions": [
+ "error",
+ "input_audio_buffer.speech_started",
+ "input_audio_buffer.speech_stopped",
+ "conversation.audio.delta"
+ ]
+ }
}
-
- if self.VC_play_TYPE == VC_play_TYPE_PCM:
- json_data["payload"]["out_format"]='pcm'
- if self.VC_record_TYPE == VC_record_TYPE_AMR :
- json_data["payload"]["in_format"]='amr'
- pass
- if self.VC_mode == 1:
- json_data["payload"]["voice_detection"]='disable'
- self.voice_chat_state = VC_State_None
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
+ # if self.VC_play_TYPE == VC_play_TYPE_PCM:
+ # json_data["payload"]["out_format"]='pcm'
+ # if self.VC_record_TYPE == VC_record_TYPE_AMR :
+ # json_data["payload"]["in_format"]='amr'
+ # pass
+ # if self.VC_mode == 1:
+ # json_data["payload"]["voice_detection"]='disable'
+ self.VC_state = VC_State_None
+ print("AI_client_VC_start_requset:{}".format(ujson.dumps(json_data)))
+ self.AI_client_VC_send(ujson.dumps(json_data))
#开始上传语音
- def AI_client_voice_chat_send_speech(self):
+ def AI_client_VC_send_speech(self):
json_data = \
{
"header":{
},
"payload":
{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
+ #self.AI_client_VC_send(ujson.dumps(json_data))
self.VC_Speech_Start()#开启线程获取录音数据
- self.voice_chat_state = VC_State_SpeechStart
+ self.VC_state = VC_State_SpeechStart
+ def AI_client_VC_input_audio_buffer_append(self,data):
+ json_data = \
+ {
+ "id": "event_id",
+ "event_type": "input_audio_buffer.append",
+ "data": {
+ "delta": ubinascii.b2a_base64(data)
+ }
+ }
+ self.AI_client_VC_send(ujson.dumps(json_data))
#结束上传语音
- def AI_client_voice_chat_end_speech(self):
+ def AI_client_VC_end_speech(self):
json_data = \
{
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"StopSpeech"
- },
- "payload":{
- "dialog_id":self.VC_dialog_id
- }
+ "id": "event_id",
+ "event_type": "input_audio_buffer.complete",
+ "data": {}
}
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
- self.VC_Speech_End()#停止线程录音
+ self.AI_client_VC_send(ujson.dumps(json_data))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone})
#通知服务器开始播放
- def AI_client_voice_chat_LocalRespondingStarted(self):
+ def AI_client_VC_LocalRespondingStarted(self):
json_data = \
{
"header":{
"event":"LocalRespondingStarted"
},
"payload":{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
+ self.AI_client_VC_send(ujson.dumps(json_data))
#通知服务器播放结束
- def AI_client_voice_chat_LocalRespondingEnded(self):
+ def AI_client_VC_LocalRespondingEnded(self):
json_data = \
{
"header":{
"event":"LocalRespondingEnded"
},
"payload":{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
+ # json_data = \
+ # {
+ # "header":{
+ # "trace_id":self.get_trace_id(),
+ # "event":"AAAAAAAAAAAAAA1"
+ # },
+ # "payload":{
+ # "dialog_id":self.VC_dialog_id,
+ # "session_id": self.session_id ,
+ # }
+ # }
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
# utime.sleep_ms(1)
- # self.AI_client_voice_chat_send(ujson.dumps(json_data))
- self.voice_chat_state = VC_State_End
+ # self.AI_client_VC_send(ujson.dumps(json_data))
+ self.VC_state = VC_State_End
#客户端打断对话
- def AI_client_voice_chat_RequestToSpeak(self):
+ def AI_client_VC_RequestToSpeak(self):
json_data = \
{
"header":{
"event":"RequestToSpeak"
},
"payload":{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
- print("AI_client_voice_chat_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ print("AI_client_VC_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
# utime.sleep_ms(1)
- #请求TTS事件
- def AI_client_voice_chat_RequestToRespond(self,text):
+ #请求TTS或者chat事件
+ def AI_client_VC_RequestToRespond(self):
+ self.session_id = self.get_session_id()#调试临时打开
json_data = \
{
"header":{
},
"payload":{
"dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
"type":"transcript",#prompt是跳过asr,transcript是跳过asr和大模型
- "text":text
+ "text":""
}
}
- print("AI_client_voice_chat_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+
+ print("AI_client_VC_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ # if self.VC_state == VC_State_RequestToRespond:
+ # print("AI_client_VC_RequestToRespond 重复 tts_str:{}\nasr_str:{}".format(self.AI_TTS_str,self.AI_ASR_str))
+ self.VC_state = VC_State_RequestToRespond
+ if self.AI_TTS_str != "":
+ json_data["payload"]["text"] = self.AI_TTS_str
+ json_data["payload"]["type"] = "transcript"
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
+ self.AI_TTS_str = ""
+ elif self.AI_ASR_str != "":
+ json_data["payload"]["text"] = self.AI_ASR_str
+ json_data["payload"]["type"] = "prompt"
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
+ # if dev_type != "7PIN" :
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone})
+ #
+ #self.AI_ASR_str = ""
# utime.sleep_ms(1)
- #发送数据队列
- def AI_send_data_queue_thread(self):
- print("AI_send_data_queue_thread:start")
- count_t = 0
- while True:
- if self.AI_send_data_queue.empty() :
- count_t+=1
- # if count_t%200 == 0:
- # print("self.AI_send_data_queue.empty")
- utime.sleep_ms(5)
- else:
- #data[0]是websocket连接对象编号,data[1]是数据
- #print("AI_send_data_queue_thread:get")
- data = self.AI_send_data_queue.get()
- #print("AI_send_data_queue_thread:get2")
- if data != None:
- try:
- #data["func"](data["data"])
- # 发送数据
- #bytes_data = bytes(data[1])
- #data[0].send(data[1])
- #print("AI_send_data_queue_thread:len:{}".format(len(data[1])))
- if data[0] == AI_client_voice_chat_num:
- # if self.AI_client_voice_chat_isconnect == 0:
- # try:
- # self.websocket_connect_voice_chat()
- # except Exception as e: #网络连接异常
- # usys.print_exception(e)
- self.pingping_timerout = 0
- #print("VC: send_data len:{}".format(len(data[1])))
- if self.AI_client_voice_chat != None and self.AI_client_voice_chat_isconnect == 1:
- self.AI_client_voice_chat.send(data[1])
- #print("VC: send_data len:{}".format(len(data[1])))
- #print("VC: send_data end")
- except Exception as e:
- print("DeviceInfo_queue_thread:ERROR:{}".format(e))
- usys.print_exception(e)
- if data[0] == AI_client_voice_chat_num:
- #self.websocket_error_voice_chat()
- pass
- #self.websocket_deconnect_voice_chat()
- self.AI_client_voice_chat_isconnect = 0
- try:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error_voice_chat})
- EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- except Exception as e: #网络连接异常
- usys.print_exception(e)
-
+ def chenggong_tone(self):
+ EventMesh.publish("audio_montage_play",["chenggong.mp3"])
+ def send_tone(self):
+ EventMesh.publish("audio_montage_play",["send_tone.mp3"])
+ #给服务器回应ack
+ def AI_client_VC_Read(self):
+ json_data = \
+ {
+ "header":{
+ "trace_id":self.get_trace_id(),
+ "event":"Read"
+ },
+ "payload":{
+ "dialog_id":self.VC_dialog_id
+ }
+ }
+ print("AI_client_VC_Read!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
+ #for i in range(6):
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
+ # utime.sleep_ms(1)
+ if self.AI_client_VC != None and self.AI_client_VC_isconnect == 1:
+ self.AI_client_VC.send(ujson.dumps(json_data))
+
############################################
+ #关闭音频播放线程
+ def AI_audio_queue_thread_close(self):
+ print("AI_audio_queue_thread_close1!!!!!!!!!!!!!!!!!!!!!!")
+ if self.AI_audio_queue_thread_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_audio_queue_thread_lock == 0 or count <=0:
+ break
+ else:
+ self.AI_audio_queue_thread_lock = 2
+ print("AI_audio_queue_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_audio_queue_thread_lock = 0
+ print("AI_audio_queue_thread_close2!!!!!!!!!!!!!!!!!")
+ try:
+ _thread.stop_thread(self.AI_audio_queue_thread_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_audio_queue_thread_id = 0
# 音频队列
def AI_audio_queue_thread(self):
print("AI_audio_queue_thread start")
count = 0
+ if self.AI_audio_queue.empty()!=True:
+ self.AI_audio_queue.clear()
+ print("音频数据还有剩余!!!!!!!!!!!!")
while True:
try:
- # if self.AI_send_data_queue_thread_id == 0:
- # break
- # print("AI_audio_queue_thread")
+ if self.AI_audio_queue_thread_lock == 2:
+ print("AI_audio_queue_thread 该退出了")
+ break
+ #
+ count+=1
+ if count%500 == 1:
+ print("AI_audio_queue_thread on")
+ utime.sleep_ms(1)
+ #print("AI_audio_queue_thread")
if self.AI_audio_queue.empty() :
- utime.sleep_ms(5)
- count+=1
- if count%1000 == 1:
- print("AI_audio_queue_thread on")
+ self.AI_audio_queue_thread_lock = 0
+
+
else:
+ self.AI_audio_queue_thread_lock = 1
data = self.AI_audio_queue.get()
self.close_timerout = 0
if self.play_flag == 0:
self.play_flag =1
- print("AI_client_voice_chat_LocalRespondingStarted!!!")
- self.AI_client_voice_chat_LocalRespondingStarted()#通知服务器开始播放
- print("\r\naudio_queue:len:{},data{}".format(len(data[0]),len(data[1])))
+ #self.AI_client_tts_data_len=len(data)
+ #print("audio_queue:len:{}".format(len(data[0])))
+
if len(data[0]) > 10:
+ for i in range(5):
+ if self.VC_Play_flag == 0:
+ self.VC_Play_Start()
+ utime.sleep_ms(2)
+ else:
+ break
try:
if self.VC_play_TYPE == VC_play_TYPE_PCM:
- if self.VC_play_samplerate == 8000:
- tmp= self.aud.playStream(1,data[0] )
- elif self.VC_play_samplerate == 16000:
- # if tmp != 0:
- # print("playStream:WAV:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data[0])))
- # # #播放失败的时候填充WAV头
- # data_len = len(data[0])
- # data_len_b = data_len.to_bytes(4,'little')#数据长度转16进制数组
- # h_data = [ 0x52 ,0x49 ,0x46 ,0x46 #,0x24 ,0x00 ,0x00 ,0x00 #文件标识、文件大小
- # ,0x57 ,0x41 ,0x56 ,0x45 ,0x66 ,0x6D ,0x74 ,0x20 #文件格式、格式块标识符
- # ,0x10 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x80 ,0x3E ,0x00 ,0x00 #格式块大小4、音频格式2、声道数2、采样率4
- # ,0x80 ,0x3E ,0x00 ,0x00 ,0x02 ,0x00 ,0x10 ,0x00 ,0x64 ,0x61 ,0x74 ,0x61]#每秒字节数4、数据块对齐2、位深度2、data4
- # h_data_b = bytes(h_data)
- # file_len = data_len+len(h_data_b)+4+4
- # file_len_b = file_len.to_bytes(4,'little')#文件长度转16进制数组
- # h_data_b = h_data_b[:4]+file_len_b+h_data_b[4:]+data_len_b
- # #self.aud.playStream(2, h_data_b)#播放音频流
- # tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流
- # print("playStream2:WAV:tmp:{} !!!!!!!!!!!!".format(tmp))
-
-
+ # if self.VC_play_samplerate == 8000:
+ # tmp= self.aud.playStream(1,data[0] )
+ # else:
write_buf = bytearray(data[0])
- #print("play_pcm.stream_write1!!")
+ #print("play_pcm.stream_write1 len:{}".format(len(write_buf)))
if self.play_pcm != None:
+ #print("play_pcm.stream_write !!!")
ret = self.play_pcm.stream_write(write_buf,len(write_buf))
#ret= self.aud.playStream(1, data[0])#播放音频流
- print("play_pcm.stream_write:{}".format(ret))
+ self.tts_out_data_len += ret
+ #print("play_pcm.stream_write2:{}".format(self.tts_out_data_len))
elif self.VC_play_TYPE == VC_play_TYPE_MP3:
tmp= self.aud.playStream(3, data[0])#播放音频流
# tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流
# print("3playStream:tmp:{} !!!!!!!!!!!!".format(tmp))
- print("出:{}!!!".format(len(data[0])))
+
mem = gc.mem_free()
- print('1剩余内存RAM:{} KB'.format(mem / 1024))
+ #print('1剩余内存RAM:{} KB'.format(mem / 1024))
except Exception as e:
print("AI_audio_queue_thread:ERROR:")
usys.print_exception(e)
- # if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
+ # if self.VC_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
# #通知服务器播放结束
- # self.AI_client_voice_chat_LocalRespondingEnded()
+ # self.AI_client_VC_LocalRespondingEnded()
except Exception as e:
print("AI_audio_queue_thread:ERROR:")
usys.print_exception(e)
+ self.AI_audio_queue_thread_lock = 0
#print("AI_audio_queue_thread:exit")
def factory_mode(self):
print("factory_mode")
EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
EventMesh.publish("publish_AI_btnInfo",{"func":self.factory_start})
def factory_start(self):
- self.factory_timer.start(1000, 1, self.factory_timer_cb)
+ self.factory_timer.start(3000, 1, self.factory_timer_cb)
def factory_timer_cb(self, *args, **kwargs):
print("factory_timer_cb play......")
- self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
+
def Close(self):
+ self.VC_Thinking_timerout = 0
+ self.VC_satrt_flag = 0
+ self.AI_TTS_str = ""
+ self.AI_ASR_str = ""
+ self.AI_ASR_str_tmp = ""
+ self.AI_ASR_flag = 0
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
print("ai_VC Close1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ EventMesh.publish("close_led")
+ self.tts_in_data_len = 0
+ self.tts_out_data_len = 0
+ #必须先销毁线程,不然线程会容易报错
+ try:
+ self.AI_ASR_send_data_queue_thread_close()#销毁ASR发送线程
+ except Exception as e:
+ usys.print_exception(e)
+ try:
+ self.AI_audio_queue_thread_close()#销毁音频线程
+ except Exception as e:
+ usys.print_exception(e)
+ try:
+ self.AI_VC_send_data_queue_thread_close()#销毁数据发送线程
+ except Exception as e:
+ usys.print_exception(e)
+ self.VC_Speech_End()
+ print("ai_VC Close1.1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
self.VC_init()
- if self.AI_send_data_queue.empty()!=True:
- self.AI_send_data_queue.clear()
+
+ print("ai_VC Close1.2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
try:
- #销毁线程
- if self.AI_audio_queue_thread_id != 0:
- try:
- _thread.stop_thread(self.AI_audio_queue_thread_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_audio_queue_thread_id = 0
- if self.AI_send_data_queue_thread_id != 0:
- try:
- _thread.stop_thread(self.AI_send_data_queue_thread_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_send_data_queue_thread_id = 0
-
-
+ self.websocket_deconnect_asr()
except Exception as e:
usys.print_exception(e)
- print("ai_VC Close2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
try:
- self.websocket_deconnect_voice_chat()
+ self.websocket_deconnect_VC()
except Exception as e:
usys.print_exception(e)
- print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
+ print("ai_VC Close1.3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
+ print("ai_VC Close2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
+
+ self.AI_ASR_timer.stop()
self._1S_timer.stop()
self.factory_timer.stop()
+
+ if self.record_data_save_flag == 1:
+ if self.record_fd :
+ self.record_fd.close()
+ self.record_fd = None
+ if self.play_data_save_flag == 1:
+ if self.play_fd !=None:
+ self.play_fd.close()
+ print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
+
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ self.AI_ASR_send_buf_len = 0
+ #self.AI_WS_connect_Queue.put(self.AI_client_VC)
+
+ # try:
+ # while True:
+ # if self.AI_WS_connect_Queue.empty()!=True:
+ # AI_WS_connect = self.AI_WS_connect_Queue.get()
+ # if AI_WS_connect :
+ # try:
+ # AI_WS_connect._close()
+ # AI_WS_connect = None
+ # except Exception as e:
+ # usys.print_exception(e)
+ # else:
+ # print("websocket链接已为空")
+ # else:
+ # break
+ # except Exception as e:
+ # usys.print_exception(e)
+
def VC_init2(self):
self.VC_init()
-
+
print("ai_VC VC_init2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
try:
- self.websocket_deconnect_voice_chat()
+ self.websocket_deconnect_VC()
except Exception as e:
usys.print_exception(e)
print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
self._1S_timer.stop()
-
- def VC_init(self):
-
- print("VC_init:AI_send_data_queue:size:{}".format(self.AI_send_data_queue.size()))
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ self.AI_ASR_send_buf_len = 0
if self.AI_audio_queue.empty()!=True:
self.AI_audio_queue.clear()
+ def VC_init(self):
+
+ print("VC_init:AI_VC_send_data_queue:size:{}".format(self.AI_VC_send_data_queue.size()))
+
- self.AI_TTS_str = ""
print("VC_init2")
- self.VC_Speech_End()
+ #self.VC_Speech_End()
print("VC_init3")
self.VC_Play_End()
print("VC_init4")
- EventMesh.publish("close_led")
+ if self.AI_audio_queue.empty()!=True:
+ self.AI_audio_queue.clear()
# num = EventMesh.publish("get_volum_size")
# if num == None:
# num = 8
from misc import Power,USB,PowerKey
import ntptime
import machine
+import dataCall
+import constants
+import versions
+
+dev_type = "G10"
+#dev_type = "7PIN_BK"#小瑞
+#dev_type = "7PIN"#柒牌
+#dev_type = 'momo'#食梦貘
+#dev_type = 'sjgq'#四季甘泉
class AI_led(Abstract):
def __init__(self):
- self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
- self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
- self.led_blue = Pin(Pin.GPIO44, Pin.OUT, Pin.PULL_PD, 1)
+ if dev_type == "G10":
+ self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
+ self.led_green = Pin(Pin.GPIO44, Pin.OUT, Pin.PULL_PD, 1)
+ self.led_blue = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
+ else:
+ self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0)
+ self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1)
+ self.led_blue = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1)
+
#=1 红灯闪,=2白灯闪,=3绿灯闪,=4全部灯闪
self.led_flicker_flag = 0
self.led_flicker_on_off_flag = 0
self.led_flicker_flag = 4
self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb)
- def led_flicker_timer_cb_(self, *args, **kwargs):
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_dev_timer_event})
+ def led_flicker_timer_cb(self, *args, **kwargs):
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.led_flicker_timer_cb_})
def led_flicker_timer_cb_(self):
if self.led_flicker_flag == 0:
self.led_flicker_timer.stop()
self.led_blue.write(0)
self.led_green.write(0)
-audio_buf = ['dianliangshengyu10', 'dianliangshengyu100', 'dianliangshengyu20', 'dianliangshengyu40', 'dianliangshengyu60', 'dianliangshengyu80', 'dianliangshengyu90', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'peizhichenggong', 'qiehuanchenggong', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_POWER_OFF_1', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_SIM_FAILE', 'xianyikaiji', 'xinhaoruo1', 'xinhaoruo2', 'yinliangyizuida', 'yinliangyizuixiao', 'zhengzaiguanji']
-
+audio_buf = ['chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_READ_TIME_A', 'R_READ_TIME_B', 'R_READ_TIME_C', 'R_READ_TIME_D', 'R_READ_TIME_E', 'R_READ_TIME_F', 'R_READ_TIME_G', 'R_READ_TIME_H', 'R_READ_TIME_I', 'R_READ_TIME_J', 'R_READ_TIME_K', 'R_READ_TIME_L', 'R_READ_TIME_M', 'R_READ_TIME_N', 'R_READ_TIME_O', 'R_READ_TIME_P', 'R_READ_TIME_Q', 'R_READ_TIME_R', 'R_READ_TIME_S', 'R_READ_TIME_T', 'R_READ_TIME_U', 'R_READ_TIME_V', 'R_READ_TIME_W', 'R_READ_TIME_X', 'R_READ_TIME_Y', 'R_READ_TIME_Z', 'send_tone', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji']
class AI_dev(Abstract):
# AI
def __init__(self):
- self.is_wdt = 1 #是否开启看门狗
- self.VBATT_tab = {"charge_full":4300,100 :4250 , 90:3994 , 80:3883, 60: 3707, 40:3604, 20:3537, 10:3486,}
+ self.is_wdt = 0 #是否开启看门狗
+
+ self.VBATT_tab = {"charge_full":4300,"100" :4250 , "90":4179 , "80":4070, "60": 3883, "40":3770, "20":3699, "10":3652,"5":3600,}
self.KeyAI_status = 0
self.KeyAI_timer_count = 0
self.KeyAI_long_press = 0
self.KeyAI_press = 0
+ if self.is_wdt == 1:
+ self.wdt = WDT(30) #开启看门狗
+ # self.wdt_timer = osTimer()
+ # self.wdt_timer.start(5000, 1, self.wdt_timer_cb)
+ count = 0
+ while True:
+ count += 1
+ if count > 20 :
+ break
+ data = dataCall.getInfo(1, 0)
+ print("data call INFO {}".format(data))
+ if data[2][0]:
+ self.network_state = 1
+ break
+ print("等待网络 {}...".format(count))
+ utime.sleep_ms(500)
self.KeyAI_timer = osTimer()
- #self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
- self.extint_AI = ExtInt(ExtInt.GPIO20,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
- #self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
+ if dev_type == "G10":
+ self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
+ self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+ else:
+ self.pwk_key = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+ #self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
+ self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
self.extint_AI.enable()
self.pwk_key_status = 0
self.pwk_key_timer_count = 0
self.pwk_key_long_press = 0
self.pwk_key_press = 0
self.pwk_key_timer = osTimer()
- self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_DISABLE, self.pwk_extint_cb)
- #self.pwk_key = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+ #self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_DISABLE, self.pwk_extint_cb)
+
self.pwk_key.enable()
+ print("AI_dev:1")
self.btnInfo_queue = Queue(100)
self.btnInfo_queue_count = 0
- _thread.stack_size(10*1024)
+ _thread.stack_size(16*1024)
self.btnInfo_queue_thread_id = _thread.start_new_thread(self.btnInfo_queue_thread, ())
_thread.stack_size(8*1024)
EventMesh.subscribe("publish_AI_btnInfo",self.publish_AI_btnInfo)
EventMesh.subscribe("audio_montage_play",self.audio_montage_play)
EventMesh.subscribe("paly_iccid_imei",self.paly_iccid_imei)
EventMesh.subscribe("paly_device_res_error",self.paly_device_res_error)
- if self.is_wdt == 1:
- self.wdt = WDT(30) #开启看门狗
- # self.wdt_timer = osTimer()
- # self.wdt_timer.start(5000, 1, self.wdt_timer_cb)
+ print("AI_dev:2")
self.pk = PowerKey()
self.pk.powerKeyEventRegister(self.powerKey_callback)
self.usb = USB()
self.usb.setCallback(self.usb_event_cb)
self.usb_status = self.usb.getStatus()
self.usb_charge_flag = 0
+ self.Low_power_warning_timer = 0
self.AI_dev_timer = osTimer()
self.AI_dev_timer.start(10000, 1, self.AI_dev_timer_cb)
+ print("AI_dev:AI_dev_timer")
self.aud = audio.Audio(0)
+ self.Low_power_warning_flag = 0
self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
if self.VC_TTS_volume == None:
self.VC_TTS_volume = 100
#self.aud.play(1,0,'U:/static/xianyikaiji.mp3')#开机音频
#EventMesh.publish("audio_montage_play",["xianyikaiji.mp3"])
#EventMesh.publish("publish_AI_btnInfo",{"func":self.ntptime_cb})
+ self.check_rest_timer_count = 0
+ print("AI_dev:end")
def ntptime_cb(self):
#ntptime.settime(8)
print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
#self.aud.play(1,1,'U:/static/R_CHARGE_IN.mp3')
EventMesh.publish("open_led_red")#充电红灯常亮
EventMesh.publish("audio_montage_play",["R_CHARGE_IN.mp3"])
+ self.Low_power_warning_flag = 0
pass
elif status == 0:#拨出usbs
self.usb_status = 0
#EventMesh.debug_log("btnInfo_queue:ERROR:{}".format(e))
usys.print_exception(e)
def publish_AI_btnInfo(self,event,msg):
+ #print("publish_AI_btnInfo 1")
self.btnInfo_queue.put(msg)
self.btnInfo_queue_count+=1
if self.btnInfo_queue_count > 80:
# self.btnInfo_queue = Queue(100)
EventMesh.publish("VC_error") #播放报错
utime.sleep_ms(1000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
Power.powerRestart()
EventMesh.publish("set_storage_config",["powerRestart",1])
-
+ #print("publish_AI_btnInfo 2")
def powerKey_callback(self, status):
print("powerKey_callback:{}".format(status))
self.pwk_key_status = 0
pass
if self.pwk_key_status == 0:#按下
+
if self.pwk_key_press == 0 :
self.pwk_key.disable()
self.pwk_key_press = 1
self.pwk_key_timer.start(100, 1, self.pwk_key_timer_cb)
self.pwk_key_timer_count = 0
#EventMesh.publish("AI_key_press")
-
except Exception as e:
usys.print_exception(e)
def pwk_key_timer_cb(self, *args, **kwargs):
if self.pwk_key_long_press == 0:
self.pwk_key_long_press = 1
#EventMesh.publish("AI_key_long_press")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_Long_Press})
+ EventMesh.publish("audio_montage_play",["zhengzaiguanji.mp3"])
+ #self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频
+ EventMesh.publish("open_led_red")
+ utime.sleep_ms(2000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ Power.powerDown()
+ #print("AI_key_release")
+ EventMesh.publish("pwk_key_long_press")
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_Long_Press})
if self.pwk_key_status == 1:#松开
#print("pwk_key_timer_cb:{}".format(self.pwk_key_timer_count))
- if self.pwk_key_timer_count >= 5: #防抖200ms
+ key_count = 5
+ if dev_type == "7PIN_BK":
+ key_count = 3
+ if self.pwk_key_timer_count >= key_count: #防抖200ms
#EventMesh.publish("AI_key_release")
EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release})
self.pwk_key.enable()
if self.KeyAI_status == 0:#按下
if self.KeyAI_press == 0 :
+ EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
self.extint_AI.disable()
self.KeyAI_press = 1
self.KeyAI_long_press = 0
self.KeyAI_timer.start(100, 1, self.KeyAI_timer_cb)
self.KeyAI_timer_count = 0
#EventMesh.publish("AI_key_press")
- self.aud.aud_tone_play(10,200)#播放按键音
+ if dev_type == "7PIN" :
+ self.aud.aud_tone_play(10,200)#播放按键音
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})
except Exception as e:
usys.print_exception(e)
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_long_press})
if self.KeyAI_status == 1:#松开
#print("KeyAI_timer_cb:{}".format(self.KeyAI_timer_count))
- if self.KeyAI_timer_count >= 5: #防抖200ms
+ key_count = 5
+ if dev_type == "7PIN_BK":
+ key_count = 3
+ if self.KeyAI_timer_count >= key_count: #防抖200ms
#EventMesh.publish("AI_key_release")
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_release})
self.extint_AI.enable()
usys.print_exception(e)
def AI_key_press(self):
+ self.check_rest_timer_count = 0
print("AI_key_press")
EventMesh.publish("AI_key_press")
+
def AI_key_long_press(self):
+ self.check_rest_timer_count = 0
print("AI_key_long_press")
EventMesh.publish("AI_key_long_press")
def AI_key_release(self):
print("AI_key_release")
EventMesh.publish("AI_key_release")
+
def pwk_key_Long_Press(self):
+ self.check_rest_timer_count = 0
print("pwk_key_long_press!!!!!!!")
print("pwk_key_long_press!!!!!!!")
#self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频
EventMesh.publish("open_led_red")
utime.sleep_ms(3000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
Power.powerDown()
#print("AI_key_release")
EventMesh.publish("pwk_key_long_press")
def pwk_key_release(self):
+ self.check_rest_timer_count = 0
#print("pwk_key_release")
EventMesh.publish("pwk_key_release")
def wdt_timer_cb(self, *args, **kwargs):
if self.is_wdt == 1:
self.wdt.feed()
+
def AI_dev_timer_cb(self, *args, **kwargs):
- print("AI_dev_timer_cb")
+ #print("AI_dev_timer_cb")
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_dev_timer_event})
def AI_dev_timer_event(self):
if self.is_wdt == 1:
EventMesh.publish("audio_montage_play",["R_CHARGE_FULL.mp3"])
#self.aud.play(1,0,'U:/static/R_CHARGE_FULL.mp3')#充电已满
self.usb_charge_flag = 1
- if self.usb_status == 0 and Vbatt<self.VBATT_tab[20]and VC_satrt_flag == 0:#低电报警
+ if self.usb_status == 0 and Vbatt<self.VBATT_tab["20"]and VC_satrt_flag == 0 and self.Low_power_warning_flag ==0:#低电报警
+ self.Low_power_warning_flag = 1
EventMesh.publish("flicker_led_red")
#self.aud.play(1,0,'Low_power_warning.mp3')
- if self.usb_charge_flag == 0 :
- EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"])
- self.usb_charge_flag = 1
+ # self.Low_power_warning_timer+=1
+ # if self.Low_power_warning_timer >= 2:
+ # self.Low_power_warning_timer = 0
+ EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"])
+
+ if self.usb_status == 0 and Vbatt<self.VBATT_tab["5"]:
+ EventMesh.publish("audio_montage_play",["didianguanji.mp3"])
+ utime.sleep_ms(4500)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ Power.powerDown()
+
+ self.check_rest_timer_count += 1
+ if self.check_rest_timer_count >= 8640:#24小时没按键,则关机
+ self.pwk_key_Long_Press()
def get_battery(self, event=None, msg=None):
Vbatt = Power.getVbatt()
- if Vbatt>self.VBATT_tab[90]:
+ if Vbatt>self.VBATT_tab["90"]:
return 100
- if Vbatt>self.VBATT_tab[80]:
+ if Vbatt>self.VBATT_tab["80"]:
return 90
- if Vbatt>self.VBATT_tab[60]:
+ if Vbatt>self.VBATT_tab["60"]:
return 80
- if Vbatt>self.VBATT_tab[40]:
+ if Vbatt>self.VBATT_tab["40"]:
return 60
- if Vbatt>self.VBATT_tab[20]:
+ if Vbatt>self.VBATT_tab["20"]:
return 40
- if Vbatt>self.VBATT_tab[10]:
+ if Vbatt>self.VBATT_tab["10"]:
return 20
- if Vbatt<=self.VBATT_tab[10]:
+ if Vbatt<=self.VBATT_tab["10"]:
return 10
def audio_montage_play(self,event,msg):
self.aud.stopPlayStream()
+ self.aud.stopAll()
str_data='mp3files='
for i in msg:
try:
str_data = str_data[:-1]
print("audio_montage_play:{}".format(str_data))
self.aud.montage_play('U:/static/audio.bin',1,1,str_data)
+
def paly_iccid_imei(self,event,msg):
str_data = 'mp3files={}.mp3+'.format(audio_buf.index("liuliangtishi"))#流量提示
imei = modem.getDevImei()
iccid = sim.getIccid()
+ print("paly_iccid_imei:ICCID:{}".format(iccid))
if iccid != -1 and len(iccid) > 5:
- str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+'.format(audio_buf.index("R_READ_TIME_{}".format(iccid[0]))\
+ iccid = iccid.upper()
+ if len(iccid) <20:
+ for i in range(20-len(iccid)):
+ iccid = "0"+iccid
+ str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+'.format(audio_buf.index("R_READ_TIME_{}".format(iccid[0]))\
,audio_buf.index("R_READ_TIME_{}".format(iccid[1])),audio_buf.index("R_READ_TIME_{}".format(iccid[2])),audio_buf.index("R_READ_TIME_{}".format(iccid[3])),\
audio_buf.index("R_READ_TIME_{}".format(iccid[4])),audio_buf.index("R_READ_TIME_{}".format(iccid[5])),audio_buf.index("R_READ_TIME_{}".format(iccid[6])),audio_buf.index("R_READ_TIME_{}".format(iccid[7])),\
audio_buf.index("R_READ_TIME_{}".format(iccid[8])),audio_buf.index("R_READ_TIME_{}".format(iccid[9])),audio_buf.index("R_READ_TIME_{}".format(iccid[10])),audio_buf.index("R_READ_TIME_{}".format(iccid[11])),\
- audio_buf.index("R_READ_TIME_{}".format(iccid[12])),audio_buf.index("R_READ_TIME_{}".format(iccid[13])),audio_buf.index("R_READ_TIME_{}".format(iccid[14])))
- str_data += '{}.mp3+'.format(audio_buf.index("IMEIhao"))#IMEI号为:
- str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3'.format(audio_buf.index("R_READ_TIME_{}".format(imei[0]))\
- ,audio_buf.index("R_READ_TIME_{}".format(imei[1])),audio_buf.index("R_READ_TIME_{}".format(imei[2])),audio_buf.index("R_READ_TIME_{}".format(imei[3])),\
- audio_buf.index("R_READ_TIME_{}".format(imei[4])),audio_buf.index("R_READ_TIME_{}".format(imei[5])),audio_buf.index("R_READ_TIME_{}".format(imei[6])),audio_buf.index("R_READ_TIME_{}".format(imei[7])),\
- audio_buf.index("R_READ_TIME_{}".format(imei[8])),audio_buf.index("R_READ_TIME_{}".format(imei[9])),audio_buf.index("R_READ_TIME_{}".format(imei[10])),audio_buf.index("R_READ_TIME_{}".format(imei[11])),\
- audio_buf.index("R_READ_TIME_{}".format(imei[12])),audio_buf.index("R_READ_TIME_{}".format(imei[13])),audio_buf.index("R_READ_TIME_{}".format(imei[14])))
- #print("str_data:{}".format(str_data))
+ audio_buf.index("R_READ_TIME_{}".format(iccid[12])),audio_buf.index("R_READ_TIME_{}".format(iccid[13])),audio_buf.index("R_READ_TIME_{}".format(iccid[14])),audio_buf.index("R_READ_TIME_{}".format(iccid[15])),\
+ audio_buf.index("R_READ_TIME_{}".format(iccid[16])),audio_buf.index("R_READ_TIME_{}".format(iccid[17])),audio_buf.index("R_READ_TIME_{}".format(iccid[18])),audio_buf.index("R_READ_TIME_{}".format(iccid[19])))
+ str_data += '{}.mp3+'.format(audio_buf.index("shouhou"))#可联系售后解决,联系方式见售后客服电话是400-886-8777或到微信公众号柒牌SEVENBRAND自行充值:
self.aud.montage_play('U:/static/audio.bin',1,1,str_data)
#鉴权出错,播放imei号
def paly_device_res_error(self,event,msg):
str_data = 'mp3files={}.mp3+'.format(audio_buf.index("jianquancuowu"))#AI功能异常,请联系客户查询,设备号为:
imei = modem.getDevImei()
+ imei = imei.upper()
str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3'.format(audio_buf.index("R_READ_TIME_{}".format(imei[0]))\
,audio_buf.index("R_READ_TIME_{}".format(imei[1])),audio_buf.index("R_READ_TIME_{}".format(imei[2])),audio_buf.index("R_READ_TIME_{}".format(imei[3])),\
audio_buf.index("R_READ_TIME_{}".format(imei[4])),audio_buf.index("R_READ_TIME_{}".format(imei[5])),audio_buf.index("R_READ_TIME_{}".format(imei[6])),audio_buf.index("R_READ_TIME_{}".format(imei[7])),\
audio_buf.index("R_READ_TIME_{}".format(imei[12])),audio_buf.index("R_READ_TIME_{}".format(imei[13])),audio_buf.index("R_READ_TIME_{}".format(imei[14])))
#print("str_data:{}".format(str_data))
self.aud.montage_play('U:/static/audio.bin',1,1,str_data)
+
#存储信息
class getStorageDataManager(Abstract):#获取内存数据
def __init__(self):
class device_res_author(Abstract):
def __init__(self) :
+ print("device_res_author __init__ start !!!!!!!!!!!!!!!!!")
self.deviceId = modem.getDevImei()#"876226002022574"
self.SHA1_BLOCK_SIZE = 64
self.PAD_BLOCK_SIZE = 16
self.pid = "cqxJZi5CNgzjS3mX21Zw"
self.dev_res_timer = osTimer()
- self.dev_res_timer.start(10000, 1, self.dev_timer_cb)
+ self.dev_res_timer.start(20000, 1, self.dev_timer_cb)
self.dev_res_timerCount = 0
self.ud_token_timer = osTimer()
- self.ud_token_timer.start(30000, 1, self.ud_token_timer_cb)
+ self.ud_token_timer.start(10000, 1, self.ud_token_timer_cb)
self.ud_token_timer_Count = 0
self.dev_token = None
self.res_error_count = 0
EventMesh.subscribe("dev_active", self.dev_active)
EventMesh.subscribe("dev_sign_in", self.dev_sign_in)
EventMesh.subscribe("dev_NTP", self.dev_NTP)
- EventMesh.publish_async("dev_NTP",thread_size = 8192)
- count = 0
- while True:
- if self.ntptime_flag == 1:
- break
- utime.sleep_ms(1)
- count+=1
- if count>600:
- break
- EventMesh.publish_async("dev_active",thread_size = 8192)
- EventMesh.publish_async("dev_sign_in",thread_size = 8192)
- # self.dev_active() #设备激活
- # self.dev_sign_in() #设备登入
-
+ #EventMesh.publish_async("dev_NTP",thread_size = 8192)
+
+ # count = 0
+ # while True:
+ # if self.ntptime_flag == 1:
+ # break
+ # utime.sleep_ms(1)
+ # count+=1
+ # if count>600:
+ # break
+ # EventMesh.publish_async("dev_active",thread_size = 8192)
+ # EventMesh.publish_async("dev_sign_in",thread_size = 8192)
+
+ self.dev_NTP()#获取时间
+ self.dev_active() #设备激活
+ self.dev_sign_in() #设备登入
+ print("device_res_author __init__ end !!!!!!!!!!!!!!!!!")
+
def get_dev_token(self, event, msg):
return self.dev_token
#网络校时
- def dev_NTP(self, event, msg):
- url = "http://dmp.raisound.com/bz-api/dev/time"
- response = request.get(url)
- data = response.json()
- print("dev_NTP:{}".format(data))
- if data:
- try:
- timeSecond = data["data"]["timestamp"]//1000
-
- next_alarm_time = utime.localtime(timeSecond)
- print("timeSecond {} next_alarm_time {}".format(timeSecond,next_alarm_time))
- machine.RTC().datetime((next_alarm_time[0],next_alarm_time[1],next_alarm_time[2],next_alarm_time[6],next_alarm_time[3],next_alarm_time[4],next_alarm_time[5],0))
- self.ntptime_flag = 1
- except Exception as e:
- usys.print_exception(e)
+ def dev_NTP(self, event=None, msg=None):
+ response = None
+ try:
+ print("dev_NTP1")
+ url = "http://dmp.raisound.com/bz-api/dev/time"
+ response = request.get(url,timeout=5)
+ data = response.json()
+ print("dev_NTP:{}".format(data))
+ if data:
+ try:
+ timeSecond = data["data"]["timestamp"]//1000
+
+ next_alarm_time = utime.localtime(timeSecond)
+ print("timeSecond {} next_alarm_time {}".format(timeSecond,next_alarm_time))
+ machine.RTC().datetime((next_alarm_time[0],next_alarm_time[1],next_alarm_time[2],next_alarm_time[6],next_alarm_time[3],next_alarm_time[4],next_alarm_time[5],0))
+ self.ntptime_flag = 1
+ except Exception as e:
+ usys.print_exception(e)
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+ print("dev_NTP end")
def dev_timer_cb(self, *args): #设备资源管理鉴权平台定时器
EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_timer_cb_})
def dev_timer_cb_(self):
#if EventMesh.DEV_RES_MANAGE_AUTHEN_PLATFORM == 1:
- if self.dev_token == None:
- if self.ntptime_flag == 0:
- self.ntptime_flag = 1
- EventMesh.publish_async("dev_NTP",thread_size = 8192)
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_NTP})
- print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
- EventMesh.publish_async("dev_active",thread_size = 8192)
- EventMesh.publish_async("dev_sign_in",thread_size = 8192)
- # self.dev_active() #设备激活
- # self.dev_sign_in() #设备登入
- self.dev_res_timerCount+=1
- if self.dev_res_timerCount > 6: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程
- self.dev_res_timerCount=0
- self.dev_res_timer.stop()
+ try:
+ if self.dev_token == None:
+ if self.ntptime_flag == 0:
+ self.ntptime_flag = 1
+ EventMesh.publish_async("dev_NTP",thread_size = 8192)
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_NTP})
+ print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
+ EventMesh.publish_async("dev_active",thread_size = 8192)
+ EventMesh.publish_async("dev_sign_in",thread_size = 8192)
+ # self.dev_active() #设备激活
+ # self.dev_sign_in() #设备登入
+ self.dev_res_timerCount+=1
+ if self.dev_res_timerCount > 3: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程
+ self.dev_res_timerCount=0
+ self.dev_res_timer.stop()
+ except Exception as e:
+ usys.print_exception(e)
def ud_token_timer_cb(self, *args):
EventMesh.publish("publish_AI_btnInfo",{"func":self.ud_token_timer_cb_})
def ud_token_timer_cb_(self):
- #print("ud_token_timer_!!!!")
- self.ud_token_timer_Count+=1
- if self.ud_token_timer_Count >= 20: #定时30*200s时更新token
- self.ud_token_timer_Count = 0
- EventMesh.publish_async("update_dev_token",thread_size = 8192)
-
+ try:
+ #print("ud_token_timer_!!!!")
+ self.ud_token_timer_Count+=1
+ if self.ud_token_timer_Count >= 720: #定时10*3000s时更新token
+ self.ud_token_timer_Count = 0
+ EventMesh.publish_async("dev_sign_in",thread_size = 8192)
+ except Exception as e:
+ usys.print_exception(e)
def get_sim_Status(self):
return sim.getStatus()
def HMAC(self,k, m):
result = self.unpad(result) # 除去补16字节的多余字符
return str(result, 'utf-8') # 以字符串的形式返回
#激活接口 没有密码走激活
- def dev_active(self, event, msg):
+ def dev_active(self, event=None, msg=None):
signal = net.csqQueryPoll()
if signal == -1 or self.get_sim_Status() != 1:#网络不正常
print("dev_active 无 SIM卡!!!!!!!!\r\n")
return
+ print("dev_active 1\r\n")
# 签名内容: = deviceId+pid+timeStamp
dev_pass = ""
dev_pass = EventMesh.publish("get_storage_config","dev_pass")
if dev_pass == None:
dev_pass = ""
if dev_pass == "" or dev_pass == None:
- date_tmp = utime.localtime() #获取当前时间
- print("date_tmp:{}\r\n".format(date_tmp)) #转换时间戳s
- timeStamp = (utime.mktime(date_tmp))*1000#获取时间戳ms
- deviceId = self.deviceId #"876226002022574" #以imei号
- pid = self.pid
- key = self.key
- sign_data = "{}{}{}".format(deviceId,pid,timeStamp) #签名内容
- print("sign_data:{}\r\n".format(sign_data))
- sha256_hex = self.get_hmac_sha256(key,sign_data)
- print("sha256_hex:{}\r\n".format(sha256_hex))
-
- data = {
- "deviceId":"{}".format(deviceId), #设备名
- "pid":pid, #产品PID
- "sign":"{}".format(sha256_hex), #HMACSHA256签名后的数据
- "timeStamp":timeStamp, #要以ms的形式
- "signMethod":"HMACSHA256" #签名方式 HMACSHA256
- }
- print(ujson.dumps(data))
- headers_T ={"Content-Type":"application/json"}
- url = "http://dmp.raisound.com/bz-api/dev/auth/active"
- data =ujson.dumps(data)
- response = 0
- response_result = 0
try:
- response = request.put(url,data=data,headers = headers_T)
- response_result = 1
- except Exception as e:
- print("put error!!!!!\r\n")
+ date_tmp = utime.localtime() #获取当前时间
+ print("date_tmp:{}\r\n".format(date_tmp)) #转换时间戳s
+ timeStamp = (utime.mktime(date_tmp))*1000#获取时间戳ms
+ deviceId = self.deviceId #"876226002022574" #以imei号
+ pid = self.pid
+ key = self.key
+ sign_data = "{}{}{}".format(deviceId,pid,timeStamp) #签名内容
+ print("sign_data:{}\r\n".format(sign_data))
+ sha256_hex = self.get_hmac_sha256(key,sign_data)
+ print("sha256_hex:{}\r\n".format(sha256_hex))
+
+ data = {
+ "deviceId":"{}".format(deviceId), #设备名
+ "pid":pid, #产品PID
+ "sign":"{}".format(sha256_hex), #HMACSHA256签名后的数据
+ "timeStamp":timeStamp, #要以ms的形式
+ "signMethod":"HMACSHA256" #签名方式 HMACSHA256
+ }
+ print(ujson.dumps(data))
+ headers_T ={"Content-Type":"application/json"}
+ url = "http://dmp.raisound.com/bz-api/dev/auth/active"
+ data =ujson.dumps(data)
+ response = None
response_result = 0
-
- IV = "" #偏移量
- PASSWORD= "" #服务器返回后的加密内容 密码
- if response_result == 1: #访问成功ip
- if response.status_code == 200:
- print("headers:{}".format(response.headers))
- content = response.content
- c = next(content)
- # "api.xcloudtech.com"
- # d_server_port = 9000
- data = ujson.loads(c)
- # data = response.json()
- print("data-{}".format(data))
- if data != None:
- if "success" in data:
- if data['success'] == True:
- if "data" in data:
- data_tmp = data["data"]
- if "nonce" in data_tmp: #偏移量
- IV = data_tmp["nonce"]
- if "password" in data_tmp:
- PASSWORD = data_tmp["password"]
- # EventMesh.publish("set_storage_config",["dev_pass",PASS])
- if data["code"] == 20001:#鉴权成功
- pass
- elif data["code"] > 50000:#时间错误
- self.res_error_count+=1
- if self.res_error_count>=3:
- self.res_error_count = 0
- EventMesh.publish("paly_device_res_error")
- if data["code"] == 50003:#时间错误
- self.ntptime_flag = 0
- if PASSWORD != None and IV != None:
- if len(PASSWORD) != 0 and len(IV) != 0:
- password = PASSWORD
- iv = IV
- #解密 之后保存本地下一次登入做使用
- decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密
- print("decrypt_data {}".format(decrypt_data))
- EventMesh.publish("set_storage_config",["dev_pass",decrypt_data])
-
-
- print("IV:{}\r\n PASS:{}".format(IV,PASSWORD))
+ try:
+ response = request.put(url,data=data,headers = headers_T,timeout=5)
+ response_result = 1
+ except Exception as e:
+ usys.print_exception(e)
+ print("put error!!!!!\r\n")
+ response_result = 0
+
+ IV = "" #偏移量
+ PASSWORD= "" #服务器返回后的加密内容 密码
+ if response_result == 1: #访问成功ip
+ if response.status_code == 200:
+ print("headers:{}".format(response.headers))
+ content = response.content
+ c = next(content)
+ # "api.xcloudtech.com"
+ # d_server_port = 9000
+ data = ujson.loads(c)
+ # data = response.json()
+ print("data-{}".format(data))
+ if data != None:
+ if "success" in data:
+ if data['success'] == True:
+ if "data" in data:
+ data_tmp = data["data"]
+ if "nonce" in data_tmp: #偏移量
+ IV = data_tmp["nonce"]
+ if "password" in data_tmp:
+ PASSWORD = data_tmp["password"]
+ # EventMesh.publish("set_storage_config",["dev_pass",PASS])
+ if data["code"] == 20001:#鉴权成功
+ pass
+ elif data["code"] > 50000:#时间错误
+ self.res_error_count+=1
+ if self.res_error_count>=3:
+ self.res_error_count = 0
+ #EventMesh.publish("paly_device_res_error")
+ if data["code"] == 50003:#时间错误
+ self.ntptime_flag = 0
+ if PASSWORD != None and IV != None:
+ if len(PASSWORD) != 0 and len(IV) != 0:
+ password = PASSWORD
+ iv = IV
+ #解密 之后保存本地下一次登入做使用
+ decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密
+ print("decrypt_data {}".format(decrypt_data))
+ EventMesh.publish("set_storage_config",["dev_pass",decrypt_data])
+ print("IV:{}\r\n PASS:{}".format(IV,PASSWORD))
+ if response != None:
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ print("dev_active end\r\n")
return [response_result,PASSWORD,IV]
#随机生成16个字节的字符串作为加密的IV 偏移量
def generate_random_string(self,length=16):
return random_str
#设备登入 没有Token 走登入获取token
- def dev_sign_in(self, event, msg):
+ def dev_sign_in(self, event=None, msg=None):
signal = net.csqQueryPoll()
if signal == -1 or self.get_sim_Status() != 1:#网络不正常
print("dev_sign_in 无 SIM卡!!!!!!!!\r\n")
return
+ print("dev_sign_in 1")
token = ""
- token = self.dev_token
- dev_pass = EventMesh.publish("get_storage_config","dev_pass")
- #print("token:{}\r\n".format(token))
- if token == None:
- token = ""
- if dev_pass == None:
- dev_pass = ""
- if len(dev_pass) == 0:#没有密码
- return
- if token == None or token == "":
+ try:
+ token = self.dev_token
+ dev_pass = EventMesh.publish("get_storage_config","dev_pass")
+ #print("token:{}\r\n".format(token))
+ if token == None:
+ token = ""
+ if dev_pass == None:
+ dev_pass = ""
+ if len(dev_pass) == 0:#没有密码
+ return
+ #if token == None or token == "":
if 1: #返回结果成功
#获取本地保存的密码
decrypt_data=EventMesh.publish("get_storage_config","dev_pass")
response_result = 0
response = 0
try:
- response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T)
+ response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T,timeout=5)
response_result = 1
except Exception as e:
+ usys.print_exception(e)
print("post error!!!!!\r\n")
response_result = 0
# {'msg': '', 'code': 20001, 'success': True,
# 'data': {'deviceId': '876226002022574',
# 'token': '95436a9e09fd0ff89feb8825257dca982f'}
# }
- token = ""
+
+ #self.dev_token = ""
if response_result == 1:
if response.status_code == 200:
content = response.content
self.dev_token = data_tmp["token"]
if data["code"] == 50003:#时间错误
self.ntptime_flag = 0
- print("token:{}\r\n".format(token))
+ print("token:{}\r\n".format(self.dev_token))
+ if response != None:
+ response.close()
pass
+ except Exception as e:
+ print("post error!!!!!\r\n")
+ response_result = 0
+ print("dev_sign_in end")
#获取新的令牌 更新token
- def update_dev_token(self, event, msg):
+ def update_dev_token(self, event=None, msg=None):
print("update_dev_token")
- dev_pass = ""
- dev_pass = EventMesh.publish("get_storage_config","dev_pass")
-
- if dev_pass == None:
+ try:
dev_pass = ""
- if len(dev_pass) == 0: #没有密码走激活
- print("no dev_pass:{}\r\n".format(dev_pass))
- EventMesh.publish("dev_active")
- token = self.dev_token
- if token == None:
- token = ""
- if len(token) == 0: #没有token走登入
- print("no dev_token:{}\r\n".format(token))
- #self.dev_sign_in()
- EventMesh.publish("dev_sign_in")
- dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
- token = self.dev_token
- if token == None:
- token = ""
- if len(token) != 0:
- response_result=0
- response = 0
- headers_T = {"bz-dt":"{}".format(token)}
- try:
- response = request.get(dev_tokenip,headers = headers_T)
- response_result = 1
- except Exception as e:
- print("get error!!!!!\r\n")
- response_result = 0
- if response_result == 1:
- if response.status_code == 200:
+ dev_pass = EventMesh.publish("get_storage_config","dev_pass")
+
+ if dev_pass == None:
+ dev_pass = ""
+ if len(dev_pass) == 0: #没有密码走激活
+ print("no dev_pass:{}\r\n".format(dev_pass))
+ EventMesh.publish("dev_active")
+ token = self.dev_token
+ if token == None:
+ token = ""
+ if len(token) == 0: #没有token走登入
+ print("no dev_token:{}\r\n".format(token))
+ #self.dev_sign_in()
+ EventMesh.publish("dev_sign_in")
+ dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
+ token = self.dev_token
+ if token == None:
+ token = ""
+ if len(token) != 0:
+ response_result=0
+ response = None
+ headers_T = {"bz-dt":"{}".format(token)}
+ try:
+ response = request.get(dev_tokenip,headers = headers_T,timeout=5)
+ response_result = 1
+ except Exception as e:
+ print("get error!!!!!\r\n")
+ response_result = 0
+ if response_result == 1:
+ if response.status_code == 200:
+ try:
+ headers_data = response.headers
+ # print("headers_data!!!!! headers_data:{}\r\n".format(headers_data))
+ if "bz-dt" in headers_data: #bz-dt字段是否在头部数据里面 如果有就需要更新
+ bz_dt = headers_data["bz-dt"]
+ self.dev_token = bz_dt.replace(" ", "") #去掉所有的空格符
+ print("update_dev_token:{}".format(self.dev_token))
+ except Exception as e:
+ print("headers_data!!!!! error\r\n")
+ if response != None:
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ print("update_dev_token end")
+
+#OTA升级
+class OTA():
+ def __init__(self):
+ #EventMesh.subscribe("min_sys_ota",self.min_sys_ota)
+ self.downloadFileVoURL1= ""
+ self.downloadFileVoURL2= ""
+ #小系统升级,返回0,没有升级;返回,1有升级,正在执行升级;返回2,电压不够
+ def min_sys_ota(self,event=None,msg=None):
+ print("min_sys_ota")
+ signal = net.csqQueryPoll()
+ if signal == -1 or sim.getStatus() != 1:#网络不正常
+ print("min_sys_ota 无 SIM卡!!!!!!!!\r\n")
+ return 0
+ # return 0
+ response = None
+ ret_str =0
+ self.downloadFileVoURL1= ""
+ self.downloadFileVoURL2= ""
+ try:
+ sourceVersion = versions.Build_Time
+ sourceVersion = "7PIN-"+sourceVersion[:10]+"-"+sourceVersion[11:-3]
+ print("sourceVersion:{}".format(sourceVersion))
+ sourceVersion = sourceVersion.replace(" ", "0")
+ print("sourceVersion2:{}".format(sourceVersion))
+ #url = "http://iot.api.thisiot.com/ota/task?deviceId=860132060348836&sourceVersion=2024-12-20-15:35-1"
+ url = "http://dmp.raisound.com/bz-api/ota/task?deviceId={}&sourceVersion={}".format(modem.getDevImei(),sourceVersion)
+ print(url)
+ response = request.get(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("min_sys_ota1:{}".format(data))
+
+ if data:
try:
- headers_data = response.headers
- # print("headers_data!!!!! headers_data:{}\r\n".format(headers_data))
- if "bz-dt" in headers_data: #bz-dt字段是否在头部数据里面 如果有就需要更新
- bz_dt = headers_data["bz-dt"]
- self.dev_token = bz_dt.replace(" ", "") #去掉所有的空格符
- print("update_dev_token:{}".format(self.dev_token))
+ if data["code"] == 20007:#有新版本
+ if "fileList"in data["data"]:
+ if len(data["data"]["fileList"]) == 2:
+ for fileList in data["data"]["fileList"]:
+ if fileList["fileName"] == "dfota_2.bin":
+ self.downloadFileVoURL2 = fileList["url"]
+ elif fileList["fileName"] == "dfota_1.bin":
+ self.downloadFileVoURL1 = fileList["url"]
+
+ if data["code"] == 20006:#已是最新版本
+ ret_str = 0
+
except Exception as e:
- print("headers_data!!!!! error\r\n")
+ usys.print_exception(e)
+ else:
+ print("min_sys_ota get error")
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
- pass
-
-
-
-
-#阿里voice_chat状态枚举
+ print("min_sys_ota:downloadFileVoURL1:{},\ndownloadFileVoURL2:{}".format(self.downloadFileVoURL1,self.downloadFileVoURL2))
+ print("min_sys_ota end")
+ if self.downloadFileVoURL2!="" and self.downloadFileVoURL1!="":
+ battery = EventMesh.publish("get_battery")
+ if battery>=40:
+ self.ota_timer = osTimer()
+ self.ota_timer.start(15000, 0, self.ota_timer_cb)
+ ret_str = 1
+ else:
+ ret_str = 2
+ return ret_str
+
+ def ota_timer_cb(self, *args, **kwargs):
+ import fota
+ fota_obj = fota()
+ fota_obj.httpDownload(url1=self.downloadFileVoURL1,url2=self.downloadFileVoURL2)
+ #ota升级结果返回,开机时调用一次即可
+ def ota_result(self,event=None,msg=None):
+ response = None
+ try:
+ currentVersion = versions.Build_Time
+ currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3]
+ print("currentVersion1:{}".format(currentVersion))
+ currentVersion = currentVersion.replace(" ", "0")
+ print("currentVersion2:{}".format(currentVersion))
+ url = "http://dmp.raisound.com/bz-api/ota/result?deviceId={}¤tVersion={}".format(modem.getDevImei(),currentVersion)
+ print(url)
+ response = request.post(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("ota_result:{}".format(data))
+ else:
+ print("ota_result error!!!!")
+ for i in response.text:
+ print(i)
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+ #ICCID上传
+ def pots_ICCID(self,event=None,msg=None):
+ response = None
+ try:
+ iccid = sim.getIccid()
+ if iccid != -1 and len(iccid) > 5:
+ print("pots_ICCID:{}".format(iccid))
+ #Headers = {'Transfer-Encodong':'chunked'}
+ #http://dmp.raisound.com/bz-api/dev/iccid?deviceId=866610001099679&iccid=89860002192307889057
+ url = "http://dmp.raisound.com/bz-api/dev/iccid?deviceId={}&iccid={}".format(modem.getDevImei(),iccid)
+ print(url)
+ response = request.post(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("pots_ICCID:{}".format(data))
+ else:
+ print("pots_ICCID error!!!!")
+ for i in response.text:
+ print(i)
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+#阿里VC状态枚举
VC_State_None=0
VC_State_Listening=1#听
VC_State_SpeechStart=2#说开始
-VC_State_SpeechEnd=3#说结束
-VC_State_Thinking=4#想(chat)
-VC_State_Responding=5#音频播放
-VC_State_TTSStart=6
-VC_State_TTSData=7
-VC_State_TTSFinish=8
-VC_State_TTSEnd=9
-VC_State_TTSError=10
-VC_State_DialogError=11
-VC_State_End=12
+VC_State_SpeechIng=3#正在说
+VC_State_SpeechEnd=4#说结束
+VC_State_RequestToRespond=5 #TTS请求或者chat请求
+VC_State_Thinking=6#想(chat)
+VC_State_Responding=7#音频播放
+VC_State_TTSStart=8
+VC_State_TTSData=9
+VC_State_TTSFinish=10
+VC_State_TTSEnd=11
+VC_State_TTSError=12
+VC_State_DialogError=13
+VC_State_End=14
VC_record_TYPE_PCM = 0
VC_record_TYPE_AMR = 1
# AI_client_asr_num = 0
# AI_client_chat_num = 1
# AI_client_tts_num = 2
-AI_client_voice_chat_num = 3
+AI_client_VC_num = 3
AI_client_asr_num = 4
+
+
class AI_VC(Abstract):
# AI
def __init__(self):
+ try:
+ self.http_get_config()#获取/更新配置参数
+ except Exception as e:
+ usys.print_exception(e)
+ self.VC_30S_timer = osTimer()
+ self.VC_30S_timer.start(30000, 1, self.VC_30S_timer_cb)
+ self.get_config_timer_count = 0
self.record_data_save_flag = 0 #是否保存录音文件
self.play_data_save_flag = 0 #是否保存tts数据到文件
self.record_fd = None
self.play_fd = None
self.is_VC_ACK = 0 #是否开启ack应答模式
-
+ self.is_long_record = 0 #是否开启长录音模式(语音打断模式)
+ self.ai_OTA = OTA()
+ self.is_auth = 0 #是否开启dmp鉴权
#self.VC_mode = 0 #0:短按连续问答模式 1:长按录音模式
- self.VC_mode = EventMesh.publish("get_storage_config","VC_mode")#音色配置
+ self.VC_mode = EventMesh.publish("get_storage_config","VC_mode")#
if self.VC_mode == None :
self.VC_mode = 0
+ self.is_up_error= 0 #是否上传错误id
+ self.error_data = []
+ self.asr_taskid = ""
+ self.VC_taskid = ""
+ self.VC_server = 2 #0柒牌正式服务器,1:测试服务器1,2:测试服务器2
+
+ self.server_ip = EventMesh.publish("get_storage_config","server_ip")#
+ if self.server_ip == None:
+ if self.VC_server == 1:#
+ self.server_ip="118.145.158.207:22083"
+ elif self.VC_server == 2:#
+ self.server_ip="118.145.158.207:22082"
+ elif self.VC_server == 4:#
+ self.server_ip="118.145.158.207:22084"
+ elif self.VC_server == 5:#
+ self.server_ip="amp-wss.raisound.com"
+ elif self.VC_server == 6:#
+ self.server_ip="118.145.158.207:22080"
+ else:
+ self.server_ip="sevenpin.qipai.com.cn"
+
+ if dev_type == 'momo':#
+ self.server_ip="118.145.158.207:22080"
+ elif dev_type == "7PIN":
+ self.server_ip="sevenpin.qipai.com.cn"
+ elif dev_type == "sjgq":
+ self.server_ip="118.145.158.207:22084"
+ #开机提示音
+ self.power_on_tone = EventMesh.publish("get_storage_config","power_on_tone")#
+ if dev_type != "7PIN":
+ self.power_on_tone = None
+ if self.power_on_tone == None:
+ if dev_type == "G10":
+ self.power_on_tone = "已开机,您好!我是北科瑞讯智能 AI bot_name"
+ elif dev_type == "7PIN_BK":
+ self.power_on_tone = "小瑞来了!我们一起来愉快地聊天吧!"
+ elif dev_type == "momo":
+ self.power_on_tone = "DuloDulo,我是上古神兽食梦貘,主人可以叫我momo,我来自《山海经》,是一只以梦为食的神秘灵兽,每当颜色朦胧、人们入睡时,我就会悄悄飞到人们的床头,用我长长的鼻子把噩梦统统吞噬掉,只留下甜甜的美梦。从今往后,就由我守护在主人身边,一起度过每一个星河璀璨的夜晚。"
+ elif dev_type == "sjgq":
+ self.power_on_tone = "您好!我是巴马四季甘泉的智能助手。我可以为你解答各种各样的问题,像是有关巴马四季甘泉知识库、中基长寿科学产品、卫斯曼院士国际先进医疗中心的问题,还有日常生活与工作、旅游信息、健康咨询、教育与学习、情感交流、全球资讯、世界文化等方面的问题哦。你有没有这方面的问题想要问我呀?"
+ else:
+ self.power_on_tone = "您好!我是世界首创柒牌男装AI生活好帮手-bot_name, 很高兴为您服务,我可以帮您解答柒牌公司知识库、日常生活与工作、旅游信息、健康与运动咨询、教育与学习、情感交流、全球资讯、世界文化等问题!请问您有什么需要我帮忙的吗?"
+
- self.VC_server = 2 #0正式服务器,1:测试服务器1,2:测试服务器2
self.VC_record_TYPE = VC_record_TYPE_PCM #0:PCM 1:AMR
self.VC_play_TYPE = VC_play_TYPE_PCM #0:PCM 1:mp3
self.VC_record_samplerate = 16000
self.VC_play_samplerate = 16000
+
self.VC_TTS_voice_type = EventMesh.publish("get_storage_config","VC_TTS_voice_type")#音色配置
- if self.VC_TTS_voice_type == None:
- #女,男,童,粤,川
- self.VC_TTS_voice_type = {"0":"huoshan::zh_female_wanwanxiaohe_moon_bigtts","1":"huoshan::zh_male_wennuanahu_moon_bigtts","2":"huoshan::ICL_zh_female_huoponvhai_tob",
- "3":"aliyun::longjiaxin","4":"huoshan::zh_female_daimengchuanmei_moon_bigtts"}
+ if self.VC_TTS_voice_type == None or ("男" in self.VC_TTS_voice_type) == False:
+ if dev_type == "G10" or dev_type == "7PIN_BK":
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"小瑞",
+ "voice":"zh_female_wanwanxiaohe_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"小瑞",
+ "voice":"zh_male_wennuanahu_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"小瑞",
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ "粤":{
+ "bot_name":"小瑞",
+ "voice":"zh_female_wanqudashu_moon_bigtts" ,
+ "lang":"zh-hk"
+ },
+ "四川":{
+ "bot_name":"小瑞",
+ "voice":"zh_female_daimengchuanmei_moon_bigtts",
+ "lang":"&lang=zh-cn-sc"
+ },
+ "个性":{
+ "bot_name":"小瑞",
+ "voice":"zh_male_sunwukong_mars_bigtts" ,
+ "lang":"zh-cn"
+ }
+
+ }
+ elif dev_type == 'momo':
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"食梦貘",
+ "voice":"zh_female_shaoergushi_mars_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"食梦貘",
+ "voice":"zh_male_yangguangqingnian_mars_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"食梦貘",
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ }
+ elif dev_type == 'sjgq':
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"小巴",
+ "voice":"zh_female_wanwanxiaohe_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"小巴",
+ "voice":"zh_male_wennuanahu_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"小巴",
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ }
+ else:
+ #女,男,童,粤,川,个性声
+ self.VC_TTS_voice_type = {
+ "女":{
+ "bot_name":"柒妹妹",
+ "voice":"huoshan::zh_female_wanwanxiaohe_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "男":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::zh_male_wennuanahu_moon_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "童":{
+ "bot_name":"柒乐乐",
+ "voice":"huoshan::ICL_zh_female_huoponvhai_tob" ,
+ "lang":"zh-cn"
+ },
+ "粤":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::zh_female_wanqudashu_moon_bigtts" ,
+ "lang":"zh-hk"
+ },
+ "四川":{
+ "bot_name":"柒妹妹",
+ "voice":"huoshan::zh_female_daimengchuanmei_moon_bigtts",
+ "lang":"&lang=zh-cn-sc"
+ },
+ "个性":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::zh_male_sunwukong_mars_bigtts" ,
+ "lang":"zh-cn"
+ },
+ "英语":{
+ "bot_name":"柒先生",
+ "voice":"huoshan::en_male_smith_mars_bigtts" ,
+ "lang":"zh-cn"
+ }
+
+
+ }
+
# self.VC_TTS_voice_type = {0:"zh_female_xinlingjitang_moon_bigtts",1:"zh_male_wennuanahu_moon_bigtts",2:"ICL_zh_female_huoponvhai_tob",
# 3:"aliyun::longjiaxin",4:"zh_female_daimengchuanmei_moon_bigtts"}
#self.VC_TTS_voice_type = ["aliyun::longxiaoxia","aliyun::longnan","aliyun::longling"]
- EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type])
+
+ #EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type])
+
+ try:
+ self.VC_TTS_voice_key = EventMesh.publish("get_storage_config","VC_TTS_voice_key")#音色配置
+ if self.VC_TTS_voice_key == None :
+ if dev_type == "7PIN_BK":
+ self.VC_TTS_voice_key = "童"
+ elif dev_type == "momo":
+ self.VC_TTS_voice_key = "男"
+ else:
+ self.VC_TTS_voice_key = "男"
+ if self.VC_TTS_voice_key in self.VC_TTS_voice_type:
+ pass
+ else:
+ self.VC_TTS_voice_key = list(self.VC_TTS_voice_type.keys())[0]
+ print("音色配置:{}:{}\r\n\r\n".format(self.VC_TTS_voice_key,self.VC_TTS_voice_type[self.VC_TTS_voice_key]))
+ self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
+ except Exception as e:
+ usys.print_exception(e)
- self.VC_TTS_voice_num = EventMesh.publish("get_storage_config","VC_TTS_voice_num")#音色配置
- if self.VC_TTS_voice_num == None or self.VC_TTS_voice_num>=len(self.VC_TTS_voice_type):
- self.VC_TTS_voice_num = 1
-
- self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
if self.VC_TTS_volume == None:
self.VC_TTS_volume = 100
self.AI_audio_queue_thread_id = 0
- self.AI_send_data_queue_thread_id = 0
-
+ self.AI_audio_queue_thread_lock = 0
+ self.AI_VC_send_data_queue_thread_id = 0
+ self.AI_VC_send_data_queue_thread_lock = 0
+ self.AI_ASR_send_data_queue_thread_id = 0
+ self.AI_ASR_send_data_queue_thread_lock = 0
self.AI_record_tmp_queue = Queue(100)
- self.AI_send_data_queue = Queue(100)
+ self.AI_ASR_send_data_queue = Queue(200)
+ self.AI_VC_send_data_queue = Queue(100)
self.AI_audio_queue = Queue(100)
+ #self.AI_WS_connect_Queue = Queue(100) #释放用
self.AI_TTS_str = ""
self.AI_ASR_str = ""
self.AI_ASR_flag = 0
self.AI_ASR_str_tmp = ""
-
+ self.AI_ASR_send_buf_len = 0
+ self.AI_ASR_text_tmp = ""
+ self.AI_ASR_text_repet_count = 0
# #开始线程
# if self.AI_audio_queue_thread_id ==0:
# self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ())
# else:
# print("AI_VC_start :AI_audio_queue_thread_id != 0 ")
- # if self.AI_send_data_queue_thread_id == 0:
- # self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ())
+ # if self.AI_VC_send_data_queue_thread_id == 0:
+ # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ())
- self.voice_chat_state = VC_State_None #阿里ai voice_chat状态
- self.VC_dialog_id = ""
+ self.VC_state = VC_State_None #阿里ai VC状态
+ self.VC_dialog_id = ""#
self.VC_message_id=None
self.VC_task_id =None
- self.AI_client_voice_chat = None
- self.AI_client_voice_chat_recv_id = 0
- self.AI_client_voice_chat_isconnect =0
- self.AI_client_voice_chat_debug =0
-
- self.asr_state = VC_State_None #阿里VC_ASR voice_chat状态
- self.VC_asr_dialog_id = ""
- self.VC_asr_message_id=None
- self.VC_asr_task_id =None
+ self.AI_client_VC = None
+ self.AI_client_VC_recv_id = 0
+ self.AI_client_VC_recv_lock = 0
+ self.AI_client_VC_isconnect =0
+ self.AI_client_VC_debug =0
+
+ self.asr_state = VC_State_None #阿里VC_ASR VC状态
+ self.key_state = 0
+
self.AI_client_asr = None
self.AI_client_asr_recv_id = 0
+ self.AI_client_asr_recv_lock = 0
self.AI_client_asr_isconnect =0
self.AI_ASR_timer = osTimer()
self.AI_ASR_timer_count = 0
self.AI_client_asr_debug =0
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
self.VC_Thinking_timerout = 0
- self.asr_satrt_flag = 0
+ self.VC_Speech_end_timerout = 0
self.record_pcm = None
self.play_pcm = None
self.VC_record_thread_id = 0
+ self.VC_record_thread_lock = 0
self.VC_pingping_timerout = 0
self.asr_pingping_timerout = 0
self.factory_timer = osTimer()
self.record = audio.Record()
#self.record.end_callback(self.record_callback)
self.record.gain_set(4,10)
+ #self.record.gain_set(4,12)
self.aud = audio.Audio(0)
self.aud.setCallback(self.audio_cb)
#self.aud.setVolume(self.VC_TTS_volume //10)
self.tts_in_data_len = 0
self.tts_out_data_len = 0
self.VC_satrt_flag = 0
+ self.session_id = ""
EventMesh.subscribe("AI_key_press", self.AI_key_press)
EventMesh.subscribe("AI_key_release", self.AI_key_release)
EventMesh.subscribe("AI_key_long_press", self.AI_key_long_press)
EventMesh.subscribe("get_AI_audio_queue", self.get_AI_audio_queue)
EventMesh.subscribe("get_VC_satrt_flag", self.get_VC_satrt_flag)
EventMesh.subscribe("VC_error", self.VC_error)
-
+
EventMesh.publish("close_led")
- #开机提示语,如果联网失败,直接提示信号弱
- #女,男,童,粤,川
+
self.bot_name = "柒先生"
- if self.VC_TTS_voice_num == 0 or self.VC_TTS_voice_num == 3 or self.VC_TTS_voice_num == 4:
- self.bot_name = "柒妹妹"
- elif self.VC_TTS_voice_num == 1:
- self.bot_name = "柒先生"
- elif self.VC_TTS_voice_num == 2:
- self.bot_name = "柒乐乐"
- #EventMesh.publish("get_storage_config",["powerRestart",1])
- powerRestart = EventMesh.publish("get_storage_config","powerRestart")#音量配置
- if powerRestart == None:
- powerRestart = 0
- if powerRestart == 1:
- EventMesh.publish("get_storage_config",["powerRestart",0])
-
- else:
- self.AI_TTS_str = "已开机,您好!我是柒牌 AI 智能男装生活好帮手-{}, 很高兴为您服务,我可以帮您解答日常生活、工作,旅游信息、健康咨询、教育与学习、情感交流、全球资讯等问题!请问您有什么需要我帮忙的吗?".format(self.bot_name )
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ try:
+ if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]:
+ self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"]
+ else:
+ print("not bot_name!!!!!!!!!!!!!!!!!!!!!!")
+ except Exception as e:
+ usys.print_exception(e)
+ try:
+ if self.ai_OTA.min_sys_ota()==1:
+ #if 0:
+ self.AI_TTS_str = "检测到有新版本需要升级啦!升级时可千万别断电或乱按哦,升级完成后设备会自动重启,重启就代表升级成功"
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ # if self.ai_OTA.min_sys_ota()==2:
+ # self.AI_TTS_str = "检测到有新版本需要升级啦!电量低于40%,无法保证升级正常执行,请充满电后重启设备再次升级!"
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ else:
+ try:
+ self.ai_OTA.ota_result()
+ self.ai_OTA.pots_ICCID()
+ except Exception as e:
+ usys.print_exception(e)
+ #开机提示语,如果联网失败,直接提示信号弱
+
+ #"voice":{"女":"柒妹妹-huoshan::zh_female_wanwanxiaohe_moon_bigtts","男":"柒先生-huoshan::zh_male_wennuanahu_moon_bigtts","童":"柒乐乐huoshan::ICL_zh_female_huoponvhai_tob","广东":"柒先生-huoshan::zh_female_wanqudashu_moon_bigtts","四川":"柒妹妹-huoshan::zh_female_daimengchuanmei_moon_bigtts","个性":"柒先生-zh_male_sunwukong_mars_bigtts"}
+ #EventMesh.publish("get_storage_config",["powerRestart",1])
+ powerRestart = EventMesh.publish("get_storage_config","powerRestart")#=1非正常重启
+ if powerRestart == None:
+ powerRestart = 0
+ if powerRestart == 1:
+ EventMesh.publish("set_storage_config",["powerRestart",0])
+
+ else:
+
+ self.AI_TTS_str = self.power_on_tone.replace("bot_name", self.bot_name)
+ print("开机提示:{}".format(self.AI_TTS_str))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
+
+
+ except Exception as e:
+ usys.print_exception(e)
+
def post_processor_after_instantiation(self):
pass
def get_AI_audio_queue(self, event, msg):
return self.AI_audio_queue
def get_VC_satrt_flag(self, event, msg):
return self.VC_satrt_flag
-
+
+
+ def VC_30S_timer_cb(self, *args): #
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_30S_timer_cb_})
+
+ def VC_30S_timer_cb_(self):
+ self.get_config_timer_count += 1
+ if self.get_config_timer_count >= 2*60*2:#2小时更新配置参数
+ self.get_config_timer_count = 0
+ try:
+ self.http_get_config()#获取/更新配置参数
+ except Exception as e:
+ usys.print_exception(e)
+ #提交错误id
+ def ud_error(self,error_data):
+ response = None
+ if self.is_up_error == 1:
+ try:
+ # currentVersion = versions.Build_Time
+ # currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3]
+ url = "http://{}/health?task_id={}".format(self.server_ip,error_data[0]+error_data[1])
+ print(url)
+ response = request.get(url,timeout=5)
+ if response.status_code == 200:
+
+ print("ud_error:ok")
+ else:
+ print("ud_error error!!!!")
+ for i in response.text:
+ print(i)
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+ #获取配置参数
+ def http_get_config(self, event=None, msg=None):
+ print("http_get_config")
+
+ response = None
+ #http://180.184.206.142/bz-api/dev/config?deviceId=xxx
+ try:
+ url = "http://dmp.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei())
+ print(url)
+ response = request.get(url,timeout=5)
+ if response.status_code == 200:
+ data = response.json()
+ print("http_get_config:{}".format(data))
+
+ if data:
+ try:
+ if data["code"] == 20000:#有配置
+ if data["data"] :
+ if "version" in data["data"]:
+ config_version = EventMesh.publish("get_storage_config","config_version")#音量配置
+ if config_version != data["data"]["version"]:
+ config_version = data["data"]["version"]
+ EventMesh.publish("set_storage_config",["config_version",config_version])
+ if "VC_TTS_voice_type" in data["data"]:
+ self.VC_TTS_voice_type = data["data"]["VC_TTS_voice_type"]
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type])
+ print("配置VC_TTS_voice_type成功")
+ if "server_ip" in data["data"]:
+ self.server_ip = data["data"]["server_ip"]
+ EventMesh.publish("set_storage_config",["server_ip",self.server_ip])
+ print("配置server_ip成功")
+ if "power_on_tone" in data["data"]:
+ self.power_on_tone = data["data"]["power_on_tone"]
+ EventMesh.publish("set_storage_config",["power_on_tone",self.power_on_tone])
+ print("配置power_on_tone成功")
+
+ except Exception as e:
+ usys.print_exception(e)
+ else:
+ print("status_code:{}".format(response.status_code))
+ print("http_get_config:error!!!!!!!!!!")
+ response.close()
+ except Exception as e:
+ usys.print_exception(e)
+ if response != None:
+ response.close()
+
def audio_cb(self,event):
if event == 0:
self.audio_play_state =1
def AI_key_press(self, event, msg):#按键按下
print("AI_key_press")
+ self.get_config_timer_count = 0
+ self.key_state = 1
#self.aud.aud_tone_play(10,200)#播放按键音
- self.asr_satrt_flag = 1#
self.AI_TTS_str = ""#"你好,有什么吩咐"
self.AI_ASR_str = ""
self.AI_ASR_str_tmp = ""
- # if self.voice_chat_state != VC_State_None:
+ self.VC_state = VC_State_None
+ # if self.VC_state != VC_State_None:
# EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
# EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(10)})
- if self.VC_record_state_flag >1:#如果在录音,就先停止录音
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
-
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ #if self.VC_record_state_flag >1:#如果在录音,就先停止录音
+ self.VC_Speech_End()
+
+ self.VC_Speech_Start()
+ self.AI_VC_start()
# self.Close()
# self.AI_VC_start()
self.AI_key_long_press_flag = 0
def AI_key_release(self, event, msg):#按键弹起
print("AI_key_release123")
+ self.key_state = 0
if self.AI_key_long_press_flag == 1 :#有长按
- self.AI_client_voice_chat_end_speech()
+ #self.AI_client_VC_end_speech()
+ EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_asr_StopTranscription_requset})
+ #self.AI_client_asr_StopTranscription_requset()#请求停止
+ if self.VC_mode == 1 :#长按单次问答模式
+ if self.AI_ASR_str_tmp != "":
+ print("AI_key_release:asr_str:{}".format(self.AI_ASR_str))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
else :
if self.VC_mode == 1 :#长按单次问答模式
- try:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
- except Exception as e:
- usys.print_exception(e)
- EventMesh.publish("audio_montage_play",["key_prompt.mp3"])
- #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可
+ # try:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ # except Exception as e:
+ # usys.print_exception(e)
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.key_prompt}) #提示请您按住中间的按钮开始讲话,讲完松开即可
+ self.AI_TTS_str = "请您按住中间的按钮开始讲话,讲完松开即可 "
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
#self.VC_Speech_End()
print("pwk_key_release")
EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ def key_prompt(self):
+ EventMesh.publish("audio_montage_play",["key_prompt.mp3"])
+ #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可
def VC_error(self, event, msg):#错误播报
self.websocket_error()
#EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
#****************************************ASR连接**********************************************************************
def websocket_connect_asr(self):
print("websocket_connect_asr:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_asr_isconnect,self.AI_client_asr_debug))
+ self.AI_ASR_text_repet_count = 0
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
+ self.AI_ASR_text_tmp = ""
if self.AI_client_asr_isconnect == 1:
return
- # 创建VC客户端
+ # 创建ASR客户端
try:
signal = net.csqQueryPoll()
if signal == -1 or sim.getStatus() != 1:#网络正常
self.websocket_error()
return
- # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
+
# self.AI_client_asr = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
- if self.VC_server == 1:#
- self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws', debug=True)#测试环境
- elif self.VC_server == 2:#
- if self.VC_TTS_voice_num <= 2:
- self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshao&lang=zh-cn', debug=True)#普通话测试环境
- elif self.VC_TTS_voice_num == 3:
- self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshan&lang=zh-hk', debug=True)#粤语测试环境
- elif self.VC_TTS_voice_num == 4:
- self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshan&lang=zh-cn-sc', debug=True)#四川话测试环境
- else :
- self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshan&lang=zh-cn', debug=True)#普通话测试环境
- else:
- token = EventMesh.publish("get_dev_token")
- print("token:{}".format(token))
- if token != None:
- self.AI_client_asr = uwebsocket.Client.connect('ws://amp.raisound.com/asr/ws?dt={}'.format(token), debug=True)
+ req_str = ""
+ platform = "platform=huoshan"
+ #platform= "platform=xfyun-ita"
+ platform= "platform=xfyun-bigmodel-ita"
+ lang = "lang=zh-cn"#普通话测试环境
+ try:
+ if "loang" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]:
+ lang = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["lang"]
else:
- pass
- return
+ print("not lang!!!!!!!!!!!!!!!!!!!!!!")
+ except Exception as e:
+ usys.print_exception(e)
+ req_str = "asr/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
+ print("req_str:{}".format(req_str))
+ token = EventMesh.publish("get_dev_token")
+ print("token:{}".format(token))
+ url = 'ws://{}/{}&dt={}'.format(self.server_ip,req_str,token)
+ print("websocket_connect_asr URL:{}".format(url))
+ self.AI_client_asr = uwebsocket.Client.connect(url, debug=True)#
+ #self.AI_WS_connect_Queue.put(self.AI_client_asr)
+
except Exception as e: #网络连接异常
usys.print_exception(e)
- print("websocket_connect_voice_chat error!!!\r\n")
+ print("websocket_connect_asr error!!!\r\n")
#self.connect_timerout_popup(2)
str_error = str(e)
if str_error.find("[Errno 22] EINVAL")!= -1:
self.websocket_error()
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ EventMesh.publish("set_storage_config",["powerRestart",1])#调试临时关闭
utime.sleep_ms(1000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
Power.powerRestart()
- EventMesh.publish("set_storage_config",["powerRestart",1])
+
self.websocket_error()
return
return
self.AI_client_asr_debug+=1
utime.sleep_ms(10)
- self.AI_client_asr.settimeout(6)
- # 线程接收数据
- if self.AI_client_asr_recv_id != 0:
- try:
- _thread.stop_thread(self.AI_client_asr_recv_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_client_asr_recv_id = 0
+ #self.AI_client_asr.settimeout(5)
+ #开启发送线程
+ if self.AI_ASR_send_data_queue_thread_id == 0:
+ _thread.stack_size(self.Audio_buf_size+8*1024)
+ self.AI_ASR_send_data_queue_thread_id = _thread.start_new_thread(self.AI_ASR_send_data_queue_thread, ())
+ _thread.stack_size(8*1024)
+ print("AI_VC_start :AI_ASR_send_data_queue_thread_id :{} ".format(self.AI_ASR_send_data_queue_thread_id))
+ print("websocket_connect_asr 222!!!\r\n")
+ self.AI_client_asr_recv_thread_close()#关闭读线程
+ # 创建线程接收数据
_thread.stack_size(self.Audio_buf_size+8*1024)
self.AI_client_asr_recv_id = _thread.start_new_thread(self.AI_client_asr_recv, (self.AI_client_asr,))
_thread.stack_size(8*1024)
self.AI_client_asr_isconnect = 1
+ self.AI_ASR_timer.start(1000, 1, self.AI_ASR_timer_cb)
+ self.AI_client_asr_start_requset()#开始请求
print("websocket_connect_asr:OK!!!!!!!!!!!!!!!!!!!!!")
def websocket_deconnect_asr(self):
print("websocket_deconnect_asr {}!!!!!!!".format(self.AI_client_asr_isconnect))
print("websocket_deconnect_asr!!!!!!!")
- if self.AI_client_asr_recv_id != 0:#关闭线程
+ self.AI_ASR_text_repet_count = 0
+ self.AI_ASR_text_tmp = ""
+ self.AI_ASR_timer.stop()
+ #self.AI_ASR_send_data_queue_thread_close()#关闭发送线程
+ self.AI_client_asr_recv_thread_close()#关闭读线程
+ if self.AI_client_asr_isconnect == 1 or self.AI_client_asr!= None:
try:
- _thread.stop_thread(self.AI_client_asr_recv_id)
+ self.AI_client_asr_isconnect = 0
+ count = 500
+ while True:#等待发完数据
+ count-=1
+ if count <=0 or self.AI_ASR_send_data_queue_thread_lock == 0:
+ break
+ print("等待发送完成:{}".format(count))
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ utime.sleep_ms(1)
+
+ try:
+ self.AI_client_asr_StopTranscription_requset()#发送停止ASR
+ self.AI_client_asr.close()
+ except Exception as e:
+ usys.print_exception(e)
+ utime.sleep_ms(200)#再尝试关闭一次
+ try:
+ self.AI_client_asr.close()
+
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_asr_debug-=1
+ try:
+ self.AI_client_asr._close()
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_asr = None
except Exception as e:
usys.print_exception(e)
- self.AI_client_asr_recv_id = 0
- if self.AI_client_asr_isconnect == 1 or self.AI_client_asr!= None:
- self.AI_client_asr_isconnect = 0
- self.AI_client_asr.close()
- self.AI_client_asr = None
- self.AI_client_asr_debug-=1
print("websocket_deconnect_asr {}!!!!!!!".format(self.AI_client_asr_isconnect))
#websocket发送数据
# else:
# pass
# #print("ASR ASR AI_client_asr_send:len:{}".format(len(data_str)))
- self.AI_send_data_queue.put([AI_client_asr_num,data_str])
+ self.AI_ASR_send_data_queue.put([AI_client_asr_num,data_str])
+
def AI_client_asr_ping(self):
pass
if self.AI_client_asr_isconnect == 1:
#self.AI_client_asr.write_frame(0x09,b'ping ping')
self.AI_client_asr_send("ping")
-
+ def set_AI_ASR_flag(self,data):
+ self.AI_ASR_flag = data
def AI_ASR_timer_cb(self, *args): #
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_ASR_timer_cb_})
def AI_ASR_timer_cb_(self):
- if self.VC_record_state_flag == 3:
- self.AI_ASR_timer_count+=1
- if self.AI_ASR_timer_count >=10 :#10*500ms终止asr
- print("AI_ASR_timer_count timerout!!!!!")
- #self.AI_client_asr_StopTranscription_requset()
+ if self.AI_ASR_check_timeout > 0:
+ print("AI_ASR_check_timeout:{}".format(self.AI_ASR_check_timeout))
+ self.AI_ASR_check_timeout-=1
+ if self.AI_ASR_check_timeout <=0:
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 3#发送停止后3秒后没正式结果就提示
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_asr_StopTranscription_requset})
+
+ if self.AI_ASR_error_timeout>0:
+ self.AI_ASR_error_timeout-=1
+ print("AI_ASR_error_timeout:{}".format(self.AI_ASR_error_timeout))
+ if self.AI_ASR_error_timeout <= 0:
+ self.AI_ASR_error_timeout = 0
+ #if self.AI_ASR_str == "":
+ if self.AI_ASR_str_tmp == "" and self.AI_ASR_str == "" and self.AI_ASR_text_tmp == "":
+ self.AI_TTS_str = "没有识别到您说话,请重试"
+ else :
+ self.AI_ASR_str = self.AI_ASR_str_tmp + self.AI_ASR_str+self.AI_ASR_text_tmp
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
+ print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
+ print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连ASR
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) #重连ASR
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.set_AI_ASR_flag,"data":1})#设置以打断过一次
+ if self.VC_record_state_flag > 1:
+ self.VC_record_state_flag =1
+ pass
+ #关闭ASR数据发送线程
+ def AI_ASR_send_data_queue_thread_close(self):
+ if self.AI_ASR_send_data_queue_thread_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_ASR_send_data_queue_thread_lock == 0 or count <=0:
+ break
+ else:
+ self.AI_ASR_send_data_queue_thread_lock = 2
+ print("AI_ASR_send_data_queue_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_ASR_send_data_queue_thread_lock = 0
+ print("AI_ASR_send_data_queue_thread_close")
+ try:
+ _thread.stop_thread(self.AI_ASR_send_data_queue_thread_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_ASR_send_data_queue_thread_id = 0
+ #发送数据队列
+ def AI_ASR_send_data_queue_thread(self):
+ print("AI_ASR_send_data_queue_thread:start")
+ count_t = 0
+ while True:
+ if self.AI_ASR_send_data_queue_thread_lock == 2:
+ print("AI_ASR_send_data_queue_thread:该退出了")
+ break
+ if self.AI_ASR_send_data_queue.empty() :#不能去掉,去掉会卡死
+ self.AI_ASR_send_data_queue_thread_lock = 0
+ count_t+=1
+ utime.sleep_ms(1)
+ else:
+ #data[0]是websocket连接对象编号,data[1]是数据
+ #print("AI_ASR_send_data_queue_thread:get")
+
+ self.AI_ASR_send_data_queue_thread_lock = 1
+ data = self.AI_ASR_send_data_queue.get()
+ #print("AI_ASR_send_data_queue_thread:num{} len{}".format(data[0],len(data[1])))
+ if data != None:
+ try:
+ # 发送数据
+ if data[0] == AI_client_asr_num:
+ self.AI_ASR_send_buf_len -= len(data[1])
+ self.asr_pingping_timerout = 0
+ if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
+ self.AI_client_asr.send(data[1])
+ if isinstance(data[1], str):#是字符串
+ print("ASR ASR: send_data:{}".format(data[1]))
+ # else:
+ # print("ASR ASR: send_data!:{}".format(len(data[1])))
+ else:
+ if isinstance(data[1], str):#是字符串
+ print("ASR ASR: send_data error!!!:{}".format(data[1]))
+ else:
+ print("ASR ASR: send_data error!!!:{}".format(len(data[1])))
- self.AI_ASR_timer.stop()
- else:
- self.AI_ASR_timer.stop()
- #Ai VC websocket返回数据
+ except Exception as e:
+ usys.print_exception(e)
+ if data[0] == AI_client_asr_num:
+ if self.AI_client_asr_isconnect != 0:
+ print("ASR发送数据错误,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR发送出错了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连
+ utime.sleep_ms(1)
+ self.AI_ASR_send_data_queue_thread_lock = 0
+
+ #ASR关闭读线程
+ def AI_client_asr_recv_thread_close(self):
+ if self.AI_client_asr_recv_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_client_asr_recv_lock == 1:
+ self.AI_client_asr_recv_lock = 2
+ if self.AI_client_asr_recv_lock == 0 or count <=0:
+ break
+ else:
+ print("AI_client_asr_recv_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_client_asr_recv_lock = 0
+ print("AI_client_asr_recv_thread_close")
+ try:
+ _thread.stop_thread(self.AI_client_asr_recv_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_asr_recv_id = 0
+
+ #Ai ASR websocket返回数据
def AI_client_asr_recv(self,cli):
while True:
try:
# 死循环接收数据
+ self.AI_client_asr_recv_lock = 0
utime.sleep_ms(1)
recv_data = cli.recv()
+ if self.AI_client_asr_recv_lock == 2:#要关闭线程了
+ print("AI_client_asr_recv 该退出了")
+ break
+ self.AI_client_asr_recv_lock = 1
self.close_timerout = 0#服务器有返回清零退出时间
- if not recv_data:
- # 服务器关闭连接或客户端关闭连接
- print("AI_client_asr_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- #self.AI_client_voice_chat_isconnect = 0
- #self.websocket_deconnect_voice_chat()
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
- # #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)})
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
+ if recv_data == "websocket close":
+ # 服务器关闭连接
+ print("ASR 服务器主动关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR连接断开了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
+ break
+ elif recv_data == "":#客户端关闭连接
+ print("ASR ASR :客户端关闭连接")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR连接断开了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
break
try:
if isinstance(recv_data, str):
jsload_data = ujson.loads(recv_data)
print("ASR ASR recv_data: {}".format(jsload_data))
if jsload_data["status"] != 20000000:#返回错误
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
+ print("ASR返回非20000000状态码,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})
+ self.ud_error(["asr",self.asr_taskid])
break
+
+ if jsload_data["task_id"] != None:
+ self.asr_taskid = jsload_data["task_id"]
if jsload_data["event"] != None:
if jsload_data["event"] == "TranscriptionStarted": #开始录音
self.VC_record_state_flag = 2
-
+ self.VC_state = VC_State_SpeechStart
EventMesh.publish("open_led_blue")
+ self.AI_ASR_error_timeout = 0
+
pass
- if jsload_data["event"] == "Changed" or jsload_data["event"] == "SentenceEnd" : #开始录音Changed
- if self.VC_record_state_flag == 2:
- self.AI_ASR_timer.start(500, 1, self.AI_ASR_timer_cb)
-
- self.AI_ASR_timer_count = 0
- if jsload_data["result"]["result"]:
- #self.AI_listen_text = str(jsload_data["result"]["result"])
- text= str(jsload_data["result"]["result"])
- print("ASR recv self.voice_chat_state :{}".format(self.voice_chat_state))
- if self.voice_chat_state >= VC_State_TTSStart:#开始播音后不响应asr结果
- print("asr continue")
- continue
- EventMesh.publish("open_led_blue")
- if jsload_data["result"]["is_end"] == True: #asr结束
- self.VC_record_state_flag = 4
- ret= self.check_text(text)
- if ret == 0:#配置指令
- #print("check_text ok:{} self.VC_TTS_voice_num:{},{}".format(text,self.VC_TTS_voice_num,self.VC_TTS_voice_type[self.VC_TTS_voice_num]))
- if self.AI_send_data_queue.empty()!=True:
- self.AI_send_data_queue.clear()
- EventMesh.publish("open_led_all")
- try:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- except Exception as e:
- usys.print_exception(e)
- continue
- elif ret == 1:#不处理
- pass
- else:#正常asr
- self.AI_ASR_str = text#
- if self.AI_ASR_flag == 0:#d第一次识别,没有打断
- self.AI_ASR_str_tmp = self.AI_ASR_str
- self.AI_ASR_flag = 1
- else:#第二次识别,打断了
- self.AI_ASR_str = self.AI_ASR_str_tmp+text
- print("ASR ASR 打断 续集 AI_ASR_str {}".format(self.AI_ASR_str))
- self.AI_ASR_str_tmp = self.AI_ASR_str
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat})#关闭vc连接
- self.AI_ASR_str+="\r\n\r\n"
- print("asr recv :asr_str:{}".format(self.AI_ASR_str))
- EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,"data":(500)}) #等一秒
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
+ elif jsload_data["event"] == "Changed" or jsload_data["event"] == "SentenceEnd" : #开始录音Changed
+ # if self.VC_record_state_flag == 2:
+ #
+
+ self.AI_ASR_timer_count = 0
+ if jsload_data["result"]["result"]:
+ #self.AI_listen_text = str(jsload_data["result"]["result"])
+ text= str(jsload_data["result"]["result"])
+ print("ASR recv self.VC_state :{}".format(self.VC_state))
+ if self.is_long_record == 0:
+ if self.VC_state >= VC_State_TTSStart:#开始播音后不响应asr结果
+ print("asr continue")
+ continue
+ EventMesh.publish("open_led_blue")
+
+ if jsload_data["result"]["is_end"] == True: #asr结束
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
+ self.AI_ASR_text_repet_count = 0
+ self.AI_ASR_text_tmp = ""
+ self.VC_record_state_flag = 4
+ ret= self.check_text(text)
+ if ret == 0:#配置指令
+
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ self.AI_ASR_send_buf_len = 0
+ EventMesh.publish("open_led_all")
+ try:
+
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+ #print("AI_client_asr_recv VC_Speech_End")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ except Exception as e:
+ usys.print_exception(e)
+ continue
+ elif ret == 1:#不处理
+ pass
+ else:#正常asr
+ if self.VC_mode == 0 :#连续问答模式
+ self.AI_ASR_str = text#
+ if self.AI_ASR_flag == 0:#d第一次识别,没有打断
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ else:#第二次识别,打断了
+ self.AI_ASR_str = self.AI_ASR_str_tmp+text
+ print("ASR ASR 打断 续集 AI_ASR_str {}".format(self.AI_ASR_str))
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ if self.is_long_record != 0:
+ #if self.VC_state >= VC_State_TTSStart:#如果已经播放了,关闭VC连接,重新打开,处理音频数据太多问题
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})#关闭vc连接
+ self.AI_ASR_flag = 1
+ print("asr recv :asr_str:{}".format(self.AI_ASR_str))
+ #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,"data":(500)}) #等一秒
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ elif self.VC_mode == 1:#单对话模式
+ self.AI_ASR_str += text#
+ self.AI_ASR_str_tmp = self.AI_ASR_str
+ if self.key_state == 0:#按键已经弹起
+ self.AI_ASR_str_tmp =""
+ print("asr recv :asr_str:{}".format(self.AI_ASR_str))
+ #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,"data":(500)}) #等一秒
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ self.VC_state = VC_State_SpeechEnd
+ elif jsload_data["result"]["is_end"] == False:
- elif jsload_data["result"]["is_end"] == False:
- self.VC_record_state_flag = 3
- if self.AI_ASR_flag ==1 :#如果已经识别过一次asr
- self.AI_ASR_flag = 2
- print("asr 打断,关闭VC连接")
- self.AI_ASR_str = ""
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat})#关闭vc连接
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_voice_chat})#连接服务器
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_start_requset})#请求
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- EventMesh.publish("publish_AI_btnInfo",{"func":EventMesh.publish,"data":"open_led_blue"})#
- pass
+ self.VC_state = VC_State_SpeechIng
+ if self.AI_ASR_text_tmp != "" and self.AI_ASR_text_tmp == text:
+ pass
+ # self.AI_ASR_text_repet_count+=1
+ # if self.AI_ASR_text_repet_count>=40:#重复30次下发一样结果,就报错
+ # print("asr 错误,无正式结果:{}".format(text))
+ # #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})#
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})
+ else:
+ self.AI_ASR_check_timeout = 5 #5秒没更新结果,强制stop
+ self.AI_ASR_error_timeout = 0
+ self.AI_ASR_text_repet_count = 0
+ if self.VC_mode == 0 :#连续问答模式
+ self.AI_ASR_text_tmp = text
+ self.VC_record_state_flag = 3
+ if self.AI_ASR_flag ==1 :#如果已经识别过一次asr
+ self.AI_ASR_flag = 2
+ print("asr 打断,关闭VC连接")
+ self.AI_ASR_str = ""
+ if self.is_long_record != 0:
+ self.VC_Play_End()
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})#关闭vc连接
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_VC})#连接服务器
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_start_requset})#请求
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ EventMesh.publish("publish_AI_btnInfo",{"func":EventMesh.publish,"data":"open_led_blue"})#
+ elif self.VC_mode ==1:#单对话模式
+ self.AI_ASR_str_tmp =""
+
except Exception as e:
usys.print_exception(e)
except Exception as e:
error_str = str(e)
- print("ASR ASR:e;{}".format(error_str))
- if error_str.find("[Errno 110] ETIMEDOUT")!= -1:
- print("ASR ASR:recv TIMEDOUT 正常")
+ print("ASR ASR:e:{}".format(error_str))
+ #usys.print_exception(e)
+ if error_str.find("[Errno 110]")!= -1:
+ #print("ASR ASR:recv TIMEDOUT 正常")
+ pass
else:
usys.print_exception(e)
+ print("{}".format(cli))
#self.websocket_error()
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})#
+ print("ASR读数据报错,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})#
+ self.ud_error(["asr",self.asr_taskid])
break
self.AI_client_asr_isconnect = 0
self.AI_client_asr_recv_id = 0
+ self.AI_client_asr_recv_lock = 0
print("AI_client_asr_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
#ASR开始会话
def AI_client_asr_start_requset(self):
-
+ self.session_id = self.get_session_id()
json_data = \
{
"header":{
"payload":{
"format":"pcm",
"sample_rate":self.VC_record_samplerate,
- "voice_detection":"enabled",
+ "session_id": self.session_id ,
}
}
if self.VC_record_TYPE == VC_record_TYPE_AMR :
json_data["payload"]["format"]='amr'
pass
- # if self.VC_mode == 1:
- #json_data["payload"]["voice_detection"]='disable'
-
+
+ self.AI_ASR_error_timeout = 5
self.AI_client_asr_send(ujson.dumps(json_data))
#ASR终止
def AI_client_asr_StopTranscription_requset(self):
+ print("AI_client_asr_StopTranscription_requset!!!!!")
json_data = \
{
"header":{
}
}
- self.AI_client_asr_send(ujson.dumps(json_data))
-
+ #self.AI_client_asr_send(ujson.dumps(json_data))
+ if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
+ self.AI_client_asr.send(ujson.dumps(json_data))
+
#开始录音
def VC_Speech_Start(self):
- #self.voice_chat_state = VC_State_SpeechStart
- print("VC_Speech_Start VC_record_state_flag:{} self.AI_ASR_flag:{}!!!!!!!!".format(self.VC_record_state_flag,self.AI_ASR_flag))
- if self.AI_ASR_flag != 0:
- return
- if self.VC_record_state_flag == 0:
- self.websocket_connect_asr()
- self.AI_client_asr_start_requset()#开始请求
- if self.VC_record_thread_id != 0:
+ try:
+
+ #self.VC_state = VC_State_SpeechStart
+ print("VC_Speech_Start VC_record_state_flag:{} self.AI_ASR_flag:{}!!!!!!!!".format(self.VC_record_state_flag,self.AI_ASR_flag))
+ if self.AI_ASR_flag != 0:
+ return
+
+ if self.VC_record_state_flag == 0:
+ if dev_type != "7PIN" :
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.chenggong_tone})
+ #self.websocket_connect_asr()
+ self.VC_record_thread_close()#关闭录音线程
+ _thread.stack_size(self.Audio_buf_size+8*1024)
+ self.VC_record_thread_id = _thread.start_new_thread(self.VC_record_thread,())
+ _thread.stack_size(8*1024)
+ print("self.VC_record_thread_id:{}".format(self.VC_record_thread_id))
try:
- _thread.stop_thread(self.VC_record_thread_id)
- except Exception as e:
- usys.print_exception(e)
- self.VC_record_thread_id = 0
- _thread.stack_size(self.Audio_buf_size+8*1024)
- self.VC_record_thread_id = _thread.start_new_thread(self.VC_record_thread,())
- _thread.stack_size(8*1024)
- print("self.VC_record_thread_id:{}".format(self.VC_record_thread_id))
- if self.VC_record_TYPE == VC_record_TYPE_AMR :
- try :
- self.record.stream_start(audio.Record.AMRNB, self.VC_record_samplerate, 0)
+
+ if self.VC_record_TYPE == VC_record_TYPE_AMR :
+ try :
+ self.record.stream_start(audio.Record.AMRNB, self.VC_record_samplerate, 0)
+ except Exception as e:
+ usys.print_exception(e)
+ elif self.VC_record_TYPE == VC_record_TYPE_PCM:
+ print("record_pcm.stream_read_start()!!!!!!!!!!!!")
+ self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0)
+ # if self.record_pcm != None:
+ # try:
+ # self.record_pcm.stream_stop()
+ # self.record_pcm.close()
+ # self.record_pcm = None
+ # except Exception as e:
+ # usys.print_exception(e)
+ # if self.record_pcm == None:
+ # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2)
+ # print("audio.Audio.PCM:ret:{}".format(ret))
+ # ret = self.record_pcm.stream_read_start()
+ # print("self.record_pcm.stream_read_start:ret:{}".format(ret))
except Exception as e:
- usys.print_exception(e)
- elif self.VC_record_TYPE == VC_record_TYPE_PCM:
- print("record_pcm.stream_read_start()!!!!!!!!!!!!")
- self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0)
- # if self.record_pcm != None:
- # try:
- # self.record_pcm.stream_stop()
- # self.record_pcm.close()
- # self.record_pcm = None
- # except Exception as e:
- # usys.print_exception(e)
- # if self.record_pcm == None:
- # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2)
- # print("audio.Audio.PCM:ret:{}".format(ret))
- # ret = self.record_pcm.stream_read_start()
- # print("self.record_pcm.stream_read_start:ret:{}".format(ret))
+ usys.print_exception(e)
+
+ self.VC_record_state_flag = 2
+ except Exception as e:
+ self.websocket_error()
self.VC_record_state_flag = 1
+ self.VC_Speech_End()#关闭录音
+ usys.print_exception(e)
+
#停止录音
def VC_Speech_End(self):
try:
self.AI_ASR_flag = 0
self.AI_ASR_str_tmp = ""
self.AI_ASR_str = ""
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
- #self.websocket_deconnect_asr()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+
if self.VC_record_state_flag == 0:
return
#self.AI_client_asr_StopTranscription_requset()#请求停止
# usys.print_exception(e)
except Exception as e:
usys.print_exception(e)
+ self.VC_record_thread_close()#关闭录音线程
+ if self.AI_record_tmp_queue.empty() != True:
+ self.AI_record_tmp_queue.clear()
+ # try:
+ # self.websocket_deconnect_asr()
+ # except Exception as e:
+ # usys.print_exception(e)
+ self.VC_record_state_flag = 0
+ print("VC_Speech_End VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))
+ #关闭录音线程
+ def VC_record_thread_close(self):
if self.VC_record_thread_id != 0:
+ count =50
+ while True:
+ count -= 1
+ if self.VC_record_thread_lock == 1:
+ self.VC_record_thread_lock = 2
+ if self.VC_record_thread_lock == 0 or count <=0:
+ break
+ else:
+ print("VC_record_thread_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.VC_record_thread_lock = 0
+ print("VC_record_thread_thread_close")
try:
_thread.stop_thread(self.VC_record_thread_id)
except Exception as e:
- usys.print_exception(e)
- self.VC_record_thread_id = 0
-
- self.VC_record_state_flag = 0
- print("VC_Speech_End VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))
+ usys.print_exception(e)
+ self.VC_record_thread_id = 0
#获取录音数据
def VC_record_thread(self):
##return
# if self.VC_record_TYPE == 1:
# h_data= [0x23,0x21 ,0x41 ,0x4D ,0x52 ,0x0A ]
# h_data_b = bytes(h_data)
- # self.AI_client_voice_chat_send(h_data_b)
-
- count = 0
+ # self.AI_client_VC_send(h_data_b)
+ AI_record_tmp_queue_len = 0
while True:
try:
-
+ if self.VC_record_thread_lock == 2:
+ break
+ self.VC_record_thread_lock = 1
# 死循环接收数据
- #if self.voice_chat_state == VC_State_SpeechStart:
+ #if self.VC_state == VC_State_SpeechStart:
Record_read_buf = bytearray(self.Audio_buf_size)
Record_len = 0
#print("VC_record_thread:{}".format(Record_len))
if Record_len > 0:
read_buf = bytes(Record_read_buf[:Record_len])
- if self.record_fd != None:
- self.record_fd.write(read_buf)
- print("write record:{}".format(len(read_buf)))
- if self.VC_record_state_flag >= 2:
- self.AI_client_asr_send(read_buf)
+ if self.record_data_save_flag == 1:
+ if self.record_fd == None:
+ try:
+ uos.remove('/usr/record_data.pcm')
+ except Exception as e:
+ usys.print_exception(e)
+ self.record_fd = open('/usr/record_data.pcm','w')
+ if self.record_fd != None:
+ self.record_fd.write(read_buf)
+ print("write record:{}".format(len(read_buf)))
+ # count+=Record_len
+ # if count >150*1024:
+ # self.record_fd.close()
+ #self.record_fd = None
+ # if self.VC_record_state_flag >= 2:
+ # self.AI_client_asr_send(read_buf)
- # if self.voice_chat_state != VC_State_SpeechStart:#没发送前先存起来
- # self.AI_record_tmp_queue.put(read_buf)
- # else:
- # while True:
- # if self.AI_record_tmp_queue.empty() == True:
- # break
- # else:
- # self.AI_client_voice_chat_send(self.AI_record_tmp_queue.get()) #发送之前存的数据
- # self.AI_client_voice_chat_send(read_buf)
+ if self.VC_record_state_flag <=1 :#没发送前先存起来
+ self.AI_record_tmp_queue.put(read_buf)
+ AI_record_tmp_queue_len += len(read_buf)
+ else:
+ AI_record_tmp_queue_len = 0
+ while True:
+ if self.AI_record_tmp_queue.empty() == True:
+ break
+ else:
+ self.AI_client_VC_input_audio_buffer_append(self.AI_record_tmp_queue.get())
+ #self.AI_client_asr_send(self.AI_record_tmp_queue.get()) #发送之前存的数据
+ #self.AI_client_asr_send(read_buf)
+ self.AI_client_VC_input_audio_buffer_append(read_buf)
#print("VC_record_thread:{}".format(len(read_buf)))
- count+=len(read_buf)
+ #count+=len(read_buf)
# if count>=500*1024:#结束
- # self.AI_client_voice_chat_end_speech()
+ # self.AI_client_VC_end_speech()
# break
- utime.sleep_ms(40)
- # if self.voice_chat_state >= VC_State_SpeechEnd:
+ # count+=1
+ # if count %10 == 0:
+ # print("VC_record_thread on line {} asr recv :{} send:{}".format(self.VC_record_state_flag,_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_VC_send_data_queue_thread_id)))
+
+ # if self.VC_state >= VC_State_SpeechEnd:
# break
- count+=1
- if count %10 == 0:
- print("VC_record_thread on line {} asr recv :{} send:{}".format(self.VC_record_state_flag,_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_send_data_queue_thread_id)))
+
except Exception as e:
usys.print_exception(e)
#break
-
+ self.VC_record_thread_lock = 0
+ utime.sleep_ms(100)
#fd.close()
print("VC_record_thread:exit")
self.VC_record_thread_id = 0#线程退出
+ self.VC_record_thread_lock = 0
###################################################### VC ###################################################################################
- def websocket_connect_voice_chat(self):
- print("websocket_connect_voice_chat:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_voice_chat_isconnect,self.AI_client_voice_chat_debug))
- if self.AI_client_voice_chat_isconnect == 1:
+ def websocket_connect_VC(self):
+ print("websocket_connect_VC:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_VC_isconnect,self.AI_client_VC_debug))
+ if self.AI_client_VC_isconnect == 1:
return
# 创建VC客户端
try:
if signal == -1 or sim.getStatus() != 1:#网络正常
self.websocket_error()
return
- #女,男,童,粤,川
- self.bot_name = "柒先生"
- if self.VC_TTS_voice_num == 0 or self.VC_TTS_voice_num == 3 or self.VC_TTS_voice_num == 4:
- self.bot_name = "柒妹妹"
- elif self.VC_TTS_voice_num == 1:
- self.bot_name = "柒先生"
- elif self.VC_TTS_voice_num == 2:
- self.bot_name = "柒乐乐"
- req_str = ""
- ack = ""
- if self.is_VC_ACK == 1:
- ack = "&ack=1"
- lang = "&lang=zh-cn"#普通话测试环境
- if self.VC_TTS_voice_num <= 2:
- lang = "&lang=zh-cn"#普通话测试环境
- elif self.VC_TTS_voice_num == 3:
- lang = "&lang=zh-hk"#粤语测试环境
- elif self.VC_TTS_voice_num == 4:
- lang = "&lang=zh-cn-sc"#四川话测试环境
- #platform = "&platform=huoshan&is_bot=1"
- platform = "&platform=raisound"
- req_str = "is_auth=0{}{}{}".format(platform,ack,lang)
- print("req_str:{}".format(req_str))
- # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
- # self.AI_client_voice_chat = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
- if self.VC_server == 1:#
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws', debug=False)#测试环境
- elif self.VC_server == 2:#
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?{}'.format(req_str), debug=False)
-
- else:
- token = EventMesh.publish("get_dev_token")
- print("token:{}".format(token))
- if token != None:
- self.AI_client_voice_chat = uwebsocket.Client.connect('ws://amp.raisound.com/voice-chat/ws?dt={}'.format(token), debug=False)
+ try:
+ if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]:
+ self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"]
else:
- self.websocket_error()
- return
- print("websocket_connect_voice_chat:OK!!!!!!!!!!!!!!!!!!!!!")
+ print("not bot_name!!!!!!!!!!!!!!!!!!!!!!")
+ except Exception as e:
+ usys.print_exception(e)
+
+ # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
+ # self.AI_client_VC = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
+
+ url="wss://ws.coze.cn/v1/chat?bot_id=7481164663863459850"
+ print("VC VC:url{}".format(url))
+ Headers = {"Authorization":"Bearer pat_SSaiOzccrRLaQEaB4sdshvHZQzqjeWD5jq2GWPVoWRx4N8XcdraHWYqdDjK5zpR1"}
+ self.AI_client_VC = uwebsocket.Client.connect(url, headers=Headers,debug=True)
+ #self.AI_WS_connect_Queue.put(self.AI_client_VC)
+
+
+ print("websocket_connect_VC:OK!!!!!!!!!!!!!!!!!!!!!")
except Exception as e: #网络连接异常
usys.print_exception(e)
- print("websocket_connect_voice_chat error!!!\r\n")
+ print("websocket_connect_VC error!!!\r\n")
str_error = str(e)
if str_error.find("[Errno 22] EINVAL")!= -1:
- print("websocket_connect_voice_chat:str_error:{}".format(str_error))
+ print("websocket_connect_VC:str_error:{}".format(str_error))
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
+ print("[Errno 22] EINVAL!!!\r\n")
self.websocket_error()
+ EventMesh.publish("set_storage_config",["powerRestart",1])#调试临时关闭
utime.sleep_ms(1000)
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
Power.powerRestart()
- EventMesh.publish("set_storage_config",["powerRestart",1])
+
self.websocket_error()
return
- print("AI_client_voice_chat:{}".format(self.AI_client_voice_chat))
- if self.AI_client_voice_chat == None:
+ #print("AI_client_VC:{}".format(self.AI_client_VC))
+ if self.AI_client_VC == None:
EventMesh.publish("update_dev_token")#获取token
self.websocket_error()
return
- self.AI_client_voice_chat_debug+=1
+ self.AI_client_VC_debug+=1
utime.sleep_ms(10)
- self.AI_client_voice_chat.settimeout(6)
+ #self.AI_client_VC.settimeout(5)
+ #self.AI_VC_send_data_queue_thread_close()#关闭发送线程
+ if self.AI_VC_send_data_queue_thread_id == 0:
+ _thread.stack_size(self.Audio_buf_size+8*1024)
+ self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ())
+ _thread.stack_size(8*1024)
+ print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id))
+ self.AI_client_VC_recv_thread_close()#关闭读线程
# 线程接收数据
- if self.AI_client_voice_chat_recv_id != 0:
- try:
- _thread.stop_thread(self.AI_client_voice_chat_recv_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_client_voice_chat_recv_id = 0
_thread.stack_size(self.Audio_buf_size+8*1024)
- self.AI_client_voice_chat_recv_id = _thread.start_new_thread(self.AI_client_voice_chat_recv, (self.AI_client_voice_chat,))
+ self.AI_client_VC_recv_id = _thread.start_new_thread(self.AI_client_VC_recv, (self.AI_client_VC,))
_thread.stack_size(8*1024)
- self.AI_client_voice_chat_isconnect = 1
- print("websocket_connect_voice_chat end")
- def websocket_error(self):
-
+ self.AI_client_VC_isconnect = 1
+ print("websocket_connect_VC end")
+ def websocket_error(self,TTS_str=None):
print("websocket_error1!!!!")
self.Close()
print("websocket_error1.1!!!!")
self.AI_ASR_str_tmp = ""
self.AI_ASR_flag = 0
self.VC_Speech_End()
- self.websocket_error_count+=1
- if self.websocket_error_count <=3:
- EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
- elif self.websocket_error_count <10 :
- EventMesh.publish("audio_montage_play",["xinhaoruo2.mp3"])
- elif self.websocket_error_count >=10:
- EventMesh.publish("paly_iccid_imei")
+ EventMesh.publish("close_led")
+ if TTS_str == None:
+ self.websocket_error_count+=1
+ # if self.websocket_error_count <=3:
+ # EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
+ if self.websocket_error_count <10 :
+ EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
+ elif self.websocket_error_count >=10:
+ EventMesh.publish("paly_iccid_imei")
+ # else:
+ # EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"])
+ #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3')
+ if self.websocket_error_count <3 :
+ utime.sleep_ms(3000)
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
else:
- EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"])
- #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3')
-
+ print("websocket_error:tts:{}".format(TTS_str))
+ self.AI_TTS_str = TTS_str
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
print("websocket_error2")
- #self.VC_Speech_End()
- EventMesh.publish("close_led")
+
print("websocket_error4")
- if self.websocket_error_count <3 :
- utime.sleep_ms(3000)
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
- def websocket_deconnect_voice_chat(self):
- print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
- print("websocket_deconnect_voice_chat!!!!!!!")
- if self.AI_client_voice_chat_recv_id != 0:#关闭线程
+ def websocket_deconnect_VC(self):
+ #print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect))
+ print("websocket_deconnect_VC!!!!!!!")
+ self.AI_client_VC_recv_thread_close()#关闭读线程
+ self.AI_client_VC_recv_id = 0
+ if self.AI_client_VC_isconnect == 1 or self.AI_client_VC!=None:
try:
- _thread.stop_thread(self.AI_client_voice_chat_recv_id)
+ self.AI_client_VC_isconnect = 0
+ count = 500
+ while True:#等待发完数据
+ count-=1
+ if count <=0 or self.AI_VC_send_data_queue_thread_lock == 0:
+ break
+ utime.sleep_ms(1)
+
+ try:
+ self.AI_client_VC.close()
+ self.AI_client_VC_debug -=1
+ #self.AI_client_VC=None
+ except Exception as e:
+ usys.print_exception(e)
+ try :
+ self.AI_client_VC.close()
+ self.AI_client_VC_debug -=1
+ #self.AI_client_VC=None
+ except Exception as e:
+ usys.print_exception(e)
+ try :
+ self.AI_client_VC._close()
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_VC = None
except Exception as e:
usys.print_exception(e)
- self.AI_client_voice_chat_recv_id = 0
- if self.AI_client_voice_chat_isconnect == 1 or self.AI_client_voice_chat!=None:
- self.AI_client_voice_chat_isconnect = 0
- self.AI_client_voice_chat.close()
- self.AI_client_voice_chat_debug -=1
- self.AI_client_voice_chat=None
- print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
+ print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect))
#websocket发送ping
- def AI_client_voice_chat_ping(self):
+ def AI_client_VC_ping(self):
pass
- if self.AI_client_voice_chat_isconnect == 1:
- #self.AI_client_voice_chat.write_frame(0x09,b'ping ping')
- self.AI_client_voice_chat_send("ping")
+ if self.AI_client_VC_isconnect == 1:
+ #self.AI_client_VC.write_frame(0x09,b'ping ping')
+ self.AI_client_VC_send("ping")
#print("websocket ping ping")
#websocket发送数据
- def AI_client_voice_chat_send(self,data_str):
+ def AI_client_VC_send(self,data_str):
# if isinstance(data_str, str):#是字符串
- # print("AI_client_voice_chat_send:{}".format(data_str))
+ # print("AI_client_VC_send:{}".format(data_str))
# pass
# else:
- # print("AI_client_voice_chat_send:len{}".format(len(data_str)))
- self.AI_send_data_queue.put([AI_client_voice_chat_num,data_str])
+ # print("AI_client_VC_send:len{}".format(len(data_str)))
+ self.AI_VC_send_data_queue.put([AI_client_VC_num,data_str])
+ #关闭数据发送线程
+ def AI_VC_send_data_queue_thread_close(self):
+ if self.AI_VC_send_data_queue_thread_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_VC_send_data_queue_thread_lock == 0 or count <=0:
+ break
+ else:
+ self.AI_VC_send_data_queue_thread_lock = 2
+ print("AI_VC_send_data_queue_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ self.AI_VC_send_data_queue_thread_lock = 0
+ print("AI_VC_send_data_queue_thread_close")
+ try:
+ _thread.stop_thread(self.AI_VC_send_data_queue_thread_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_VC_send_data_queue_thread_id = 0
+ #发送数据队列
+ def AI_VC_send_data_queue_thread(self):
+ print("AI_VC_send_data_queue_thread:start")
+ count_t = 0
+ while True:
+ if self.AI_VC_send_data_queue_thread_lock == 2:
+ print("AI_VC_send_data_queue_thread,该退出了")
+ break
+ if self.AI_VC_send_data_queue.empty() :#不能去掉,去掉会卡死
+ self.AI_VC_send_data_queue_thread_lock = 0
+ count_t+=1
+ # if count_t%200 == 0:
+ # print("self.AI_VC_send_data_queue.empty")
+ utime.sleep_ms(1)
+ else:
+ #data[0]是websocket连接对象编号,data[1]是数据
+ #print("AI_VC_send_data_queue_thread:get")
+
+ self.AI_VC_send_data_queue_thread_lock = 1
+ data = self.AI_VC_send_data_queue.get()
+
+
+ #print("AI_VC_send_data_queue_thread:num{} len{}".format(data[0],len(data[1])))
+ if data != None:
+ try:
+ #data["func"](data["data"])
+ # 发送数据
+ #bytes_data = bytes(data[1])
+ #data[0].send(data[1])
+ #print("AI_VC_send_data_queue_thread:len:{}".format(len(data[1])))
+ #print("AI_VC_send_data_queue_thread on line asr recv :{} vc recv:{}".format(_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_client_VC_recv_id)))
+ if data[0] == AI_client_VC_num:
+ self.VC_pingping_timerout = 0
+ if isinstance(data[1], str):#是字符串
+ if len(data[1])<600:
+ print("VC VC: send_data:{}".format(data[1]))
+ else:
+ pass
+ #print("VC VC: send_data:{}...".format(data[1][:300]))
+ #print("VC: send_data len:{}".format(len(data[1])))
+ if self.AI_client_VC != None and self.AI_client_VC_isconnect == 1:
+ self.AI_client_VC.send(data[1])
+ else:
+ print("VC VC: send_data:ERROR:{}".format(data[1]))
+ #print("VC: send_data end")
+ #print("VC: send_data end")
+ except Exception as e:
+ print("DeviceInfo_queue_thread:ERROR:{}".format(e))
+ usys.print_exception(e)
+ if data[0] == AI_client_VC_num:
+ #self.websocket_error()
+ pass
+
+
+ try:
+ if self.AI_client_VC_isconnect != 0:
+ print("VC发送数据错误,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC发送出错了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
+ except Exception as e: #网络连接异常
+ usys.print_exception(e)
+
+ utime.sleep_ms(1)
+ self.AI_VC_send_data_queue_thread_lock = 0
+ #VC关闭读线程
+ def AI_client_VC_recv_thread_close(self):
+ if self.AI_client_VC_recv_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_client_VC_recv_lock == 1:
+ self.AI_client_VC_recv_lock = 2
+ if self.AI_client_VC_recv_lock == 0 or count <=0:
+ break
+ else:
+ print("AI_client_VC_recv_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_client_VC_recv_lock = 0
+ print("AI_client_VC_recv_thread_close")
+ try:
+ _thread.stop_thread(self.AI_client_VC_recv_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_client_VC_recv_id = 0
#Ai VC websocket返回数据
- def AI_client_voice_chat_recv(self,cli):
+ def AI_client_VC_recv(self,cli):
count = 0
while True:
try:
# 死循环接收数据
+ self.AI_client_VC_recv_lock = 0
if self.is_VC_ACK == 1:
- self.AI_client_voice_chat_Read()
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_Read})
+ self.AI_client_VC_Read()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_Read})
count+=1
- if self.voice_chat_state >= VC_State_TTSStart and (self.tts_in_data_len - self.tts_out_data_len > 64*1024 or count>3):
+ if self.VC_state >= VC_State_TTSStart and (self.tts_in_data_len - self.tts_out_data_len > 64*1024 or count>5):
count = 0
utime.sleep_ms(1)
+ if self.VC_state < VC_State_TTSStart:
+ utime.sleep_ms(1)
recv_data = cli.recv()
+ if self.AI_client_VC_recv_lock == 2:
+ print("AI_client_VC_recv 该退出了")
+ break
+ self.AI_client_VC_recv_lock = 1
self.close_timerout = 0#服务器有返回清零退出时间
- if not recv_data:
- # 服务器关闭连接或客户端关闭连接
- print("服务器主动关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- #self.AI_client_voice_chat_isconnect = 0
- #self.websocket_error()
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
- #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)})
-
+ if recv_data == "websocket close":
+ # 服务器关闭连接
+ print("VC 服务器关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ #self.AI_client_VC_isconnect = 0
+ #self.websocket_deconnect_VC()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ # #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
+ break
+ elif recv_data == "":#客户端关闭连接
+ print("VC VC :客户端关闭连接")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
break
try:
self.websocket_error_count = 0
if isinstance(recv_data, str):#返回的是字符串
- print("VC VC:recv_data:{}".format(recv_data))
+ if len(recv_data)<700:
+ print("VC VC:recv_data:{}".format(recv_data))
+ else:
+ print("VC VC:recv_data long :{}".format(recv_data[:700]))
jsload_data = ujson.loads(recv_data)
- #print("AI_client_voice_chat_recv jsload_data = {}".format(jsload_data))
- if jsload_data["status"] != 20000000:#返回错误
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
- break
- if jsload_data["event"] == "Started" :#会话开始
- payload = jsload_data["payload"]
- self.VC_dialog_id = payload["dialog_id"]
- self.VC_task_id = jsload_data["task_id"]
+ #print("AI_client_VC_recv jsload_data = {}".format(jsload_data))
+ if jsload_data["event_type"] == "chat.updated" :#会话开始
+ print("VC:Started!!!!!!!!\r\n")
+ print("VC:Started!!!!!!!!\r\n")
print("VC:Started!!!!!!!!\r\n")
- elif jsload_data["event"] == "SpeechContent" :#asr转译
- print("VC:SpeechContent!!!!!!!!\r\n")
- payload = jsload_data["payload"]
-
-
- if(payload['finished'] == True):#asr结束
- self.voice_chat_state = VC_State_SpeechEnd
- #self.VC_Speech_End()#停止录音
- text = payload["text"]
- if self.check_text(text) == 0:
- #print("check_text ok:{} self.VC_TTS_voice_num:{},{}".format(text,self.VC_TTS_voice_num,self.VC_TTS_voice_type[self.VC_TTS_voice_num]))
-
- #EventMesh.publish("open_led_all")
-
- if self.AI_send_data_queue.empty()!=True:
- self.AI_send_data_queue.clear()
- EventMesh.publish("open_led_all")
- try:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- except Exception as e:
- usys.print_exception(e)
-
- pass
- else:
- pass
-
- elif jsload_data["event"] == "SpeechEnded" :#服务器下发ASR说话结束
- self.voice_chat_state = VC_State_SpeechEnd
- elif jsload_data["event"] == "RespondingContent" :#chat回答
- pass
- elif jsload_data["event"] == "RespondingStarted" :#音频开始下发
- self.play_flag = 0
- self.voice_chat_state = VC_State_TTSStart
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
- self.VC_Thinking_timerout = 0#关闭超时重试
- # self.VC_Speech_End()#停止录音
- # self.VC_Play_Start()
- EventMesh.publish("open_led_green")#绿色
- #self.tts_fd = open('/usr/tts_tesr.pcm','w')
+ self.AI_client_VC_send_speech()#开始上传语音
+ elif jsload_data["event_type"] == "conversation.audio_transcript.update" :#音频转译
+ #self.VC_Speech_end_timerout = 2
+ self.AI_ASR_str = jsload_data["data"]['content']
+ # if self.AI_ASR_str.find("。") != -1 or self.AI_ASR_str.find("?") != -1 or self.AI_ASR_str.find("!") != -1:
+ # self.VC_Speech_end_timerout = 0
+ # self.AI_client_VC_end_speech()#发送说话终止
+
+ elif jsload_data["event_type"] == "conversation.chat.created" :#开始对话
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone})
+ self.open_play_flag = 0
if self.play_data_save_flag == 1:
try:
uos.remove('/usr/play_data.pcm')
except Exception as e:
usys.print_exception(e)
self.play_fd = open('/usr/play_data.pcm','w')
+
+ elif jsload_data["event_type"] == "conversation.message.delta":#返回大模型回答数据
+ if self.open_play_flag == 0:
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})#打开播放
+ self.open_play_flag =1
+ elif jsload_data["event_type"] == "conversation.audio.delta":#下发音频数据
- pass
- elif jsload_data["event"] == "RespondingEnded" :#音频下发结束
- #if self.voice_chat_state == VC_State_TTSStart:
- print("RespondingEnded!!!!!!" )
- self.voice_chat_state = VC_State_TTSEnd
- if self.asr_satrt_flag == 0 :
- self.asr_satrt_flag =1
+ audio_data = ubinascii.a2b_base64(jsload_data["data"]['content'])
+ print("下发音频数据1:{}".format(len(audio_data)))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[audio_data,""]})
if self.play_data_save_flag == 1:
if self.play_fd !=None:
+ self.play_fd.write(audio_data)
+ elif jsload_data["event_type"] == "conversation.audio.completed":#结束播放
+ if self.play_data_save_flag == 1:
+ if self.play_fd !=None:
+ print("输出音频文件关闭")
self.play_fd.close()
- #self.tts_fd.close()
- #pass
- elif jsload_data["event"] == "DialogStateChanged" :#状态切换事件
- payload = jsload_data["payload"]
- if payload["state"] == "Listening":#可以说了
- self.voice_chat_state = VC_State_Listening
- if self.AI_TTS_str != "" or self.AI_ASR_str != "":#有tts数据,则请求TTS数据,没有就请求开始上传语音
- self.AI_client_voice_chat_RequestToRespond()
- else:
- #self.VC_Speech_Start()#开启线程获取录音数据
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#
- #self.AI_client_voice_chat_send_speech()#开始上传语音
+
+ # elif jsload_data["event"] == "SpeechContent" :#asr转译
+ # print("VC:SpeechContent!!!!!!!!\r\n")
+ # payload = jsload_data["payload"]
+
+
+ # if(payload['finished'] == True):#asr结束
+ # self.VC_state = VC_State_SpeechEnd
+ # #self.VC_Speech_End()#停止录音
+ # text = payload["text"]
+ # if self.check_text(text) == 0:
+ # if self.AI_VC_send_data_queue.empty()!=True:
+ # self.AI_VC_send_data_queue.clear()
+ # if self.AI_ASR_send_data_queue.empty()!=True:
+ # self.AI_ASR_send_data_queue.clear()
+ # self.AI_ASR_send_buf_len = 0
+ # EventMesh.publish("open_led_all")
+ # try:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+
+ # # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ # except Exception as e:
+ # usys.print_exception(e)
- #EventMesh.publish("open_led_red")
- if payload["state"] == "Thinking":#思考
- self.voice_chat_state = VC_State_Thinking
- if self.VC_Thinking_timerout == 0:
- self.VC_Thinking_timerout = 15#倒计时15秒,如果没有音频数据返回就重试
- EventMesh.publish("open_led_red_green")#黄色
- if payload["state"] == "Responding":#开始音频播放
- #self.voice_chat_state = VC_State_Responding#
- pass
- elif jsload_data["event"] == "RequestAccepted" :#请求上传语音被允许
- #self.voice_chat_state = VC_State_Responding
- #self.AI_client_voice_chat_send_speech()#开始上传语音
- pass
+ # pass
+ # else:
+ # pass
+
+ # elif jsload_data["event"] == "SpeechEnded" :#服务器下发ASR说话结束
+ # self.VC_state = VC_State_SpeechEnd
+ # elif jsload_data["event"] == "RespondingContent" :#chat回答
+ # pass
+
+ # elif jsload_data["event"] == "RespondingStarted" :#音频开始下发
+ # self.play_flag = 0
+ # self.VC_state = VC_State_TTSStart
+ # if self.is_long_record == 0:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})#
+ # else:
+ # self.AI_ASR_str_tmp = ""
+ # self.AI_ASR_str = ""
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
+ # self.VC_Thinking_timerout = 0#关闭超时重试
+ # # self.VC_Play_Start()
+ # EventMesh.publish("open_led_green")#绿色
+ # #self.tts_fd = open('/usr/tts_tesr.pcm','w')
+ # if self.play_data_save_flag == 1:
+ # try:
+ # uos.remove('/usr/play_data.pcm')
+ # except Exception as e:
+ # usys.print_exception(e)
+ # self.play_fd = open('/usr/play_data.pcm','w')
+
+ # pass
+ # elif jsload_data["event"] == "RespondingEnded" :#音频下发结束
+ # #if self.VC_state == VC_State_TTSStart:
+
+ # print("RespondingEnded!!!!!!" )
+ # self.VC_state = VC_State_TTSEnd
+ # self.LocalRespondingEnded_timerout = 10 #最长倒数10秒发送音频结束或者终止对话
+ # if self.VC_mode == 0 :#连续问答模式
+ # #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})#调试临时打开
+ # if dev_type != "7PIN_BK":
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音
+ # pass
+ # if self.play_data_save_flag == 1:
+ # if self.play_fd !=None:
+ # self.play_fd.close()
+ # #self.tts_fd.close()
+ # #pass
+ # elif jsload_data["event"] == "DialogStateChanged" :#状态切换事件
+ # payload = jsload_data["payload"]
+ # if payload["state"] == "Listening":#可以说了
+ # self.VC_state = VC_State_Listening
+ # if self.AI_TTS_str != "" or self.AI_ASR_str != "":#有tts数据,则请求TTS数据,没有就请求开始上传语音
+ # self.AI_client_VC_RequestToRespond()
+ # else:
+ # pass
+ # #self.VC_Speech_Start()#开启线程获取录音数据
+ # if self.is_long_record == 0:
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#
+ # #self.AI_client_VC_send_speech()#开始上传语音
+
+ # #EventMesh.publish("open_led_red")
+ # if payload["state"] == "Thinking":#思考
+ # self.VC_state = VC_State_Thinking
+ # if self.VC_Thinking_timerout == 0:
+ # self.VC_Thinking_timerout = 15#倒计时15秒,如果没有音频数据返回就重试
+ # EventMesh.publish("open_led_red_green")#黄色
+ # if payload["state"] == "Responding":#开始音频播放
+ # #self.VC_state = VC_State_Responding#
+ # pass
+ # elif jsload_data["event"] == "RequestAccepted" :#请求上传语音被允许
+ # #self.VC_state = VC_State_Responding
+ # #self.AI_client_VC_send_speech()#开始上传语音
+ # pass
else:#下发音频数据
#self.AI_ASR_str = ""#下发音频后清掉asr结果
+
print("下发音频数据1:{}".format(len(recv_data)))
+
if self.play_data_save_flag == 1:
if self.play_fd !=None:
self.play_fd.write(recv_data)
# print("下发音频数据2:{}".format(len(recv_data)))
- if self.voice_chat_state >= VC_State_TTSStart:
- self.put_record_data([recv_data,""])
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]})
+ if self.VC_state >= VC_State_TTSStart:
+ #self.put_record_data([recv_data,""])
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]})
+ utime.sleep_ms(1)
except Exception as e:
usys.print_exception(e)
except Exception as e:
error_str = str(e)
- print("VC VC:e:{}".format(error_str))
+ #print("VC VC:e:{}".format(error_str))
if error_str.find("[Errno 110] ETIMEDOUT")!= -1:
- print("VC VC:recv TIMEDOUT 正常")
+ #print("VC VC:recv TIMEDOUT 正常")
+ pass
else:
usys.print_exception(e)
#self.websocket_error()
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})#
+ print("VC VC :读数据报错,退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC出错了,请重试"})
+ self.ud_error(["VC",self.VC_taskid])
break
- self.AI_client_voice_chat_isconnect = 0
- self.AI_client_voice_chat_recv_id = 0
- print("AI_client_voice_chat_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ self.AI_client_VC_isconnect = 0
+ self.AI_client_VC_recv_id = 0
+ self.AI_client_VC_recv_lock = 0
+ print("AI_client_VC_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
def put_record_data(self,data):
#print("下发音频数据1:{}".format(len(data[0])))
ret=self.AI_audio_queue.put(data)
self.tts_in_data_len += len(data[0])
- print("下发音频数据2:{},{}".format(len(data[0]),self.tts_in_data_len))
+ #print("下发音频数据2:{},{}".format(len(data[0]),self.tts_in_data_len))
def check_text(self,text):
if len(text)>60:
return -1
try:
if isinstance(text, str):
- if text.find("更改声音") != -1:
- self.VC_TTS_voice_num += 1
- if self.VC_TTS_voice_num >= len(self.VC_TTS_voice_type):
- self.VC_TTS_voice_num = 0
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音") != -1 and text.find("改") != -1 and (text.find("男声") != -1 or text.find("男") != -1 ):
- self.VC_TTS_voice_num = 1
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音") != -1 and text.find("改") != -1 and (text.find("女声") != -1 or text.find("女") != -1 ):
- self.VC_TTS_voice_num = 0
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音") != -1 and text.find("改") != -1 and (text.find("同声") != -1 or text.find("童") != -1 ):
- self.VC_TTS_voice_num = 2
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音") != -1 and text.find("改") != -1 and (text.find("粤") != -1 or text.find("越野") != -1 ):
- self.VC_TTS_voice_num = 3
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
- return 0
- if text.find("声音") != -1 and text.find("改") != -1 and text.find("四川话") != -1 :
- self.VC_TTS_voice_num = 4
-
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
- # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
- self.AI_TTS_str = "更改成功"
+ if text.find("声音") != -1 and text.find("改") != -1:
+ try:
+ for key in self.VC_TTS_voice_type:
+ if text.find(key) != -1 :
+ self.VC_TTS_voice_key = key
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ self.AI_TTS_str = "更改成功"
+ return 0
+ except Exception as e:
+ usys.print_exception(e)
+ if text.find("男") != -1 :
+ if "男" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "男"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("女") != -1 :
+ if "女" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "女"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("同声") != -1 or text.find("童") != -1 :
+ if "童" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "童"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("粤") != -1 or text.find("越野") != -1 or text.find("广东话") != -1:
+ if "粤" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "粤"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("四川") != -1 :
+ if "四川" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "四川"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("个性") != -1 :
+ if "个性" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "个性"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ if text.find("英语") != -1 :
+ if "英语" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "英语"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ self.AI_TTS_str = "更改成功"
+ return 0
+ self.AI_TTS_str = "更改失败,没找到对应声音"
return 0
if text.find("切换对话模式") != -1:
if self.VC_mode == 0:
else:
self.VC_mode = 0
self.AI_TTS_str = "已切换到长对话模式"
- EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_mode])
+ EventMesh.publish("set_storage_config",["VC_mode",self.VC_mode])
# EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
#self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
return 0
- if text.find("音量") != -1 and text.find("加") != -1 :
- self.VC_TTS_volume += 10
- if self.VC_TTS_volume > 100:
- #EventMesh.publish("audio_montage_play",["yinliangyizuida.mp3"])
- #self.aud.play(1,0,'U:/static/yinliangyizuida.mp3')#音量已最大
- self.AI_TTS_str = "音量已最大"
- self.VC_TTS_volume = 100
- else:
- self.aud.setVolume(self.VC_TTS_volume //10)
- EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
- #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
- self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
-
- return 0
- if text.find("音量") != -1 and text.find("减") != -1:
- self.VC_TTS_volume -= 10
- if self.VC_TTS_volume < 0:
- self.VC_TTS_volume = 0
- #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"])
- #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小
- self.AI_TTS_str = "音量已最小"
- else:
- self.aud.setVolume(self.VC_TTS_volume //10)
- EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
- #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
- #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
- self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
- return 0
- if text.find("电量") != -1 and text.find("查询") != -1:
- battery = EventMesh.publish("get_battery")
- #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
- #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
- self.AI_TTS_str = "电量剩余百分之{}".format(battery)
- return 0
- if text.find("电压") != -1 and text.find("查询") != -1:
- Vbatt = Power.getVbatt()
- #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
- #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
- self.AI_TTS_str = "当前电池电压{}".format(Vbatt)
- return 0
+ if text.find("音量") != -1:
+ if text.find("加") != -1 :
+ self.VC_TTS_volume += 10
+ if self.VC_TTS_volume > 100:
+ #EventMesh.publish("audio_montage_play",["yinliangyizuida.mp3"])
+ #self.aud.play(1,0,'U:/static/yinliangyizuida.mp3')#音量已最大
+ self.AI_TTS_str = "音量已最大"
+ self.VC_TTS_volume = 100
+ else:
+ self.aud.setVolume(self.VC_TTS_volume //10)
+ EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
+ #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
+ self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
+
+ return 0
+ if text.find("减") != -1:
+ self.VC_TTS_volume -= 10
+ if self.VC_TTS_volume < 0:
+ self.VC_TTS_volume = 0
+ #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"])
+ #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小
+ self.AI_TTS_str = "音量已最小"
+ else:
+ self.aud.setVolume(self.VC_TTS_volume //10)
+ EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
+ #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功
+ self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume)
+ return 0
+
if text.find("进入工厂模式") != -1 :
self.factory_mode()
return 1
- if text.find("信号") != -1 and text.find("查询") != -1:
- signal = net.csqQueryPoll()
-
- self.AI_TTS_str = "当前信号{}".format(signal)
+ if text.find("查询") != -1:
+
+ if text.find("信号") != -1 :
+ signal = net.csqQueryPoll()
+
+ self.AI_TTS_str = "当前信号{}".format(signal)
+ return 0
+ if text.find("电量") != -1 :
+ battery = EventMesh.publish("get_battery")
+ print("电量查询:{}".format(battery))
+ #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
+ #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
+ self.AI_TTS_str = "电量剩余百分之{}".format(battery)
+ return 0
+ if text.find("电压") != -1 :
+ Vbatt = Power.getVbatt()
+ #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
+ #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
+ self.AI_TTS_str = "当前电池电压{}".format(Vbatt)
+ return 0
+
+ if text.find("卡号") != -1 :
+ iccid = sim.getIccid()
+ if iccid != -1 and len(iccid) > 5:
+ print("iccid{}".format(iccid))
+ self.AI_TTS_str = "当前卡号为:{}".format(iccid)
+ else:
+ self.AI_TTS_str = "卡号查询失败"
+ return 0
+ if text.find("设备号") != -1 :
+ imei = modem.getDevImei()
+ if imei != -1 and len(imei) > 5:
+ print("IMEI:{}".format(imei))
+ self.AI_TTS_str = "当前设备号为:{}".format(imei)
+ else:
+ self.AI_TTS_str = "设备号查询失败"
+ return 0
+ if text.find("版本") != -1 :
+ sourceVersion = versions.Build_Time
+ self.AI_TTS_str ="Mr-Seven-"+sourceVersion
+ return 0
+ if text.find("服务器地址") != -1 :
+ self.AI_TTS_str ="服务器地址"+self.server_ip
+ return 0
+ if text.find("升级") != -1 and (text.find("OTA") != -1 or text.find("ota") != -1):
+ if self.ai_OTA.min_sys_ota()==1:
+ self.AI_TTS_str = "有新版本,准备开始升级,升级过程会多次重启设备,请保证流量充足及电量充足"
+ else:
+ self.AI_TTS_str = "当前已是最新版本"
return 0
if len(text)<12 and (text.find("再见") != -1 or text.find("拜拜") != -1):
sign_data = ubinascii.hexlify(res)
sign_data = sign_data.decode('ascii')
return sign_data
+
+ def get_session_id(self,data = "session_id"):
+ t = utime.mktime(utime.localtime())
+ t = t*1000+urandom.randint(0, 1000)
+ md5_data = "{}{}".format(data,t)#md5签名
+ sign_data = ""
+ hash_obj = uhashlib.md5(md5_data)
+ res = hash_obj.digest()
+
+ # 转成十六进制表示
+ sign_data = ubinascii.hexlify(res)
+ sign_data = sign_data.decode('ascii')
+ return sign_data
+
def get_new_message_id(self):
message_id = self.get_trace_id()+"aaa"+self.get_trace_id()
self.VC_message_id=message_id[:32]
self.tts_in_data_len = 0
self.tts_out_data_len = 0
if self.VC_play_TYPE == VC_play_TYPE_PCM:
- if self.VC_play_samplerate == 8000:
- pass
- elif self.VC_play_samplerate == 16000:
- if self.play_pcm == None:
- self.play_pcm = audio.Audio.PCM(0,1,16000,1,1,2)
- #self.play_pcm.setVolume(11)
- ret = self.play_pcm.stream_write_start()
- print("self.record_pcm.stream_write_start:ret:{}".format(ret))
+ # if self.VC_play_samplerate == 8000:
+ # pass
+ # elif self.VC_play_samplerate == 16000:
+ # if self.play_pcm == None:
+ # self.play_pcm = audio.Audio.PCM(0,1,16000,1,1,2)
+ # #self.play_pcm.setVolume(11)
+ # ret = self.play_pcm.stream_write_start()
+ # print("self.record_pcm.stream_write_start:ret:{}".format(ret))
+ if self.play_pcm == None:
+ self.aud.stopPlayStream()
+ self.aud.stopAll()
+ self.play_pcm = audio.Audio.PCM(0,1,self.VC_play_samplerate,1,1,2)
+ #self.play_pcm.setVolume(11)
+ ret = self.play_pcm.stream_write_start()
+ print("音频初始化:self.record_pcm.stream_write_start:ret:{}".format(ret))
elif self.VC_play_TYPE == VC_play_TYPE_MP3:
pass
#停止播放声音
if self.VC_play_samplerate == 8000:
self.aud.stopPlayStream()
self.aud.stopAll()
- elif self.VC_play_samplerate == 16000:
+ else:
if self.play_pcm != None:
print("Close:play_pcm.close()!!!!!!!!!!!!!!!!!!")
try:
EventMesh.publish("system_sleep_rest")#防止黑屏
self.close_timerout += 1
- if self.close_timerout > 30:#20秒没数据就close
+ if self.close_timerout > 60:#20秒没数据就close
- if self.voice_chat_state >= VC_State_Thinking:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
+ if self.VC_state >= VC_State_SpeechIng:
+ print("接口无响应,超时退出")
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"接口超时了。请重试"})
+ self.ud_error(["VC",self.VC_taskid])
else:
EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
# print("get_audio_state !!!!!{} {} {}\r\n".format(self.play_end,EventMesh.publish("get_audio_state"),self.play_flag))
- #self.LocalRespondingEnded_timerout+=1
- if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
- self.LocalRespondingEnded_timerout += 1
- if self.LocalRespondingEnded_timerout >= 4:
- self.LocalRespondingEnded_timerout = 0
- if self.VC_mode == 1 :#长按单次问答模式
- EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
- else:
- #通知服务器播放结束
- self.AI_client_voice_chat_LocalRespondingEnded()
+ if self.LocalRespondingEnded_timerout>0 :#
+ self.LocalRespondingEnded_timerout -= 1
+ print("LocalRespondingEnded_timerout:{}".format(self.LocalRespondingEnded_timerout))
+ if self.LocalRespondingEnded_timerout <= 0 or (self.play_pcm != None and self.play_pcm.stream_is_empty() == 1) :#超时或者音频播放完,
+ self.LocalRespondingEnded_timerout = 0
+ if self.VC_mode == 1 :#长按单次问答模式
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ else:
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音
+ #通知服务器播放结束
+ self.AI_client_VC_LocalRespondingEnded()
self.VC_pingping_timerout+=1
- if self.VC_pingping_timerout>5:
+ if self.VC_pingping_timerout>3:
self.VC_pingping_timerout=0
- self.AI_client_voice_chat_ping()
+ #self.AI_client_VC_ping()
self.asr_pingping_timerout += 1
- if self.asr_pingping_timerout>5:
+ if self.asr_pingping_timerout>3:
self.asr_pingping_timerout=0
self.AI_client_asr_ping()
if self.VC_Thinking_timerout > 0 and self.VC_Thinking_timerout < 100:#VC Thinking超时后重新开始
if self.VC_Thinking_timerout == 0:
self.VC_Thinking_timerout = 100
print("Thinking重试,重试!!!!!!!!!!!!!!!!!!!!!")
- self.voice_chat_state = VC_State_None
+ self.VC_state = VC_State_None
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
pass
-
+ if self.VC_Speech_end_timerout >0:
+ self.VC_Speech_end_timerout-=1
+ if self.VC_Speech_end_timerout <=0:
+ self.VC_Speech_end_timerout = 0
+ self.AI_client_VC_end_speech()#发送说话终止
#VC开始
def AI_VC_start(self):
print("AI_VC_start1")
#self.aud.aud_tone_play(16,200)#播放按键音
self.LocalRespondingEnded_timerout = 0
self.close_timerout = 0
+
-
- if self.record_data_save_flag == 1:
- try:
- uos.remove('/usr/record_data.pcm')
- except Exception as e:
- usys.print_exception(e)
- self.record_fd = open('/usr/record_data.pcm','w')
#
- if self.AI_client_voice_chat_isconnect == 0:#没连接的时候请求开始
- self.websocket_connect_voice_chat()#连接服务器
- self.AI_client_voice_chat_start_requset()
+ if self.AI_client_VC_isconnect == 0:#没连接的时候请求开始
+ self.websocket_connect_VC()#连接服务器
+ self.AI_client_VC_start_requset()
#utime.sleep_ms(50)
else:
- print("self.voice_chat_state :{}".format(self.voice_chat_state ))
- if self.voice_chat_state > VC_State_SpeechStart:
+ print("self.VC_state :{}".format(self.VC_state ))
+ if self.VC_state > VC_State_SpeechStart:
#客户端打断对话
print("打断对话")
- # self.websocket_deconnect_voice_chat()
- # self.websocket_connect_voice_chat()#连接服务器
- # self.AI_client_voice_chat_start_requset()
- self.AI_client_voice_chat_RequestToSpeak()
- elif self.voice_chat_state == VC_State_Listening:
+ # self.websocket_deconnect_VC()
+ # self.websocket_connect_VC()#连接服务器
+ # self.AI_client_VC_start_requset()
+ self.AI_client_VC_RequestToSpeak()
+ elif self.VC_state == VC_State_Listening:
#直接chat
print("直接chat")
- self.AI_client_voice_chat_RequestToRespond()
+ self.AI_client_VC_RequestToRespond()
+ return
else:
print("异常状态")
- #self.AI_client_voice_chat_RequestToSpeak()
- self.websocket_deconnect_voice_chat()
- self.websocket_connect_voice_chat()#连接服务器
- self.AI_client_voice_chat_start_requset()
- if self.AI_client_voice_chat_isconnect == 0:
+ #self.AI_client_VC_RequestToSpeak()
+ self.websocket_deconnect_VC()
+ self.websocket_connect_VC()#连接服务器
+ self.AI_client_VC_start_requset()
+ if self.AI_client_VC_isconnect == 0:
return
print("AI_VC_start3")
- self.voice_chat_state = VC_State_None
+
+ self.VC_state = VC_State_None
if self.AI_TTS_str == "":#没有tts要播放的时候才开始录音
- self.websocket_connect_asr()
- if self.AI_client_asr_isconnect == 0:
- return
#开始asr录音
self.VC_Speech_Start()
- pass
+ # pass
print("AI_VC_start4")
+
#开始线程
+
+ # if self.AI_VC_send_data_queue_thread_id == 0:
+ # _thread.stack_size(self.Audio_buf_size+8*1024)
+ # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ())
+ # _thread.stack_size(8*1024)
+ # print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id))
+
if self.AI_audio_queue_thread_id ==0:
_thread.stack_size(24*1024)
self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ())
print("AI_VC_start :AI_audio_queue_thread_id :{} ".format(self.AI_audio_queue_thread_id))
else:
print("AI_VC_start :AI_audio_queue_thread_id != 0 ")
- if self.AI_send_data_queue_thread_id == 0:
- _thread.stack_size(self.Audio_buf_size+8*1024)
- self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ())
- _thread.stack_size(8*1024)
- print("AI_VC_start :AI_send_data_queue_thread_id :{} ".format(self.AI_send_data_queue_thread_id))
self._1S_timer.start(1000,1,self._1S_timer_cb)
- self.VC_pingping_timerout = 0
- self.asr_pingping_timerout = 0
+ # self.VC_pingping_timerout = 0
+ # self.asr_pingping_timerout = 0
print("AI_VC_start5")
#开始会话
- def AI_client_voice_chat_start_requset(self):
-
- json_data = \
+ def AI_client_VC_start_requset(self):
+ voice="huoshan::zh_male_wennuanahu_moon_bigtts"
+ try:
+ voice = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["voice"]
+ except Exception as e:
+ usys.print_exception(e)
+ json_data =\
{
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"Start"
+ "id": "event_id",
+ "event_type": "chat.update",
+ "data": {
+ "chat_config": {
+ "auto_save_history": True, #保存历史记录。默认 true
+ #"conversation_id": "1235984as1d54", #conversation_id
+ "user_id": "86952145024", #标识当前与智能体的用户,由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户,不同的 user_id,其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离,可将此参数固定为一个任意字符串
+ "meta_data": {}, #附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。
+ "custom_variables": {}, #智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。
+ "extra_params": {}, #附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。
+ "parameters": {"custom_var_1": "测试"}
},
- "payload":{
- "dialog_id":self.VC_dialog_id,
- "device_id":modem.getDevImei(),
- "user_agent":"python",
- "in_format":"pcm",
- "out_format":"mp3",
- "in_sample_rate":self.VC_record_samplerate,
- "sample_rate":self.VC_play_samplerate,
- "space_time": 150,
- "volume": str(self.VC_TTS_volume),
- "voice":self.VC_TTS_voice_type[str(self.VC_TTS_voice_num)],
- "voice_detection":"enabled",
- "simple_response":True,
- "custom_variables":{
- "bot_name":"{}".format(self.bot_name)
- }
+ "input_audio": { #输入音频格式
+ "format": "pcm", #输入音频格式,支持 pcm/wav/ogg。默认 wav
+ #"codec": "pcm", #输入音频编码。 pcm/opus。默认 pcm
+ "samplate_rate": self.VC_record_samplerate, #采样率
+ "channel": 1, #通道数
+ "bit_depth": 16 #位深
},
-
+ "output_audio": { #输出音频格式
+
+ "codec": "pcm", #pcm/opus 输出音频格式, 默认 pcm
+ "pcm_config": {
+ "sample_rate": self.VC_play_samplerate, #码率
+
+ },
+ "speech_rate": 50, #回复的语速,取值范围 [-50, 100],默认为 0,-50 表示 0.5 倍速,100 表示 2倍速
+ #"voice_id": "zh_female_shaoergushi_mars_bigtts"
+ },
+ "turn_detection": {
+ "type": "server_vad",
+ "prefix_padding_ms": 600,
+ "silence_duration_ms": 500,
+ },
+ }
}
- if self.VC_play_TYPE == VC_play_TYPE_PCM:
- json_data["payload"]["out_format"]='pcm'
- if self.VC_record_TYPE == VC_record_TYPE_AMR :
- json_data["payload"]["in_format"]='amr'
- pass
- if self.VC_mode == 1:
- json_data["payload"]["voice_detection"]='disable'
- self.voice_chat_state = VC_State_None
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
+ # if self.VC_play_TYPE == VC_play_TYPE_PCM:
+ # json_data["payload"]["out_format"]='pcm'
+ # if self.VC_record_TYPE == VC_record_TYPE_AMR :
+ # json_data["payload"]["in_format"]='amr'
+ # pass
+ # if self.VC_mode == 1:
+ # json_data["payload"]["voice_detection"]='disable'
+ self.VC_state = VC_State_None
+ self.AI_client_VC_send(ujson.dumps(json_data))
#开始上传语音
- def AI_client_voice_chat_send_speech(self):
+ def AI_client_VC_send_speech(self):
json_data = \
{
"header":{
},
"payload":
{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
+ #self.AI_client_VC_send(ujson.dumps(json_data))
self.VC_Speech_Start()#开启线程获取录音数据
- self.voice_chat_state = VC_State_SpeechStart
+ self.VC_state = VC_State_SpeechStart
+ def AI_client_VC_input_audio_buffer_append(self,data):
+ json_data = \
+ {
+ "id": "event_id",
+ "event_type": "input_audio_buffer.append",
+ "data": {
+ "delta": ubinascii.b2a_base64(data)
+ }
+ }
+ self.AI_client_VC_send(ujson.dumps(json_data))
#结束上传语音
- def AI_client_voice_chat_end_speech(self):
+ def AI_client_VC_end_speech(self):
json_data = \
{
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"StopSpeech"
- },
- "payload":{
- "dialog_id":self.VC_dialog_id
- }
+ "id": "event_id",
+ "event_type": "input_audio_buffer.complete",
+ "data": {}
}
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
+ self.AI_client_VC_send(ujson.dumps(json_data))
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
- #self.VC_Speech_End()#停止线程录音
+
#通知服务器开始播放
- def AI_client_voice_chat_LocalRespondingStarted(self):
+ def AI_client_VC_LocalRespondingStarted(self):
json_data = \
{
"header":{
"event":"LocalRespondingStarted"
},
"payload":{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
- self.AI_client_voice_chat_send(ujson.dumps(json_data))
+ self.AI_client_VC_send(ujson.dumps(json_data))
#通知服务器播放结束
- def AI_client_voice_chat_LocalRespondingEnded(self):
+ def AI_client_VC_LocalRespondingEnded(self):
json_data = \
{
"header":{
"event":"LocalRespondingEnded"
},
"payload":{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
+ # json_data = \
+ # {
+ # "header":{
+ # "trace_id":self.get_trace_id(),
+ # "event":"AAAAAAAAAAAAAA1"
+ # },
+ # "payload":{
+ # "dialog_id":self.VC_dialog_id,
+ # "session_id": self.session_id ,
+ # }
+ # }
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
# utime.sleep_ms(1)
- # self.AI_client_voice_chat_send(ujson.dumps(json_data))
- self.voice_chat_state = VC_State_End
+ # self.AI_client_VC_send(ujson.dumps(json_data))
+ self.VC_state = VC_State_End
#客户端打断对话
- def AI_client_voice_chat_RequestToSpeak(self):
+ def AI_client_VC_RequestToSpeak(self):
json_data = \
{
"header":{
"event":"RequestToSpeak"
},
"payload":{
- "dialog_id":self.VC_dialog_id
+ "dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
}
}
- print("AI_client_voice_chat_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ print("AI_client_VC_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
# utime.sleep_ms(1)
#请求TTS或者chat事件
- def AI_client_voice_chat_RequestToRespond(self):
+ def AI_client_VC_RequestToRespond(self):
+ self.session_id = self.get_session_id()#调试临时打开
json_data = \
{
"header":{
},
"payload":{
"dialog_id":self.VC_dialog_id,
+ "session_id": self.session_id ,
"type":"transcript",#prompt是跳过asr,transcript是跳过asr和大模型
"text":""
}
}
- print("AI_client_voice_chat_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ print("AI_client_VC_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ # if self.VC_state == VC_State_RequestToRespond:
+ # print("AI_client_VC_RequestToRespond 重复 tts_str:{}\nasr_str:{}".format(self.AI_TTS_str,self.AI_ASR_str))
+ self.VC_state = VC_State_RequestToRespond
if self.AI_TTS_str != "":
json_data["payload"]["text"] = self.AI_TTS_str
json_data["payload"]["type"] = "transcript"
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
self.AI_TTS_str = ""
elif self.AI_ASR_str != "":
json_data["payload"]["text"] = self.AI_ASR_str
json_data["payload"]["type"] = "prompt"
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
+ # if dev_type != "7PIN" :
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone})
+ #
#self.AI_ASR_str = ""
# utime.sleep_ms(1)
+ def chenggong_tone(self):
+ EventMesh.publish("audio_montage_play",["chenggong.mp3"])
+ def send_tone(self):
+ EventMesh.publish("audio_montage_play",["send_tone.mp3"])
#给服务器回应ack
- def AI_client_voice_chat_Read(self):
+ def AI_client_VC_Read(self):
json_data = \
{
"header":{
"dialog_id":self.VC_dialog_id
}
}
- print("AI_client_voice_chat_Read!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ print("AI_client_VC_Read!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
#for i in range(6):
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
# utime.sleep_ms(1)
- if self.AI_client_voice_chat != None and self.AI_client_voice_chat_isconnect == 1:
- self.AI_client_voice_chat.send(ujson.dumps(json_data))
- #发送数据队列
- def AI_send_data_queue_thread(self):
- print("AI_send_data_queue_thread:start")
- count_t = 0
- while True:
- if self.AI_send_data_queue.empty() :#不能去掉,去掉会卡死
- count_t+=1
- # if count_t%200 == 0:
- # print("self.AI_send_data_queue.empty")
- utime.sleep_ms(1)
- else:
- #data[0]是websocket连接对象编号,data[1]是数据
- #print("AI_send_data_queue_thread:get")
- data = self.AI_send_data_queue.get()
- #print("AI_send_data_queue_thread:num{} len{}".format(data[0],len(data[1])))
- if data != None:
- try:
- #data["func"](data["data"])
- # 发送数据
- #bytes_data = bytes(data[1])
- #data[0].send(data[1])
- #print("AI_send_data_queue_thread:len:{}".format(len(data[1])))
- #print("AI_send_data_queue_thread on line asr recv :{} vc recv:{}".format(_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_client_voice_chat_recv_id)))
- if data[0] == AI_client_voice_chat_num:
- self.VC_pingping_timerout = 0
- if isinstance(data[1], str):#是字符串
- print("VC VC: send_data:{}".format(data[1]))
- #print("VC: send_data len:{}".format(len(data[1])))
- if self.AI_client_voice_chat != None and self.AI_client_voice_chat_isconnect == 1:
- self.AI_client_voice_chat.send(data[1])
- #print("VC: send_data end")
-
- if data[0] == AI_client_asr_num:
- self.asr_pingping_timerout = 0
- if isinstance(data[1], str):#是字符串
- print("ASR ASR: send_data:{}".format(data[1]))
- if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
- self.AI_client_asr.send(data[1])
- #print("VC: send_data end")
- except Exception as e:
- print("DeviceInfo_queue_thread:ERROR:{}".format(e))
- usys.print_exception(e)
- if data[0] == AI_client_voice_chat_num:
- #self.websocket_error()
- pass
- #self.websocket_deconnect_voice_chat()
- self.AI_client_voice_chat_isconnect = 0
- try:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
- #self.websocket_deconnect_voice_chat()
- except Exception as e: #网络连接异常
- usys.print_exception(e)
- if data[0] == AI_client_asr_num:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连
-
+ if self.AI_client_VC != None and self.AI_client_VC_isconnect == 1:
+ self.AI_client_VC.send(ujson.dumps(json_data))
+
############################################
+ #关闭音频播放线程
+ def AI_audio_queue_thread_close(self):
+ print("AI_audio_queue_thread_close1!!!!!!!!!!!!!!!!!!!!!!")
+ if self.AI_audio_queue_thread_id != 0:
+ count =500
+ while True:
+ count -= 1
+ if self.AI_audio_queue_thread_lock == 0 or count <=0:
+ break
+ else:
+ self.AI_audio_queue_thread_lock = 2
+ print("AI_audio_queue_thread going:{}...".format(count))
+ utime.sleep_ms(1)
+ self.AI_audio_queue_thread_lock = 0
+ print("AI_audio_queue_thread_close2!!!!!!!!!!!!!!!!!")
+ try:
+ _thread.stop_thread(self.AI_audio_queue_thread_id)
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_audio_queue_thread_id = 0
# 音频队列
def AI_audio_queue_thread(self):
print("AI_audio_queue_thread start")
count = 0
while True:
try:
- # if self.AI_send_data_queue_thread_id == 0:
- # break
- # print("AI_audio_queue_thread")
+ if self.AI_audio_queue_thread_lock == 2:
+ print("AI_audio_queue_thread 该退出了")
+ break
+ #
+ count+=1
+ if count%500 == 1:
+ print("AI_audio_queue_thread on")
+ utime.sleep_ms(1)
+ #print("AI_audio_queue_thread")
if self.AI_audio_queue.empty() :
- utime.sleep_ms(1)
- count+=1
- if count%5000 == 1:
- print("AI_audio_queue_thread on")
+ self.AI_audio_queue_thread_lock = 0
+
+
else:
+ self.AI_audio_queue_thread_lock = 1
data = self.AI_audio_queue.get()
self.close_timerout = 0
if self.play_flag == 0:
self.play_flag =1
- print("AI_client_voice_chat_LocalRespondingStarted!!!")
- self.AI_client_voice_chat_LocalRespondingStarted()#通知服务器开始播放
+ print("AI_client_VC_LocalRespondingStarted!!!")
+ self.AI_client_VC_LocalRespondingStarted()#通知服务器开始播放
#self.AI_client_tts_data_len=len(data)
- print("audio_queue:len:{},data{}".format(len(data[0]),len(data[1])))
+ print("audio_queue:len:{}".format(len(data[0])))
if len(data[0]) > 10:
try:
if self.VC_play_TYPE == VC_play_TYPE_PCM:
- if self.VC_play_samplerate == 8000:
- tmp= self.aud.playStream(1,data[0] )
- elif self.VC_play_samplerate == 16000:
+ # if self.VC_play_samplerate == 8000:
+ # tmp= self.aud.playStream(1,data[0] )
+ # elif self.VC_play_samplerate == 16000:
ret = self.play_pcm.stream_write(write_buf,len(write_buf))
#ret= self.aud.playStream(1, data[0])#播放音频流
self.tts_out_data_len += ret
- print("play_pcm.stream_write:{}".format(self.tts_out_data_len))
+ #print("play_pcm.stream_write:{}".format(self.tts_out_data_len))
elif self.VC_play_TYPE == VC_play_TYPE_MP3:
tmp= self.aud.playStream(3, data[0])#播放音频流
# tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流
# print("3playStream:tmp:{} !!!!!!!!!!!!".format(tmp))
- #print("出:{},{}!!!".format(len(data[0]),self.AI_client_tts_data_len))
+
mem = gc.mem_free()
#print('1剩余内存RAM:{} KB'.format(mem / 1024))
except Exception as e:
print("AI_audio_queue_thread:ERROR:")
usys.print_exception(e)
- # if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
+ # if self.VC_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
# #通知服务器播放结束
- # self.AI_client_voice_chat_LocalRespondingEnded()
+ # self.AI_client_VC_LocalRespondingEnded()
except Exception as e:
print("AI_audio_queue_thread:ERROR:")
usys.print_exception(e)
+ self.AI_audio_queue_thread_lock = 0
#print("AI_audio_queue_thread:exit")
def factory_mode(self):
print("factory_mode")
EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
EventMesh.publish("publish_AI_btnInfo",{"func":self.factory_start})
def factory_start(self):
- self.factory_timer.start(1000, 1, self.factory_timer_cb)
+ self.factory_timer.start(3000, 1, self.factory_timer_cb)
def factory_timer_cb(self, *args, **kwargs):
print("factory_timer_cb play......")
- self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+ EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
def Close(self):
self.VC_Thinking_timerout = 0
self.AI_ASR_str = ""
self.AI_ASR_str_tmp = ""
self.AI_ASR_flag = 0
+ self.AI_ASR_check_timeout = 0
+ self.AI_ASR_error_timeout = 0
print("ai_VC Close1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
EventMesh.publish("close_led")
self.tts_in_data_len = 0
self.tts_out_data_len = 0
+ #必须先销毁线程,不然线程会容易报错
+ try:
+ self.AI_ASR_send_data_queue_thread_close()#销毁ASR发送线程
+ except Exception as e:
+ usys.print_exception(e)
+ try:
+ self.AI_audio_queue_thread_close()#销毁音频线程
+ except Exception as e:
+ usys.print_exception(e)
+ try:
+ self.AI_VC_send_data_queue_thread_close()#销毁数据发送线程
+ except Exception as e:
+ usys.print_exception(e)
+ self.VC_Speech_End()
print("ai_VC Close1.1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
self.VC_init()
- self.VC_Speech_End()
+
print("ai_VC Close1.2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- if self.AI_send_data_queue.empty()!=True:
- self.AI_send_data_queue.clear()
- print("ai_VC Close1.3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
try:
- #销毁线程
- if self.AI_audio_queue_thread_id != 0:
- try:
- _thread.stop_thread(self.AI_audio_queue_thread_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_audio_queue_thread_id = 0
- if self.AI_send_data_queue_thread_id != 0:
- try:
- _thread.stop_thread(self.AI_send_data_queue_thread_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_send_data_queue_thread_id = 0
-
-
- except Exception as e:
- usys.print_exception(e)
- print("ai_VC Close2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- try:
- self.websocket_deconnect_voice_chat()
+ self.websocket_deconnect_asr()
except Exception as e:
usys.print_exception(e)
- print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
try:
- self.websocket_deconnect_asr()
+ self.websocket_deconnect_VC()
except Exception as e:
usys.print_exception(e)
+ print("ai_VC Close1.3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
+ print("ai_VC Close2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+
+
self.AI_ASR_timer.stop()
self._1S_timer.stop()
self.factory_timer.stop()
if self.play_data_save_flag == 1:
if self.play_fd !=None:
self.play_fd.close()
+ print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ self.AI_ASR_send_buf_len = 0
+ #self.AI_WS_connect_Queue.put(self.AI_client_VC)
+
+ # try:
+ # while True:
+ # if self.AI_WS_connect_Queue.empty()!=True:
+ # AI_WS_connect = self.AI_WS_connect_Queue.get()
+ # if AI_WS_connect :
+ # try:
+ # AI_WS_connect._close()
+ # AI_WS_connect = None
+ # except Exception as e:
+ # usys.print_exception(e)
+ # else:
+ # print("websocket链接已为空")
+ # else:
+ # break
+ # except Exception as e:
+ # usys.print_exception(e)
+
def VC_init2(self):
self.VC_init()
- if self.AI_send_data_queue.empty()!=True:
- self.AI_send_data_queue.clear()
+
print("ai_VC VC_init2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
try:
- self.websocket_deconnect_voice_chat()
+ self.websocket_deconnect_VC()
except Exception as e:
usys.print_exception(e)
print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
self._1S_timer.stop()
-
-
- def VC_init(self):
-
- print("VC_init:AI_send_data_queue:size:{}".format(self.AI_send_data_queue.size()))
+ if self.AI_VC_send_data_queue.empty()!=True:
+ self.AI_VC_send_data_queue.clear()
+ if self.AI_ASR_send_data_queue.empty()!=True:
+ self.AI_ASR_send_data_queue.clear()
+ self.AI_ASR_send_buf_len = 0
if self.AI_audio_queue.empty()!=True:
self.AI_audio_queue.clear()
+ def VC_init(self):
+
+ print("VC_init:AI_VC_send_data_queue:size:{}".format(self.AI_VC_send_data_queue.size()))
+
print("VC_init2")
#self.VC_Speech_End()
self.VC_Play_End()
print("VC_init4")
-
+ if self.AI_audio_queue.empty()!=True:
+ self.AI_audio_queue.clear()
# num = EventMesh.publish("get_volum_size")
# if num == None:
# num = 8