You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

368 lines
15 KiB

3 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "main_control_service.hpp"
  2. #include "iflytopcpp/core/components/stringutils.hpp"
  3. #include "version.hpp"
  4. using namespace iflytop;
  5. using namespace core;
  6. using namespace std;
  7. /***********************************************************************************************************************
  8. * ============================================================================================================= *
  9. ***********************************************************************************************************************/
  10. #define SET_DEVICE_STATE(id, value, uint) \
  11. receipt["deviceState"][index]["id"] = id; \
  12. receipt["deviceState"][index]["value"] = fmt::format("{}", value); \
  13. receipt["deviceState"][index]["unit"] = uint; \
  14. index++;
  15. /*********************************************************************************************************************
  16. * ============================================================================================================= *
  17. *********************************************************************************************************************/
  18. void MainControlService::initializeVoiceProcess() {
  19. m_beforeWakeupVoiceProcesser->setAmplifyDB(20);
  20. m_beforeasrVoiceProcesser->setAmplifyDB(24);
  21. logger->info("MainControlService::start.....");
  22. /**
  23. * @brief
  24. * 1,
  25. * 1,ASR预处理算法
  26. */
  27. m_audioRecoderService->onRecordData.connect([this](shared_ptr<AudioClip> audioClip) {
  28. if (!audioClip) {
  29. logger->error("onRecordData audioClip is null");
  30. return;
  31. }
  32. m_audioLoggingService->loggerMICVoice(audioClip); // 录音
  33. m_commonVoiceProcesser->writeVoice(audioClip); // 交给通用预处理逻辑
  34. });
  35. m_commonVoiceProcesser->onAfterProcessVoice.connect([this](shared_ptr<AudioClip> audioClip) {
  36. if (!audioClip) {
  37. logger->error("onAfterProcessVoice audioClip is null");
  38. return;
  39. }
  40. m_beforeWakeupVoiceProcesser->writeVoice(audioClip); // 交给唤醒词预处理逻辑
  41. if (m_conversationSession) m_beforeasrVoiceProcesser->writeVoice(audioClip); // 交给asr预处理逻辑
  42. });
  43. /**
  44. * @brief
  45. * 1
  46. */
  47. m_beforeWakeupVoiceProcesser->onAfterProcessVoice.connect([this](shared_ptr<AudioClip> audioClip) {
  48. if (!audioClip) {
  49. logger->error("onAfterProcessVoice audioClip is null");
  50. return;
  51. }
  52. m_audioLoggingService->loggerBeforeWakeupVoice(audioClip);
  53. m_wakeupProcesser->processVoice(audioClip->data(), audioClip->size());
  54. });
  55. /**
  56. * @brief
  57. */
  58. m_wakeupProcesser->onWakeupSignal.connect([this](float wakeup_score) {
  59. logger->info("onWakeupSignal wakeup_score {}", wakeup_score);
  60. /**
  61. * @brief session
  62. */
  63. m_workQueue->enQueue([this]() { constructSession(); });
  64. });
  65. /**
  66. * @brief asr预处理算法回调
  67. */
  68. m_beforeasrVoiceProcesser->onAfterProcessVoice.connect([this](shared_ptr<AudioClip> audioClip) {
  69. if (!audioClip) {
  70. logger->error("onAfterProcessVoice audioClip is null");
  71. return;
  72. }
  73. auto session = m_conversationSession;
  74. if (!session) return;
  75. if (zsteady_clock().elapsedTimeMs(session->getBuildtp()) < 1000) return;
  76. m_audioLoggingService->loggerASRVoice(audioClip);
  77. m_aiuiService->aiuiWrite((const char*)audioClip->data(), audioClip->size());
  78. });
  79. m_aiuiService->onMessage.connect([&](json& rxjson) {
  80. lock_guard<recursive_mutex> lock(m_voiceprocessmutex);
  81. json msg = rxjson;
  82. m_workQueue->enQueue([this, msg]() {
  83. try {
  84. processasrResult(msg);
  85. } catch (const std::exception& e) {
  86. logger->error("processasrResult error:{}", e.what());
  87. }
  88. });
  89. });
  90. m_audioRecoderService->startRecord();
  91. }
  92. void MainControlService::triggerProcessConversationSession() {
  93. m_smartSoundboxPlayer->playConversationTTS(m_conversationSession->getAsrTTSLocalURL(), nullptr);
  94. json nlpResult = m_conversationSession->getNlpResult();
  95. if (nlpResult["data"]["intent"]["shouldEndSession"] == "true") {
  96. logger->info("endSession");
  97. if (m_endsessionTimer->isRunning()) m_endsessionTimer->stop();
  98. endSession();
  99. return;
  100. }
  101. }
  102. void MainControlService::processasrResult_nlp(json& rxjson) {
  103. logger->info("rx nlp:{}", rxjson.dump());
  104. m_conversationSession->setNlpResult(rxjson);
  105. m_smartSoundboxPlayer->playConversationTTS(m_conversationSession->getAsrTTSLocalURL(), nullptr);
  106. }
  107. void MainControlService::processasrResult_tts(json& rxjson) {
  108. /**
  109. * @brief tts数据
  110. */
  111. logger->debug("rx tts:frame {}", rxjson["data"]["json_args"]["frame_id"].get<int>());
  112. bool isendFrame = false;
  113. string ttsurl;
  114. m_aiuiService->parseTTSContent(rxjson, isendFrame, ttsurl);
  115. if (isendFrame) {
  116. logger->info("rx tts end,url={}", ttsurl);
  117. m_conversationSession->setAsrTTSLocalURL(ttsurl);
  118. triggerProcessConversationSession();
  119. }
  120. }
  121. void MainControlService::processasrResult(json rxjson) {
  122. lock_guard<recursive_mutex> lock(m_voiceprocessmutex);
  123. string action = rxjson["action"];
  124. if (action == "started") {
  125. logger->info("processasr: rx started:{}", rxjson.dump());
  126. } else if (action == "error") {
  127. logger->info("processasr: rx error:{}", rxjson.dump());
  128. } else if (action == "vad") {
  129. logger->info("processasr: rx vad:{}", rxjson.dump());
  130. } else if (action == "result") {
  131. string sub = rxjson["data"]["sub"];
  132. if (sub == "nlp") {
  133. /**
  134. * @brief nlp数据
  135. */
  136. processasrResult_nlp(rxjson);
  137. } else if (sub == "tts") {
  138. /**
  139. * @brief tts数据
  140. */
  141. processasrResult_tts(rxjson);
  142. } else if (sub == "iat") {
  143. logger->info("rx iat:{}", rxjson.dump());
  144. } else if (sub == "vad") {
  145. logger->info("rx vad:{}", rxjson.dump());
  146. } else {
  147. logger->info("rx {}:{}", sub, rxjson.dump());
  148. }
  149. } else {
  150. logger->info("rx unkown:{}", rxjson.dump());
  151. }
  152. }
  153. void MainControlService::constructSession() {
  154. /**
  155. * @brief
  156. * 1.
  157. * 2. session还没有结束,session
  158. * 3. asr
  159. * 4. session
  160. * 5. ,10s内无人应答session
  161. */
  162. lock_guard<recursive_mutex> lock(m_voiceprocessmutex);
  163. m_smartSoundboxPlayer->triggerWakeup();
  164. if (m_conversationSession) {
  165. if (m_endsessionTimer->isRunning()) m_endsessionTimer->stop();
  166. endSession();
  167. }
  168. m_conversationSession = make_shared<ConversationSession>();
  169. logger->info("constructSession:============ {} ===========", m_conversationSession->getSessionId());
  170. m_audioLoggingService->triggerWakeup(m_conversationSession->getSessionId());
  171. m_aiuiService->aiuiInit();
  172. if (m_endsessionTimer->isRunning()) m_endsessionTimer->stop();
  173. m_endsessionTimer->setTimeout(
  174. [this]() {
  175. logger->info("no hum voice detected, end session");
  176. endSession();
  177. },
  178. 10000);
  179. }
  180. void MainControlService::endSession() {
  181. lock_guard<recursive_mutex> lock(m_voiceprocessmutex);
  182. if (m_conversationSession) {
  183. m_conversationSession = nullptr;
  184. m_aiuiService->aiuiFinished();
  185. m_aiuiService->aiuiDestroy();
  186. }
  187. m_audioLoggingService->endwakeup();
  188. }
  189. void MainControlService::initialize() {
  190. GET_TO_SERVICE(m_zwebService);
  191. GET_TO_SERVICE(m_deviceIOService);
  192. GET_TO_SERVICE(m_beforeWakeupVoiceProcesser);
  193. GET_TO_SERVICE(m_beforeasrVoiceProcesser);
  194. GET_TO_SERVICE(m_wakeupProcesser);
  195. GET_TO_SERVICE(m_audioRecoderService);
  196. GET_TO_SERVICE(m_audioLoggingService);
  197. GET_TO_SERVICE(m_smartSoundboxPlayer);
  198. GET_TO_SERVICE(m_aiuiService);
  199. GET_TO_SERVICE(m_commonVoiceProcesser);
  200. m_endsessionTimer.reset(new SimpleTimer("endSessionTimer"));
  201. m_workQueue.reset(new WorkQueue("mainControlServiceVoiceProcessCtrlWQ"));
  202. // 监听从webservice来的websocket消息
  203. m_zwebService->startWork([this](const json& command, json& receipt) {
  204. try {
  205. processReceiveMessage(kzwebService, command, receipt);
  206. } catch (const std::exception& e) {
  207. logger->error("process message fail {}", string(e.what()));
  208. } catch (...) {
  209. logger->error("process message fail {}", "catch unknown exception");
  210. }
  211. });
  212. /**
  213. * @brief
  214. */
  215. initializeVoiceProcess();
  216. };
  217. void MainControlService::processReceiveMessage(fromwhere_t fromwhere, const json& in, json& receipt) {
  218. logger->info("process receive message from {},{}", fromwhere2str(fromwhere), in.dump());
  219. if (in["command"] == "getVersion") {
  220. receipt["version"] = VERSION;
  221. }
  222. /*********************************************************************************************************************
  223. * ================================================================================================= *
  224. *********************************************************************************************************************/
  225. else if (in["command"] == "loggerSetLevel") {
  226. int loggerLevel = in["loggerLevel"];
  227. string loggerName = in["loggerName"];
  228. logger->info("loggerSetLevel {} {}", loggerName, loggerLevel);
  229. SpdLoggerFactory::Instance().createLogger(loggerName)->set_level((level::level_enum)loggerLevel);
  230. } else if (in["command"] == "loggerGetAllLoggers") {
  231. receipt["loggers"] = SpdLoggerFactory::Instance().loggerNames();
  232. }
  233. /*********************************************************************************************************************
  234. * =============================================================================================================*
  235. *********************************************************************************************************************/
  236. else if (in["command"] == "getDeviceState") {
  237. #if 0
  238. {
  239. "deviceState":[
  240. {
  241. "id":"wind_speed",
  242. "value":"12",
  243. "unit":"m/s"
  244. }
  245. ]
  246. }
  247. #endif
  248. int index = 0;
  249. DeviceIOService::env_sensor_state_t env = m_deviceIOService->getEnvSensorState();
  250. SET_DEVICE_STATE("wind_speed", env.wind_speed, "m/s");
  251. SET_DEVICE_STATE("wind_direction", env.wind_direction, "m/s");
  252. SET_DEVICE_STATE("temperature", env.temperature, "");
  253. SET_DEVICE_STATE("humidity", env.humidity, "%");
  254. SET_DEVICE_STATE("noise", env.noise, "dB");
  255. SET_DEVICE_STATE("pm2_5", env.pm2_5, "ug/m³");
  256. SET_DEVICE_STATE("pm10", env.pm10, "ug/m³");
  257. SET_DEVICE_STATE("co2", env.co2, "ppm");
  258. SET_DEVICE_STATE("atmospheric_pressure", env.atmospheric_pressure, "hPa");
  259. SET_DEVICE_STATE("tvoc", env.tvoc, "ppm");
  260. SET_DEVICE_STATE("hcho", env.hcho, "mg/m³");
  261. SET_DEVICE_STATE("light_intensity", env.atmospheric_pressure, "lux");
  262. SET_DEVICE_STATE("InterTemperature", m_deviceIOService->getInterTemperature(), "");
  263. SET_DEVICE_STATE("fan1powerRate", m_deviceIOService->fanGetState(0), "%");
  264. SET_DEVICE_STATE("fan2powerRate", m_deviceIOService->fanGetState(1), "%");
  265. auto relaystate = m_deviceIOService->relayStateGet();
  266. SET_DEVICE_STATE("routerPower", relaystate.getState(DeviceIOService::kRouterPower), "-");
  267. SET_DEVICE_STATE("touchScreenPower", relaystate.getState(DeviceIOService::kTouchScreenPower), "-");
  268. SET_DEVICE_STATE("usbChargerPower", relaystate.getState(DeviceIOService::kUsbChargerPower), "-");
  269. SET_DEVICE_STATE("cameraPower", relaystate.getState(DeviceIOService::kCameraPower), "-");
  270. SET_DEVICE_STATE("lightPower", relaystate.getState(DeviceIOService::kLightPower), "-");
  271. auto inputdeviceState = m_deviceIOService->getinputState();
  272. SET_DEVICE_STATE("emergency", inputdeviceState.getState(DeviceIOService::kEmergency), "-");
  273. SET_DEVICE_STATE("waterImmersionSensor", inputdeviceState.getState(DeviceIOService::kWaterImmersionSensor), "-");
  274. SET_DEVICE_STATE("humanProximitySensor", inputdeviceState.getState(DeviceIOService::kHumanProximitySensor), "-");
  275. } else if (in["command"] == "relayControl") {
  276. uint32_t type = in["type"];
  277. bool value = in["value"];
  278. m_deviceIOService->relayControl(type, value);
  279. } else if (in["command"] == "fanSetState") {
  280. int id = in["id"];
  281. float power = in["power"];
  282. m_deviceIOService->fanSetState(id, power);
  283. } else if (in["command"] == "relayStateGet") {
  284. auto relaystate = m_deviceIOService->relayStateGet();
  285. receipt["state"]["rawState"] = StringUtils().bytet2Binary(relaystate.state, 32, false);
  286. receipt["state"]["routerPower"] = relaystate.getState(DeviceIOService::kRouterPower);
  287. receipt["state"]["touchScreenPower"] = relaystate.getState(DeviceIOService::kTouchScreenPower);
  288. receipt["state"]["usbChargerPower"] = relaystate.getState(DeviceIOService::kUsbChargerPower);
  289. receipt["state"]["cameraPower"] = relaystate.getState(DeviceIOService::kCameraPower);
  290. receipt["state"]["lightPower"] = relaystate.getState(DeviceIOService::kLightPower);
  291. } else if (in["command"] == "inputStateGet") {
  292. auto inputdeviceState = m_deviceIOService->getinputState();
  293. // logger->info("{}", inputdeviceState.state);
  294. receipt["state"]["rawState"] = StringUtils().bytet2Binary(inputdeviceState.state, 32, false);
  295. receipt["state"]["emergency"] = inputdeviceState.getState(DeviceIOService::kEmergency);
  296. receipt["state"]["waterImmersionSensor"] = inputdeviceState.getState(DeviceIOService::kWaterImmersionSensor);
  297. receipt["state"]["humanProximitySensor"] = inputdeviceState.getState(DeviceIOService::kHumanProximitySensor);
  298. } else if (in["command"] == "idcardread") {
  299. bool state = false;
  300. string info;
  301. m_deviceIOService->idcardread(state, info);
  302. receipt["state"] = state;
  303. receipt["info"] = info;
  304. } else if (in["command"] == "getInterTemperature") {
  305. receipt["temperature"] = m_deviceIOService->getInterTemperature();
  306. } else if (in["command"] == "getEnvSensorState") {
  307. DeviceIOService::env_sensor_state_t env = m_deviceIOService->getEnvSensorState();
  308. receipt["wind_speed"] = env.wind_speed;
  309. receipt["wind_direction"] = env.wind_direction;
  310. receipt["temperature"] = env.temperature;
  311. receipt["humidity"] = env.humidity;
  312. receipt["noise"] = env.noise;
  313. receipt["pm2_5"] = env.pm2_5;
  314. receipt["pm10"] = env.pm10;
  315. receipt["co2"] = env.co2;
  316. receipt["atmospheric_pressure"] = env.atmospheric_pressure;
  317. receipt["tvoc"] = env.tvoc;
  318. receipt["hcho"] = env.hcho;
  319. receipt["light_intensity"] = env.light_intensity;
  320. } else if (in["command"] == "fanGetState") {
  321. // int id = in["id"];
  322. receipt["power"][0] = m_deviceIOService->fanGetState(0);
  323. receipt["power"][1] = m_deviceIOService->fanGetState(0);
  324. }
  325. }