diff --git a/assistant/package.json b/assistant/package.json index cb1fb6c..dff73b2 100644 --- a/assistant/package.json +++ b/assistant/package.json @@ -10,7 +10,7 @@ ], "author": "abearxiong (https://www.xiongxiao.me)", "license": "MIT", - "packageManager": "pnpm@10.26.1", + "packageManager": "pnpm@10.26.2", "type": "module", "files": [ "dist", @@ -76,7 +76,7 @@ "access": "public" }, "dependencies": { - "@kevisual/ha-api": "^0.0.1", + "@kevisual/ha-api": "^0.0.4", "@kevisual/video-tools": "^0.0.12", "eventemitter3": "^5.0.1", "lowdb": "^7.0.1", diff --git a/assistant/src/services/asr/qwen-asr.ts b/assistant/src/services/asr/qwen-asr.ts index e1d51fb..57c4984 100644 --- a/assistant/src/services/asr/qwen-asr.ts +++ b/assistant/src/services/asr/qwen-asr.ts @@ -3,7 +3,7 @@ import { QwenAsrRelatime } from "@kevisual/video-tools/src/asr/index.ts"; import { Listener, WebSocketListenerFun, WebSocketReq } from "@kevisual/router"; import { lightHA } from "@/routes/ha-api/ha.ts"; -const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelatime, msgId: string }>, res) => { +const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelatime, msgId: string, startTime?: number }>, res) => { const { ws, emitter, id, data } = req; let asr = ws.data.asr; @@ -22,7 +22,7 @@ const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelati ws.send(JSON.stringify({ type: 'asr', code: 200, message: 'asr服务已连接', time: Date.now() })); if (!asr) return; asr.emitter.on('message', (message) => { - console.log('ASR message', message); + // console.log('ASR message', message); }); asr.emitter.on('partial', (message) => { // console.log('ASR message', message); @@ -39,6 +39,8 @@ const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelati asr.emitter.on('result', async ({ text, raw }) => { let msgId = ws.data.msgId; ws.data.msgId = Math.random().toString(36).substring(2, 10); + const endTime = Date.now(); + console.log('cost time', ws.data.startTime ? (endTime - ws.data.startTime) : 0); ws.send(JSON.stringify({ type: 'result', msgId: msgId, @@ -63,11 +65,12 @@ const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelati if (obj.type) { try { const search = await lightHA.searchLight(obj.appName || ''); + console.log('searchTime', Date.now() - endTime); if (search.id) { - lightHA.toggleLight({ entity_id: search.id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); + await lightHA.runService({ entity_id: search.id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); } else if (search.hasMore) { const [first] = search.result; - lightHA.toggleLight({ entity_id: first.entity_id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); + await lightHA.runService({ entity_id: first.entity_id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); } else { console.log('未找到对应设备:', obj.appName); } @@ -76,6 +79,7 @@ const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelati console.error('控制失败', e); } } + console.log('toogle light time', Date.now() - endTime); }); asr.start(); } @@ -84,18 +88,26 @@ const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelati } const isConnected = await asr.checkConnected(); if (!isConnected) return; - console.log('ASR receive data', 'has voice', !!data?.voice); if (data?.type === 'blankVoice') { asr.sendBlank(); + console.log('ASR receive data', 'blank voice'); } else if (data?.voice) { - console.log('ASR receive voice', data.voice.slice(0, 30)); + if (!data?.isRelatime) { + console.log('ASR receive data', 'has voice', !!data?.voice); + } const isBrowserFormat = data.format === 'float32'; + const time = data?.time || 0; + if (time) { + console.log('receiveDelay', Date.now() - time); + } let voice: Buffer; if (isBrowserFormat) { voice = await asr.fixBrowerBuffer(data.voice); } else { voice = Buffer.from(data.voice, 'base64'); } + console.log('sendTime', Date.now()); + ws.data.startTime = Date.now(); asr.sendBuffer(voice); } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55ae963..efa9bdb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,7 +40,7 @@ importers: version: 7.7.3 unstorage: specifier: ^1.17.3 - version: 1.17.3(idb-keyval@6.2.1) + version: 1.17.3(idb-keyval@6.2.2) devDependencies: '@kevisual/dts': specifier: ^0.0.3 @@ -112,8 +112,8 @@ importers: assistant: dependencies: '@kevisual/ha-api': - specifier: ^0.0.1 - version: 0.0.1 + specifier: ^0.0.4 + version: 0.0.4 '@kevisual/video-tools': specifier: ^0.0.12 version: 0.0.12(dotenv@17.2.3)(supports-color@10.2.2) @@ -131,7 +131,7 @@ importers: version: 6.0.14(supports-color@10.2.2) unstorage: specifier: ^1.17.3 - version: 1.17.3(idb-keyval@6.2.1) + version: 1.17.3(idb-keyval@6.2.2) devDependencies: '@kevisual/ai': specifier: ^0.0.19 @@ -216,7 +216,7 @@ importers: dependencies: '@astrojs/mdx': specifier: ^4.3.13 - version: 4.3.13(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2)) + version: 4.3.13(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2)) '@astrojs/react': specifier: ^4.4.2 version: 4.4.2(@types/node@25.0.3)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -225,7 +225,7 @@ importers: version: 3.6.0 '@astrojs/vue': specifier: ^5.1.3 - version: 5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.26(typescript@5.8.2)) + version: 5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.26(typescript@5.8.2)) '@kevisual/api': specifier: ^0.0.5 version: 0.0.5 @@ -258,7 +258,7 @@ importers: version: 6.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) astro: specifier: ^5.16.6 - version: 5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2) + version: 5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -1266,6 +1266,9 @@ packages: '@kevisual/cache@0.0.3': resolution: {integrity: sha512-BWEck69KYL96/ywjYVkML974RHjDJTj2ITQND1zFPR+hlBV1H1p55QZgSYRJCObg3EAV1S9Zic/fR2T4pfe8yg==} + '@kevisual/cache@0.0.4': + resolution: {integrity: sha512-NlyriJ9fC27TgQhWYbEH9hG84R2k0lIofOxo/+nVHN6a6LJSLnVbpDIysRcnH8MI52n/XHfWwLSjeDDL3D1/cQ==} + '@kevisual/context@0.0.4': resolution: {integrity: sha512-HJeLeZQLU+7tCluSfOyvkgKLs0HjCZrdJlZgEgKRSa8XTwZfMAUt6J7qZTbrZAHBlPtX68EPu/PI8JMCeu3WAQ==} @@ -1273,8 +1276,8 @@ packages: resolution: {integrity: sha512-4T/m2LqhtwWEW+lWmg7jLxKFW7VtIAftsWFDDZvh10bZunqFf8iXxChHcVSQWikghJb4cq1IkWzPkvc2l+Asdw==} hasBin: true - '@kevisual/ha-api@0.0.1': - resolution: {integrity: sha512-6wFXbHIVvQhK08XMdsCm5A5P/CrepDiqd4k5x+kwOlhHHhFlu+WbGYh+wxdi4+62+W7WxZK7jjNt2x8ioQEFgg==} + '@kevisual/ha-api@0.0.4': + resolution: {integrity: sha512-ZBtfE/zFieDU7ff9zo4pKR7LDhFEdkDQuYU/uH5ZJkFWke4gOxEIatZcM6CJmgKDjoMLMk2w+gpk8eJqJ42GBw==} '@kevisual/hot-api@0.0.3': resolution: {integrity: sha512-qZ4CNK08StZP4+DR1vWwJhKVDoSXXC+PBFG4ZxtkXF5vO2rybE055zp1n3dg5jo8GwW5wxpqMIG3KBp3pYSTkg==} @@ -3381,6 +3384,9 @@ packages: idb-keyval@6.2.1: resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -5357,12 +5363,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@4.3.13(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))': + '@astrojs/mdx@4.3.13(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))': dependencies: '@astrojs/markdown-remark': 6.3.10 '@mdx-js/mdx': 3.1.1 acorn: 8.15.0 - astro: 5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2) + astro: 5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2) es-module-lexer: 1.7.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -5421,12 +5427,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/vue@5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.26(typescript@5.8.2))': + '@astrojs/vue@5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.26(typescript@5.8.2))': dependencies: '@vitejs/plugin-vue': 5.2.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)) '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)) '@vue/compiler-sfc': 3.5.25 - astro: 5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2) + astro: 5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2) vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2) vite-plugin-vue-devtools: 7.7.9(rollup@4.43.0)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)) vue: 3.5.26(typescript@5.8.2) @@ -6359,6 +6365,12 @@ snapshots: dependencies: idb-keyval: 6.2.1 + '@kevisual/cache@0.0.4': + dependencies: + idb-keyval: 6.2.2 + lru-cache: 11.2.4 + nanoid: 5.1.6 + '@kevisual/context@0.0.4': {} '@kevisual/dts@0.0.3(typescript@5.8.2)': @@ -6372,10 +6384,11 @@ snapshots: transitivePeerDependencies: - typescript - '@kevisual/ha-api@0.0.1': + '@kevisual/ha-api@0.0.4': dependencies: - dotenv: 17.2.3 + '@kevisual/cache': 0.0.4 fuse.js: 7.1.0 + lru-cache: 11.2.4 '@kevisual/hot-api@0.0.3(dotenv@17.2.3)': dependencies: @@ -7898,7 +7911,7 @@ snapshots: astring@1.9.0: {} - astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2): + astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2): dependencies: '@astrojs/compiler': 2.13.0 '@astrojs/internal-helpers': 0.7.5 @@ -7953,7 +7966,7 @@ snapshots: ultrahtml: 1.6.0 unifont: 0.6.0 unist-util-visit: 5.0.0 - unstorage: 1.17.3(idb-keyval@6.2.1) + unstorage: 1.17.3(idb-keyval@6.2.2) vfile: 6.0.3 vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2) vitefu: 1.1.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)) @@ -8114,7 +8127,7 @@ snapshots: centra@2.7.0: dependencies: - follow-redirects: 1.15.9(debug@4.3.7) + follow-redirects: 1.15.9(debug@4.3.7(supports-color@10.2.2)) transitivePeerDependencies: - debug @@ -9086,6 +9099,8 @@ snapshots: idb-keyval@6.2.1: {} + idb-keyval@6.2.2: {} + ieee754@1.2.1: {} ignore@7.0.5: {} @@ -11117,7 +11132,7 @@ snapshots: universalify@2.0.1: {} - unstorage@1.17.3(idb-keyval@6.2.1): + unstorage@1.17.3(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -11128,7 +11143,7 @@ snapshots: ofetch: 1.5.1 ufo: 1.6.1 optionalDependencies: - idb-keyval: 6.2.1 + idb-keyval: 6.2.2 update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: