UNPKG

@libs-scripts-mep/mpai

Version:

Inference MPAI client

189 lines (143 loc) 7.11 kB
import Log from "../../script-loader/utils-script.js" import FWLink from "../../daq-fwlink/FWLink.js" export class MPAI { static port = 8866 /**@type {WebSocket} */ static ws = new WebSocket(`ws://localhost:${this.port}`) /**@type {{error: string; tag: string; image: string; counts: string; centers: string; classes: string; fingerprint: string} | {info: string} | {error: string} | null} */ static serverResponse = null static async connect(url = `ws://localhost:${this.port}`) { if (this.ws && this.ws.readyState === WebSocket.OPEN) { console.warn(`🟢 Serial client already connected`) return true } return new Promise((resolve, reject) => { this.ws = new WebSocket(url) this.setCallbacks() this.ws.onopen = () => { console.warn(`🟢 Conectado ao servidor mpai na porta ${this.port}`) resolve(true) } this.ws.onerror = (error) => { console.warn(`Erro no WebSocket: ${error.message}`) reject(error) } this.ws.onclose = () => { console.warn(`🔴 Desconectado do servidor na porta ${this.port}`) this.ws = null reject(new Error('WebSocket closed')) } }) } static async delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)) } static setCallbacks() { if (!this.ws) return this.ws.onopen = () => { console.warn(`🟢 Conectado ao servidor mpai na porta ${this.port}`) } this.ws.onclose = () => { console.warn(`🔴 Desconectado do servidor mpai na porta ${this.port}`) this.ws = null // Limpar ws para permitir reconexão } this.ws.onerror = (error) => { console.warn(`Erro no WebSocket: ${error.message}`) // Não rejeitar aqui, pois a reconexão será tentada em sendRequest } this.ws.onmessage = (event) => { try { const result = JSON.parse(event.data) MPAI.serverResponse = result } catch (error) { console.log(error) } } } static async infer(base64Img, tag, confidence, referencePath) { if (MPAI.ws == null || MPAI.ws.readyState != WebSocket.OPEN) { await MPAI.connect() } MPAI.serverResponse = null // Remove o cabeçalho 'data:image/xxx;base64,' se existir const cleanBase64 = base64Img.replace(/^data:image\/\w+;base64,/, '') MPAI.ws.send(JSON.stringify({ image: cleanBase64, tag, confidence, reference_path: referencePath })) while (MPAI.serverResponse == null) { await MPAI.delay(100) } return MPAI.serverResponse } static async loadModel(modelPath) { MPAI.serverResponse = null MPAI.ws.send(JSON.stringify({ model_path: modelPath })) while (MPAI.serverResponse == null) { await MPAI.delay(100) } return MPAI.serverResponse } static async killServer() { MPAI.ws.send(JSON.stringify({ kill: true })) } static async delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)) } static { window.MPAI = MPAI; MPAI.connect() } } export class MPAIServer { static debugMode = true static async delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)) } static async init(depCheckerFilePath, serverFilePath) { await MPAIServer.checkDependencies(depCheckerFilePath) await MPAIServer.startWebsocket(serverFilePath) await MPAI.connect() } static async startWebsocket(pyFilePath = MPAIServer.getScriptPath() + '/node_modules/@libs-scripts-mep/mpai/apps/mpai_server.py') { const start = Date.now() while (true) { const elapsed = Date.now() - start if (MPAI.ws?.readyState === WebSocket.OPEN) { Log.warn(`✅ MPAI server already running on port ${MPAI.port}`, Log.Colors.Orange.Orange) return { success: true, msg: "MPAI server already running on port " + MPAI.port } } else if (elapsed > 1000) { Log.warn(`⚙️ Starting MPAI server on port ${MPAI.port}`, Log.Colors.Orange.Orange) FWLink.runInstructionS("EXEC", ["Python", pyFilePath, "true", "true"]) return Promise.race([ new Promise((resolve) => { const id = FWLink.PVIEventObserver.add((message, params) => { const msg = params?.[0] if (MPAIServer.debugMode && msg.includes("[MPAI SERVER]")) { Log.warn(msg, Log.Colors.Brown.SandyBrown) } if (msg.includes("[MPAI SERVER]") && msg?.includes("Subindo Servidor MPAI na porta")) { FWLink.PVIEventObserver.remove(id) resolve({ success: true, msg }) } }, "PVI.Sniffer.sniffer.PID_") }), new Promise((resolve) => setTimeout(() => { resolve({ success: false, msg: `❌ MPAI server failed to start on port ${MPAI.port}` }) }, 10000) ) ]) } await MPAI.delay(100) } } static getScriptPath() { const pathC = location.pathname.slice(location.pathname.indexOf("C:/"), location.pathname.lastIndexOf("/")) const pathI = location.pathname.slice(location.pathname.indexOf("I:/"), location.pathname.lastIndexOf("/")) if (pathC.length > 0) { return pathC } else if (pathI.length > 0) { return pathI } } static async checkDependencies(pyFilePath = MPAIServer.getScriptPath() + '/node_modules/@libs-scripts-mep/mpai/core/compat.py') { return new Promise((resolve) => { const id = FWLink.PVIEventObserver.add((message, params) => { const msg = params?.[0] if (MPAIServer.debugMode && msg.includes("[MPAI DEP]")) { Log.warn(msg, Log.Colors.Brown.SandyBrown) } if (msg.includes("[MPAI DEP]") && msg.includes("Package version check and update completed.")) { FWLink.PVIEventObserver.remove(id) Log.console("MPAI: Dependências instaladas com sucesso.", Log.Colors.Green.SpringGreen) resolve({ success: true, msg: msg, }) } }, "PVI.Sniffer.sniffer.PID_") setTimeout(() => { FWLink.runInstructionS("EXEC", ["Python", pyFilePath, "true", "true"]) }, 300) }) } static { window.MPAIServer = MPAIServer } }