diff --git a/webapp/src/app/sfera-observer/sfera-observer.component.html b/webapp/src/app/sfera-observer/sfera-observer.component.html index e5e15944..57b771cf 100644 --- a/webapp/src/app/sfera-observer/sfera-observer.component.html +++ b/webapp/src/app/sfera-observer/sfera-observer.component.html @@ -32,6 +32,7 @@

SFERA Communication

+
@if (environmentControl.value) { diff --git a/webapp/src/app/sfera-observer/sfera-observer.component.ts b/webapp/src/app/sfera-observer/sfera-observer.component.ts index 61db2049..a09b9259 100644 --- a/webapp/src/app/sfera-observer/sfera-observer.component.ts +++ b/webapp/src/app/sfera-observer/sfera-observer.component.ts @@ -12,7 +12,12 @@ import { SbbCheckboxModule } from "@sbb-esta/angular/checkbox"; import { environment } from "../../environment/environment"; import { MessageTableComponent, TableData } from "./message-table/message-table.component"; import { SbbTableDataSource } from "@sbb-esta/angular/table"; -import { READONLY_MODE, SferaXmlCreation, SpRequestOptions } from "./sfera-xml-creation"; +import { + READONLY_MODE, + SferaXmlCreation, + SpRequestOptions, + TcRequestOptions +} from "./sfera-xml-creation"; import { SbbAccordionModule } from "@sbb-esta/angular/accordion"; @Component({ @@ -134,6 +139,8 @@ export class SferaObserverComponent implements OnDestroy { return `JP: ${this.getJourneyProfileStatus(document)}, #SP: ${this.getJourneyProfileNumberOfSPs(document)}`; } else if (this.containsElement(document, 'SegmentProfile')) { return this.getSegmentProfiles(document); + } else if(this.containsElement(document, 'TrainCharacteristics')) { + return this.getTrainCharacteristics(document); } } else if (type == "SFERA_B2G_RequestMessage") { if (this.isHandshakeRequest(document)) { @@ -205,7 +212,12 @@ export class SferaObserverComponent implements OnDestroy { private getSegmentProfiles(document: Document) { const segmentProfiles = Array.from(document.getElementsByTagName("SegmentProfile")); - return segmentProfiles.map(segmentProfile => `SP ${this.getSegmentProfileId(segmentProfile)}: ${this.getSegmentProfileStatus(segmentProfile)}, Length: ${this.getSegmentProfileLength(segmentProfile)}`).join('\n') + return segmentProfiles.map(segmentProfile => `SP ${this.getSegmentProfileId(segmentProfile)}: ${this.getSegmentProfileStatus(segmentProfile)}, Length: ${this.getSegmentProfileLength(segmentProfile)}`).join(', ') + } + + private getTrainCharacteristics(document: Document) { + const trainCharacteristics = Array.from(document.getElementsByTagName("TrainCharacteristics")); + return trainCharacteristics.map(trainCharacteristic => `TC ${this.getTrainCharacteristicsId(trainCharacteristic)}`).join(', '); } private getSegmentProfileStatus(element: Element) { @@ -220,6 +232,10 @@ export class SferaObserverComponent implements OnDestroy { return element.getAttribute("SP_ID"); } + private getTrainCharacteristicsId(element: Element) { + return element.getAttribute("TC_ID"); + } + sendXml() { const xmlString = this.xmlStringControl.value; this.mqService.publish(this.b2gTopic!, xmlString); @@ -286,6 +302,40 @@ export class SferaObserverComponent implements OnDestroy { this.mqService.publish(this.b2gTopic!, spRequest); } + sendTCRequest() { + const jpReplies = this.data.filter(row => row.type === 'SFERA_G2B_ReplyMessage' && row.info.includes('JP: Valid')) + if (jpReplies.length === 0) { + alert('No JP request sent') + return; + } + + const dom = this.toDom(jpReplies[jpReplies.length - 1].message) + + const trainCharacteristicsRefs = Array.from(dom.getElementsByTagName('TrainCharacteristicsRef')); + + const trainCharacteristics = trainCharacteristicsRefs.map(element => { + const tcId = element.getAttribute('TC_ID'); + const ruId = element.getElementsByTagName('TC_RU_ID')[0].textContent; + const minorVersion = element.getAttribute('TC_VersionMajor'); + const majorVersion = element.getAttribute('TC_VersionMinor'); + + return { + ruId: ruId, + tcId: tcId, + majorVersion: majorVersion, + minorVersion: minorVersion + } as TcRequestOptions; + }); + + const tcRequest = SferaXmlCreation.createRequest({ + header: { + sourceDevice: this.clientIdControl.value + }, + tcRequests: trainCharacteristics + }); + this.mqService.publish(this.b2gTopic!, tcRequest); + } + sendHSRWrongSferaVersion() { const handshakeRequest = SferaXmlCreation.createHandshakeRequest({ header: { diff --git a/webapp/src/app/sfera-observer/sfera-xml-creation.ts b/webapp/src/app/sfera-observer/sfera-xml-creation.ts index c6407392..303e0641 100644 --- a/webapp/src/app/sfera-observer/sfera-xml-creation.ts +++ b/webapp/src/app/sfera-observer/sfera-xml-creation.ts @@ -43,10 +43,18 @@ export interface SpRequestOptions { minorVersion: string; } +export interface TcRequestOptions { + ruId: string; + tcId: string; + majorVersion: string; + minorVersion: string; +} + export interface RequestOptions { header?: SferaHeaderOptions, - jpRequests?: JpRequestOptions[] - spRequests?: SpRequestOptions[] + jpRequests?: JpRequestOptions[], + spRequests?: SpRequestOptions[], + tcRequests?: TcRequestOptions[] } export interface SupportedOperationModes { @@ -106,6 +114,7 @@ export class SferaXmlCreation { const jpRequests = this.createJpRequest(options.jpRequests); const spRequests = this.createSpRequest(options.spRequests); + const tcRequests = this.createTcRequest(options.tcRequests); return ` @@ -116,6 +125,7 @@ export class SferaXmlCreation { ${jpRequests} ${spRequests} + ${tcRequests} `; @@ -167,6 +177,16 @@ export class SferaXmlCreation { return (strings || []).join(''); } + static createTcRequest(tcRequests: TcRequestOptions[] | undefined): string { + const strings = tcRequests?.map(tcRequest => { + return ` + ${tcRequest.ruId} + + `; + }) + return (strings || []).join(''); + } + private static defaultHeader(): SferaHeaderOptions { return { sferaVersion: '2.01',