This commit is contained in:
joseph le 2026-03-26 09:27:17 +07:00
parent 7888fc4090
commit 36dc75bee8
4 changed files with 58 additions and 55 deletions

View File

@ -1021,7 +1021,7 @@ export default class LineConnection {
await sendMessageToMail( await sendMessageToMail(
`[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Raw log issue ${result?.errors?.some((e) => e.category === 'SPECIAL_KEYWORD') ? '+ Special keywords' : ''}`, `[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Raw log issue ${result?.errors?.some((e) => e.category === 'SPECIAL_KEYWORD') ? '+ Special keywords' : ''}`,
tableHTML + tableHTML +
`${` `${`
<hr /> <hr />
<p>Logs:</p> <p>Logs:</p>
<div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;"> <div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;">
@ -1062,9 +1062,9 @@ export default class LineConnection {
<td style="padding:6px; text-align:center;">${r.rule}</td> <td style="padding:6px; text-align:center;">${r.rule}</td>
<td style="padding:6px; text-align:center;">${r.message}</td> <td style="padding:6px; text-align:center;">${r.message}</td>
<td style="padding:6px; font-family:monospace;">${escapeHtml(r.log.trim()) <td style="padding:6px; font-family:monospace;">${escapeHtml(r.log.trim())
.split('*') .split('*')
.filter((el) => el) .filter((el) => el)
.join('<br/>*')}</td> .join('<br/>*')}</td>
</tr> </tr>
` `
) )
@ -1229,6 +1229,10 @@ Ports Missing/Down: ${missing.length}\n\n`
lineId: this.config.id, lineId: this.config.id,
data: ports, data: ports,
}) })
if (ports.length === this.config.ports.length) {
this.sendReportPhysicalTest()
this.endTesting()
}
} }
} catch (error) { } catch (error) {
console.log('checkingPhysicalPort', error) console.log('checkingPhysicalPort', error)
@ -1433,7 +1437,7 @@ Ports Missing/Down: ${missing.length}\n\n`
await sendMessageToMail( await sendMessageToMail(
`[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Load IOS Report`, `[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Load IOS Report`,
body + body +
`${` `${`
<hr /> <hr />
<p>Logs:</p> <p>Logs:</p>
<div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;"> <div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;">
@ -1471,7 +1475,7 @@ Ports Missing/Down: ${missing.length}\n\n`
await sendMessageToMail( await sendMessageToMail(
`[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Load License Report`, `[ATC] - [${this.config.stationName} - Line: ${this.config.lineNumber}] - Load License Report`,
body + body +
`${` `${`
<hr /> <hr />
<p>Logs:</p> <p>Logs:</p>
<div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;"> <div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;">
@ -1776,15 +1780,15 @@ ${log}
<hr /> <hr />
<div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;"> <div style="white-space: break-spaces; background-color: #f5f5f5; color: black; padding: 8px; max-height: 500px; overflow-y: scroll; border: 1px #ccc solid;"><span style="color: black;">
${escapeHtml(output) ${escapeHtml(output)
.replace('show ver', '') .replace('show ver', '')
.replace('sh ver', '') .replace('sh ver', '')
.replace('show version', '') .replace('show version', '')
.replace('sh version', '') .replace('sh version', '')
.replace(mem, `<span style="color: ${isWarningRAM ? 'red' : 'black'};">${mem}</span>`) .replace(mem, `<span style="color: ${isWarningRAM ? 'red' : 'black'};">${mem}</span>`)
.replace( .replace(
flash, flash,
`<span style="color: ${isWarningFlash ? 'red' : 'black'};">${flash}</span>` `<span style="color: ${isWarningFlash ? 'red' : 'black'};">${flash}</span>`
)}</span></div> )}</span></div>
` `
await sendMessageToMail(subject, body) await sendMessageToMail(subject, body)
} }
@ -1857,14 +1861,13 @@ ${log}
IOS: <b>${dataShowVersion?.SOFTWARE_IMAGE ?? ''}</b> <b>${dataShowVersion?.VERSION ?? ''}</b><br/> IOS: <b>${dataShowVersion?.SOFTWARE_IMAGE ?? ''}</b> <b>${dataShowVersion?.VERSION ?? ''}</b><br/>
MEM: <b>${dataShowVersion?.MEMORY ? convertFromKilobytesString(dataShowVersion?.MEMORY) : ''}</b><br/> MEM: <b>${dataShowVersion?.MEMORY ? convertFromKilobytesString(dataShowVersion?.MEMORY) : ''}</b><br/>
FLASH: <b>${dataShowVersion?.USB_FLASH ? convertFromKilobytesString(dataShowVersion?.USB_FLASH) : ''}</b><br/> FLASH: <b>${dataShowVersion?.USB_FLASH ? convertFromKilobytesString(dataShowVersion?.USB_FLASH) : ''}</b><br/>
Licenses: <b>${ Licenses: <b>${dataShowLic
dataShowLic ? dataShowLic
? dataShowLic ?.filter((el) => el.LICENSE_TYPE?.toLowerCase()?.includes('permanent'))
?.filter((el) => el.LICENSE_TYPE?.toLowerCase()?.includes('permanent')) ?.map((v) => v.FEATURE)
?.map((v) => v.FEATURE) ?.join(', ')
?.join(', ') : ''
: '' }</b><br/>
}</b><br/>
Summary: <b style="color: ${!summary?.includes('No hardware issues found') ? '#ff0000' : ''};">${summary}</b><br/> Summary: <b style="color: ${!summary?.includes('No hardware issues found') ? '#ff0000' : ''};">${summary}</b><br/>
Issues: <b style="color: ${issue.filter((el) => !el.includes('No issues detected')).length ? '#ff0000' : 'black'};">${issue?.length ? `<br>- ` + issue.join(`<br>- `) : 'No issues detected.'}</b><br/> Issues: <b style="color: ${issue.filter((el) => !el.includes('No issues detected')).length ? '#ff0000' : 'black'};">${issue?.length ? `<br>- ` + issue.join(`<br>- `) : 'No issues detected.'}</b><br/>
</td> </td>
@ -1872,23 +1875,21 @@ ${log}
Total Ports: ${portPhysical?.length}<br/> Total Ports: ${portPhysical?.length}<br/>
Ports Tested (Link UP): <b style="color: #008000;">${tested.length} (${testedPoE?.length} PoE, ${testedSFP?.length} SFP)</b><br/> Ports Tested (Link UP): <b style="color: #008000;">${tested.length} (${testedPoE?.length} PoE, ${testedSFP?.length} SFP)</b><br/>
Ports Missing/Down: <b style="color: #ff0000;">${missing.length}</b><br/> Ports Missing/Down: <b style="color: #ff0000;">${missing.length}</b><br/>
${ ${missingPoE?.length
missingPoE?.length ? `
? `
<br/><b style="color: #ff0000;">Ports Missing PoE</b><br/> <br/><b style="color: #ff0000;">Ports Missing PoE</b><br/>
<br/> <br/>
<div style="column-count: 6;">${missingPoE.map((p) => physicalTest.normalizePortName(p.name)).join('<br/>')}</div> <div style="column-count: 6;">${missingPoE.map((p) => physicalTest.normalizePortName(p.name)).join('<br/>')}</div>
` `
: '' : ''
} }
${ ${missingSFP?.length
missingSFP?.length ? `
? `
<br/><b style="color: #ff0000;">Ports Missing SFP</b><br/> <br/><b style="color: #ff0000;">Ports Missing SFP</b><br/>
<br/> <br/>
<div style="column-count: 6;">${missingSFP.map((p) => physicalTest.normalizePortName(p.name)).join('<br/>')}</div>` <div style="column-count: 6;">${missingSFP.map((p) => physicalTest.normalizePortName(p.name)).join('<br/>')}</div>`
: '' : ''
} }
${reasonSkipPhysical} ${reasonSkipPhysical}
</td> </td>
</tr> </tr>

View File

@ -181,32 +181,29 @@ export class PhysicalPortTest {
</tr> </tr>
</table> </table>
<br/> <br/>
${ ${missing.length
missing.length ? `
? `
<br/> <br/>
<b style="color: #ff0000;">Missing Ports</b><br/> <b style="color: #ff0000;">Missing Ports</b><br/>
<table cellpadding="6" cellspacing="0" border="1" style="margin-top: 10px; border-collapse: collapse; width: 100%"> <table cellpadding="6" cellspacing="0" border="1" style="margin-top: 10px; border-collapse: collapse; width: 100%">
<tr> <tr>
${ ${missingPoE?.length
missingPoE?.length ? `<td>
? `<td>
<div style="column-count: 12;">${missingPoE.map((p) => this.normalizePortName(p.name)).join('<br/>')}</div> <div style="column-count: 12;">${missingPoE.map((p) => this.normalizePortName(p.name)).join('<br/>')}</div>
</td>` </td>`
: '' : ''
} }
${ ${missingSFP?.length
missingSFP?.length ? `<td>
? `<td>
<div style="column-count: 4;">${missingSFP.map((p) => this.normalizePortName(p.name)).join('<br/>')}</div> <div style="column-count: 4;">${missingSFP.map((p) => this.normalizePortName(p.name)).join('<br/>')}</div>
</td>` </td>`
: '' : ''
} }
</tr> </tr>
</table> </table>
` `
: '' : ''
} }
<br/> <br/>
<br/> <br/>
`.trim() `.trim()
@ -276,6 +273,10 @@ export class PhysicalPortTest {
} }
}) })
} }
if (ports.length === this.expectedPorts.length) {
this.done = true
this.onDone()
}
} }
return this.getTestedPorts() return this.getTestedPorts()

View File

@ -41,7 +41,8 @@ const parseLog = (data: string) => {
}) })
// If "pid", "vid", or "sn" are matched, push a completed record // If "pid", "vid", or "sn" are matched, push a completed record
if (currentRecord.pid || currentRecord.vid || currentRecord.sn) { if (currentRecord.pid || currentRecord.vid || currentRecord.sn) {
records.push({ ...currentRecord }) if (!currentRecord?.name?.toLowerCase().includes('stack'))
records.push({ ...currentRecord })
currentRecord = { currentRecord = {
name: '', name: '',
descr: '', descr: '',

View File

@ -53,22 +53,22 @@ type StationAction = (
export default class SocketIoProvider { export default class SocketIoProvider {
private static _io: CustomServer private static _io: CustomServer
constructor(protected app: ApplicationService) {} constructor(protected app: ApplicationService) { }
/** /**
* Register bindings to the container * Register bindings to the container
*/ */
register() {} register() { }
/** /**
* The container bindings have booted * The container bindings have booted
*/ */
async boot() {} async boot() { }
/** /**
* The application has been booted * The application has been booted
*/ */
async start() {} async start() { }
/** /**
* The process has been started * The process has been started
@ -83,7 +83,7 @@ export default class SocketIoProvider {
/** /**
* Preparing to shutdown the app * Preparing to shutdown the app
*/ */
async shutdown() {} async shutdown() { }
public static get io() { public static get io() {
return this._io return this._io
@ -100,7 +100,7 @@ export class WebSocketIo {
lineConnecting: number[] = [] // key = lineId lineConnecting: number[] = [] // key = lineId
intervalKeepConnect: { [key: string]: NodeJS.Timeout } = {} intervalKeepConnect: { [key: string]: NodeJS.Timeout } = {}
constructor(protected app: ApplicationService) {} constructor(protected app: ApplicationService) { }
async boot() { async boot() {
const SOCKET_IO_PORT = env.get('SOCKET_PORT') || 8989 const SOCKET_IO_PORT = env.get('SOCKET_PORT') || 8989