From b9d25e8c7fc3a4b1b5f03a01d0e0644f9afd4507 Mon Sep 17 00:00:00 2001 From: joylink_zhangsai <1021828630@qq.com> Date: Thu, 2 Nov 2023 15:50:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B1=8F=E8=94=BD=E9=97=A8?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=8E=A5=E5=8F=A3=EF=BC=9B=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=B1=8F=E8=94=BD=E9=97=A8=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/simulation.go | 34 ++- bj-rtss-message | 2 +- docs/docs.go | 215 +++++++++++--- docs/swagger.json | 215 +++++++++++--- docs/swagger.yaml | 147 +++++++-- dto/error.go | 1 + dto/request_proto/request.pb.go | 262 ++++++++++++++-- message_server/sfp_ms.go | 5 +- protobuf/file.bin | Bin 95419 -> 0 bytes protobuf/main_test.go | 280 ------------------ rtss_simulation | 2 +- ts/protos/graphicData/ibpGraphics.pb.go | 2 +- ts/protos/graphicData/picture.pb.go | 2 +- ts/protos/graphicData/pslGraphics.pb.go | 2 +- .../relayCabinetLayoutGraphics.pb.go | 2 +- .../graphicData/stationLayoutGraphics.pb.go | 2 +- ts/protos/state/device_state.pb.go | 199 +++++++------ .../wayside/memory/wayside_memory_map_init.go | 2 + .../wayside/memory/wayside_memory_psd.go | 34 +++ .../wayside/memory/wayside_memory_psd_test.go | 110 +++++++ 20 files changed, 991 insertions(+), 527 deletions(-) delete mode 100644 protobuf/file.bin delete mode 100644 protobuf/main_test.go create mode 100644 ts/simulation/wayside/memory/wayside_memory_psd_test.go diff --git a/api/simulation.go b/api/simulation.go index d9a1c88..8299b55 100644 --- a/api/simulation.go +++ b/api/simulation.go @@ -38,6 +38,7 @@ func InitSimulationRouter(api *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddle authed.POST("/ibp/key/operation", ibpKeyOperation) authed.GET("/:id/getMapKilometerRange", getMapKilometerRange) authed.POST("/psl/operation", pslBtnOperation) + authed.POST("/psd/operation", psdOperation) // 初始化地图信息 initPublishMapInfo() @@ -397,7 +398,7 @@ func ibpKeyOperation(c *gin.Context) { c.JSON(http.StatusOK, "ok") } -// PSL操作 +// PSL按钮操作 // // @Summary PSL操作 // @@ -412,7 +413,7 @@ func ibpKeyOperation(c *gin.Context) { // // @Success 200 {object} string // @Failure 500 {object} dto.ErrorDto -// @Router /api/v1/simulation/ibp/operation [post] +// @Router /api/v1/simulation/psl/operation [post] func pslBtnOperation(c *gin.Context) { req := &dto.PslOperationReqDto{} if err := c.ShouldBind(&req); err != nil { @@ -424,6 +425,35 @@ func pslBtnOperation(c *gin.Context) { c.JSON(http.StatusOK, "ok") } +// 屏蔽门操作 +// +// @Summary 屏蔽门操作 +// +// @Security JwtAuth +// +// @Description 屏蔽门操作 +// @Tags ATS测试仿真Api +// @Accept json +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Param PsdOperationReq body request_proto.PsdOperationReq true "屏蔽门操作" +// +// @Success 200 {object} string +// @Failure 500 {object} dto.ErrorDto +// @Router /api/v1/simulation/psd/operation [post] +func psdOperation(c *gin.Context) { + req := &request_proto.PsdOperationReq{} + if err := c.ShouldBind(&req); err != nil { + panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()}) + } + simulation := checkDeviceDataAndReturn(req.SimulationId) + slog.Info("传入状态参数", req) + if err := memory.HandlePsdOperation(simulation, req); err != nil { + panic(dto.ErrorDto{Code: dto.ArgumentError, Message: err.Error()}) + } + c.JSON(http.StatusOK, "ok") +} + // 获取仿真地图的公里标范围 // // @Summary 获取仿真地图的公里标范围 diff --git a/bj-rtss-message b/bj-rtss-message index ebfb67b..92c5696 160000 --- a/bj-rtss-message +++ b/bj-rtss-message @@ -1 +1 @@ -Subproject commit ebfb67be9c57e2bf9b3e4b8887f028911b9dba96 +Subproject commit 92c5696b7eb3b47b387f48e094f5c8644ddb7da8 diff --git a/docs/docs.go b/docs/docs.go index f768548..b158f08 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -3536,7 +3536,105 @@ const docTemplate = `{ } } }, - "/api/v1/simulation/ibp/operation": { + "/api/v1/simulation/list": { + "get": { + "security": [ + { + "JwtAuth": [] + } + ], + "description": "获取ATS测试系统所有仿真实例的基本信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ATS测试仿真Api" + ], + "summary": "获取ATS测试系统所有仿真实例的基本信息", + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.SimulationInfoRspDto" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/dto.ErrorDto" + } + } + } + } + }, + "/api/v1/simulation/psd/operation": { + "post": { + "security": [ + { + "JwtAuth": [] + } + ], + "description": "屏蔽门操作", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ATS测试仿真Api" + ], + "summary": "屏蔽门操作", + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "description": "屏蔽门操作", + "name": "PsdOperationReq", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request_proto.PsdOperationReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/dto.ErrorDto" + } + } + } + } + }, + "/api/v1/simulation/psl/operation": { "post": { "security": [ { @@ -3588,52 +3686,6 @@ const docTemplate = `{ } } }, - "/api/v1/simulation/list": { - "get": { - "security": [ - { - "JwtAuth": [] - } - ], - "description": "获取ATS测试系统所有仿真实例的基本信息", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ATS测试仿真Api" - ], - "summary": "获取ATS测试系统所有仿真实例的基本信息", - "parameters": [ - { - "type": "string", - "description": "JWT Token", - "name": "Authorization", - "in": "header", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dto.SimulationInfoRspDto" - } - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/dto.ErrorDto" - } - } - } - } - }, "/api/v1/simulation/relay/operation": { "post": { "security": [ @@ -5301,6 +5353,12 @@ const docTemplate = `{ }, "simulationId": { "type": "string" + }, + "trainIn": { + "type": "boolean" + }, + "trainOut": { + "type": "boolean" } } }, @@ -6058,6 +6116,69 @@ const docTemplate = `{ } } }, + "request_proto.PsdOperationReq": { + "type": "object", + "properties": { + "deviceId": { + "description": "设备id", + "type": "string" + }, + "mapId": { + "description": "图id", + "type": "integer" + }, + "operation": { + "description": "操作", + "allOf": [ + { + "$ref": "#/definitions/request_proto.Psd_Operation" + } + ] + }, + "simulationId": { + "description": "仿真id", + "type": "string" + } + } + }, + "request_proto.Psd_Operation": { + "type": "integer", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "x-enum-comments": { + "Psd_CancelGm": "取消关门", + "Psd_CancelKm4": "取消四编组开门", + "Psd_CancelKm8": "取消八编组开门", + "Psd_ForceGm": "强制关门", + "Psd_ForceKm4": "强制四编组开门", + "Psd_ForceKm8": "强制八编组开门", + "Psd_Gm": "关门", + "Psd_Km4": "四编组开门", + "Psd_Km8": "八编组开门" + }, + "x-enum-varnames": [ + "Psd_Undefined", + "Psd_Km4", + "Psd_CancelKm4", + "Psd_Km8", + "Psd_CancelKm8", + "Psd_Gm", + "Psd_CancelGm", + "Psd_ForceKm4", + "Psd_ForceKm8", + "Psd_ForceGm" + ] + }, "request_proto.Section_Operation": { "type": "integer", "enum": [ diff --git a/docs/swagger.json b/docs/swagger.json index 2f75dcb..7285fc3 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -3529,7 +3529,105 @@ } } }, - "/api/v1/simulation/ibp/operation": { + "/api/v1/simulation/list": { + "get": { + "security": [ + { + "JwtAuth": [] + } + ], + "description": "获取ATS测试系统所有仿真实例的基本信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ATS测试仿真Api" + ], + "summary": "获取ATS测试系统所有仿真实例的基本信息", + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.SimulationInfoRspDto" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/dto.ErrorDto" + } + } + } + } + }, + "/api/v1/simulation/psd/operation": { + "post": { + "security": [ + { + "JwtAuth": [] + } + ], + "description": "屏蔽门操作", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ATS测试仿真Api" + ], + "summary": "屏蔽门操作", + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "description": "屏蔽门操作", + "name": "PsdOperationReq", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request_proto.PsdOperationReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/dto.ErrorDto" + } + } + } + } + }, + "/api/v1/simulation/psl/operation": { "post": { "security": [ { @@ -3581,52 +3679,6 @@ } } }, - "/api/v1/simulation/list": { - "get": { - "security": [ - { - "JwtAuth": [] - } - ], - "description": "获取ATS测试系统所有仿真实例的基本信息", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ATS测试仿真Api" - ], - "summary": "获取ATS测试系统所有仿真实例的基本信息", - "parameters": [ - { - "type": "string", - "description": "JWT Token", - "name": "Authorization", - "in": "header", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dto.SimulationInfoRspDto" - } - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/dto.ErrorDto" - } - } - } - } - }, "/api/v1/simulation/relay/operation": { "post": { "security": [ @@ -5294,6 +5346,12 @@ }, "simulationId": { "type": "string" + }, + "trainIn": { + "type": "boolean" + }, + "trainOut": { + "type": "boolean" } } }, @@ -6051,6 +6109,69 @@ } } }, + "request_proto.PsdOperationReq": { + "type": "object", + "properties": { + "deviceId": { + "description": "设备id", + "type": "string" + }, + "mapId": { + "description": "图id", + "type": "integer" + }, + "operation": { + "description": "操作", + "allOf": [ + { + "$ref": "#/definitions/request_proto.Psd_Operation" + } + ] + }, + "simulationId": { + "description": "仿真id", + "type": "string" + } + } + }, + "request_proto.Psd_Operation": { + "type": "integer", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "x-enum-comments": { + "Psd_CancelGm": "取消关门", + "Psd_CancelKm4": "取消四编组开门", + "Psd_CancelKm8": "取消八编组开门", + "Psd_ForceGm": "强制关门", + "Psd_ForceKm4": "强制四编组开门", + "Psd_ForceKm8": "强制八编组开门", + "Psd_Gm": "关门", + "Psd_Km4": "四编组开门", + "Psd_Km8": "八编组开门" + }, + "x-enum-varnames": [ + "Psd_Undefined", + "Psd_Km4", + "Psd_CancelKm4", + "Psd_Km8", + "Psd_CancelKm8", + "Psd_Gm", + "Psd_CancelGm", + "Psd_ForceKm4", + "Psd_ForceKm8", + "Psd_ForceGm" + ] + }, "request_proto.Section_Operation": { "type": "integer", "enum": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ae3b795..e5b14b2 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -70,6 +70,10 @@ definitions: $ref: '#/definitions/request_proto.Section_Operation' simulationId: type: string + trainIn: + type: boolean + trainOut: + type: boolean required: - id - mapId @@ -598,6 +602,56 @@ definitions: description: 名称 type: string type: object + request_proto.Psd_Operation: + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + type: integer + x-enum-comments: + Psd_CancelGm: 取消关门 + Psd_CancelKm4: 取消四编组开门 + Psd_CancelKm8: 取消八编组开门 + Psd_ForceGm: 强制关门 + Psd_ForceKm4: 强制四编组开门 + Psd_ForceKm8: 强制八编组开门 + Psd_Gm: 关门 + Psd_Km4: 四编组开门 + Psd_Km8: 八编组开门 + x-enum-varnames: + - Psd_Undefined + - Psd_Km4 + - Psd_CancelKm4 + - Psd_Km8 + - Psd_CancelKm8 + - Psd_Gm + - Psd_CancelGm + - Psd_ForceKm4 + - Psd_ForceKm8 + - Psd_ForceGm + request_proto.PsdOperationReq: + properties: + deviceId: + description: 设备id + type: string + mapId: + description: 图id + type: integer + operation: + allOf: + - $ref: '#/definitions/request_proto.Psd_Operation' + description: 操作 + simulationId: + description: 仿真id + type: string + type: object request_proto.Section_Operation: enum: - 0 @@ -2985,7 +3039,69 @@ paths: summary: ATS测试-IBP钥匙操作 tags: - ATS测试仿真Api - /api/v1/simulation/ibp/operation: + /api/v1/simulation/list: + get: + consumes: + - application/json + description: 获取ATS测试系统所有仿真实例的基本信息 + parameters: + - description: JWT Token + in: header + name: Authorization + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/dto.SimulationInfoRspDto' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/dto.ErrorDto' + security: + - JwtAuth: [] + summary: 获取ATS测试系统所有仿真实例的基本信息 + tags: + - ATS测试仿真Api + /api/v1/simulation/psd/operation: + post: + consumes: + - application/json + description: 屏蔽门操作 + parameters: + - description: JWT Token + in: header + name: Authorization + required: true + type: string + - description: 屏蔽门操作 + in: body + name: PsdOperationReq + required: true + schema: + $ref: '#/definitions/request_proto.PsdOperationReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/dto.ErrorDto' + security: + - JwtAuth: [] + summary: 屏蔽门操作 + tags: + - ATS测试仿真Api + /api/v1/simulation/psl/operation: post: consumes: - application/json @@ -3018,35 +3134,6 @@ paths: summary: PSL操作 tags: - ATS测试仿真Api - /api/v1/simulation/list: - get: - consumes: - - application/json - description: 获取ATS测试系统所有仿真实例的基本信息 - parameters: - - description: JWT Token - in: header - name: Authorization - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/dto.SimulationInfoRspDto' - type: array - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/dto.ErrorDto' - security: - - JwtAuth: [] - summary: 获取ATS测试系统所有仿真实例的基本信息 - tags: - - ATS测试仿真Api /api/v1/simulation/relay/operation: post: consumes: diff --git a/dto/error.go b/dto/error.go index 9e8674e..863d43d 100644 --- a/dto/error.go +++ b/dto/error.go @@ -13,6 +13,7 @@ const ( // DataOperationError 数据操作错误(增删改查操作出了意料之外的错误都算) DataOperationError = 2002 ArgumentParseError = 3000 + ArgumentError = 3001 //参数错误。指参数对应的数据不存在等情况 NoAuthOperationError = 4001 diff --git a/dto/request_proto/request.pb.go b/dto/request_proto/request.pb.go index 0ae6092..63ccf16 100644 --- a/dto/request_proto/request.pb.go +++ b/dto/request_proto/request.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.31.0 // protoc v4.23.1 // source: request.proto @@ -233,6 +233,76 @@ func (Section_Operation) EnumDescriptor() ([]byte, []int) { return file_request_proto_rawDescGZIP(), []int{3, 0} } +type Psd_Operation int32 + +const ( + Psd_Undefined Psd_Operation = 0 + Psd_Km4 Psd_Operation = 1 //四编组开门 + Psd_CancelKm4 Psd_Operation = 2 //取消四编组开门 + Psd_Km8 Psd_Operation = 3 //八编组开门 + Psd_CancelKm8 Psd_Operation = 4 //取消八编组开门 + Psd_Gm Psd_Operation = 5 //关门 + Psd_CancelGm Psd_Operation = 6 //取消关门 + Psd_ForceKm4 Psd_Operation = 7 //强制四编组开门 + Psd_ForceKm8 Psd_Operation = 8 //强制八编组开门 + Psd_ForceGm Psd_Operation = 9 //强制关门 +) + +// Enum value maps for Psd_Operation. +var ( + Psd_Operation_name = map[int32]string{ + 0: "Undefined", + 1: "Km4", + 2: "CancelKm4", + 3: "Km8", + 4: "CancelKm8", + 5: "Gm", + 6: "CancelGm", + 7: "ForceKm4", + 8: "ForceKm8", + 9: "ForceGm", + } + Psd_Operation_value = map[string]int32{ + "Undefined": 0, + "Km4": 1, + "CancelKm4": 2, + "Km8": 3, + "CancelKm8": 4, + "Gm": 5, + "CancelGm": 6, + "ForceKm4": 7, + "ForceKm8": 8, + "ForceGm": 9, + } +) + +func (x Psd_Operation) Enum() *Psd_Operation { + p := new(Psd_Operation) + *p = x + return p +} + +func (x Psd_Operation) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Psd_Operation) Descriptor() protoreflect.EnumDescriptor { + return file_request_proto_enumTypes[3].Descriptor() +} + +func (Psd_Operation) Type() protoreflect.EnumType { + return &file_request_proto_enumTypes[3] +} + +func (x Psd_Operation) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Psd_Operation.Descriptor instead. +func (Psd_Operation) EnumDescriptor() ([]byte, []int) { + return file_request_proto_rawDescGZIP(), []int{4, 0} +} + // 道岔 type Turnout struct { state protoimpl.MessageState @@ -422,6 +492,117 @@ func (*Section) Descriptor() ([]byte, []int) { return file_request_proto_rawDescGZIP(), []int{3} } +// 屏蔽门 +type Psd struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Psd) Reset() { + *x = Psd{} + if protoimpl.UnsafeEnabled { + mi := &file_request_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Psd) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Psd) ProtoMessage() {} + +func (x *Psd) ProtoReflect() protoreflect.Message { + mi := &file_request_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Psd.ProtoReflect.Descriptor instead. +func (*Psd) Descriptor() ([]byte, []int) { + return file_request_proto_rawDescGZIP(), []int{4} +} + +// 屏蔽门操作请求 +type PsdOperationReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SimulationId string `protobuf:"bytes,1,opt,name=simulationId,proto3" json:"simulationId,omitempty"` // 仿真id + MapId int32 `protobuf:"varint,2,opt,name=mapId,proto3" json:"mapId,omitempty"` // 图id + DeviceId string `protobuf:"bytes,3,opt,name=deviceId,proto3" json:"deviceId,omitempty"` // 设备id + Operation Psd_Operation `protobuf:"varint,4,opt,name=operation,proto3,enum=request.Psd_Operation" json:"operation,omitempty"` // 操作 +} + +func (x *PsdOperationReq) Reset() { + *x = PsdOperationReq{} + if protoimpl.UnsafeEnabled { + mi := &file_request_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PsdOperationReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PsdOperationReq) ProtoMessage() {} + +func (x *PsdOperationReq) ProtoReflect() protoreflect.Message { + mi := &file_request_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PsdOperationReq.ProtoReflect.Descriptor instead. +func (*PsdOperationReq) Descriptor() ([]byte, []int) { + return file_request_proto_rawDescGZIP(), []int{5} +} + +func (x *PsdOperationReq) GetSimulationId() string { + if x != nil { + return x.SimulationId + } + return "" +} + +func (x *PsdOperationReq) GetMapId() int32 { + if x != nil { + return x.MapId + } + return 0 +} + +func (x *PsdOperationReq) GetDeviceId() string { + if x != nil { + return x.DeviceId + } + return "" +} + +func (x *PsdOperationReq) GetOperation() Psd_Operation { + if x != nil { + return x.Operation + } + return Psd_Undefined +} + var File_request_proto protoreflect.FileDescriptor var file_request_proto_rawDesc = []byte{ @@ -471,9 +652,28 @@ var file_request_proto_rawDesc = []byte{ 0x0b, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x50, 0x64, 0x72, 0x73, 0x74, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x63, 0x63, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x63, - 0x63, 0x10, 0x05, 0x42, 0x15, 0x5a, 0x13, 0x2e, 0x2f, 0x64, 0x74, 0x6f, 0x2f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x63, 0x10, 0x05, 0x22, 0x91, 0x01, 0x0a, 0x03, 0x50, 0x73, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x09, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4b, 0x6d, 0x34, 0x10, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4b, 0x6d, 0x34, 0x10, 0x02, + 0x12, 0x07, 0x0a, 0x03, 0x4b, 0x6d, 0x38, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x61, 0x6e, + 0x63, 0x65, 0x6c, 0x4b, 0x6d, 0x38, 0x10, 0x04, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x6d, 0x10, 0x05, + 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x47, 0x6d, 0x10, 0x06, 0x12, 0x0c, + 0x0a, 0x08, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x4b, 0x6d, 0x34, 0x10, 0x07, 0x12, 0x0c, 0x0a, 0x08, + 0x46, 0x6f, 0x72, 0x63, 0x65, 0x4b, 0x6d, 0x38, 0x10, 0x08, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x6f, + 0x72, 0x63, 0x65, 0x47, 0x6d, 0x10, 0x09, 0x22, 0x9d, 0x01, 0x0a, 0x0f, 0x50, 0x73, 0x64, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x0c, 0x73, + 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x70, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x6d, 0x61, 0x70, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x34, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, + 0x73, 0x64, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x15, 0x5a, 0x13, 0x2e, 0x2f, 0x64, 0x74, 0x6f, + 0x2f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -488,24 +688,28 @@ func file_request_proto_rawDescGZIP() []byte { return file_request_proto_rawDescData } -var file_request_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_request_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_request_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_request_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_request_proto_goTypes = []interface{}{ (Turnout_Operation)(0), // 0: request.Turnout.Operation (Signal_Operation)(0), // 1: request.Signal.Operation (Section_Operation)(0), // 2: request.Section.Operation - (*Turnout)(nil), // 3: request.Turnout - (*TurnoutOperationReq)(nil), // 4: request.TurnoutOperationReq - (*Signal)(nil), // 5: request.Signal - (*Section)(nil), // 6: request.Section + (Psd_Operation)(0), // 3: request.Psd.Operation + (*Turnout)(nil), // 4: request.Turnout + (*TurnoutOperationReq)(nil), // 5: request.TurnoutOperationReq + (*Signal)(nil), // 6: request.Signal + (*Section)(nil), // 7: request.Section + (*Psd)(nil), // 8: request.Psd + (*PsdOperationReq)(nil), // 9: request.PsdOperationReq } var file_request_proto_depIdxs = []int32{ 0, // 0: request.TurnoutOperationReq.operation:type_name -> request.Turnout.Operation - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 3, // 1: request.PsdOperationReq.operation:type_name -> request.Psd.Operation + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_request_proto_init() } @@ -562,14 +766,38 @@ func file_request_proto_init() { return nil } } + file_request_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Psd); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_request_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PsdOperationReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_request_proto_rawDesc, - NumEnums: 3, - NumMessages: 4, + NumEnums: 4, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/message_server/sfp_ms.go b/message_server/sfp_ms.go index 738b3bc..532e99c 100644 --- a/message_server/sfp_ms.go +++ b/message_server/sfp_ms.go @@ -104,8 +104,9 @@ func (ms *SfpMs) collectPsdStates() ([]*state.PsdState, error) { } } psdStateArr = append(psdStateArr, &state.PsdState{ - Id: door.Common.Id, - OpenDoorCodes: openSubDoor, + Id: door.Common.Id, + Close: component.PsdStateType.Get(psdEntry).Close, + OpenAsdCodes: openSubDoor, }) } } diff --git a/protobuf/file.bin b/protobuf/file.bin deleted file mode 100644 index 669973d35fff9014b2b04b0eb1fb2f65569dce92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95419 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 z 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 diff --git a/protobuf/main_test.go b/protobuf/main_test.go deleted file mode 100644 index b8e86ac..0000000 --- a/protobuf/main_test.go +++ /dev/null @@ -1,280 +0,0 @@ -package protobuf - -import ( - "fmt" - "os" - "testing" - - "google.golang.org/protobuf/proto" - "joylink.club/bj-rtsts-server/ts/protos/graphicData" - proto2 "joylink.club/rtsssimulation/repository/model/proto" -) - -func TestBuildRepository(t *testing.T) { - - bytes, err := os.ReadFile("./file.bin") - dir, _ := os.Getwd() - println(dir) - if err != nil { - panic(err) - } - storage := &graphicData.RtssGraphicStorage{} - err = proto.Unmarshal(bytes, storage) - if err != nil { - panic(err) - } - repo := &proto2.Repository{} - - //todo 数据中id为379的区段B端无计轴,临时在代码里修改,后续删除 - storage.AxleCountings = append(storage.AxleCountings, &graphicData.AxleCounting{ - Common: &graphicData.CommonInfo{ - Id: "10000", - }, - KilometerSystem: &graphicData.KilometerSystem{ - Kilometer: 13403549, - CoordinateSystem: "MAIN_LINE", - Direction: graphicData.Direction_RIGHT, - }, - AxleCountingRef: []*graphicData.RelatedRef{{ - DeviceType: graphicData.RelatedRef_Section, - Id: "379", - DevicePort: graphicData.RelatedRef_B, - }}, - Index: 0, - // Invent: false, - Type: 0, - }) - - axleCountingMap := make(map[string]*graphicData.AxleCounting) - for _, data := range storage.AxleCountings { - if data.KilometerSystem == nil { - println(fmt.Sprintf("计轴[%s]缺少公里标", data.Common.Id)) - continue - } - axleCountingMap[data.Common.Id] = data - cpType := proto2.CheckPointType_AxleCounter - // if data.Invent { - // cpType = proto2.CheckPointType_Boundary - // } - cp := &proto2.CheckPoint{ - Id: data.Common.Id, - Km: convertKm(data.KilometerSystem), - Type: cpType, - DevicePorts: convertDevicePorts(data.AxleCountingRef), - } - repo.CheckPoints = append(repo.CheckPoints, cp) - } - for _, data := range storage.Section { - var turnoutIds []string - if data.SectionType == graphicData.Section_TurnoutPhysical { - turnoutIds = findTurnoutIds(axleCountingMap, data.AxleCountings) - } - physicalSection := &proto2.PhysicalSection{ - Id: data.Common.Id, - ADevicePort: convertDevicePort(data.PaRef), - BDevicePort: convertDevicePort(data.PbRef), - TurnoutIds: turnoutIds, - } - repo.PhysicalSections = append(repo.PhysicalSections, physicalSection) - } - for _, data := range storage.Turnouts { - var km *proto2.Kilometer - for _, ks := range data.KilometerSystem { - if ks.Kilometer != 0 { - km = convertKm(ks) - break - } - } - for _, kc := range buildKmConverts(data.KilometerSystem) { - repo.KilometerConverts = append(repo.KilometerConverts, kc) - } - turnout := &proto2.Turnout{ - Id: data.Common.Id, - Km: km, - ADevicePort: convertDevicePort(data.PaRef), - BDevicePort: convertDevicePort(data.PbRef), - CDevicePort: convertDevicePort(data.PcRef), - } - repo.Turnouts = append(repo.Turnouts, turnout) - } - for _, data := range storage.Signals { - var sectionId string - var turnoutPort *proto2.DevicePort - switch data.RefDev.DeviceType { - case graphicData.RelatedRef_Section: - sectionId = data.RefDev.Id - case graphicData.RelatedRef_Turnout: - turnoutPort = convertDevicePort(data.RefDev) - } - signal := &proto2.Signal{ - Id: data.Common.Id, - Km: convertKm(data.KilometerSystem), - SectionId: sectionId, - TurnoutPort: turnoutPort, - } - repo.Signals = append(repo.Signals, signal) - } - for _, data := range storage.Transponders { - var sectionId string - var turnoutPort *proto2.DevicePort - switch data.TransponderRef.DeviceType { - case graphicData.RelatedRef_Section: - sectionId = data.TransponderRef.Id - case graphicData.RelatedRef_Turnout: - turnoutPort = convertDevicePort(data.TransponderRef) - } - responder := &proto2.Transponder{ - Id: data.Common.Id, - Km: convertKm(data.KilometerSystem), - SectionId: sectionId, - TurnoutPort: turnoutPort, - } - repo.Transponders = append(repo.Transponders, responder) - } - slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker) - for _, data := range storage.SlopeKiloMarker { - slopeKsMap[data.Common.Id] = data - for _, kc := range buildKmConverts(data.KilometerSystem) { - repo.KilometerConverts = append(repo.KilometerConverts, kc) - } - } - curveKsMap := make(map[string]*graphicData.CurvatureKiloMarker) - for _, data := range storage.CurvatureKiloMarker { - curveKsMap[data.Common.Id] = data - for _, kc := range buildKmConverts(data.KilometerSystem) { - repo.KilometerConverts = append(repo.KilometerConverts, kc) - } - } - for _, data := range storage.Slopes { - var kms []*proto2.Kilometer - for _, id := range data.RefDeviceId { - kms = append(kms, convertKm(slopeKsMap[id].KilometerSystem[0])) - } - slope := &proto2.Slope{ - Id: data.Common.Id, - Kms: kms, - Degree: data.SlopeNumber, - } - repo.Slopes = append(repo.Slopes, slope) - } - for _, data := range storage.Curvatures { - var kms []*proto2.Kilometer - for _, id := range data.RefDeviceId { - kms = append(kms, convertKm(curveKsMap[id].KilometerSystem[0])) - } - slope := &proto2.SectionalCurvature{ - Id: data.Common.Id, - Kms: kms, - Radius: data.CurvatureNumber, - } - repo.SectionalCurvatures = append(repo.SectionalCurvatures, slope) - } - repoBytes, err := proto.Marshal(repo) - if err != nil { - panic(err) - } - err = os.WriteFile("./repo.bin", repoBytes, os.ModePerm) - println(err) -} - -func convertKm(ks *graphicData.KilometerSystem) *proto2.Kilometer { - var dir proto2.Direction - switch ks.Direction { - case graphicData.Direction_LEFT: - dir = proto2.Direction_LEFT - case graphicData.Direction_RIGHT: - dir = proto2.Direction_RIGHT - } - return &proto2.Kilometer{ - Value: ks.Kilometer, - CoordinateSystem: ks.CoordinateSystem, - Direction: dir, - } -} - -func convertDevicePort(ref *graphicData.RelatedRef) *proto2.DevicePort { - if ref == nil { - return nil - } - var deviceType proto2.DeviceType - var port proto2.Port - switch ref.DevicePort { - case graphicData.RelatedRef_A: - port = proto2.Port_A - case graphicData.RelatedRef_B: - port = proto2.Port_B - case graphicData.RelatedRef_C: - port = proto2.Port_C - } - switch ref.DeviceType { - case graphicData.RelatedRef_Section: - deviceType = proto2.DeviceType_DeviceType_PhysicalSection - case graphicData.RelatedRef_Turnout: - deviceType = proto2.DeviceType_DeviceType_Turnout - default: - panic(fmt.Sprintf("异常的设备类型-%s", ref.DeviceType)) - } - return &proto2.DevicePort{ - DeviceId: ref.Id, - DeviceType: deviceType, - Port: port, - } -} - -func convertDevicePorts(refList []*graphicData.RelatedRef) []*proto2.DevicePort { - var dps []*proto2.DevicePort - for _, ref := range refList { - dps = append(dps, convertDevicePort(ref)) - } - return dps -} - -func findTurnoutIds(axleCountingMap map[string]*graphicData.AxleCounting, axleIds []string) []string { - if len(axleIds) <= 2 { - return nil - } - turnoutMap := make(map[string]bool) - for _, axleId := range axleIds { - axle := axleCountingMap[axleId] - relTurnoutCount := 0 - var turnoutId string - for _, ref := range axle.AxleCountingRef { - if ref.DeviceType == graphicData.RelatedRef_Turnout { - relTurnoutCount++ - turnoutId = ref.Id - } - } - if relTurnoutCount == 1 { - turnoutMap[turnoutId] = true - } - } - var turnoutIds []string - for id, _ := range turnoutMap { - turnoutIds = append(turnoutIds, id) - } - return turnoutIds -} - -func buildKmConverts(ksList []*graphicData.KilometerSystem) []*proto2.KilometerConvert { - var kmConvers []*proto2.KilometerConvert - for i, ks := range ksList { - if ks.Kilometer == 0 { - continue - } - for j := i + 1; j < len(ksList); j++ { - if ks.Kilometer == 0 { - continue - } - kmConvers = append(kmConvers, buildKmConvert(ks, ksList[j])) - } - } - return kmConvers -} - -func buildKmConvert(ks1 *graphicData.KilometerSystem, ks2 *graphicData.KilometerSystem) *proto2.KilometerConvert { - return &proto2.KilometerConvert{ - KmA: convertKm(ks1), - KmB: convertKm(ks2), - SameTrend: false, - } -} diff --git a/rtss_simulation b/rtss_simulation index ec32973..d77c370 160000 --- a/rtss_simulation +++ b/rtss_simulation @@ -1 +1 @@ -Subproject commit ec3297327025acb20e33268705d600be0c1f87fb +Subproject commit d77c37055ba841091f417b1c36fd8d3f6beb15c5 diff --git a/ts/protos/graphicData/ibpGraphics.pb.go b/ts/protos/graphicData/ibpGraphics.pb.go index ed3142d..90d7633 100644 --- a/ts/protos/graphicData/ibpGraphics.pb.go +++ b/ts/protos/graphicData/ibpGraphics.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.31.0 // protoc v4.23.1 // source: ibpGraphics.proto diff --git a/ts/protos/graphicData/picture.pb.go b/ts/protos/graphicData/picture.pb.go index c59a50e..32a004e 100644 --- a/ts/protos/graphicData/picture.pb.go +++ b/ts/protos/graphicData/picture.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.31.0 // protoc v4.23.1 // source: picture.proto diff --git a/ts/protos/graphicData/pslGraphics.pb.go b/ts/protos/graphicData/pslGraphics.pb.go index 43d468d..de96dad 100644 --- a/ts/protos/graphicData/pslGraphics.pb.go +++ b/ts/protos/graphicData/pslGraphics.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.31.0 // protoc v4.23.1 // source: pslGraphics.proto diff --git a/ts/protos/graphicData/relayCabinetLayoutGraphics.pb.go b/ts/protos/graphicData/relayCabinetLayoutGraphics.pb.go index 52442f4..883af1b 100644 --- a/ts/protos/graphicData/relayCabinetLayoutGraphics.pb.go +++ b/ts/protos/graphicData/relayCabinetLayoutGraphics.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.31.0 // protoc v4.23.1 // source: relayCabinetLayoutGraphics.proto diff --git a/ts/protos/graphicData/stationLayoutGraphics.pb.go b/ts/protos/graphicData/stationLayoutGraphics.pb.go index 43eb347..48b933f 100644 --- a/ts/protos/graphicData/stationLayoutGraphics.pb.go +++ b/ts/protos/graphicData/stationLayoutGraphics.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.31.0 // protoc v4.23.1 // source: stationLayoutGraphics.proto diff --git a/ts/protos/state/device_state.pb.go b/ts/protos/state/device_state.pb.go index ece74b6..94144da 100644 --- a/ts/protos/state/device_state.pb.go +++ b/ts/protos/state/device_state.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.31.0 // protoc v4.23.1 // source: device_state.proto @@ -1643,8 +1643,9 @@ type PsdState struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` //屏蔽门的id - OpenDoorCodes []int32 `protobuf:"varint,2,rep,packed,name=openDoorCodes,proto3" json:"openDoorCodes,omitempty"` //开启的小门的编号 + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` //屏蔽门的id + OpenAsdCodes []int32 `protobuf:"varint,2,rep,packed,name=openAsdCodes,proto3" json:"openAsdCodes,omitempty"` //开启的滑动门的编号 + Close bool `protobuf:"varint,3,opt,name=close,proto3" json:"close,omitempty"` //屏蔽门整体的关闭(继电器)状态 } func (x *PsdState) Reset() { @@ -1686,13 +1687,20 @@ func (x *PsdState) GetId() string { return "" } -func (x *PsdState) GetOpenDoorCodes() []int32 { +func (x *PsdState) GetOpenAsdCodes() []int32 { if x != nil { - return x.OpenDoorCodes + return x.OpenAsdCodes } return nil } +func (x *PsdState) GetClose() bool { + if x != nil { + return x.Close + } + return false +} + // 钥匙状态 type KeyState struct { state protoimpl.MessageState @@ -2309,98 +2317,99 @@ var file_device_state_proto_rawDesc = []byte{ 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x34, 0x0a, 0x0a, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x40, 0x0a, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x54, 0x0a, 0x08, 0x50, 0x73, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x70, 0x65, - 0x6e, 0x44, 0x6f, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, - 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x6e, 0x44, 0x6f, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x22, - 0x2e, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, - 0x65, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x67, 0x65, 0x61, 0x72, 0x22, - 0x9e, 0x02, 0x0a, 0x0f, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x72, - 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x77, 0x69, - 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x12, 0x3b, 0x0a, 0x0e, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0c, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x93, 0x04, 0x0a, 0x10, 0x41, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x74, 0x72, - 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x73, 0x77, 0x69, 0x74, - 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x70, 0x65, + 0x6e, 0x41, 0x73, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, + 0x0c, 0x6f, 0x70, 0x65, 0x6e, 0x41, 0x73, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x63, 0x6c, + 0x6f, 0x73, 0x65, 0x22, 0x2e, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x67, 0x65, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x67, + 0x65, 0x61, 0x72, 0x22, 0x9e, 0x02, 0x0a, 0x0f, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x12, 0x26, + 0x0a, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, + 0x72, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, - 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6c, 0x79, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0a, - 0x72, 0x65, 0x70, 0x6c, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x34, 0x0a, 0x0b, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x42, 0x75, - 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x62, 0x75, 0x74, 0x74, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x0a, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x41, - 0x6c, 0x61, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x0a, 0x4c, 0x69, 0x67, - 0x68, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x0a, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x08, - 0x70, 0x73, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x73, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x08, 0x70, 0x73, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x4b, 0x65, 0x79, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x4b, 0x65, - 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x50, 0x75, 0x73, 0x68, 0x65, - 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, - 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, - 0x12, 0x34, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x72, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x76, 0x61, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xd8, 0x01, - 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x69, - 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, - 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3f, 0x0a, 0x0f, 0x53, 0x69, 0x6d, 0x75, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x41, - 0x55, 0x53, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x01, - 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, - 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x03, 0x2a, 0x37, 0x0a, 0x0b, 0x53, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x41, 0x78, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x6f, - 0x67, 0x69, 0x63, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x10, - 0x03, 0x42, 0x4c, 0x0a, 0x25, 0x63, 0x6c, 0x75, 0x62, 0x2e, 0x6a, 0x6f, 0x79, 0x6c, 0x69, 0x6e, - 0x6b, 0x2e, 0x62, 0x6a, 0x72, 0x74, 0x73, 0x73, 0x2e, 0x61, 0x74, 0x73, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x42, 0x10, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x11, 0x2e, 0x2f, - 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x52, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, + 0x12, 0x3b, 0x0a, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0e, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, + 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x93, 0x04, 0x0a, 0x10, 0x41, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x74, 0x72, 0x61, + 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x0a, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x0b, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6c, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, + 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x62, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x0a, 0x41, 0x6c, + 0x61, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x0a, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, + 0x0a, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x2b, 0x0a, 0x08, 0x70, 0x73, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x73, 0x64, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x08, 0x70, 0x73, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, + 0x08, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x08, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x50, + 0x75, 0x73, 0x68, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x34, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x09, 0x76, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x6c, + 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x22, 0xd8, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x69, + 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3f, 0x0a, 0x0f, 0x53, + 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, + 0x0a, 0x05, 0x50, 0x41, 0x55, 0x53, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, + 0x52, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, + 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x03, 0x2a, 0x37, 0x0a, 0x0b, + 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, + 0x6e, 0x79, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x78, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x09, + 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x68, 0x79, + 0x73, 0x69, 0x63, 0x10, 0x03, 0x42, 0x4c, 0x0a, 0x25, 0x63, 0x6c, 0x75, 0x62, 0x2e, 0x6a, 0x6f, + 0x79, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x62, 0x6a, 0x72, 0x74, 0x73, 0x73, 0x2e, 0x61, 0x74, 0x73, + 0x2e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x42, 0x10, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x5a, 0x11, 0x2e, 0x2f, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/ts/simulation/wayside/memory/wayside_memory_map_init.go b/ts/simulation/wayside/memory/wayside_memory_map_init.go index 5ae68bf..9ba5eac 100644 --- a/ts/simulation/wayside/memory/wayside_memory_map_init.go +++ b/ts/simulation/wayside/memory/wayside_memory_map_init.go @@ -327,6 +327,8 @@ func getUidMapByType(uidData any, m interface{}) map[string]*elementIdStructure return (uidData.(*StationUidStructure)).ButtonIds case *graphicData.Station: return (uidData.(*StationUidStructure)).StationIds + case *graphicData.ScreenDoor: + return (uidData.(*StationUidStructure)).PsdIds default: panic(&dto.ErrorDto{Code: dto.ArgumentParseError, Message: "类型未映射字段"}) } diff --git a/ts/simulation/wayside/memory/wayside_memory_psd.go b/ts/simulation/wayside/memory/wayside_memory_psd.go index 05af74b..3de4e49 100644 --- a/ts/simulation/wayside/memory/wayside_memory_psd.go +++ b/ts/simulation/wayside/memory/wayside_memory_psd.go @@ -1 +1,35 @@ package memory + +import ( + "fmt" + "joylink.club/bj-rtsts-server/dto/request_proto" + "joylink.club/bj-rtsts-server/ts/protos/graphicData" + "joylink.club/rtsssimulation/fi" +) + +// 处理道岔操作 +func HandlePsdOperation(simulation *VerifySimulation, req *request_proto.PsdOperationReq) error { + uid := QueryUidByMidAndComId(req.MapId, req.DeviceId, &graphicData.ScreenDoor{}) + switch req.Operation { + case request_proto.Psd_Km4: + return fi.SetInterlockKm4(simulation.World, uid) + case request_proto.Psd_CancelKm4: + return fi.CancelInterlockKm4(simulation.World, uid) + case request_proto.Psd_Km8: + return fi.SetInterlockKm8(simulation.World, uid) + case request_proto.Psd_CancelKm8: + return fi.CancelInterlockKm8(simulation.World, uid) + case request_proto.Psd_Gm: + return fi.SetInterlockGm(simulation.World, uid) + case request_proto.Psd_CancelGm: + return fi.CancelInterlockGm(simulation.World, uid) + case request_proto.Psd_ForceKm4: + + case request_proto.Psd_ForceKm8: + + case request_proto.Psd_ForceGm: + default: + panic(fmt.Sprintf("未知的道岔操作:%s", req.Operation)) + } + return nil +} diff --git a/ts/simulation/wayside/memory/wayside_memory_psd_test.go b/ts/simulation/wayside/memory/wayside_memory_psd_test.go new file mode 100644 index 0000000..f7b0679 --- /dev/null +++ b/ts/simulation/wayside/memory/wayside_memory_psd_test.go @@ -0,0 +1,110 @@ +package memory + +import ( + "fmt" + "joylink.club/bj-rtsts-server/dto/request_proto" + "joylink.club/bj-rtsts-server/ts" + "joylink.club/bj-rtsts-server/ts/protos/graphicData" + "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/consts" + "joylink.club/rtsssimulation/entity" + "testing" + "time" +) + +// 先创建一个仿真再调 +func TestHandlePsdOperation(t *testing.T) { + simInfo := ts.ListAllSimulations()[0] + simId := simInfo.SimulationId + var mapId int32 + for _, id := range simInfo.MapIds { + if QueryGiType(id) == graphicData.PictureType_StationLayout { + mapId = id + } + } + if mapId == 0 { + fmt.Println("无信号布置图") + return + } + data := QueryGiData[*graphicData.RtssGraphicStorage](mapId) + deviceId := data.ScreenDoors[0].Common.Id + + simulation := ts.FindSimulation(simId) + wantErr := false + uid := QueryUidByMidAndComId(mapId, deviceId, &graphicData.Turnout{}) + entry, _ := entity.GetEntityByUid(simulation.World, uid) + asdList := component.AsdListType.Get(entry) + psdModel := entity.GetWorldData(simulation.World).Repo.FindPsd(uid) + + for key, value := range request_proto.Psd_Operation_value { + name := fmt.Sprintf("执行操作:%s", key) + req := &request_proto.PsdOperationReq{ + SimulationId: "", + MapId: mapId, + DeviceId: deviceId, + Operation: request_proto.Psd_Operation(value), + } + t.Run(name, func(t *testing.T) { + if err := HandlePsdOperation(simulation, req); (err != nil) != wantErr { + t.Errorf("HandlePsdOperation() error = %v, wantErr %v", err, wantErr) + } + tick := time.Tick(5 * time.Second) + <-tick + switch req.Operation { + case request_proto.Psd_Km4: + group := psdModel.FindAsdGroup(4) + for i, asd := range asdList.List { + pos := component.TwoPositionTransformType.Get(asd).Pos + if int32(i) < group.Start || int32(i) > group.End { + if pos != consts.TwoPosMin { + t.Errorf("4编组开门操作[编号:%d]的滑动门位置[%d]不正确", i, pos) + } + } else { + if pos != consts.TwoPosMax { + t.Errorf(fmt.Sprintf("4编组开门操作[编号:%d]的滑动门位置[%d]不正确", i, pos)) + } + } + } + case request_proto.Psd_CancelKm4: + if component.PscType.Get(entry).InterlockKM4 == true { + t.Errorf("取消4编组开门失败") + } + case request_proto.Psd_Km8: + group := psdModel.FindAsdGroup(8) + for i, asd := range asdList.List { + pos := component.TwoPositionTransformType.Get(asd).Pos + if int32(i) < group.Start || int32(i) > group.End { + if pos != consts.TwoPosMin { + t.Errorf("8编组开门操作[编号:%d]的滑动门位置[%d]不正确", i, pos) + } + } else { + if pos != consts.TwoPosMax { + t.Errorf("8编组开门操作[编号:%d]的滑动门位置[%d]不正确", i, pos) + } + } + } + case request_proto.Psd_CancelKm8: + if component.PscType.Get(entry).InterlockKM8 == true { + t.Errorf("取消8编组开门失败") + } + case request_proto.Psd_Gm: + for i, asd := range asdList.List { + pos := component.TwoPositionTransformType.Get(asd).Pos + if pos != consts.TwoPosMin { + t.Errorf("4编组开门操作[编号:%d]的滑动门位置[%d]不正确", i, pos) + } + } + case request_proto.Psd_CancelGm: + if component.PscType.Get(entry).InterlockGM == true { + t.Errorf("取消关门失败") + } + case request_proto.Psd_ForceKm4: + + case request_proto.Psd_ForceKm8: + + case request_proto.Psd_ForceGm: + + } + }) + } +}