From 990f57a3422f3d7f4e0fe40b10a10d6b4ffcabb1 Mon Sep 17 00:00:00 2001 From: nguyentrungthat <80239428+nguentrungthat@users.noreply.github.com> Date: Wed, 5 Nov 2025 16:48:30 +0700 Subject: [PATCH] Update --- BACKEND/app/services/apc_connection.ts | 39 ++- BACKEND/app/services/switch_connection.ts | 35 +-- BACKEND/providers/socket_io_provider.ts | 206 ++++++++++++- FRONTEND/src/components/ButtonAction.tsx | 15 +- FRONTEND/src/components/DragTabs.tsx | 8 +- FRONTEND/src/components/DrawerControl.tsx | 348 +++++++--------------- 6 files changed, 342 insertions(+), 309 deletions(-) diff --git a/BACKEND/app/services/apc_connection.ts b/BACKEND/app/services/apc_connection.ts index cb9c428..896236d 100644 --- a/BACKEND/app/services/apc_connection.ts +++ b/BACKEND/app/services/apc_connection.ts @@ -1,4 +1,5 @@ import net, { Socket } from 'node:net' +import { appendLog } from '../ultils/helper.js' interface APCOptions { host: string @@ -54,10 +55,19 @@ class APCController { this.socket.connect(this.apc_port, this.apc_ip, () => { this.status = 'CONNECTED' this.socket.setEncoding('utf8') - this.socket.on('data', (data) => this._handleData(data.toString())) - this.socket.on('close', () => this._handleClose()) - this.socket.on('timeout', () => this._handleTimeout()) - this.socket.on('error', (err) => this._handleError(err)) + resolve() + }) + this.socket.on('data', (data) => this._handleData(data.toString())) + this.socket.on('close', () => { + this._handleClose() + resolve() + }) + this.socket.on('timeout', () => { + this._handleTimeout() + resolve() + }) + this.socket.on('error', (err) => { + this._handleError(err) resolve() }) }) @@ -78,7 +88,7 @@ class APCController { this.output += data this.output = this.output.slice(-10000) this.buffer += data - this.buffer = this.buffer.slice(-1000) + this.buffer = this.buffer.slice(-10000) this.onData(this.buffer, this.status) @@ -90,6 +100,7 @@ class APCController { this.buffer = '' } } + // appendLog(data, 0, 0, this.apc_number || 0) } private _handleClose(): void { @@ -140,8 +151,9 @@ class APCController { }) } - private _send(command: string): void { + public _send(command: string): void { if (this.socket && !this.socket.destroyed && this.socket.readyState) { + // console.log('SEND COMMAND TO APC:', command) this.socket.write(this._convertSpecialKey(command) + '\r\n') } } @@ -185,13 +197,18 @@ class APCController { public async returnToMainMenu(maxAttempts = 5): Promise { for (let i = 0; i < maxAttempts; i++) { this._send('\x1B') - const menuText = await this._waitFor('Main Menu', 5000) + // const menuText = await this._waitFor('Main Menu', 5000) - if (menuText.includes('Control Console') || menuText.includes('Device Manager')) { - return - } + // if (menuText.includes('Control Console') || menuText.includes('Device Manager')) { + // return + // } } - throw new Error('Unable to return to main menu after ESC attempts') + // throw new Error('Unable to return to main menu after ESC attempts') + } + + public async navigateToOutlets(): Promise { + await this.returnToMainMenu() + this._send('1') } public async navigateToOutlet(outletNumber: number): Promise { diff --git a/BACKEND/app/services/switch_connection.ts b/BACKEND/app/services/switch_connection.ts index dd7050c..804d7d8 100644 --- a/BACKEND/app/services/switch_connection.ts +++ b/BACKEND/app/services/switch_connection.ts @@ -16,7 +16,7 @@ interface SwitchControllerOptions { port?: number username: string password: string - onData?: (data?: any) => void + onData?: (data?: string, status?: string) => void keep_connect?: boolean } @@ -25,41 +25,28 @@ export default class SwitchController { private port: number private username: string private password: string - private keep_connect: boolean - private onData: (data?: any) => void + private onData: (data?: string, status?: string) => void private socket: net.Socket - private status: 'CONNECTED' | 'DISCONNECTED' - private buffer: string - private output: string + public status: 'CONNECTED' | 'DISCONNECTED' + public buffer: string private promptCallbacks: PromptCallback[] public ports: PortInfo[] public portGroups: PortInfo[][] private isEnable: boolean - private checkingPorts: boolean - constructor({ - host, - port = 23, - username, - password, - onData, - keep_connect = false, - }: SwitchControllerOptions) { + constructor({ host, port = 23, username, password, onData }: SwitchControllerOptions) { this.host = host this.port = port this.username = username this.password = password - this.keep_connect = keep_connect this.onData = onData || (() => {}) this.socket = new net.Socket() this.status = 'DISCONNECTED' this.buffer = '' - this.output = '' this.promptCallbacks = [] this.ports = [] this.portGroups = [] this.isEnable = false - this.checkingPorts = false } private sleep(ms: number) { @@ -81,11 +68,11 @@ export default class SwitchController { private _handleClose() { this.status = 'DISCONNECTED' this.isEnable = false - this.onData(`[DISCONNECTED]`) + this.onData(`[DISCONNECTED]`, this.status) } private _handleError(err: Error & { code?: string }) { - this.onData(`[ERROR] ${err.message}`) + this.onData(`[ERROR] ${err.message}`, this.status) } private _waitFor(prompt: string, timeout = 5000): Promise { @@ -117,7 +104,7 @@ export default class SwitchController { this.status = 'CONNECTED' this.isEnable = false this.socket.setEncoding('utf8') - this.checkStatusAllPorts() + // this.checkStatusAllPorts() this.socket.on('data', (data) => this._handleData(data.toString())) resolve() }) @@ -143,7 +130,7 @@ export default class SwitchController { if (this.promptCallbacks.length === 0) this.buffer = '' } catch (err: any) { console.error('Error checking port status:', err) - this.onData(`[ERROR] ${err.message}`) + this.onData(`[ERROR] ${err.message}`, this.status) } }, 5000) } @@ -244,7 +231,6 @@ export default class SwitchController { } public async getPorts(): Promise { - this.checkingPorts = true this._send('show interface status') await this.sleep(2000) const statusOutput = this.buffer @@ -295,8 +281,7 @@ export default class SwitchController { const groupedArray = Object.values(grouped) this.ports = ports this.portGroups = groupedArray - this.onData() - this.checkingPorts = false + this.onData('', this.status) return true } diff --git a/BACKEND/providers/socket_io_provider.ts b/BACKEND/providers/socket_io_provider.ts index 13c0a86..f247b73 100644 --- a/BACKEND/providers/socket_io_provider.ts +++ b/BACKEND/providers/socket_io_provider.ts @@ -10,6 +10,7 @@ import Line from '#models/line' import Station from '#models/station' import APCController from '#services/apc_connection' import { sleep } from '../app/ultils/helper.js' +import SwitchController from '#services/switch_connection' interface HandleOptions { command?: string @@ -66,6 +67,7 @@ export class WebSocketIo { lineConnecting: number[] = [] // key = lineId userConnecting: Map = new Map() apcsControl: Map = new Map() + switchControl: Map = new Map() constructor(protected app: ApplicationService) {} @@ -238,25 +240,166 @@ export class WebSocketIo { }) socket.on('control_apc', async (data) => { - const { lineIds, stationId, action } = data + const { outletNumbers, action, station, apcName } = data + if (action === 'reconnect') { + if (!station) return + const apcIp = (station as any)[`${apcName}_ip`] as string + const apc = this.apcsControl.get(apcIp) + if (apc) await apc.reconnect() + } else { + for (const outletNumber of outletNumbers) { + if (!outletNumber || outletNumber < 0) return + if (!station) return + // find line from station by apcName and outletNumber + const lines = await Line.query() + .where('station_id', station.id) + .andWhere('apc_name', apcName) + .andWhere('outlet', outletNumber) + if (lines.length > 0) { + const line = this.lineMap.get(lines[0].id) + if (line) this.setTimeoutConnect(lines[0].id, line, 300000) + } - await this.handleLineOperation( - io, - stationId, - lineIds, - async (line) => line.apcControl(action), - { actionApc: action, timeout: 120000 } - ) + const apcIp = (station as any)[`${apcName}_ip`] as string + const apc = this.apcsControl.get(apcIp) + if (apc && apc.status === 'CONNECTED') { + switch (action) { + case 'on': + await apc?.turnOnOutlet(outletNumber) + break + case 'off': + await apc?.turnOffOutlet(outletNumber) + break + case 'restart': + await apc?.restartOutlet(outletNumber) + break + case 'reconnect': + await apc?.reconnect() + break + default: + break + } + setTimeout(() => { + apc?.navigateToOutlets() + }, 10000) + } else if (apc && apc.status !== 'CONNECTED') { + await apc.reconnect() + switch (action) { + case 'on': + await apc?.turnOnOutlet(outletNumber) + break + case 'off': + await apc?.turnOffOutlet(outletNumber) + break + case 'restart': + await apc?.restartOutlet(outletNumber) + break + default: + break + } + setTimeout(() => { + apc?.navigateToOutlets() + }, 10000) + } + } + } }) socket.on('connect_apc', async (data) => { - const { apcIp, station, apcName } = data - const apc = this.apcsControl.get(apcIp) - if (apc && apc.status === 'CONNECTED') { - return - } else if (apc && apc.status !== 'CONNECTED') { - await apc.reconnect() - } else await this.connectApc(io, apcName, station) + try { + const { apcIp, station, apcName } = data + const apc = this.apcsControl.get(apcIp) + if (apc && apc.status === 'CONNECTED') { + socket.emit('apc_output', { + stationId: station.id, + apcNumber: apcName === 'apc_1' ? 1 : 2, + data: apc.output, + status: apc.status, + }) + } else if (apc && apc.status !== 'CONNECTED') { + await apc.reconnect() + } else await this.connectApc(io, apcName, station) + } catch (error) { + console.log(error) + } + }) + + socket.on('connect_switch', async (data) => { + try { + const { ip, station } = data + const element = this.switchControl.get(ip) + if (element && element.status === 'CONNECTED') { + socket.emit('switch_output', { + stationId: station.id, + ports: element.ports, + status: element.status, + }) + } else if (element && element.status !== 'CONNECTED') { + await element.reconnect() + } else await this.connectSwitch(io, station) + } catch (error) { + console.log(error) + } + }) + + socket.on('control_switch', async (data) => { + const { ports, command, ip, station } = data + const element1 = this.switchControl.get(ip) + if (!element1) { + await this.connectSwitch(io, station) + } + const element = this.switchControl.get(ip) + if (element) { + switch (command) { + case 'on': + ports.forEach(async (port: string) => { + console.log(`Turn on port ${port}`) + await element?.turnPortOn(port) + await sleep(500) + }) + break + case 'off': + ports.forEach(async (port: string) => { + console.log(`Turn off port ${port}`) + await element?.turnPortOff(port) + await sleep(500) + }) + break + case 'restart': + ports.forEach(async (port: string) => { + console.log(`Restarting on port ${port}`) + await element?.restartPort(port) + await sleep(500) + }) + break + case 'on-poe': + ports.forEach(async (port: string) => { + console.log(`Turn on port poe ${port}`) + await element?.enablePoE(port) + await sleep(500) + }) + break + case 'off-poe': + ports.forEach(async (port: string) => { + console.log(`Turn off port poe ${port}`) + await element?.disablePoE(port) + await sleep(500) + }) + break + case 'restart-poe': + ports.forEach(async (port: string) => { + console.log(`Restarting on port poe ${port}`) + await element?.restartPoE(port) + await sleep(500) + }) + break + case 'reconnect': + await element?.reconnect() + break + default: + break + } + } }) }) @@ -404,6 +547,39 @@ export class WebSocketIo { } } + private async connectSwitch(socket: any, station: Station) { + try { + const ip = station.switch_control_ip as string + const port = station.switch_control_port as number + const username = station.switch_control_username as string + const password = station.switch_control_password as string + + if (!ip || !port || !username || !password) throw new Error(`Missing Switch configuration`) + + // Tạo APC Controller instance + const infoSwitch = new SwitchController({ + host: ip, + port: port, + username: username, + password: password, + onData: (ports?: string, status?: string) => { + socket.emit('switch_output', { + stationId: station.id, + ports: ports, + status, + }) + }, + }) + // Connect và login + await infoSwitch.connect() + await infoSwitch.login() + await infoSwitch.getPorts() + this.switchControl.set(ip, infoSwitch) + } catch (error) { + 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`) diff --git a/FRONTEND/src/components/ButtonAction.tsx b/FRONTEND/src/components/ButtonAction.tsx index f337233..ac558a6 100644 --- a/FRONTEND/src/components/ButtonAction.tsx +++ b/FRONTEND/src/components/ButtonAction.tsx @@ -342,9 +342,10 @@ export const ButtonControlApc = ({ onClick={() => { setSelectedLines([]); socket?.emit("control_apc", { - lineIds: selectedLines.map((el) => el.id), - stationId: station.id, + outletNumbers: selectedLines.map((el) => el.outlet), + station: station, action: "on", + apcName: "apc_" + (i + 1), }); }} > @@ -361,9 +362,10 @@ export const ButtonControlApc = ({ onClick={() => { setSelectedLines([]); socket?.emit("control_apc", { - lineIds: selectedLines.map((el) => el.id), - stationId: station.id, + outletNumbers: selectedLines.map((el) => el.outlet), + station: station, action: "off", + apcName: "apc_" + (i + 1), }); }} > @@ -380,9 +382,10 @@ export const ButtonControlApc = ({ onClick={() => { setSelectedLines([]); socket?.emit("control_apc", { - lineIds: selectedLines.map((el) => el.id), - stationId: station.id, + outletNumbers: selectedLines.map((el) => el.outlet), + station: station, action: "restart", + apcName: "apc_" + (i + 1), }); }} > diff --git a/FRONTEND/src/components/DragTabs.tsx b/FRONTEND/src/components/DragTabs.tsx index ea5e913..63187a2 100644 --- a/FRONTEND/src/components/DragTabs.tsx +++ b/FRONTEND/src/components/DragTabs.tsx @@ -263,7 +263,7 @@ export default function DraggableTabs({ /> } /> - {/* + - - */} + */} + = ({ TSelectedOutlet[] >([]); const [isSubmit, setIsSubmit] = useState(true); - const [isConnected, setIsConnected] = useState(true); - const debounceConnect = useDebounce(() => { - stationAPI?.apcs?.forEach((apc) => { - socket?.emit(SOCKET_EVENTS.CONNECT_APC.CONNECT_APC_FROM_WEB, { - apc, - station_id: stationAPI.id, - }); - }); - }, 1000); useEffect(() => { if (!open) { - // setListOutlet([]) setListOutletSelected([]); - // setIsSubmit(true) - // setIsConnected(true) } }, [open]); @@ -160,42 +148,48 @@ export const DrawerAPCControl: React.FC = ({ } }; - useEffect(() => { - if (stationAPI?.apcs && isConnected) { - setIsSubmit(false); - setIsConnected(false); - debounceConnect(); - } - }, [stationAPI, isConnected]); - useEffect(() => { socket?.on("apc_output", (data) => { if (data.stationId !== stationAPI.id) return; const outlets: TSelectedOutlet[] = []; - setDataStation((prev) => { - const apc1 = - data.apcNumber === 1 - ? { ...prev.apc1, output: data.data, status: data.status } - : prev.apc1; - const apc2 = - data.apcNumber === 2 - ? { ...prev.apc2, output: data.data, status: data.status } - : prev.apc2; - [apc1, apc2].forEach(async (apc, i) => { - if (!apc) return; - const result: TSelectedOutlet[] = []; - const lines = apc?.output?.split("\n") || []; - await detectOutlet(apc, lines, result, i); - console.log("result", result); - outlets.push(...result); - }); - return { ...prev, apc1: apc1, apc2: apc2 }; + const apc1 = + data.apcNumber === 1 + ? { output: data.data, status: data.status } + : dataStation?.apc1; + const apc2 = + data.apcNumber === 2 + ? { output: data.data, status: data.status } + : dataStation?.apc2; + setDataStation((prev) => ({ ...prev, apc1: apc1, apc2: apc2 })); + [apc1, apc2].forEach((apc, i) => { + if (!apc) return; + const result: TSelectedOutlet[] = []; + const lines = apc?.output?.split("\n") || []; + detectOutlet(apc, lines, result, i); + outlets.push(...result); }); - // console.log("outlets", outlets); + setTimeout(() => { + if (apc1 || apc2) setIsSubmit(false); - setListOutlet(outlets); + if (outlets.length > 0) + setListOutlet( + listOutlet.map((el) => + outlets.find((o) => o.number === el.number && o.apc === el.apc) + ? { + ...el, + ...outlets.find( + (o) => o.number === el.number && o.apc === el.apc + ), + } + : el + ) + ); + }, 1000); }); - }, [socket]); + return () => { + socket?.off("apc_output"); + }; + }, [socket, dataStation]); const toggleSelect = (outlet: TSelectedOutlet, number: number) => { setListOutletSelected((prev) => @@ -275,17 +269,12 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="yellow" onClick={() => { - socket?.emit( - SOCKET_EVENTS.SEND_COMMAND_TO_APC - .SEND_COMMAND_TO_APC_FROM_WEB, - { - station_id: dataStation.id, - apc_number: 1, - command: "reconnect", - isAction: true, - outlet_number: 0, - } - ); + socket?.emit("control_apc", { + outletNumbers: [], + station: stationAPI, + action: "reconnect", + apcName: "apc_1", + }); setListOutletSelected([]); // Clear selected outlets setIsSubmit(true); setTimeout(() => { @@ -408,29 +397,14 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="yellow" onClick={() => { - if ( - listOutletSelected.filter((el) => el.apc === 1).length === - 0 || - listOutletSelected.filter((el) => el.apc === 1).length === - listOutlet.filter((el) => el.apc === 1).length - ) { - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, { - apc: "apc_1", - station: stationAPI, - action: "3", - station_id: Number(stationAPI.id), - }); - } else { - listOutletSelected.forEach((el) => { - const line = findLineByOutlet(el); - if (!line) return; - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB, { - line: line, - action: "3", - station_id: Number(stationAPI.id), - }); - }); - } + socket?.emit("control_apc", { + outletNumbers: listOutletSelected + .filter((el) => el.apc === 1) + .map((el) => el.number), + station: stationAPI, + action: "restart", + apcName: "apc_1", + }); setListOutletSelected([]); setIsSubmit(true); setTimeout(() => { @@ -467,29 +441,14 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="green" onClick={() => { - if ( - listOutletSelected.filter((el) => el.apc === 1).length === - 0 || - listOutletSelected.filter((el) => el.apc === 1).length === - listOutlet.filter((el) => el.apc === 1).length - ) { - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, { - apc: "apc_1", - station: stationAPI, - action: "1", - station_id: Number(stationAPI.id), - }); - } else { - listOutletSelected.forEach((el) => { - const line = findLineByOutlet(el); - if (!line) return; - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB, { - line: line, - action: "1", - station_id: Number(stationAPI.id), - }); - }); - } + socket?.emit("control_apc", { + outletNumbers: listOutletSelected + .filter((el) => el.apc === 1) + .map((el) => el.number), + station: stationAPI, + action: "on", + apcName: "apc_1", + }); setListOutletSelected([]); setIsSubmit(true); setTimeout(() => { @@ -526,29 +485,14 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="red" onClick={() => { - if ( - listOutletSelected.filter((el) => el.apc === 1).length === - 0 || - listOutletSelected.filter((el) => el.apc === 1).length === - listOutlet.filter((el) => el.apc === 1).length - ) { - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, { - apc: "apc_1", - station: stationAPI, - action: "2", - station_id: Number(stationAPI.id), - }); - } else { - listOutletSelected.forEach((el) => { - const line = findLineByOutlet(el); - if (!line) return; - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB, { - line: line, - action: "2", - station_id: Number(stationAPI.id), - }); - }); - } + socket?.emit("control_apc", { + outletNumbers: listOutletSelected + .filter((el) => el.apc === 1) + .map((el) => el.number), + station: stationAPI, + action: "off", + apcName: "apc_1", + }); setListOutletSelected([]); setIsSubmit(true); setTimeout(() => { @@ -584,17 +528,13 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="yellow" onClick={() => { - socket?.emit( - SOCKET_EVENTS.SEND_COMMAND_TO_APC - .SEND_COMMAND_TO_APC_FROM_WEB, - { - station_id: dataStation.id, - apc_number: 2, - command: "reconnect", - isAction: true, - outlet_number: 0, - } - ); + socket?.emit("control_apc", { + outletNumbers: [], + station: stationAPI, + action: "reconnect", + apcName: "apc_2", + }); + setListOutletSelected([]); setIsSubmit(true); setTimeout(() => { setIsSubmit(false); @@ -716,29 +656,14 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="yellow" onClick={() => { - if ( - listOutletSelected.filter((el) => el.apc === 2).length === - 0 || - listOutletSelected.filter((el) => el.apc === 2).length === - listOutlet.filter((el) => el.apc === 2).length - ) { - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, { - apc: "apc_2", - station: stationAPI, - action: "3", - station_id: Number(stationAPI.id), - }); - } else { - listOutletSelected.forEach((el) => { - const line = findLineByOutlet(el); - if (!line) return; - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB, { - line: line, - action: "3", - station_id: Number(stationAPI.id), - }); - }); - } + socket?.emit("control_apc", { + outletNumbers: listOutletSelected + .filter((el) => el.apc === 2) + .map((el) => el.number), + station: stationAPI, + action: "restart", + apcName: "apc_2", + }); setListOutletSelected([]); setIsSubmit(true); setTimeout(() => { @@ -776,29 +701,14 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="green" onClick={() => { - if ( - listOutletSelected.filter((el) => el.apc === 2).length === - 0 || - listOutletSelected.filter((el) => el.apc === 2).length === - listOutlet.filter((el) => el.apc === 2).length - ) { - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, { - apc: "apc_2", - station: stationAPI, - action: "1", - station_id: Number(stationAPI.id), - }); - } else { - listOutletSelected.forEach((el) => { - const line = findLineByOutlet(el); - if (!line) return; - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB, { - line: line, - action: "1", - station_id: Number(stationAPI.id), - }); - }); - } + socket?.emit("control_apc", { + outletNumbers: listOutletSelected + .filter((el) => el.apc === 2) + .map((el) => el.number), + station: stationAPI, + action: "on", + apcName: "apc_2", + }); setListOutletSelected([]); setIsSubmit(true); setTimeout(() => { @@ -835,29 +745,14 @@ export const DrawerAPCControl: React.FC = ({ variant="filled" color="red" onClick={() => { - if ( - listOutletSelected.filter((el) => el.apc === 2).length === - 0 || - listOutletSelected.filter((el) => el.apc === 2).length === - listOutlet.filter((el) => el.apc === 2).length - ) { - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, { - apc: "apc_2", - station: stationAPI, - action: "2", - station_id: Number(stationAPI.id), - }); - } else { - listOutletSelected.forEach((el) => { - const line = findLineByOutlet(el); - if (!line) return; - socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB, { - line: line, - action: "2", - station_id: Number(stationAPI.id), - }); - }); - } + socket?.emit("control_apc", { + outletNumbers: listOutletSelected + .filter((el) => el.apc === 2) + .map((el) => el.number), + station: stationAPI, + action: "off", + apcName: "apc_2", + }); setListOutletSelected([]); setIsSubmit(true); setTimeout(() => { @@ -876,7 +771,7 @@ export const DrawerAPCControl: React.FC = ({ -
-
+ */} ); }; @@ -909,63 +804,20 @@ export const DrawerSwitchControl: React.FC = ({ SwitchPortsProps[] >([]); const [isSubmit, setIsSubmit] = useState(true); - const [isConnected, setIsConnected] = useState(true); - const debounceConnect = useDebounce(() => { - socket?.emit(SOCKET_EVENTS.CONNECT_SWITCH.CONNECT_SWITCH_FROM_WEB, { - value: { - ip: stationAPI.switch_control_ip, - port: stationAPI.switch_control_port, - username: stationAPI.switch_control_username, - password: stationAPI.switch_control_password, - }, - station_id: stationAPI.id, - }); - }, 1000); useEffect(() => { if (!open) { - // setListPorts([]) setListPortsSelected([]); - // setIsSubmit(true) - // setIsConnected(true) } }, [open]); useEffect(() => { - if ( - stationAPI?.switch_control_ip && - stationAPI?.switch_control_port && - isConnected - ) { + if (stationAPI?.switch_control_ip && stationAPI?.switch_control_port) { setIsSubmit(false); - setIsConnected(false); - debounceConnect(); } - }, [stationAPI, isConnected]); + }, [stationAPI]); useEffect(() => { - socket?.on("connect", () => { - setIsConnected(true); - }); - - socket?.on(SOCKET_EVENTS.APP_DATA.RECEIVED, (data: TStation[]) => { - const station = data?.find((el) => stationAPI.id === el.id); - if (!station) return; - setDataStation(station); - const switches = - station?.switches && station?.switches?.length > 0 - ? station?.switches[0] - : null; - if (!switches) return; - setListPorts(switches?.portGroups || []); - }); - - socket?.on(SOCKET_EVENTS.APP_STATUS.RECEIVED, (data: TAppStatus) => { - if (data?.id.length > 3) { - setIsConnected(true); - } - }); - socket?.on( SOCKET_EVENTS.DATA_SWITCH_RECEIVED.DATA_SWITCH_RECEIVED_TO_WEB, (data: TStation[]) => {