diff --git a/src/components/draw-app/properties/CombinationTypeConfig.vue b/src/components/draw-app/properties/CombinationTypeConfig.vue
index c4b224c..4bacc6c 100644
--- a/src/components/draw-app/properties/CombinationTypeConfig.vue
+++ b/src/components/draw-app/properties/CombinationTypeConfig.vue
@@ -20,10 +20,8 @@
关联的继电器
();
+ }
+ clone(): RelayState {
+ return new RelayState(this.states.cloneMessage());
+ }
+ copyFrom(data: GraphicStateBase): void {
+ pb_1.Message.copyInto(data._state, this._state);
+ }
+ eq(data: GraphicStateBase): boolean {
+ return pb_1.Message.equals(this._state, data._state);
+ }
+}
diff --git a/src/drawApp/relayCabinetLayoutApp.ts b/src/drawApp/relayCabinetLayoutApp.ts
index f4b1f86..071f348 100644
--- a/src/drawApp/relayCabinetLayoutApp.ts
+++ b/src/drawApp/relayCabinetLayoutApp.ts
@@ -25,7 +25,7 @@ import {
import { RelayCabinetData } from './relayCabinetGraphics/RelayCabinetInteraction';
import { RelayCabinetDraw } from 'src/graphics/relayCabinet/RelayCabinetDrawAssistant';
import { Relay, RelayTemplate } from 'src/graphics/relay/Relay';
-import { RelayData } from './relayCabinetGraphics/RelayInteraction';
+import { RelayData, RelayState } from './relayCabinetGraphics/RelayInteraction';
import { RelayDraw } from 'src/graphics/relay/RelayDrawAssistant';
import {
PhaseFailureProtector,
@@ -75,7 +75,7 @@ export function initDrawApp(): IDrawApp {
});
const app = drawApp;
new RelayCabinetDraw(app, new RelayCabinetTemplate(new RelayCabinetData()));
- new RelayDraw(app, new RelayTemplate(new RelayData()));
+ new RelayDraw(app, new RelayTemplate(new RelayData(), new RelayState()));
new PhaseFailureProtectorDraw(
app,
new PhaseFailureProtectorTemplate(new PhaseFailureProtectorData())
diff --git a/src/drawApp/relayScene.ts b/src/drawApp/relayScene.ts
index 6f784d1..e39c114 100644
--- a/src/drawApp/relayScene.ts
+++ b/src/drawApp/relayScene.ts
@@ -1,13 +1,25 @@
-import { GraphicData, IGraphicApp, IGraphicStorage } from 'src/jl-graphic';
+import {
+ ClientEngine,
+ GraphicData,
+ GraphicQueryStore,
+ GraphicState,
+ IGraphicApp,
+ IGraphicScene,
+ IGraphicStorage,
+} from 'src/jl-graphic';
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
import { useLineStore } from 'src/stores/line-store';
import { toUint8Array } from 'js-base64';
import { relayCabinetGraphicData } from 'src/protos/relayCabinetLayoutGraphics';
import { RelayCabinetData } from './relayCabinetGraphics/RelayCabinetInteraction';
-import { RelayData } from './relayCabinetGraphics/RelayInteraction';
+import { RelayData, RelayState } from './relayCabinetGraphics/RelayInteraction';
import { RelayCabinetTemplate } from 'src/graphics/relayCabinet/RelayCabinet';
import { RelayTemplate } from 'src/graphics/relay/Relay';
import { SceneToPictureType } from './lineApp';
+import { getWebsocketUrl } from 'src/configs/UrlManage';
+import { getOnlyToken } from 'src/configs/TokenManage';
+import { state } from 'src/protos/device_state';
+import { Notify, QNotifyUpdateOptions } from 'quasar';
export function initRelayScene(lineApp: IGraphicApp) {
// 继电器
@@ -21,10 +33,68 @@ export function initRelayScene(lineApp: IGraphicApp) {
});
const relayGraphicTemplate = [
new RelayCabinetTemplate(new RelayCabinetData()),
- new RelayTemplate(new RelayData()),
+ new RelayTemplate(new RelayData(), new RelayState()),
];
relayScene.registerGraphicTemplates(...relayGraphicTemplate);
- return lineApp;
+ relayScene.on('postdataloaded', () => {
+ handleSubscribe(relayScene, lineApp);
+ });
+}
+
+function handleSubscribe(relayScene: IGraphicScene, lineApp: IGraphicApp) {
+ const lineStore = useLineStore();
+ const simulationId = lineStore.simulationId;
+ const mapId = lineStore.mapId;
+ const app = relayScene;
+
+ lineApp?.enableWsMassaging({
+ engine: ClientEngine.Centrifugo,
+ wsUrl: `${getWebsocketUrl()}`,
+ token: getOnlyToken() as string,
+ });
+ app.subscribe({
+ destination: `simulation-${simulationId}_${mapId}-devices-status`,
+ messageConverter: (message: Uint8Array) => {
+ const states: GraphicState[] = [];
+ const storage = state.PushedDevicesStatus.deserialize(message);
+ if (storage.all) {
+ storage.allStatus.replyState.forEach((relayState) => {
+ if (relayState.id) {
+ states.push(new RelayState(relayState));
+ }
+ });
+ } else {
+ storage.varStatus.updatedReply.forEach((relayState) => {
+ if (relayState.id) {
+ states.push(new RelayState(relayState));
+ }
+ });
+ }
+ if (states && states.length > 0) {
+ lineStore.setSocketStates(states);
+ }
+ return states;
+ },
+ graphicQueryer: (state: GraphicState, store: GraphicQueryStore) => {
+ return store.queryById(state.code);
+ },
+ });
+
+ let msgNotify: null | ((props?: QNotifyUpdateOptions | undefined) => void) =
+ null;
+ app.on('websocket-connect-state-change', (connected) => {
+ if (!connected && !msgNotify) {
+ msgNotify = Notify.create({
+ type: 'negative',
+ timeout: 0,
+ position: 'top-right',
+ message: '通信链接已断开!',
+ });
+ } else if (msgNotify && connected) {
+ msgNotify();
+ msgNotify = null;
+ }
+ });
}
async function loadRelayDatas(): Promise {
diff --git a/src/graphics/relay/Relay.ts b/src/graphics/relay/Relay.ts
index 4242529..43d62da 100644
--- a/src/graphics/relay/Relay.ts
+++ b/src/graphics/relay/Relay.ts
@@ -1,6 +1,7 @@
import { Color, Graphics } from 'pixi.js';
import {
GraphicData,
+ GraphicState,
JlGraphic,
JlGraphicTemplate,
VectorText,
@@ -16,10 +17,16 @@ export interface IRelayData extends GraphicData {
eq(other: IRelayData): boolean;
}
+export interface IRelayState extends GraphicState {
+ get xh(): boolean; //继电器吸合
+ set xh(v: boolean);
+}
+
export const relayConsts = {
radius: 8,
lineWidth: 3,
- lineColor: '0xff0000',
+ closeColor: '0x00FF00',
+ openColor: '0xff0000',
};
export class Relay extends JlGraphic {
static Type = 'Relay';
@@ -39,6 +46,11 @@ export class Relay extends JlGraphic {
get datas(): IRelayData {
return this.getDatas();
}
+
+ get states(): IRelayState {
+ return this.getStates();
+ }
+
doRepaint(): void {
this.labelGraphic.text = this.datas.code;
const labelPosition = this.datas.childTransforms?.find(
@@ -51,10 +63,16 @@ export class Relay extends JlGraphic {
}
this.refDevice.position.set(0, -20);
const relayGraphic = this.relayGraphic;
+ let relayColor = relayConsts.openColor;
+ if (this.states?.xh) {
+ relayColor = relayConsts.closeColor;
+ } else {
+ relayColor = relayConsts.openColor;
+ }
relayGraphic
.clear()
- .lineStyle(relayConsts.lineWidth, new Color(relayConsts.lineColor));
- relayGraphic.beginFill(relayConsts.lineColor);
+ .lineStyle(relayConsts.lineWidth, new Color(relayColor));
+ relayGraphic.beginFill(relayColor);
relayGraphic.drawCircle(0, 0, relayConsts.radius);
relayGraphic.endFill;
}
@@ -68,14 +86,16 @@ export class Relay extends JlGraphic {
}
export class RelayTemplate extends JlGraphicTemplate {
- constructor(dataTemplate: IRelayData) {
+ constructor(dataTemplate: IRelayData, stateTemplate?: IRelayState) {
super(Relay.Type, {
dataTemplate,
+ stateTemplate,
});
}
new(): Relay {
const relay = new Relay();
relay.loadData(this.datas);
+ relay.loadState(this.states);
return relay;
}
}
diff --git a/src/protos/device_state.ts b/src/protos/device_state.ts
index 4a3e641..ca12c58 100644
--- a/src/protos/device_state.ts
+++ b/src/protos/device_state.ts
@@ -2166,9 +2166,10 @@ export namespace state {
removedTrainId?: string[];
updatedSwitch?: SwitchState[];
updatedSection?: SectionState[];
+ updatedReply?: ReplyState[];
}) {
super();
- pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [1, 2, 3, 4], this.#one_of_decls);
+ pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [1, 2, 3, 4, 5], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("updatedTrain" in data && data.updatedTrain != undefined) {
this.updatedTrain = data.updatedTrain;
@@ -2182,6 +2183,9 @@ export namespace state {
if ("updatedSection" in data && data.updatedSection != undefined) {
this.updatedSection = data.updatedSection;
}
+ if ("updatedReply" in data && data.updatedReply != undefined) {
+ this.updatedReply = data.updatedReply;
+ }
}
}
get updatedTrain() {
@@ -2208,11 +2212,18 @@ export namespace state {
set updatedSection(value: SectionState[]) {
pb_1.Message.setRepeatedWrapperField(this, 4, value);
}
+ get updatedReply() {
+ return pb_1.Message.getRepeatedWrapperField(this, ReplyState, 5) as ReplyState[];
+ }
+ set updatedReply(value: ReplyState[]) {
+ pb_1.Message.setRepeatedWrapperField(this, 5, value);
+ }
static fromObject(data: {
updatedTrain?: ReturnType[];
removedTrainId?: string[];
updatedSwitch?: ReturnType[];
updatedSection?: ReturnType[];
+ updatedReply?: ReturnType[];
}): VariationStatus {
const message = new VariationStatus({});
if (data.updatedTrain != null) {
@@ -2227,6 +2238,9 @@ export namespace state {
if (data.updatedSection != null) {
message.updatedSection = data.updatedSection.map(item => SectionState.fromObject(item));
}
+ if (data.updatedReply != null) {
+ message.updatedReply = data.updatedReply.map(item => ReplyState.fromObject(item));
+ }
return message;
}
toObject() {
@@ -2235,6 +2249,7 @@ export namespace state {
removedTrainId?: string[];
updatedSwitch?: ReturnType[];
updatedSection?: ReturnType[];
+ updatedReply?: ReturnType[];
} = {};
if (this.updatedTrain != null) {
data.updatedTrain = this.updatedTrain.map((item: TrainState) => item.toObject());
@@ -2248,6 +2263,9 @@ export namespace state {
if (this.updatedSection != null) {
data.updatedSection = this.updatedSection.map((item: SectionState) => item.toObject());
}
+ if (this.updatedReply != null) {
+ data.updatedReply = this.updatedReply.map((item: ReplyState) => item.toObject());
+ }
return data;
}
serialize(): Uint8Array;
@@ -2262,6 +2280,8 @@ export namespace state {
writer.writeRepeatedMessage(3, this.updatedSwitch, (item: SwitchState) => item.serialize(writer));
if (this.updatedSection.length)
writer.writeRepeatedMessage(4, this.updatedSection, (item: SectionState) => item.serialize(writer));
+ if (this.updatedReply.length)
+ writer.writeRepeatedMessage(5, this.updatedReply, (item: ReplyState) => item.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
@@ -2283,6 +2303,9 @@ export namespace state {
case 4:
reader.readMessage(message.updatedSection, () => pb_1.Message.addToRepeatedWrapperField(message, 4, SectionState.deserialize(reader), SectionState));
break;
+ case 5:
+ reader.readMessage(message.updatedReply, () => pb_1.Message.addToRepeatedWrapperField(message, 5, ReplyState.deserialize(reader), ReplyState));
+ break;
default: reader.skipField();
}
}