This commit is contained in:
nguyentrungthat 2025-11-05 16:48:30 +07:00
parent a4163a1cb5
commit 990f57a342
6 changed files with 342 additions and 309 deletions

View File

@ -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<void> {
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<void> {
await this.returnToMainMenu()
this._send('1')
}
public async navigateToOutlet(outletNumber: number): Promise<void> {

View File

@ -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<string> {
@ -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<boolean> {
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
}

View File

@ -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<number, { userId: number; userName: string }> = new Map()
apcsControl: Map<string, APCController> = new Map()
switchControl: Map<string, SwitchController> = 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`)

View File

@ -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),
});
}}
>

View File

@ -263,7 +263,7 @@ export default function DraggableTabs({
/>
}
/>
{/* <Flex gap={"xs"} ms={"md"}>
<Flex gap={"xs"} ms={"md"}>
<Button
miw={"80px"}
size="xs"
@ -293,7 +293,7 @@ export default function DraggableTabs({
>
APC
</Button>
<Button
{/* <Button
miw={"80px"}
size="xs"
fz={"sm"}
@ -304,8 +304,8 @@ export default function DraggableTabs({
}}
>
Switch
</Button>
</Flex> */}
</Button> */}
</Flex>
</Flex>
<Tabs.List className={classes.list}>
<SortableContext

View File

@ -64,22 +64,10 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
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<DrawerProps> = ({
}
};
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<DrawerProps> = ({
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<DrawerProps> = ({
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<DrawerProps> = ({
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<DrawerProps> = ({
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<DrawerProps> = ({
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<DrawerProps> = ({
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<DrawerProps> = ({
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<DrawerProps> = ({
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<DrawerProps> = ({
</fieldset>
</Grid.Col>
</Grid>
<div
{/* <div
style={{ display: "flex", justifyContent: "end", marginTop: "20px" }}
>
<Button
@ -891,7 +786,7 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
>
Switch Control
</Button>
</div>
</div> */}
</Drawer>
);
};
@ -909,63 +804,20 @@ export const DrawerSwitchControl: React.FC<DrawerProps> = ({
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[]) => {