From 9c4d8d40414d6fbebdc8cc12878ccc0df7c6fa0e Mon Sep 17 00:00:00 2001 From: nguyentrungthat <80239428+nguentrungthat@users.noreply.github.com> Date: Wed, 5 Nov 2025 10:49:21 +0700 Subject: [PATCH] Update --- BACKEND/app/services/line_connection.ts | 34 +++++++++++++++++ BACKEND/providers/socket_io_provider.ts | 43 ++++++++++++++++++++++ FRONTEND/src/components/DrawerScenario.tsx | 4 +- FRONTEND/src/components/ModalTerminal.tsx | 3 +- 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/BACKEND/app/services/line_connection.ts b/BACKEND/app/services/line_connection.ts index 8175eae..f864ff9 100644 --- a/BACKEND/app/services/line_connection.ts +++ b/BACKEND/app/services/line_connection.ts @@ -51,6 +51,7 @@ export default class LineConnection { private isRunningScript: boolean private connecting: boolean private waitingScenario: boolean + private outputScenario: string constructor(config: LineConfig, socketIO: any) { this.config = config @@ -60,6 +61,7 @@ export default class LineConnection { this.isRunningScript = false this.connecting = false this.waitingScenario = false + this.outputScenario = '' } connect(timeoutMs = 5000) { @@ -94,6 +96,8 @@ export default class LineConnection { if (this.isRunningScript) { this.waitingScenario = true this.outputBuffer += message + if (!this.config.inventory) + this.outputScenario = this.outputScenario.slice(-3000) + message } if (message.includes('--More--')) this.writeCommand(' ') @@ -114,6 +118,7 @@ export default class LineConnection { lineId: id, data: message, }) + if (!this.config.inventory) this.getInventory(this.outputScenario) appendLog(message, this.config.stationId, this.config.lineNumber, this.config.port) }) @@ -219,6 +224,7 @@ export default class LineConnection { const timeoutTimer = setTimeout(() => { this.isRunningScript = false this.outputBuffer = '' + this.outputScenario = '' this.config.output += 'Timeout run scenario' this.socketIO.emit('line_output', { stationId: this.config.stationId, @@ -245,6 +251,7 @@ export default class LineConnection { } else clearTimeout(timeoutTimer) this.isRunningScript = false this.outputBuffer = '' + this.outputScenario = '' appendLog( `\n---end-scenarios---${now}---\n`, this.config.stationId, @@ -457,4 +464,31 @@ export default class LineConnection { }) } } + + getInventory = (log: string) => { + const data = textfsmResults(log, 'show inventory') + try { + data.forEach((item) => { + if (item?.textfsm && isValidJson(item?.textfsm)) { + if (['show inventory', 'sh inventory', 'show inv', 'sh inv'].includes(item.command)) { + this.config.inventory = JSON.parse(item.textfsm)[0] + } + item.textfsm = JSON.parse(item.textfsm) + } + }) + if (this.config.inventory) { + this.config.data = data + this.socketIO.emit('data_textfsm', { + stationId: this.config.stationId, + lineId: this.config.id, + data, + inventory: this.config.inventory || null, + latestScenario: this.config.latestScenario || null, + }) + this.outputScenario = '' + } + } catch (error) { + console.log(error) + } + } } diff --git a/BACKEND/providers/socket_io_provider.ts b/BACKEND/providers/socket_io_provider.ts index ff4670a..3345d90 100644 --- a/BACKEND/providers/socket_io_provider.ts +++ b/BACKEND/providers/socket_io_provider.ts @@ -1,3 +1,4 @@ +import net from 'node:net' import fs from 'node:fs' import { Server as SocketIOServer } from 'socket.io' import http from 'node:http' @@ -8,6 +9,7 @@ import { CustomServer, CustomSocket } from '../app/ultils/types.js' import Line from '#models/line' import Station from '#models/station' import APCController from '#services/apc_connection' +import { sleep } from '../app/ultils/helper.js' interface HandleOptions { command?: string @@ -287,6 +289,10 @@ export class WebSocketIo { }, socket ) + // 👉 Bước 1: clear line trước khi connect + if (line.lineClear && line.lineClear > 0) + await this.clearLineBeforeConnect(station.id, line.lineClear) + this.lineMap.set(line.id, lineConn) await lineConn.connect() lineConn.writeCommand('\r\n\r\n') @@ -397,4 +403,41 @@ export class WebSocketIo { console.log(error) } } + + private async clearLineBeforeConnect(stationId: number, clearLine: number) { + const station = await Station.find(stationId) + if (!station) throw new Error(`Station ${stationId} not found`) + + // Kết nối tới station qua Telnet / Socket + const client = new net.Socket() + return new Promise((resolve, reject) => { + client.connect(station.port, station.ip, async () => { + console.log( + `Connected to station ${station.name} (${station.ip}) to clear line ${clearLine}` + ) + // Gửi lệnh clear line + client.write(`clear line ${clearLine}\r\n`) + await sleep(500) + client.write(`\r\n\r\n`) + }) + + client.on('data', (data) => { + const output = data.toString() + if (output.includes('Clear completed') || output.includes('OK')) { + console.log(`Line ${clearLine} cleared successfully.`) + client.destroy() + resolve() + } + }) + + client.on('error', (err) => { + console.error(`Error clearing line ${clearLine}:`, err) + reject(err) + }) + + client.on('close', () => { + console.log(`Station connection closed (line ${clearLine})`) + }) + }) + } } diff --git a/FRONTEND/src/components/DrawerScenario.tsx b/FRONTEND/src/components/DrawerScenario.tsx index c074928..90bffe7 100644 --- a/FRONTEND/src/components/DrawerScenario.tsx +++ b/FRONTEND/src/components/DrawerScenario.tsx @@ -268,7 +268,7 @@ function DrawerScenario({ marginBottom: "8px", }} > - + /> */}
- Line number: {line?.line_number || ""} + Line number:{" "} + {line?.lineNumber || line?.line_number || ""} - {line?.port || ""}