@libs-scripts-mep/mpai
Version:
Inference MPAI client
158 lines (123 loc) • 6.6 kB
JavaScript
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 inferenceResult = null
static inferenceError = null
static inferenceInfo = null
static async connect() {
await this.delay(1000)
if (MPAI.ws.readyState != WebSocket.OPEN) {
MPAI.ws = new WebSocket(`ws://localhost:${this.port}`)
MPAI.ws.onopen = () => { Log.warn(`🟢 Connected to MPAI server on port ${MPAI.port}`, Log.Colors.Green.MediumSpringGreen), this.connect() }
MPAI.ws.onclose = () => { Log.warn(`🔴 Disconnected from MPAI server on port ${MPAI.port}`, Log.Colors.Red.IndianRed) }
MPAI.ws.onerror = (error) => { console.error(error) }
MPAI.ws.onmessage = (event) => {
try {
const result = JSON.parse(event.data)
if ("error" in result && "tag" in result && "image" in result && "counts" in result && "centers" in result && "classes" in result && "fingerprint" in result) {
MPAI.inferenceResult = result
console.log(result)
} else if ("info" in result) {
MPAI.inferenceInfo = result
console.warn(result.info)
} else if ("error" in result) {
MPAI.inferenceError = result
console.error(result.error)
} else {
console.log(event.data)
}
} catch (error) {
console.log(error)
}
}
} else {
console.warn("🟢 MPAI client already connected")
}
}
static async infer(base64Img, tag) {
MPAI.inferenceResult = null
MPAI.inferenceError = null
MPAI.inferenceInfo = 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 }))
while (MPAI.inferenceResult == null) { await MPAI.delay(100) }
return MPAI.inferenceResult
}
static loadModel(modelPath) {
MPAI.ws.send(JSON.stringify({ model_path: modelPath }))
}
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/inference/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/inference/infer_deps.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 }
}