Update apc
This commit is contained in:
parent
abda7c4e99
commit
d031c1e93e
|
|
@ -5,7 +5,7 @@ interface APCOptions {
|
||||||
port?: number
|
port?: number
|
||||||
username: string
|
username: string
|
||||||
password: string
|
password: string
|
||||||
onData?: (data: string) => void
|
onData?: (data: string, status: string) => void
|
||||||
number?: number
|
number?: number
|
||||||
keep_connect?: boolean
|
keep_connect?: boolean
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ class APCController {
|
||||||
private buffer: string
|
private buffer: string
|
||||||
private output: string
|
private output: string
|
||||||
private promptCallbacks: PromptCallback[]
|
private promptCallbacks: PromptCallback[]
|
||||||
private onData: (data: string) => void
|
private onData: (data: string, status: string) => void
|
||||||
private retryConnect: number
|
private retryConnect: number
|
||||||
|
|
||||||
constructor({ host, port = 23, username, password, onData, number }: APCOptions) {
|
constructor({ host, port = 23, username, password, onData, number }: APCOptions) {
|
||||||
|
|
@ -80,7 +80,7 @@ class APCController {
|
||||||
this.buffer += data
|
this.buffer += data
|
||||||
this.buffer = this.buffer.slice(-1000)
|
this.buffer = this.buffer.slice(-1000)
|
||||||
|
|
||||||
this.onData(this.buffer)
|
this.onData(this.buffer, this.status)
|
||||||
|
|
||||||
if (this.promptCallbacks.length > 0) {
|
if (this.promptCallbacks.length > 0) {
|
||||||
const { prompt, callback } = this.promptCallbacks[0]
|
const { prompt, callback } = this.promptCallbacks[0]
|
||||||
|
|
@ -95,14 +95,14 @@ class APCController {
|
||||||
private _handleClose(): void {
|
private _handleClose(): void {
|
||||||
this.status = 'DISCONNECTED'
|
this.status = 'DISCONNECTED'
|
||||||
this.output += '\r\n\r\n[DISCONNECTED] Socket closed'
|
this.output += '\r\n\r\n[DISCONNECTED] Socket closed'
|
||||||
this.onData(this.output)
|
this.onData(this.output, this.status)
|
||||||
this._cleanup()
|
this._cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _handleTimeout(): Promise<void> {
|
private async _handleTimeout(): Promise<void> {
|
||||||
this.status = 'TIMEOUT'
|
this.status = 'TIMEOUT'
|
||||||
this.output += '\r\n\r\n[TIMEOUT] Connection timed out'
|
this.output += '\r\n\r\n[TIMEOUT] Connection timed out'
|
||||||
this.onData(this.output)
|
this.onData(this.output, this.status)
|
||||||
|
|
||||||
if (this.retryConnect <= 5) {
|
if (this.retryConnect <= 5) {
|
||||||
await this.sleep(5000)
|
await this.sleep(5000)
|
||||||
|
|
@ -114,7 +114,7 @@ class APCController {
|
||||||
|
|
||||||
private _handleError(err: NodeJS.ErrnoException): void {
|
private _handleError(err: NodeJS.ErrnoException): void {
|
||||||
this.output += `\r\n\r\n[ERROR] ${err.message}`
|
this.output += `\r\n\r\n[ERROR] ${err.message}`
|
||||||
this.onData(this.output)
|
this.onData(this.output, this.status)
|
||||||
if (err.code === 'ECONNRESET') {
|
if (err.code === 'ECONNRESET') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('[ECONNRESET] Trying reconnect apc:', this.apc_ip)
|
console.log('[ECONNRESET] Trying reconnect apc:', this.apc_ip)
|
||||||
|
|
|
||||||
|
|
@ -235,17 +235,14 @@ export default class LineConnection {
|
||||||
}, script.timeout || 300000)
|
}, script.timeout || 300000)
|
||||||
|
|
||||||
const runStep = async (index: number) => {
|
const runStep = async (index: number) => {
|
||||||
console.log('Running step', index, Date.now())
|
|
||||||
if (index >= steps.length) {
|
if (index >= steps.length) {
|
||||||
clearTimeout(timeoutTimer)
|
|
||||||
if (this.waitingScenario) {
|
if (this.waitingScenario) {
|
||||||
setTimeout(() => {
|
|
||||||
this.waitingScenario = false
|
this.waitingScenario = false
|
||||||
|
setTimeout(() => {
|
||||||
runStep(index)
|
runStep(index)
|
||||||
}, 5000)
|
}, 5000)
|
||||||
return
|
return
|
||||||
}
|
} else clearTimeout(timeoutTimer)
|
||||||
console.log('End step', Date.now())
|
|
||||||
this.isRunningScript = false
|
this.isRunningScript = false
|
||||||
this.outputBuffer = ''
|
this.outputBuffer = ''
|
||||||
appendLog(
|
appendLog(
|
||||||
|
|
@ -397,12 +394,14 @@ export default class LineConnection {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
number: this.config.lineNumber,
|
number: this.config.lineNumber,
|
||||||
onData: (data: string) => {
|
onData: (data: string, status: string) => {
|
||||||
this.config.output += data
|
this.config.output += data
|
||||||
this.socketIO.emit('line_output', {
|
this.socketIO.emit('apc_output', {
|
||||||
stationId: this.config.stationId,
|
stationId: this.config.stationId,
|
||||||
lineId: this.config.id,
|
lineId: this.config.id,
|
||||||
data: data,
|
apcNumber: apcName === 'apc_1' ? 1 : 2,
|
||||||
|
data,
|
||||||
|
status,
|
||||||
})
|
})
|
||||||
appendLog(
|
appendLog(
|
||||||
cleanData(data),
|
cleanData(data),
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import env from '#start/env'
|
||||||
import { CustomServer, CustomSocket } from '../app/ultils/types.js'
|
import { CustomServer, CustomSocket } from '../app/ultils/types.js'
|
||||||
import Line from '#models/line'
|
import Line from '#models/line'
|
||||||
import Station from '#models/station'
|
import Station from '#models/station'
|
||||||
|
import APCController from '#services/apc_connection'
|
||||||
|
|
||||||
interface HandleOptions {
|
interface HandleOptions {
|
||||||
command?: string
|
command?: string
|
||||||
|
|
@ -62,6 +63,7 @@ export class WebSocketIo {
|
||||||
lineMap: Map<number, LineConnection> = new Map() // key = lineId
|
lineMap: Map<number, LineConnection> = new Map() // key = lineId
|
||||||
lineConnecting: number[] = [] // key = lineId
|
lineConnecting: number[] = [] // key = lineId
|
||||||
userConnecting: Map<number, { userId: number; userName: string }> = new Map()
|
userConnecting: Map<number, { userId: number; userName: string }> = new Map()
|
||||||
|
apcsControl: Map<string, APCController> = new Map()
|
||||||
|
|
||||||
constructor(protected app: ApplicationService) {}
|
constructor(protected app: ApplicationService) {}
|
||||||
|
|
||||||
|
|
@ -123,7 +125,7 @@ export class WebSocketIo {
|
||||||
stationId,
|
stationId,
|
||||||
lineIds,
|
lineIds,
|
||||||
async (line) => line.writeCommand(command),
|
async (line) => line.writeCommand(command),
|
||||||
{ command, timeout: 180000 }
|
{ command, timeout: 120000 }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -137,7 +139,7 @@ export class WebSocketIo {
|
||||||
async (line) => line.runScript(scenario),
|
async (line) => line.runScript(scenario),
|
||||||
{
|
{
|
||||||
scenario,
|
scenario,
|
||||||
timeout: scenario?.timeout ? Number(scenario.timeout) + 180000 : 300000,
|
timeout: scenario?.timeout ? Number(scenario.timeout) + 120000 : 300000,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
@ -201,7 +203,6 @@ export class WebSocketIo {
|
||||||
// Get file stats
|
// Get file stats
|
||||||
const stats = fs.statSync(filePath)
|
const stats = fs.statSync(filePath)
|
||||||
const fileSizeInBytes = stats.size
|
const fileSizeInBytes = stats.size
|
||||||
console.log('File size (bytes):', fileSizeInBytes)
|
|
||||||
if (fileSizeInBytes / 1024 / 1024 > 0.5) {
|
if (fileSizeInBytes / 1024 / 1024 > 0.5) {
|
||||||
// File is larger than 0.5 MB
|
// File is larger than 0.5 MB
|
||||||
const fileId = Date.now() // Mã định danh file
|
const fileId = Date.now() // Mã định danh file
|
||||||
|
|
@ -242,9 +243,17 @@ export class WebSocketIo {
|
||||||
stationId,
|
stationId,
|
||||||
lineIds,
|
lineIds,
|
||||||
async (line) => line.apcControl(action),
|
async (line) => line.apcControl(action),
|
||||||
{ actionApc: action, timeout: 180000 }
|
{ actionApc: action, timeout: 120000 }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
socket.on('connect_apc', async (data) => {
|
||||||
|
const { apcIp, station, apcName } = data
|
||||||
|
if (this.apcsControl.has(apcIp)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await this.connectApc(io, apcName, station)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
socketServer.listen(SOCKET_IO_PORT, () => {
|
socketServer.listen(SOCKET_IO_PORT, () => {
|
||||||
|
|
@ -286,7 +295,7 @@ export class WebSocketIo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setTimeoutConnect = (lineId: number, lineConn: LineConnection, timeout = 180000) => {
|
private setTimeoutConnect = (lineId: number, lineConn: LineConnection, timeout = 120000) => {
|
||||||
if (this.intervalMap[`${lineId}`]) {
|
if (this.intervalMap[`${lineId}`]) {
|
||||||
clearInterval(this.intervalMap[`${lineId}`])
|
clearInterval(this.intervalMap[`${lineId}`])
|
||||||
delete this.intervalMap[`${lineId}`]
|
delete this.intervalMap[`${lineId}`]
|
||||||
|
|
@ -351,4 +360,38 @@ export class WebSocketIo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async connectApc(socket: any, apcName: string, station: Station) {
|
||||||
|
try {
|
||||||
|
const ip = (station as any)[`${apcName}_ip`] as string
|
||||||
|
const port = (station as any)[`${apcName}_port`] as number
|
||||||
|
const username = (station as any)[`${apcName}_username`] as string
|
||||||
|
const password = (station as any)[`${apcName}_password`] as string
|
||||||
|
|
||||||
|
if (!ip || !port || !username || !password)
|
||||||
|
throw new Error(`Missing APC configuration for ${apcName}`)
|
||||||
|
|
||||||
|
// Tạo APC Controller instance
|
||||||
|
const apc = new APCController({
|
||||||
|
host: ip,
|
||||||
|
port,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
onData: (data: string, status: string) => {
|
||||||
|
socket.emit('apc_output', {
|
||||||
|
stationId: station.id,
|
||||||
|
apcNumber: apcName === 'apc_1' ? 1 : 2,
|
||||||
|
data,
|
||||||
|
status,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
// Connect và login
|
||||||
|
await apc.connect()
|
||||||
|
await apc.login()
|
||||||
|
this.apcsControl.set(ip, apc)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ import {
|
||||||
Grid,
|
Grid,
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
LoadingOverlay,
|
LoadingOverlay,
|
||||||
Button,
|
|
||||||
Box,
|
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import type {
|
import type {
|
||||||
IDataTakeOver,
|
IDataTakeOver,
|
||||||
|
|
@ -338,7 +336,7 @@ function App() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[activeTab]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
// const getLine = (lineId: number, stationId: number) => {
|
// const getLine = (lineId: number, stationId: number) => {
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,25 @@ export default function DraggableTabs({
|
||||||
fz={"sm"}
|
fz={"sm"}
|
||||||
variant="filled"
|
variant="filled"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
const station = tabs.find(
|
||||||
|
(el) => el.id.toString() === active
|
||||||
|
);
|
||||||
|
if (!station) return;
|
||||||
setOpenedAPC(true);
|
setOpenedAPC(true);
|
||||||
|
if (station?.apc_1_ip && station?.apc_1_port) {
|
||||||
|
socket?.emit("connect_apc", {
|
||||||
|
station: station,
|
||||||
|
apcIp: station?.apc_1_ip,
|
||||||
|
apcName: "apc_1",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (station?.apc_2_ip && station?.apc_2_port) {
|
||||||
|
socket?.emit("connect_apc", {
|
||||||
|
station: station,
|
||||||
|
apcIp: station?.apc_2_ip,
|
||||||
|
apcName: "apc_2",
|
||||||
|
});
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
APC
|
APC
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
import { Box, Button, Card, Checkbox, Drawer, Grid, Text } from "@mantine/core";
|
import { Box, Button, Card, Drawer, Grid, Text } from "@mantine/core";
|
||||||
import { IconRepeat, IconSection } from "@tabler/icons-react";
|
import { IconRepeat, IconSection } from "@tabler/icons-react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import classes from "./Component.module.css";
|
import classes from "./Component.module.css";
|
||||||
import type { APCProps, SwitchPortsProps, TStation } from "../untils/types";
|
import type { APCProps, SwitchPortsProps, TStation } from "../untils/types";
|
||||||
import { useDebounce } from "../untils/helper";
|
import { useDebounce } from "../untils/helper";
|
||||||
import { SOCKET_EVENTS } from "../untils/constanst";
|
import { SOCKET_EVENTS } from "../untils/constanst";
|
||||||
|
import type { Socket } from "socket.io-client";
|
||||||
|
|
||||||
interface DrawerProps {
|
interface DrawerProps {
|
||||||
stationAPI: TStation;
|
stationAPI: TStation;
|
||||||
socket: any;
|
socket: Socket | null;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
openedSwitch?: () => void;
|
openedSwitch?: () => void;
|
||||||
|
|
@ -37,7 +38,7 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
const findLineByOutlet = (outlet: TSelectedOutlet) => {
|
const findLineByOutlet = (outlet: TSelectedOutlet) => {
|
||||||
return stationAPI.lines.find(
|
return stationAPI.lines.find(
|
||||||
(line) =>
|
(line) =>
|
||||||
line.outlet === outlet.number && line.apc_name === `apc_${outlet.apc}`
|
line.outlet === outlet.number && line.apcName === `apc_${outlet.apc}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -54,7 +55,7 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
if (!line) return el;
|
if (!line) return el;
|
||||||
return {
|
return {
|
||||||
...el,
|
...el,
|
||||||
name: "Line " + line.line_number || el.name,
|
name: "Line " + line.lineNumber || el.name,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
@ -168,15 +169,25 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
}, [stationAPI, isConnected]);
|
}, [stationAPI, isConnected]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
socket?.on(SOCKET_EVENTS.APP_DATA.RECEIVED, (data: TStation[]) => {
|
socket?.on("apc_output", (data) => {
|
||||||
const station = data?.find((el) => stationAPI.id === el.id);
|
if (data.stationId !== stationAPI.id) return;
|
||||||
if (!station) return;
|
let apcs: APCProps[] = [];
|
||||||
setDataStation(station);
|
setDataStation((prev) => {
|
||||||
const apcs =
|
const apc1 =
|
||||||
station?.apcs?.sort(
|
data.apcNumber === 1
|
||||||
(a, b) => (a?.apc_number || 0) - (b?.apc_number || 0)
|
? { ...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;
|
||||||
|
apcs = [apc1, apc2];
|
||||||
|
return prev.id === data.stationId
|
||||||
|
? { ...prev, apc1: apc1, apc2: apc2 }
|
||||||
|
: prev;
|
||||||
|
});
|
||||||
const outlets: TSelectedOutlet[] = [];
|
const outlets: TSelectedOutlet[] = [];
|
||||||
|
console.log("apcs", apcs);
|
||||||
apcs.forEach(async (apc, i) => {
|
apcs.forEach(async (apc, i) => {
|
||||||
const result: TSelectedOutlet[] = [];
|
const result: TSelectedOutlet[] = [];
|
||||||
const lines = apc?.output?.split("\n") || [];
|
const lines = apc?.output?.split("\n") || [];
|
||||||
|
|
@ -185,29 +196,6 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
});
|
});
|
||||||
setListOutlet(outlets);
|
setListOutlet(outlets);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket?.on(
|
|
||||||
SOCKET_EVENTS.DATA_APC_RECEIVED.DATA_APC_RECEIVED_TO_WEB,
|
|
||||||
(data: TStation[]) => {
|
|
||||||
const outlets: TSelectedOutlet[] = [];
|
|
||||||
data
|
|
||||||
?.filter((el) => stationAPI.id === el.id)
|
|
||||||
?.forEach((station) => {
|
|
||||||
station?.apcs
|
|
||||||
?.sort((a, b) => (a?.apc_number || 0) - (b?.apc_number || 0))
|
|
||||||
.forEach(async (apc, i) => {
|
|
||||||
const result: TSelectedOutlet[] = [];
|
|
||||||
const lines = apc?.output?.split("\n") || [];
|
|
||||||
await detectOutlet(apc, lines, result, i);
|
|
||||||
outlets.push(...result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
setListOutlet(outlets);
|
|
||||||
setDataStation(
|
|
||||||
data?.find((el) => stationAPI.id === el.id) || stationAPI
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, [socket]);
|
}, [socket]);
|
||||||
|
|
||||||
const toggleSelect = (outlet: TSelectedOutlet, number: number) => {
|
const toggleSelect = (outlet: TSelectedOutlet, number: number) => {
|
||||||
|
|
@ -270,7 +258,6 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
position="bottom"
|
position="bottom"
|
||||||
>
|
>
|
||||||
<Grid>
|
<Grid>
|
||||||
{dataStation?.apcs && (
|
|
||||||
<Grid.Col span={6}>
|
<Grid.Col span={6}>
|
||||||
<fieldset style={{ padding: "4px 6px" }}>
|
<fieldset style={{ padding: "4px 6px" }}>
|
||||||
<legend>
|
<legend>
|
||||||
|
|
@ -278,10 +265,10 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
<Text fw={700} c={"#514d4d"} fz={"sm"}>
|
<Text fw={700} c={"#514d4d"} fz={"sm"}>
|
||||||
APC 1
|
APC 1
|
||||||
</Text>
|
</Text>
|
||||||
{dataStation?.apcs[0]?.status &&
|
{dataStation?.apc1?.status &&
|
||||||
RenderAPCStatus(dataStation?.apcs[0])}
|
RenderAPCStatus(dataStation?.apc1)}
|
||||||
{dataStation?.apcs[0]?.status === "DISCONNECTED" ||
|
{dataStation?.apc1?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[0]?.status === "TIMEOUT" ? (
|
dataStation?.apc1?.status === "TIMEOUT" ? (
|
||||||
<Button
|
<Button
|
||||||
style={{ height: "24px" }}
|
style={{ height: "24px" }}
|
||||||
size="xs"
|
size="xs"
|
||||||
|
|
@ -346,12 +333,11 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
fw={500}
|
fw={500}
|
||||||
fz={"14px"}
|
fz={"14px"}
|
||||||
style={{
|
style={{
|
||||||
color:
|
color: outlet.status === "ON" ? "#40c057" : "#f03e3e",
|
||||||
outlet.status === "ON" ? "#40c057" : "#f03e3e",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{findLineByOutlet(outlet)
|
{findLineByOutlet(outlet)
|
||||||
? "Line " + findLineByOutlet(outlet)?.line_number
|
? "Line " + findLineByOutlet(outlet)?.lineNumber
|
||||||
: outlet.name}
|
: outlet.name}
|
||||||
</Text>
|
</Text>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
@ -381,8 +367,7 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
variant="filled"
|
variant="filled"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 1)
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 1).length
|
listOutlet.filter((el) => el.apc === 1).length
|
||||||
) {
|
) {
|
||||||
setListOutletSelected([]);
|
setListOutletSelected([]);
|
||||||
|
|
@ -407,14 +392,13 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
listOutlet.filter((el) => el.apc === 1).length === 0 ||
|
listOutlet.filter((el) => el.apc === 1).length === 0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
0 ||
|
0 ||
|
||||||
dataStation?.apcs[0]?.status === "DISCONNECTED" ||
|
dataStation?.apc1?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[0]?.status === "TIMEOUT"
|
dataStation?.apc1?.status === "TIMEOUT"
|
||||||
}
|
}
|
||||||
title={
|
title={
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
listOutlet.filter((el) => el.apc === 1).length ||
|
listOutlet.filter((el) => el.apc === 1).length ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length === 0
|
||||||
0
|
|
||||||
? "Restart All"
|
? "Restart All"
|
||||||
: "Restart Selected"
|
: "Restart Selected"
|
||||||
}
|
}
|
||||||
|
|
@ -426,21 +410,17 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
color="yellow"
|
color="yellow"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 1)
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
.length === 0 ||
|
0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1)
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 1).length
|
listOutlet.filter((el) => el.apc === 1).length
|
||||||
) {
|
) {
|
||||||
socket?.emit(
|
socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, {
|
||||||
SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC,
|
|
||||||
{
|
|
||||||
apc: "apc_1",
|
apc: "apc_1",
|
||||||
station: stationAPI,
|
station: stationAPI,
|
||||||
action: "3",
|
action: "3",
|
||||||
station_id: Number(stationAPI.id),
|
station_id: Number(stationAPI.id),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
listOutletSelected.forEach((el) => {
|
listOutletSelected.forEach((el) => {
|
||||||
const line = findLineByOutlet(el);
|
const line = findLineByOutlet(el);
|
||||||
|
|
@ -471,14 +451,13 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
listOutlet.filter((el) => el.apc === 1).length === 0 ||
|
listOutlet.filter((el) => el.apc === 1).length === 0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
0 ||
|
0 ||
|
||||||
dataStation?.apcs[0]?.status === "DISCONNECTED" ||
|
dataStation?.apc1?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[0]?.status === "TIMEOUT"
|
dataStation?.apc1?.status === "TIMEOUT"
|
||||||
}
|
}
|
||||||
title={
|
title={
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
listOutlet.filter((el) => el.apc === 1).length ||
|
listOutlet.filter((el) => el.apc === 1).length ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length === 0
|
||||||
0
|
|
||||||
? "Turn On All"
|
? "Turn On All"
|
||||||
: "Turn On Selected"
|
: "Turn On Selected"
|
||||||
}
|
}
|
||||||
|
|
@ -490,21 +469,17 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
color="green"
|
color="green"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 1)
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
.length === 0 ||
|
0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1)
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 1).length
|
listOutlet.filter((el) => el.apc === 1).length
|
||||||
) {
|
) {
|
||||||
socket?.emit(
|
socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, {
|
||||||
SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC,
|
|
||||||
{
|
|
||||||
apc: "apc_1",
|
apc: "apc_1",
|
||||||
station: stationAPI,
|
station: stationAPI,
|
||||||
action: "1",
|
action: "1",
|
||||||
station_id: Number(stationAPI.id),
|
station_id: Number(stationAPI.id),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
listOutletSelected.forEach((el) => {
|
listOutletSelected.forEach((el) => {
|
||||||
const line = findLineByOutlet(el);
|
const line = findLineByOutlet(el);
|
||||||
|
|
@ -535,14 +510,13 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
listOutlet.filter((el) => el.apc === 1).length === 0 ||
|
listOutlet.filter((el) => el.apc === 1).length === 0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
0 ||
|
0 ||
|
||||||
dataStation?.apcs[0]?.status === "DISCONNECTED" ||
|
dataStation?.apc1?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[0]?.status === "TIMEOUT"
|
dataStation?.apc1?.status === "TIMEOUT"
|
||||||
}
|
}
|
||||||
title={
|
title={
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
listOutlet.filter((el) => el.apc === 1).length ||
|
listOutlet.filter((el) => el.apc === 1).length ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1).length ===
|
listOutletSelected.filter((el) => el.apc === 1).length === 0
|
||||||
0
|
|
||||||
? "Turn Off All"
|
? "Turn Off All"
|
||||||
: "Turn Off Selected"
|
: "Turn Off Selected"
|
||||||
}
|
}
|
||||||
|
|
@ -554,21 +528,17 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
color="red"
|
color="red"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 1)
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
.length === 0 ||
|
0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 1)
|
listOutletSelected.filter((el) => el.apc === 1).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 1).length
|
listOutlet.filter((el) => el.apc === 1).length
|
||||||
) {
|
) {
|
||||||
socket?.emit(
|
socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, {
|
||||||
SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC,
|
|
||||||
{
|
|
||||||
apc: "apc_1",
|
apc: "apc_1",
|
||||||
station: stationAPI,
|
station: stationAPI,
|
||||||
action: "2",
|
action: "2",
|
||||||
station_id: Number(stationAPI.id),
|
station_id: Number(stationAPI.id),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
listOutletSelected.forEach((el) => {
|
listOutletSelected.forEach((el) => {
|
||||||
const line = findLineByOutlet(el);
|
const line = findLineByOutlet(el);
|
||||||
|
|
@ -597,9 +567,6 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
</Box>
|
</Box>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
)}
|
|
||||||
|
|
||||||
{dataStation?.apcs && (
|
|
||||||
<Grid.Col span={6}>
|
<Grid.Col span={6}>
|
||||||
<fieldset style={{ padding: "4px 6px" }}>
|
<fieldset style={{ padding: "4px 6px" }}>
|
||||||
<legend>
|
<legend>
|
||||||
|
|
@ -607,10 +574,10 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
<Text fw={700} c={"#514d4d"} fz={"sm"}>
|
<Text fw={700} c={"#514d4d"} fz={"sm"}>
|
||||||
APC 2
|
APC 2
|
||||||
</Text>
|
</Text>
|
||||||
{dataStation?.apcs[1]?.status &&
|
{dataStation?.apc2?.status &&
|
||||||
RenderAPCStatus(dataStation?.apcs[1])}
|
RenderAPCStatus(dataStation?.apc2)}
|
||||||
{dataStation?.apcs[1]?.status === "DISCONNECTED" ||
|
{dataStation?.apc2?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[1]?.status === "TIMEOUT" ? (
|
dataStation?.apc2?.status === "TIMEOUT" ? (
|
||||||
<Button
|
<Button
|
||||||
style={{ height: "24px" }}
|
style={{ height: "24px" }}
|
||||||
size="xs"
|
size="xs"
|
||||||
|
|
@ -674,12 +641,11 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
fw={500}
|
fw={500}
|
||||||
fz={"14px"}
|
fz={"14px"}
|
||||||
style={{
|
style={{
|
||||||
color:
|
color: outlet.status === "ON" ? "#40c057" : "#f03e3e",
|
||||||
outlet.status === "ON" ? "#40c057" : "#f03e3e",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{findLineByOutlet(outlet)
|
{findLineByOutlet(outlet)
|
||||||
? "Line " + findLineByOutlet(outlet)?.line_number
|
? "Line " + findLineByOutlet(outlet)?.lineNumber
|
||||||
: outlet.name}
|
: outlet.name}
|
||||||
</Text>
|
</Text>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
@ -709,8 +675,7 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
variant="filled"
|
variant="filled"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 2)
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 2).length
|
listOutlet.filter((el) => el.apc === 2).length
|
||||||
) {
|
) {
|
||||||
setListOutletSelected([]);
|
setListOutletSelected([]);
|
||||||
|
|
@ -735,14 +700,13 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
listOutlet.filter((el) => el.apc === 2).length === 0 ||
|
listOutlet.filter((el) => el.apc === 2).length === 0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
0 ||
|
0 ||
|
||||||
dataStation?.apcs[1]?.status === "DISCONNECTED" ||
|
dataStation?.apc2?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[1]?.status === "TIMEOUT"
|
dataStation?.apc2?.status === "TIMEOUT"
|
||||||
}
|
}
|
||||||
title={
|
title={
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
listOutlet.filter((el) => el.apc === 2).length ||
|
listOutlet.filter((el) => el.apc === 2).length ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length === 0
|
||||||
0
|
|
||||||
? "Restart All"
|
? "Restart All"
|
||||||
: "Restart Selected"
|
: "Restart Selected"
|
||||||
}
|
}
|
||||||
|
|
@ -754,21 +718,17 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
color="yellow"
|
color="yellow"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 2)
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
.length === 0 ||
|
0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2)
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 2).length
|
listOutlet.filter((el) => el.apc === 2).length
|
||||||
) {
|
) {
|
||||||
socket?.emit(
|
socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, {
|
||||||
SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC,
|
|
||||||
{
|
|
||||||
apc: "apc_2",
|
apc: "apc_2",
|
||||||
station: stationAPI,
|
station: stationAPI,
|
||||||
action: "3",
|
action: "3",
|
||||||
station_id: Number(stationAPI.id),
|
station_id: Number(stationAPI.id),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
listOutletSelected.forEach((el) => {
|
listOutletSelected.forEach((el) => {
|
||||||
const line = findLineByOutlet(el);
|
const line = findLineByOutlet(el);
|
||||||
|
|
@ -787,8 +747,7 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{listOutletSelected.filter((el) => el.apc === 2).length ===
|
{listOutletSelected.filter((el) => el.apc === 2).length === 0
|
||||||
0
|
|
||||||
? "Restart All"
|
? "Restart All"
|
||||||
: "Restart Selected"}
|
: "Restart Selected"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -798,16 +757,16 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
listOutlet.filter((el) => el.apc === 2).length === 0 ||
|
listOutlet.filter((el) => el.apc === 2).length === 0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
0 ||
|
0 ||
|
||||||
dataStation?.apcs[1]?.status === "DISCONNECTED" ||
|
dataStation?.apc2?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[1]?.status === "TIMEOUT"
|
dataStation?.apc2?.status === "TIMEOUT"
|
||||||
}
|
}
|
||||||
title={
|
title={
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
listOutlet.filter((el) => el.apc === 2).length ||
|
listOutlet.filter((el) => el.apc === 2).length ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
0 ||
|
0 ||
|
||||||
dataStation?.apcs[1]?.status === "DISCONNECTED" ||
|
dataStation?.apc2?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[1]?.status === "TIMEOUT"
|
dataStation?.apc2?.status === "TIMEOUT"
|
||||||
? "Turn On All"
|
? "Turn On All"
|
||||||
: "Turn On Selected"
|
: "Turn On Selected"
|
||||||
}
|
}
|
||||||
|
|
@ -819,21 +778,17 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
color="green"
|
color="green"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 2)
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
.length === 0 ||
|
0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2)
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 2).length
|
listOutlet.filter((el) => el.apc === 2).length
|
||||||
) {
|
) {
|
||||||
socket?.emit(
|
socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, {
|
||||||
SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC,
|
|
||||||
{
|
|
||||||
apc: "apc_2",
|
apc: "apc_2",
|
||||||
station: stationAPI,
|
station: stationAPI,
|
||||||
action: "1",
|
action: "1",
|
||||||
station_id: Number(stationAPI.id),
|
station_id: Number(stationAPI.id),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
listOutletSelected.forEach((el) => {
|
listOutletSelected.forEach((el) => {
|
||||||
const line = findLineByOutlet(el);
|
const line = findLineByOutlet(el);
|
||||||
|
|
@ -864,14 +819,13 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
listOutlet.filter((el) => el.apc === 2).length === 0 ||
|
listOutlet.filter((el) => el.apc === 2).length === 0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
0 ||
|
0 ||
|
||||||
dataStation?.apcs[1]?.status === "DISCONNECTED" ||
|
dataStation?.apc2?.status === "DISCONNECTED" ||
|
||||||
dataStation?.apcs[1]?.status === "TIMEOUT"
|
dataStation?.apc2?.status === "TIMEOUT"
|
||||||
}
|
}
|
||||||
title={
|
title={
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
listOutlet.filter((el) => el.apc === 2).length ||
|
listOutlet.filter((el) => el.apc === 2).length ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2).length ===
|
listOutletSelected.filter((el) => el.apc === 2).length === 0
|
||||||
0
|
|
||||||
? "Turn Off All"
|
? "Turn Off All"
|
||||||
: "Turn Off Selected"
|
: "Turn Off Selected"
|
||||||
}
|
}
|
||||||
|
|
@ -883,21 +837,17 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
color="red"
|
color="red"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
listOutletSelected.filter((el) => el.apc === 2)
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
.length === 0 ||
|
0 ||
|
||||||
listOutletSelected.filter((el) => el.apc === 2)
|
listOutletSelected.filter((el) => el.apc === 2).length ===
|
||||||
.length ===
|
|
||||||
listOutlet.filter((el) => el.apc === 2).length
|
listOutlet.filter((el) => el.apc === 2).length
|
||||||
) {
|
) {
|
||||||
socket?.emit(
|
socket?.emit(SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC, {
|
||||||
SOCKET_EVENTS.APC_CONTROL.FROM_WEB_ALL_APC,
|
|
||||||
{
|
|
||||||
apc: "apc_2",
|
apc: "apc_2",
|
||||||
station: stationAPI,
|
station: stationAPI,
|
||||||
action: "2",
|
action: "2",
|
||||||
station_id: Number(stationAPI.id),
|
station_id: Number(stationAPI.id),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
listOutletSelected.forEach((el) => {
|
listOutletSelected.forEach((el) => {
|
||||||
const line = findLineByOutlet(el);
|
const line = findLineByOutlet(el);
|
||||||
|
|
@ -926,7 +876,6 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
|
||||||
</Box>
|
</Box>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
)}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<div
|
<div
|
||||||
style={{ display: "flex", justifyContent: "end", marginTop: "20px" }}
|
style={{ display: "flex", justifyContent: "end", marginTop: "20px" }}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,9 @@ export type TStation = {
|
||||||
owner_id: number;
|
owner_id: number;
|
||||||
owner: TUser;
|
owner: TUser;
|
||||||
users: TUser[];
|
users: TUser[];
|
||||||
apcs?: APCProps[];
|
apcs: APCProps[];
|
||||||
|
apc1: APCProps;
|
||||||
|
apc2: APCProps;
|
||||||
master_control?: boolean;
|
master_control?: boolean;
|
||||||
switch_control_ip?: string; // Optional
|
switch_control_ip?: string; // Optional
|
||||||
switch_control_port?: number; // Optional
|
switch_control_port?: number; // Optional
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue