chore(clients): roll out feed-level snapshot_status to all five clients

Task 1 added AlarmSnapshotStatus and AlarmFeedMessage.snapshot_status = 5.
Carry it downstream from the canonical Contracts protos:

- Rust vendored protos under clients/rust/protos, refreshed byte-identical
  (build.rs falls back to them for out-of-repo tarball builds)
- client descriptor set (protoc 34.1 pin)
- Go (protoc-gen-go v1.36.11 / protoc-gen-go-grpc 1.6.2)
- Python (grpcio-tools 1.80.0 pin)
- Java (gradle generateProto)

.NET needs no regeneration: the client compiles against the Contracts
Generated/ output committed with the proto change.

The hand-written CLI feed renderers switch on the payload oneof, so codegen
alone does not carry the arm. Add snapshot-status to the .NET, Go, Rust, and
Java renderers; the .NET and Go renderers were also missing provider-status,
which has been on the wire since the provider-mode work, so add it there too.
Java's renderer is an exhaustive switch expression and did not compile until
the new case landed. The Python CLI renders generic protobuf-JSON and needs
no change.

Each client README gains a paragraph on the feed-level frame next to its
existing from_truncated_snapshot paragraph: it arrives at stream open after
provider_status and before the cached active_alarm frames, then on every
verdict change including the clearing frame a monitor restart emits, so a
live consumer can track set completeness without polling QueryActiveAlarms.

GatewayDashboardDesign: list the two new payload cases the AlarmsHub forwards,
and — separately — record the GroupToRole / GroupToTag / UntaggedSessionVisibility
rows the settings page already renders but the bullet list omitted.
This commit is contained in:
Joseph Doherty
2026-08-18 05:26:06 -04:00
parent d13144a9d7
commit c7483615cf
15 changed files with 1412 additions and 408 deletions
+10
View File
@@ -156,6 +156,16 @@ poll. Treat the set as possibly incomplete rather than reconciling deletions
from it. It is set-level degraded status, not a comment on the record's own from it. It is set-level degraded status, not a comment on the record's own
fidelity, and is distinct from `Degraded` (the subtag fallback provider). fidelity, and is distinct from `Degraded` (the subtag fallback provider).
`StreamAlarmsAsync` also carries that completeness verdict at feed level, as an
`AlarmFeedMessage.PayloadOneofCase.SnapshotStatus` frame whose
`SnapshotStatus.Truncated` is true while the monitor's cached set derives from a
truncated fetch. One arrives at stream open (after the `ProviderStatus` frame,
before the cached `ActiveAlarm` frames) so a late joiner learns the current
verdict, then one on every verdict change — including the clearing frame sent
when the gateway's alarm monitor restarts and drops a truncated verdict. Track
it if you need set completeness on a live feed without polling
`QueryActiveAlarmsAsync`.
`MxGatewaySession.CloseAsync` is explicit and idempotent. Repeated calls return `MxGatewaySession.CloseAsync` is explicit and idempotent. Repeated calls return
the first `CloseSessionReply` instead of sending another close request. the first `CloseSessionReply` instead of sending another close request.
@@ -1546,8 +1546,9 @@ public static class MxGatewayClientCli
/// <summary> /// <summary>
/// Renders one <see cref="AlarmFeedMessage"/> for the human-readable /// Renders one <see cref="AlarmFeedMessage"/> for the human-readable
/// (non-JSON) stream-alarms output, distinguishing the <c>payload</c> oneof /// (non-JSON) stream-alarms output, distinguishing the <c>payload</c> oneof
/// arms: a snapshot active alarm, the snapshot-complete sentinel, or a live /// arms: a snapshot active alarm, the snapshot-complete sentinel, a live
/// transition. /// transition, the provider-mode status, or the feed-level
/// snapshot-completeness status.
/// </summary> /// </summary>
private static string FormatAlarmFeedMessage(AlarmFeedMessage feedMessage) private static string FormatAlarmFeedMessage(AlarmFeedMessage feedMessage)
{ {
@@ -1559,6 +1560,10 @@ public static class MxGatewayClientCli
$"snapshot-complete {feedMessage.SnapshotComplete}", $"snapshot-complete {feedMessage.SnapshotComplete}",
AlarmFeedMessage.PayloadOneofCase.Transition => AlarmFeedMessage.PayloadOneofCase.Transition =>
$"transition {ProtobufJsonFormatter.Format(feedMessage.Transition)}", $"transition {ProtobufJsonFormatter.Format(feedMessage.Transition)}",
AlarmFeedMessage.PayloadOneofCase.ProviderStatus =>
$"provider-status {ProtobufJsonFormatter.Format(feedMessage.ProviderStatus)}",
AlarmFeedMessage.PayloadOneofCase.SnapshotStatus =>
$"snapshot-status {ProtobufJsonFormatter.Format(feedMessage.SnapshotStatus)}",
_ => $"unknown-payload {feedMessage.PayloadCase}", _ => $"unknown-payload {feedMessage.PayloadCase}",
}; };
} }
+9
View File
@@ -153,6 +153,15 @@ deletions from it. It is set-level degraded status, not a comment on the
record's own fidelity, and is distinct from `Degraded` (the subtag fallback record's own fidelity, and is distinct from `Degraded` (the subtag fallback
provider). provider).
`StreamAlarms` also carries that completeness verdict at feed level, as a frame
whose `GetSnapshotStatus()` is non-nil and whose `GetTruncated()` is true while
the monitor's cached set derives from a truncated fetch. One arrives at stream
open (after the `GetProviderStatus()` frame, before the cached
`GetActiveAlarm()` frames) so a late joiner learns the current verdict, then one
on every verdict change — including the clearing frame sent when the gateway's
alarm monitor restarts and drops a truncated verdict. Track it if you need set
completeness on a live feed without polling `QueryActiveAlarms`.
## Write Semantics And Common Pitfalls ## Write Semantics And Common Pitfalls
These are MXAccess parity behaviors that surprise new callers. The gateway These are MXAccess parity behaviors that surprise new callers. The gateway
+7 -1
View File
@@ -1097,7 +1097,8 @@ func runStreamAlarms(ctx context.Context, args []string, stdout, stderr io.Write
// formatAlarmFeedMessage renders one AlarmFeedMessage in the CLI's plain-text // formatAlarmFeedMessage renders one AlarmFeedMessage in the CLI's plain-text
// output style, distinguishing the active-alarm snapshot, snapshot-complete // output style, distinguishing the active-alarm snapshot, snapshot-complete
// sentinel, and transition cases of the message's payload oneof. // sentinel, transition, provider-status, and snapshot-status cases of the
// message's payload oneof.
func formatAlarmFeedMessage(message *mxgateway.AlarmFeedMessage) string { func formatAlarmFeedMessage(message *mxgateway.AlarmFeedMessage) string {
switch { switch {
case message.GetActiveAlarm() != nil: case message.GetActiveAlarm() != nil:
@@ -1108,6 +1109,11 @@ func formatAlarmFeedMessage(message *mxgateway.AlarmFeedMessage) string {
case message.GetTransition() != nil: case message.GetTransition() != nil:
transition := message.GetTransition() transition := message.GetTransition()
return fmt.Sprintf("transition %s kind=%s severity=%d", transition.GetAlarmFullReference(), transition.GetTransitionKind(), transition.GetSeverity()) return fmt.Sprintf("transition %s kind=%s severity=%d", transition.GetAlarmFullReference(), transition.GetTransitionKind(), transition.GetSeverity())
case message.GetProviderStatus() != nil:
status := message.GetProviderStatus()
return fmt.Sprintf("provider-status mode=%s degraded=%t reason=%q", status.GetMode(), status.GetDegraded(), status.GetReason())
case message.GetSnapshotStatus() != nil:
return fmt.Sprintf("snapshot-status truncated=%t", message.GetSnapshotStatus().GetTruncated())
default: default:
return "unknown" return "unknown"
} }
@@ -7353,6 +7353,7 @@ type AlarmFeedMessage struct {
// *AlarmFeedMessage_SnapshotComplete // *AlarmFeedMessage_SnapshotComplete
// *AlarmFeedMessage_Transition // *AlarmFeedMessage_Transition
// *AlarmFeedMessage_ProviderStatus // *AlarmFeedMessage_ProviderStatus
// *AlarmFeedMessage_SnapshotStatus
Payload isAlarmFeedMessage_Payload `protobuf_oneof:"payload"` Payload isAlarmFeedMessage_Payload `protobuf_oneof:"payload"`
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@@ -7431,6 +7432,15 @@ func (x *AlarmFeedMessage) GetProviderStatus() *AlarmProviderStatus {
return nil return nil
} }
func (x *AlarmFeedMessage) GetSnapshotStatus() *AlarmSnapshotStatus {
if x != nil {
if x, ok := x.Payload.(*AlarmFeedMessage_SnapshotStatus); ok {
return x.SnapshotStatus
}
}
return nil
}
type isAlarmFeedMessage_Payload interface { type isAlarmFeedMessage_Payload interface {
isAlarmFeedMessage_Payload() isAlarmFeedMessage_Payload()
} }
@@ -7457,6 +7467,13 @@ type AlarmFeedMessage_ProviderStatus struct {
ProviderStatus *AlarmProviderStatus `protobuf:"bytes,4,opt,name=provider_status,json=providerStatus,proto3,oneof"` ProviderStatus *AlarmProviderStatus `protobuf:"bytes,4,opt,name=provider_status,json=providerStatus,proto3,oneof"`
} }
type AlarmFeedMessage_SnapshotStatus struct {
// Snapshot-completeness status. Emitted once on stream open and again on
// every change of the truncation verdict, so late joiners learn whether the
// feed's active-alarm set may be incomplete.
SnapshotStatus *AlarmSnapshotStatus `protobuf:"bytes,5,opt,name=snapshot_status,json=snapshotStatus,proto3,oneof"`
}
func (*AlarmFeedMessage_ActiveAlarm) isAlarmFeedMessage_Payload() {} func (*AlarmFeedMessage_ActiveAlarm) isAlarmFeedMessage_Payload() {}
func (*AlarmFeedMessage_SnapshotComplete) isAlarmFeedMessage_Payload() {} func (*AlarmFeedMessage_SnapshotComplete) isAlarmFeedMessage_Payload() {}
@@ -7465,6 +7482,8 @@ func (*AlarmFeedMessage_Transition) isAlarmFeedMessage_Payload() {}
func (*AlarmFeedMessage_ProviderStatus) isAlarmFeedMessage_Payload() {} func (*AlarmFeedMessage_ProviderStatus) isAlarmFeedMessage_Payload() {}
func (*AlarmFeedMessage_SnapshotStatus) isAlarmFeedMessage_Payload() {}
type AlarmProviderStatus struct { type AlarmProviderStatus struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Mode AlarmProviderMode `protobuf:"varint,1,opt,name=mode,proto3,enum=mxaccess_gateway.v1.AlarmProviderMode" json:"mode,omitempty"` Mode AlarmProviderMode `protobuf:"varint,1,opt,name=mode,proto3,enum=mxaccess_gateway.v1.AlarmProviderMode" json:"mode,omitempty"`
@@ -7533,6 +7552,63 @@ func (x *AlarmProviderStatus) GetSince() *timestamppb.Timestamp {
return nil return nil
} }
// Feed-level snapshot-completeness status. Emitted once on StreamAlarms open
// (after the initial provider_status frame, before the cached active_alarm
// frames) so late joiners learn the current verdict, and again on every change
// of the truncation verdict — when a reconcile reports a different verdict, and
// when the gateway's alarm monitor restarts and drops a truncated verdict with
// the cache generation it described (feed subscribers outlive that monitor
// session, so they are sent the clearing frame). Mirrors the per-record
// ActiveAlarmSnapshot.from_truncated_snapshot caveat at feed level so live
// consumers can reason about completeness without polling QueryActiveAlarms.
type AlarmSnapshotStatus struct {
state protoimpl.MessageState `protogen:"open.v1"`
// True while the monitor's cached active-alarm set derives from a truncated
// (capped) worker fetch — the set may be missing alarms. Distinct from
// provider degradation (AlarmProviderStatus.degraded), which describes the
// fidelity of the records rather than the completeness of the set.
Truncated bool `protobuf:"varint,1,opt,name=truncated,proto3" json:"truncated,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AlarmSnapshotStatus) Reset() {
*x = AlarmSnapshotStatus{}
mi := &file_mxaccess_gateway_proto_msgTypes[87]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AlarmSnapshotStatus) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AlarmSnapshotStatus) ProtoMessage() {}
func (x *AlarmSnapshotStatus) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[87]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AlarmSnapshotStatus.ProtoReflect.Descriptor instead.
func (*AlarmSnapshotStatus) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{87}
}
func (x *AlarmSnapshotStatus) GetTruncated() bool {
if x != nil {
return x.Truncated
}
return false
}
type MxStatusProxy struct { type MxStatusProxy struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
// Mirrors the `success` member of the MXAccess MXSTATUS_PROXY struct // Mirrors the `success` member of the MXAccess MXSTATUS_PROXY struct
@@ -7557,7 +7633,7 @@ type MxStatusProxy struct {
func (x *MxStatusProxy) Reset() { func (x *MxStatusProxy) Reset() {
*x = MxStatusProxy{} *x = MxStatusProxy{}
mi := &file_mxaccess_gateway_proto_msgTypes[87] mi := &file_mxaccess_gateway_proto_msgTypes[88]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -7569,7 +7645,7 @@ func (x *MxStatusProxy) String() string {
func (*MxStatusProxy) ProtoMessage() {} func (*MxStatusProxy) ProtoMessage() {}
func (x *MxStatusProxy) ProtoReflect() protoreflect.Message { func (x *MxStatusProxy) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[87] mi := &file_mxaccess_gateway_proto_msgTypes[88]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -7582,7 +7658,7 @@ func (x *MxStatusProxy) ProtoReflect() protoreflect.Message {
// Deprecated: Use MxStatusProxy.ProtoReflect.Descriptor instead. // Deprecated: Use MxStatusProxy.ProtoReflect.Descriptor instead.
func (*MxStatusProxy) Descriptor() ([]byte, []int) { func (*MxStatusProxy) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{87} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{88}
} }
func (x *MxStatusProxy) GetSuccess() int32 { func (x *MxStatusProxy) GetSuccess() int32 {
@@ -7660,7 +7736,7 @@ type MxValue struct {
func (x *MxValue) Reset() { func (x *MxValue) Reset() {
*x = MxValue{} *x = MxValue{}
mi := &file_mxaccess_gateway_proto_msgTypes[88] mi := &file_mxaccess_gateway_proto_msgTypes[89]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -7672,7 +7748,7 @@ func (x *MxValue) String() string {
func (*MxValue) ProtoMessage() {} func (*MxValue) ProtoMessage() {}
func (x *MxValue) ProtoReflect() protoreflect.Message { func (x *MxValue) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[88] mi := &file_mxaccess_gateway_proto_msgTypes[89]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -7685,7 +7761,7 @@ func (x *MxValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use MxValue.ProtoReflect.Descriptor instead. // Deprecated: Use MxValue.ProtoReflect.Descriptor instead.
func (*MxValue) Descriptor() ([]byte, []int) { func (*MxValue) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{88} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{89}
} }
func (x *MxValue) GetDataType() MxDataType { func (x *MxValue) GetDataType() MxDataType {
@@ -7908,7 +7984,7 @@ type MxArray struct {
func (x *MxArray) Reset() { func (x *MxArray) Reset() {
*x = MxArray{} *x = MxArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[89] mi := &file_mxaccess_gateway_proto_msgTypes[90]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -7920,7 +7996,7 @@ func (x *MxArray) String() string {
func (*MxArray) ProtoMessage() {} func (*MxArray) ProtoMessage() {}
func (x *MxArray) ProtoReflect() protoreflect.Message { func (x *MxArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[89] mi := &file_mxaccess_gateway_proto_msgTypes[90]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -7933,7 +8009,7 @@ func (x *MxArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use MxArray.ProtoReflect.Descriptor instead. // Deprecated: Use MxArray.ProtoReflect.Descriptor instead.
func (*MxArray) Descriptor() ([]byte, []int) { func (*MxArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{89} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{90}
} }
func (x *MxArray) GetElementDataType() MxDataType { func (x *MxArray) GetElementDataType() MxDataType {
@@ -8117,7 +8193,7 @@ type MxSparseArray struct {
func (x *MxSparseArray) Reset() { func (x *MxSparseArray) Reset() {
*x = MxSparseArray{} *x = MxSparseArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[90] mi := &file_mxaccess_gateway_proto_msgTypes[91]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8129,7 +8205,7 @@ func (x *MxSparseArray) String() string {
func (*MxSparseArray) ProtoMessage() {} func (*MxSparseArray) ProtoMessage() {}
func (x *MxSparseArray) ProtoReflect() protoreflect.Message { func (x *MxSparseArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[90] mi := &file_mxaccess_gateway_proto_msgTypes[91]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8142,7 +8218,7 @@ func (x *MxSparseArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use MxSparseArray.ProtoReflect.Descriptor instead. // Deprecated: Use MxSparseArray.ProtoReflect.Descriptor instead.
func (*MxSparseArray) Descriptor() ([]byte, []int) { func (*MxSparseArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{90} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{91}
} }
func (x *MxSparseArray) GetElementDataType() MxDataType { func (x *MxSparseArray) GetElementDataType() MxDataType {
@@ -8176,7 +8252,7 @@ type MxSparseElement struct {
func (x *MxSparseElement) Reset() { func (x *MxSparseElement) Reset() {
*x = MxSparseElement{} *x = MxSparseElement{}
mi := &file_mxaccess_gateway_proto_msgTypes[91] mi := &file_mxaccess_gateway_proto_msgTypes[92]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8188,7 +8264,7 @@ func (x *MxSparseElement) String() string {
func (*MxSparseElement) ProtoMessage() {} func (*MxSparseElement) ProtoMessage() {}
func (x *MxSparseElement) ProtoReflect() protoreflect.Message { func (x *MxSparseElement) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[91] mi := &file_mxaccess_gateway_proto_msgTypes[92]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8201,7 +8277,7 @@ func (x *MxSparseElement) ProtoReflect() protoreflect.Message {
// Deprecated: Use MxSparseElement.ProtoReflect.Descriptor instead. // Deprecated: Use MxSparseElement.ProtoReflect.Descriptor instead.
func (*MxSparseElement) Descriptor() ([]byte, []int) { func (*MxSparseElement) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{91} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{92}
} }
func (x *MxSparseElement) GetIndex() uint32 { func (x *MxSparseElement) GetIndex() uint32 {
@@ -8227,7 +8303,7 @@ type BoolArray struct {
func (x *BoolArray) Reset() { func (x *BoolArray) Reset() {
*x = BoolArray{} *x = BoolArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[92] mi := &file_mxaccess_gateway_proto_msgTypes[93]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8239,7 +8315,7 @@ func (x *BoolArray) String() string {
func (*BoolArray) ProtoMessage() {} func (*BoolArray) ProtoMessage() {}
func (x *BoolArray) ProtoReflect() protoreflect.Message { func (x *BoolArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[92] mi := &file_mxaccess_gateway_proto_msgTypes[93]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8252,7 +8328,7 @@ func (x *BoolArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use BoolArray.ProtoReflect.Descriptor instead. // Deprecated: Use BoolArray.ProtoReflect.Descriptor instead.
func (*BoolArray) Descriptor() ([]byte, []int) { func (*BoolArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{92} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{93}
} }
func (x *BoolArray) GetValues() []bool { func (x *BoolArray) GetValues() []bool {
@@ -8271,7 +8347,7 @@ type Int32Array struct {
func (x *Int32Array) Reset() { func (x *Int32Array) Reset() {
*x = Int32Array{} *x = Int32Array{}
mi := &file_mxaccess_gateway_proto_msgTypes[93] mi := &file_mxaccess_gateway_proto_msgTypes[94]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8283,7 +8359,7 @@ func (x *Int32Array) String() string {
func (*Int32Array) ProtoMessage() {} func (*Int32Array) ProtoMessage() {}
func (x *Int32Array) ProtoReflect() protoreflect.Message { func (x *Int32Array) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[93] mi := &file_mxaccess_gateway_proto_msgTypes[94]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8296,7 +8372,7 @@ func (x *Int32Array) ProtoReflect() protoreflect.Message {
// Deprecated: Use Int32Array.ProtoReflect.Descriptor instead. // Deprecated: Use Int32Array.ProtoReflect.Descriptor instead.
func (*Int32Array) Descriptor() ([]byte, []int) { func (*Int32Array) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{93} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{94}
} }
func (x *Int32Array) GetValues() []int32 { func (x *Int32Array) GetValues() []int32 {
@@ -8315,7 +8391,7 @@ type Int64Array struct {
func (x *Int64Array) Reset() { func (x *Int64Array) Reset() {
*x = Int64Array{} *x = Int64Array{}
mi := &file_mxaccess_gateway_proto_msgTypes[94] mi := &file_mxaccess_gateway_proto_msgTypes[95]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8327,7 +8403,7 @@ func (x *Int64Array) String() string {
func (*Int64Array) ProtoMessage() {} func (*Int64Array) ProtoMessage() {}
func (x *Int64Array) ProtoReflect() protoreflect.Message { func (x *Int64Array) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[94] mi := &file_mxaccess_gateway_proto_msgTypes[95]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8340,7 +8416,7 @@ func (x *Int64Array) ProtoReflect() protoreflect.Message {
// Deprecated: Use Int64Array.ProtoReflect.Descriptor instead. // Deprecated: Use Int64Array.ProtoReflect.Descriptor instead.
func (*Int64Array) Descriptor() ([]byte, []int) { func (*Int64Array) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{94} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{95}
} }
func (x *Int64Array) GetValues() []int64 { func (x *Int64Array) GetValues() []int64 {
@@ -8359,7 +8435,7 @@ type FloatArray struct {
func (x *FloatArray) Reset() { func (x *FloatArray) Reset() {
*x = FloatArray{} *x = FloatArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[95] mi := &file_mxaccess_gateway_proto_msgTypes[96]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8371,7 +8447,7 @@ func (x *FloatArray) String() string {
func (*FloatArray) ProtoMessage() {} func (*FloatArray) ProtoMessage() {}
func (x *FloatArray) ProtoReflect() protoreflect.Message { func (x *FloatArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[95] mi := &file_mxaccess_gateway_proto_msgTypes[96]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8384,7 +8460,7 @@ func (x *FloatArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use FloatArray.ProtoReflect.Descriptor instead. // Deprecated: Use FloatArray.ProtoReflect.Descriptor instead.
func (*FloatArray) Descriptor() ([]byte, []int) { func (*FloatArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{95} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{96}
} }
func (x *FloatArray) GetValues() []float32 { func (x *FloatArray) GetValues() []float32 {
@@ -8403,7 +8479,7 @@ type DoubleArray struct {
func (x *DoubleArray) Reset() { func (x *DoubleArray) Reset() {
*x = DoubleArray{} *x = DoubleArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[96] mi := &file_mxaccess_gateway_proto_msgTypes[97]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8415,7 +8491,7 @@ func (x *DoubleArray) String() string {
func (*DoubleArray) ProtoMessage() {} func (*DoubleArray) ProtoMessage() {}
func (x *DoubleArray) ProtoReflect() protoreflect.Message { func (x *DoubleArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[96] mi := &file_mxaccess_gateway_proto_msgTypes[97]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8428,7 +8504,7 @@ func (x *DoubleArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use DoubleArray.ProtoReflect.Descriptor instead. // Deprecated: Use DoubleArray.ProtoReflect.Descriptor instead.
func (*DoubleArray) Descriptor() ([]byte, []int) { func (*DoubleArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{96} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{97}
} }
func (x *DoubleArray) GetValues() []float64 { func (x *DoubleArray) GetValues() []float64 {
@@ -8447,7 +8523,7 @@ type StringArray struct {
func (x *StringArray) Reset() { func (x *StringArray) Reset() {
*x = StringArray{} *x = StringArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[97] mi := &file_mxaccess_gateway_proto_msgTypes[98]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8459,7 +8535,7 @@ func (x *StringArray) String() string {
func (*StringArray) ProtoMessage() {} func (*StringArray) ProtoMessage() {}
func (x *StringArray) ProtoReflect() protoreflect.Message { func (x *StringArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[97] mi := &file_mxaccess_gateway_proto_msgTypes[98]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8472,7 +8548,7 @@ func (x *StringArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use StringArray.ProtoReflect.Descriptor instead. // Deprecated: Use StringArray.ProtoReflect.Descriptor instead.
func (*StringArray) Descriptor() ([]byte, []int) { func (*StringArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{97} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{98}
} }
func (x *StringArray) GetValues() []string { func (x *StringArray) GetValues() []string {
@@ -8491,7 +8567,7 @@ type TimestampArray struct {
func (x *TimestampArray) Reset() { func (x *TimestampArray) Reset() {
*x = TimestampArray{} *x = TimestampArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[98] mi := &file_mxaccess_gateway_proto_msgTypes[99]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8503,7 +8579,7 @@ func (x *TimestampArray) String() string {
func (*TimestampArray) ProtoMessage() {} func (*TimestampArray) ProtoMessage() {}
func (x *TimestampArray) ProtoReflect() protoreflect.Message { func (x *TimestampArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[98] mi := &file_mxaccess_gateway_proto_msgTypes[99]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8516,7 +8592,7 @@ func (x *TimestampArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use TimestampArray.ProtoReflect.Descriptor instead. // Deprecated: Use TimestampArray.ProtoReflect.Descriptor instead.
func (*TimestampArray) Descriptor() ([]byte, []int) { func (*TimestampArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{98} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{99}
} }
func (x *TimestampArray) GetValues() []*timestamppb.Timestamp { func (x *TimestampArray) GetValues() []*timestamppb.Timestamp {
@@ -8535,7 +8611,7 @@ type RawArray struct {
func (x *RawArray) Reset() { func (x *RawArray) Reset() {
*x = RawArray{} *x = RawArray{}
mi := &file_mxaccess_gateway_proto_msgTypes[99] mi := &file_mxaccess_gateway_proto_msgTypes[100]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8547,7 +8623,7 @@ func (x *RawArray) String() string {
func (*RawArray) ProtoMessage() {} func (*RawArray) ProtoMessage() {}
func (x *RawArray) ProtoReflect() protoreflect.Message { func (x *RawArray) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[99] mi := &file_mxaccess_gateway_proto_msgTypes[100]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8560,7 +8636,7 @@ func (x *RawArray) ProtoReflect() protoreflect.Message {
// Deprecated: Use RawArray.ProtoReflect.Descriptor instead. // Deprecated: Use RawArray.ProtoReflect.Descriptor instead.
func (*RawArray) Descriptor() ([]byte, []int) { func (*RawArray) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{99} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{100}
} }
func (x *RawArray) GetValues() [][]byte { func (x *RawArray) GetValues() [][]byte {
@@ -8580,7 +8656,7 @@ type ProtocolStatus struct {
func (x *ProtocolStatus) Reset() { func (x *ProtocolStatus) Reset() {
*x = ProtocolStatus{} *x = ProtocolStatus{}
mi := &file_mxaccess_gateway_proto_msgTypes[100] mi := &file_mxaccess_gateway_proto_msgTypes[101]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -8592,7 +8668,7 @@ func (x *ProtocolStatus) String() string {
func (*ProtocolStatus) ProtoMessage() {} func (*ProtocolStatus) ProtoMessage() {}
func (x *ProtocolStatus) ProtoReflect() protoreflect.Message { func (x *ProtocolStatus) ProtoReflect() protoreflect.Message {
mi := &file_mxaccess_gateway_proto_msgTypes[100] mi := &file_mxaccess_gateway_proto_msgTypes[101]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -8605,7 +8681,7 @@ func (x *ProtocolStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use ProtocolStatus.ProtoReflect.Descriptor instead. // Deprecated: Use ProtocolStatus.ProtoReflect.Descriptor instead.
func (*ProtocolStatus) Descriptor() ([]byte, []int) { func (*ProtocolStatus) Descriptor() ([]byte, []int) {
return file_mxaccess_gateway_proto_rawDescGZIP(), []int{100} return file_mxaccess_gateway_proto_rawDescGZIP(), []int{101}
} }
func (x *ProtocolStatus) GetCode() ProtocolStatusCode { func (x *ProtocolStatus) GetCode() ProtocolStatusCode {
@@ -9115,20 +9191,23 @@ const file_mxaccess_gateway_proto_rawDesc = "" +
"session_id\"y\n" + "session_id\"y\n" +
"\x13StreamAlarmsRequest\x122\n" + "\x13StreamAlarmsRequest\x122\n" +
"\x15client_correlation_id\x18\x01 \x01(\tR\x13clientCorrelationId\x12.\n" + "\x15client_correlation_id\x18\x01 \x01(\tR\x13clientCorrelationId\x12.\n" +
"\x13alarm_filter_prefix\x18\x02 \x01(\tR\x11alarmFilterPrefix\"\xbf\x02\n" + "\x13alarm_filter_prefix\x18\x02 \x01(\tR\x11alarmFilterPrefix\"\x94\x03\n" +
"\x10AlarmFeedMessage\x12M\n" + "\x10AlarmFeedMessage\x12M\n" +
"\factive_alarm\x18\x01 \x01(\v2(.mxaccess_gateway.v1.ActiveAlarmSnapshotH\x00R\vactiveAlarm\x12-\n" + "\factive_alarm\x18\x01 \x01(\v2(.mxaccess_gateway.v1.ActiveAlarmSnapshotH\x00R\vactiveAlarm\x12-\n" +
"\x11snapshot_complete\x18\x02 \x01(\bH\x00R\x10snapshotComplete\x12M\n" + "\x11snapshot_complete\x18\x02 \x01(\bH\x00R\x10snapshotComplete\x12M\n" +
"\n" + "\n" +
"transition\x18\x03 \x01(\v2+.mxaccess_gateway.v1.OnAlarmTransitionEventH\x00R\n" + "transition\x18\x03 \x01(\v2+.mxaccess_gateway.v1.OnAlarmTransitionEventH\x00R\n" +
"transition\x12S\n" + "transition\x12S\n" +
"\x0fprovider_status\x18\x04 \x01(\v2(.mxaccess_gateway.v1.AlarmProviderStatusH\x00R\x0eproviderStatusB\t\n" + "\x0fprovider_status\x18\x04 \x01(\v2(.mxaccess_gateway.v1.AlarmProviderStatusH\x00R\x0eproviderStatus\x12S\n" +
"\x0fsnapshot_status\x18\x05 \x01(\v2(.mxaccess_gateway.v1.AlarmSnapshotStatusH\x00R\x0esnapshotStatusB\t\n" +
"\apayload\"\xb7\x01\n" + "\apayload\"\xb7\x01\n" +
"\x13AlarmProviderStatus\x12:\n" + "\x13AlarmProviderStatus\x12:\n" +
"\x04mode\x18\x01 \x01(\x0e2&.mxaccess_gateway.v1.AlarmProviderModeR\x04mode\x12\x1a\n" + "\x04mode\x18\x01 \x01(\x0e2&.mxaccess_gateway.v1.AlarmProviderModeR\x04mode\x12\x1a\n" +
"\bdegraded\x18\x02 \x01(\bR\bdegraded\x12\x16\n" + "\bdegraded\x18\x02 \x01(\bR\bdegraded\x12\x16\n" +
"\x06reason\x18\x03 \x01(\tR\x06reason\x120\n" + "\x06reason\x18\x03 \x01(\tR\x06reason\x120\n" +
"\x05since\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\"\xbe\x02\n" + "\x05since\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\"3\n" +
"\x13AlarmSnapshotStatus\x12\x1c\n" +
"\ttruncated\x18\x01 \x01(\bR\ttruncated\"\xbe\x02\n" +
"\rMxStatusProxy\x12\x18\n" + "\rMxStatusProxy\x12\x18\n" +
"\asuccess\x18\x01 \x01(\x05R\asuccess\x12A\n" + "\asuccess\x18\x01 \x01(\x05R\asuccess\x12A\n" +
"\bcategory\x18\x02 \x01(\x0e2%.mxaccess_gateway.v1.MxStatusCategoryR\bcategory\x12D\n" + "\bcategory\x18\x02 \x01(\x0e2%.mxaccess_gateway.v1.MxStatusCategoryR\bcategory\x12D\n" +
@@ -9364,7 +9443,7 @@ func file_mxaccess_gateway_proto_rawDescGZIP() []byte {
} }
var file_mxaccess_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 10) var file_mxaccess_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 10)
var file_mxaccess_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 101) var file_mxaccess_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 102)
var file_mxaccess_gateway_proto_goTypes = []any{ var file_mxaccess_gateway_proto_goTypes = []any{
(MxCommandKind)(0), // 0: mxaccess_gateway.v1.MxCommandKind (MxCommandKind)(0), // 0: mxaccess_gateway.v1.MxCommandKind
(AlarmProviderMode)(0), // 1: mxaccess_gateway.v1.AlarmProviderMode (AlarmProviderMode)(0), // 1: mxaccess_gateway.v1.AlarmProviderMode
@@ -9463,29 +9542,30 @@ var file_mxaccess_gateway_proto_goTypes = []any{
(*StreamAlarmsRequest)(nil), // 94: mxaccess_gateway.v1.StreamAlarmsRequest (*StreamAlarmsRequest)(nil), // 94: mxaccess_gateway.v1.StreamAlarmsRequest
(*AlarmFeedMessage)(nil), // 95: mxaccess_gateway.v1.AlarmFeedMessage (*AlarmFeedMessage)(nil), // 95: mxaccess_gateway.v1.AlarmFeedMessage
(*AlarmProviderStatus)(nil), // 96: mxaccess_gateway.v1.AlarmProviderStatus (*AlarmProviderStatus)(nil), // 96: mxaccess_gateway.v1.AlarmProviderStatus
(*MxStatusProxy)(nil), // 97: mxaccess_gateway.v1.MxStatusProxy (*AlarmSnapshotStatus)(nil), // 97: mxaccess_gateway.v1.AlarmSnapshotStatus
(*MxValue)(nil), // 98: mxaccess_gateway.v1.MxValue (*MxStatusProxy)(nil), // 98: mxaccess_gateway.v1.MxStatusProxy
(*MxArray)(nil), // 99: mxaccess_gateway.v1.MxArray (*MxValue)(nil), // 99: mxaccess_gateway.v1.MxValue
(*MxSparseArray)(nil), // 100: mxaccess_gateway.v1.MxSparseArray (*MxArray)(nil), // 100: mxaccess_gateway.v1.MxArray
(*MxSparseElement)(nil), // 101: mxaccess_gateway.v1.MxSparseElement (*MxSparseArray)(nil), // 101: mxaccess_gateway.v1.MxSparseArray
(*BoolArray)(nil), // 102: mxaccess_gateway.v1.BoolArray (*MxSparseElement)(nil), // 102: mxaccess_gateway.v1.MxSparseElement
(*Int32Array)(nil), // 103: mxaccess_gateway.v1.Int32Array (*BoolArray)(nil), // 103: mxaccess_gateway.v1.BoolArray
(*Int64Array)(nil), // 104: mxaccess_gateway.v1.Int64Array (*Int32Array)(nil), // 104: mxaccess_gateway.v1.Int32Array
(*FloatArray)(nil), // 105: mxaccess_gateway.v1.FloatArray (*Int64Array)(nil), // 105: mxaccess_gateway.v1.Int64Array
(*DoubleArray)(nil), // 106: mxaccess_gateway.v1.DoubleArray (*FloatArray)(nil), // 106: mxaccess_gateway.v1.FloatArray
(*StringArray)(nil), // 107: mxaccess_gateway.v1.StringArray (*DoubleArray)(nil), // 107: mxaccess_gateway.v1.DoubleArray
(*TimestampArray)(nil), // 108: mxaccess_gateway.v1.TimestampArray (*StringArray)(nil), // 108: mxaccess_gateway.v1.StringArray
(*RawArray)(nil), // 109: mxaccess_gateway.v1.RawArray (*TimestampArray)(nil), // 109: mxaccess_gateway.v1.TimestampArray
(*ProtocolStatus)(nil), // 110: mxaccess_gateway.v1.ProtocolStatus (*RawArray)(nil), // 110: mxaccess_gateway.v1.RawArray
(*durationpb.Duration)(nil), // 111: google.protobuf.Duration (*ProtocolStatus)(nil), // 111: mxaccess_gateway.v1.ProtocolStatus
(*timestamppb.Timestamp)(nil), // 112: google.protobuf.Timestamp (*durationpb.Duration)(nil), // 112: google.protobuf.Duration
(*timestamppb.Timestamp)(nil), // 113: google.protobuf.Timestamp
} }
var file_mxaccess_gateway_proto_depIdxs = []int32{ var file_mxaccess_gateway_proto_depIdxs = []int32{
111, // 0: mxaccess_gateway.v1.OpenSessionRequest.command_timeout:type_name -> google.protobuf.Duration 112, // 0: mxaccess_gateway.v1.OpenSessionRequest.command_timeout:type_name -> google.protobuf.Duration
111, // 1: mxaccess_gateway.v1.OpenSessionReply.default_command_timeout:type_name -> google.protobuf.Duration 112, // 1: mxaccess_gateway.v1.OpenSessionReply.default_command_timeout:type_name -> google.protobuf.Duration
110, // 2: mxaccess_gateway.v1.OpenSessionReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus 111, // 2: mxaccess_gateway.v1.OpenSessionReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus
9, // 3: mxaccess_gateway.v1.CloseSessionReply.final_state:type_name -> mxaccess_gateway.v1.SessionState 9, // 3: mxaccess_gateway.v1.CloseSessionReply.final_state:type_name -> mxaccess_gateway.v1.SessionState
110, // 4: mxaccess_gateway.v1.CloseSessionReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus 111, // 4: mxaccess_gateway.v1.CloseSessionReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus
17, // 5: mxaccess_gateway.v1.MxCommandRequest.command:type_name -> mxaccess_gateway.v1.MxCommand 17, // 5: mxaccess_gateway.v1.MxCommandRequest.command:type_name -> mxaccess_gateway.v1.MxCommand
0, // 6: mxaccess_gateway.v1.MxCommand.kind:type_name -> mxaccess_gateway.v1.MxCommandKind 0, // 6: mxaccess_gateway.v1.MxCommand.kind:type_name -> mxaccess_gateway.v1.MxCommandKind
18, // 7: mxaccess_gateway.v1.MxCommand.register:type_name -> mxaccess_gateway.v1.RegisterCommand 18, // 7: mxaccess_gateway.v1.MxCommand.register:type_name -> mxaccess_gateway.v1.RegisterCommand
@@ -9527,30 +9607,30 @@ var file_mxaccess_gateway_proto_depIdxs = []int32{
60, // 43: mxaccess_gateway.v1.MxCommand.get_worker_info:type_name -> mxaccess_gateway.v1.GetWorkerInfoCommand 60, // 43: mxaccess_gateway.v1.MxCommand.get_worker_info:type_name -> mxaccess_gateway.v1.GetWorkerInfoCommand
61, // 44: mxaccess_gateway.v1.MxCommand.drain_events:type_name -> mxaccess_gateway.v1.DrainEventsCommand 61, // 44: mxaccess_gateway.v1.MxCommand.drain_events:type_name -> mxaccess_gateway.v1.DrainEventsCommand
62, // 45: mxaccess_gateway.v1.MxCommand.shutdown_worker:type_name -> mxaccess_gateway.v1.ShutdownWorkerCommand 62, // 45: mxaccess_gateway.v1.MxCommand.shutdown_worker:type_name -> mxaccess_gateway.v1.ShutdownWorkerCommand
98, // 46: mxaccess_gateway.v1.WriteCommand.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 46: mxaccess_gateway.v1.WriteCommand.value:type_name -> mxaccess_gateway.v1.MxValue
98, // 47: mxaccess_gateway.v1.Write2Command.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 47: mxaccess_gateway.v1.Write2Command.value:type_name -> mxaccess_gateway.v1.MxValue
98, // 48: mxaccess_gateway.v1.Write2Command.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 48: mxaccess_gateway.v1.Write2Command.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue
98, // 49: mxaccess_gateway.v1.WriteSecuredCommand.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 49: mxaccess_gateway.v1.WriteSecuredCommand.value:type_name -> mxaccess_gateway.v1.MxValue
98, // 50: mxaccess_gateway.v1.WriteSecured2Command.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 50: mxaccess_gateway.v1.WriteSecured2Command.value:type_name -> mxaccess_gateway.v1.MxValue
98, // 51: mxaccess_gateway.v1.WriteSecured2Command.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 51: mxaccess_gateway.v1.WriteSecured2Command.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue
1, // 52: mxaccess_gateway.v1.SubscribeAlarmsCommand.forced_mode:type_name -> mxaccess_gateway.v1.AlarmProviderMode 1, // 52: mxaccess_gateway.v1.SubscribeAlarmsCommand.forced_mode:type_name -> mxaccess_gateway.v1.AlarmProviderMode
43, // 53: mxaccess_gateway.v1.SubscribeAlarmsCommand.watch_list:type_name -> mxaccess_gateway.v1.AlarmSubtagTarget 43, // 53: mxaccess_gateway.v1.SubscribeAlarmsCommand.watch_list:type_name -> mxaccess_gateway.v1.AlarmSubtagTarget
44, // 54: mxaccess_gateway.v1.SubscribeAlarmsCommand.failover:type_name -> mxaccess_gateway.v1.AlarmFailoverConfig 44, // 54: mxaccess_gateway.v1.SubscribeAlarmsCommand.failover:type_name -> mxaccess_gateway.v1.AlarmFailoverConfig
50, // 55: mxaccess_gateway.v1.WriteBulkCommand.entries:type_name -> mxaccess_gateway.v1.WriteBulkEntry 50, // 55: mxaccess_gateway.v1.WriteBulkCommand.entries:type_name -> mxaccess_gateway.v1.WriteBulkEntry
98, // 56: mxaccess_gateway.v1.WriteBulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 56: mxaccess_gateway.v1.WriteBulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue
52, // 57: mxaccess_gateway.v1.Write2BulkCommand.entries:type_name -> mxaccess_gateway.v1.Write2BulkEntry 52, // 57: mxaccess_gateway.v1.Write2BulkCommand.entries:type_name -> mxaccess_gateway.v1.Write2BulkEntry
98, // 58: mxaccess_gateway.v1.Write2BulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 58: mxaccess_gateway.v1.Write2BulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue
98, // 59: mxaccess_gateway.v1.Write2BulkEntry.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 59: mxaccess_gateway.v1.Write2BulkEntry.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue
54, // 60: mxaccess_gateway.v1.WriteSecuredBulkCommand.entries:type_name -> mxaccess_gateway.v1.WriteSecuredBulkEntry 54, // 60: mxaccess_gateway.v1.WriteSecuredBulkCommand.entries:type_name -> mxaccess_gateway.v1.WriteSecuredBulkEntry
98, // 61: mxaccess_gateway.v1.WriteSecuredBulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 61: mxaccess_gateway.v1.WriteSecuredBulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue
56, // 62: mxaccess_gateway.v1.WriteSecured2BulkCommand.entries:type_name -> mxaccess_gateway.v1.WriteSecured2BulkEntry 56, // 62: mxaccess_gateway.v1.WriteSecured2BulkCommand.entries:type_name -> mxaccess_gateway.v1.WriteSecured2BulkEntry
98, // 63: mxaccess_gateway.v1.WriteSecured2BulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 63: mxaccess_gateway.v1.WriteSecured2BulkEntry.value:type_name -> mxaccess_gateway.v1.MxValue
98, // 64: mxaccess_gateway.v1.WriteSecured2BulkEntry.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 64: mxaccess_gateway.v1.WriteSecured2BulkEntry.timestamp_value:type_name -> mxaccess_gateway.v1.MxValue
111, // 65: mxaccess_gateway.v1.ShutdownWorkerCommand.grace_period:type_name -> google.protobuf.Duration 112, // 65: mxaccess_gateway.v1.ShutdownWorkerCommand.grace_period:type_name -> google.protobuf.Duration
0, // 66: mxaccess_gateway.v1.MxCommandReply.kind:type_name -> mxaccess_gateway.v1.MxCommandKind 0, // 66: mxaccess_gateway.v1.MxCommandReply.kind:type_name -> mxaccess_gateway.v1.MxCommandKind
110, // 67: mxaccess_gateway.v1.MxCommandReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus 111, // 67: mxaccess_gateway.v1.MxCommandReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus
98, // 68: mxaccess_gateway.v1.MxCommandReply.return_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 68: mxaccess_gateway.v1.MxCommandReply.return_value:type_name -> mxaccess_gateway.v1.MxValue
97, // 69: mxaccess_gateway.v1.MxCommandReply.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy 98, // 69: mxaccess_gateway.v1.MxCommandReply.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy
64, // 70: mxaccess_gateway.v1.MxCommandReply.register:type_name -> mxaccess_gateway.v1.RegisterReply 64, // 70: mxaccess_gateway.v1.MxCommandReply.register:type_name -> mxaccess_gateway.v1.RegisterReply
65, // 71: mxaccess_gateway.v1.MxCommandReply.add_item:type_name -> mxaccess_gateway.v1.AddItemReply 65, // 71: mxaccess_gateway.v1.MxCommandReply.add_item:type_name -> mxaccess_gateway.v1.AddItemReply
66, // 72: mxaccess_gateway.v1.MxCommandReply.add_item2:type_name -> mxaccess_gateway.v1.AddItem2Reply 66, // 72: mxaccess_gateway.v1.MxCommandReply.add_item2:type_name -> mxaccess_gateway.v1.AddItem2Reply
@@ -9575,24 +9655,24 @@ var file_mxaccess_gateway_proto_depIdxs = []int32{
78, // 91: mxaccess_gateway.v1.MxCommandReply.session_state:type_name -> mxaccess_gateway.v1.SessionStateReply 78, // 91: mxaccess_gateway.v1.MxCommandReply.session_state:type_name -> mxaccess_gateway.v1.SessionStateReply
79, // 92: mxaccess_gateway.v1.MxCommandReply.worker_info:type_name -> mxaccess_gateway.v1.WorkerInfoReply 79, // 92: mxaccess_gateway.v1.MxCommandReply.worker_info:type_name -> mxaccess_gateway.v1.WorkerInfoReply
80, // 93: mxaccess_gateway.v1.MxCommandReply.drain_events:type_name -> mxaccess_gateway.v1.DrainEventsReply 80, // 93: mxaccess_gateway.v1.MxCommandReply.drain_events:type_name -> mxaccess_gateway.v1.DrainEventsReply
97, // 94: mxaccess_gateway.v1.SuspendReply.status:type_name -> mxaccess_gateway.v1.MxStatusProxy 98, // 94: mxaccess_gateway.v1.SuspendReply.status:type_name -> mxaccess_gateway.v1.MxStatusProxy
97, // 95: mxaccess_gateway.v1.ActivateReply.status:type_name -> mxaccess_gateway.v1.MxStatusProxy 98, // 95: mxaccess_gateway.v1.ActivateReply.status:type_name -> mxaccess_gateway.v1.MxStatusProxy
72, // 96: mxaccess_gateway.v1.BulkSubscribeReply.results:type_name -> mxaccess_gateway.v1.SubscribeResult 72, // 96: mxaccess_gateway.v1.BulkSubscribeReply.results:type_name -> mxaccess_gateway.v1.SubscribeResult
97, // 97: mxaccess_gateway.v1.BulkWriteResult.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy 98, // 97: mxaccess_gateway.v1.BulkWriteResult.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy
74, // 98: mxaccess_gateway.v1.BulkWriteReply.results:type_name -> mxaccess_gateway.v1.BulkWriteResult 74, // 98: mxaccess_gateway.v1.BulkWriteReply.results:type_name -> mxaccess_gateway.v1.BulkWriteResult
98, // 99: mxaccess_gateway.v1.BulkReadResult.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 99: mxaccess_gateway.v1.BulkReadResult.value:type_name -> mxaccess_gateway.v1.MxValue
112, // 100: mxaccess_gateway.v1.BulkReadResult.source_timestamp:type_name -> google.protobuf.Timestamp 113, // 100: mxaccess_gateway.v1.BulkReadResult.source_timestamp:type_name -> google.protobuf.Timestamp
97, // 101: mxaccess_gateway.v1.BulkReadResult.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy 98, // 101: mxaccess_gateway.v1.BulkReadResult.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy
76, // 102: mxaccess_gateway.v1.BulkReadReply.results:type_name -> mxaccess_gateway.v1.BulkReadResult 76, // 102: mxaccess_gateway.v1.BulkReadReply.results:type_name -> mxaccess_gateway.v1.BulkReadResult
9, // 103: mxaccess_gateway.v1.SessionStateReply.state:type_name -> mxaccess_gateway.v1.SessionState 9, // 103: mxaccess_gateway.v1.SessionStateReply.state:type_name -> mxaccess_gateway.v1.SessionState
83, // 104: mxaccess_gateway.v1.DrainEventsReply.events:type_name -> mxaccess_gateway.v1.MxEvent 83, // 104: mxaccess_gateway.v1.DrainEventsReply.events:type_name -> mxaccess_gateway.v1.MxEvent
91, // 105: mxaccess_gateway.v1.QueryActiveAlarmsReplyPayload.snapshots:type_name -> mxaccess_gateway.v1.ActiveAlarmSnapshot 91, // 105: mxaccess_gateway.v1.QueryActiveAlarmsReplyPayload.snapshots:type_name -> mxaccess_gateway.v1.ActiveAlarmSnapshot
2, // 106: mxaccess_gateway.v1.MxEvent.family:type_name -> mxaccess_gateway.v1.MxEventFamily 2, // 106: mxaccess_gateway.v1.MxEvent.family:type_name -> mxaccess_gateway.v1.MxEventFamily
98, // 107: mxaccess_gateway.v1.MxEvent.value:type_name -> mxaccess_gateway.v1.MxValue 99, // 107: mxaccess_gateway.v1.MxEvent.value:type_name -> mxaccess_gateway.v1.MxValue
112, // 108: mxaccess_gateway.v1.MxEvent.source_timestamp:type_name -> google.protobuf.Timestamp 113, // 108: mxaccess_gateway.v1.MxEvent.source_timestamp:type_name -> google.protobuf.Timestamp
97, // 109: mxaccess_gateway.v1.MxEvent.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy 98, // 109: mxaccess_gateway.v1.MxEvent.statuses:type_name -> mxaccess_gateway.v1.MxStatusProxy
112, // 110: mxaccess_gateway.v1.MxEvent.worker_timestamp:type_name -> google.protobuf.Timestamp 113, // 110: mxaccess_gateway.v1.MxEvent.worker_timestamp:type_name -> google.protobuf.Timestamp
112, // 111: mxaccess_gateway.v1.MxEvent.gateway_receive_timestamp:type_name -> google.protobuf.Timestamp 113, // 111: mxaccess_gateway.v1.MxEvent.gateway_receive_timestamp:type_name -> google.protobuf.Timestamp
84, // 112: mxaccess_gateway.v1.MxEvent.replay_gap:type_name -> mxaccess_gateway.v1.ReplayGap 84, // 112: mxaccess_gateway.v1.MxEvent.replay_gap:type_name -> mxaccess_gateway.v1.ReplayGap
85, // 113: mxaccess_gateway.v1.MxEvent.on_data_change:type_name -> mxaccess_gateway.v1.OnDataChangeEvent 85, // 113: mxaccess_gateway.v1.MxEvent.on_data_change:type_name -> mxaccess_gateway.v1.OnDataChangeEvent
86, // 114: mxaccess_gateway.v1.MxEvent.on_write_complete:type_name -> mxaccess_gateway.v1.OnWriteCompleteEvent 86, // 114: mxaccess_gateway.v1.MxEvent.on_write_complete:type_name -> mxaccess_gateway.v1.OnWriteCompleteEvent
@@ -9601,68 +9681,69 @@ var file_mxaccess_gateway_proto_depIdxs = []int32{
89, // 117: mxaccess_gateway.v1.MxEvent.on_alarm_transition:type_name -> mxaccess_gateway.v1.OnAlarmTransitionEvent 89, // 117: mxaccess_gateway.v1.MxEvent.on_alarm_transition:type_name -> mxaccess_gateway.v1.OnAlarmTransitionEvent
90, // 118: mxaccess_gateway.v1.MxEvent.on_alarm_provider_mode_changed:type_name -> mxaccess_gateway.v1.OnAlarmProviderModeChangedEvent 90, // 118: mxaccess_gateway.v1.MxEvent.on_alarm_provider_mode_changed:type_name -> mxaccess_gateway.v1.OnAlarmProviderModeChangedEvent
7, // 119: mxaccess_gateway.v1.OnBufferedDataChangeEvent.data_type:type_name -> mxaccess_gateway.v1.MxDataType 7, // 119: mxaccess_gateway.v1.OnBufferedDataChangeEvent.data_type:type_name -> mxaccess_gateway.v1.MxDataType
99, // 120: mxaccess_gateway.v1.OnBufferedDataChangeEvent.quality_values:type_name -> mxaccess_gateway.v1.MxArray 100, // 120: mxaccess_gateway.v1.OnBufferedDataChangeEvent.quality_values:type_name -> mxaccess_gateway.v1.MxArray
99, // 121: mxaccess_gateway.v1.OnBufferedDataChangeEvent.timestamp_values:type_name -> mxaccess_gateway.v1.MxArray 100, // 121: mxaccess_gateway.v1.OnBufferedDataChangeEvent.timestamp_values:type_name -> mxaccess_gateway.v1.MxArray
3, // 122: mxaccess_gateway.v1.OnAlarmTransitionEvent.transition_kind:type_name -> mxaccess_gateway.v1.AlarmTransitionKind 3, // 122: mxaccess_gateway.v1.OnAlarmTransitionEvent.transition_kind:type_name -> mxaccess_gateway.v1.AlarmTransitionKind
112, // 123: mxaccess_gateway.v1.OnAlarmTransitionEvent.original_raise_timestamp:type_name -> google.protobuf.Timestamp 113, // 123: mxaccess_gateway.v1.OnAlarmTransitionEvent.original_raise_timestamp:type_name -> google.protobuf.Timestamp
112, // 124: mxaccess_gateway.v1.OnAlarmTransitionEvent.transition_timestamp:type_name -> google.protobuf.Timestamp 113, // 124: mxaccess_gateway.v1.OnAlarmTransitionEvent.transition_timestamp:type_name -> google.protobuf.Timestamp
98, // 125: mxaccess_gateway.v1.OnAlarmTransitionEvent.current_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 125: mxaccess_gateway.v1.OnAlarmTransitionEvent.current_value:type_name -> mxaccess_gateway.v1.MxValue
98, // 126: mxaccess_gateway.v1.OnAlarmTransitionEvent.limit_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 126: mxaccess_gateway.v1.OnAlarmTransitionEvent.limit_value:type_name -> mxaccess_gateway.v1.MxValue
1, // 127: mxaccess_gateway.v1.OnAlarmTransitionEvent.source_provider:type_name -> mxaccess_gateway.v1.AlarmProviderMode 1, // 127: mxaccess_gateway.v1.OnAlarmTransitionEvent.source_provider:type_name -> mxaccess_gateway.v1.AlarmProviderMode
1, // 128: mxaccess_gateway.v1.OnAlarmProviderModeChangedEvent.mode:type_name -> mxaccess_gateway.v1.AlarmProviderMode 1, // 128: mxaccess_gateway.v1.OnAlarmProviderModeChangedEvent.mode:type_name -> mxaccess_gateway.v1.AlarmProviderMode
112, // 129: mxaccess_gateway.v1.OnAlarmProviderModeChangedEvent.at:type_name -> google.protobuf.Timestamp 113, // 129: mxaccess_gateway.v1.OnAlarmProviderModeChangedEvent.at:type_name -> google.protobuf.Timestamp
112, // 130: mxaccess_gateway.v1.ActiveAlarmSnapshot.original_raise_timestamp:type_name -> google.protobuf.Timestamp 113, // 130: mxaccess_gateway.v1.ActiveAlarmSnapshot.original_raise_timestamp:type_name -> google.protobuf.Timestamp
4, // 131: mxaccess_gateway.v1.ActiveAlarmSnapshot.current_state:type_name -> mxaccess_gateway.v1.AlarmConditionState 4, // 131: mxaccess_gateway.v1.ActiveAlarmSnapshot.current_state:type_name -> mxaccess_gateway.v1.AlarmConditionState
112, // 132: mxaccess_gateway.v1.ActiveAlarmSnapshot.last_transition_timestamp:type_name -> google.protobuf.Timestamp 113, // 132: mxaccess_gateway.v1.ActiveAlarmSnapshot.last_transition_timestamp:type_name -> google.protobuf.Timestamp
98, // 133: mxaccess_gateway.v1.ActiveAlarmSnapshot.current_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 133: mxaccess_gateway.v1.ActiveAlarmSnapshot.current_value:type_name -> mxaccess_gateway.v1.MxValue
98, // 134: mxaccess_gateway.v1.ActiveAlarmSnapshot.limit_value:type_name -> mxaccess_gateway.v1.MxValue 99, // 134: mxaccess_gateway.v1.ActiveAlarmSnapshot.limit_value:type_name -> mxaccess_gateway.v1.MxValue
1, // 135: mxaccess_gateway.v1.ActiveAlarmSnapshot.source_provider:type_name -> mxaccess_gateway.v1.AlarmProviderMode 1, // 135: mxaccess_gateway.v1.ActiveAlarmSnapshot.source_provider:type_name -> mxaccess_gateway.v1.AlarmProviderMode
110, // 136: mxaccess_gateway.v1.AcknowledgeAlarmReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus 111, // 136: mxaccess_gateway.v1.AcknowledgeAlarmReply.protocol_status:type_name -> mxaccess_gateway.v1.ProtocolStatus
97, // 137: mxaccess_gateway.v1.AcknowledgeAlarmReply.status:type_name -> mxaccess_gateway.v1.MxStatusProxy 98, // 137: mxaccess_gateway.v1.AcknowledgeAlarmReply.status:type_name -> mxaccess_gateway.v1.MxStatusProxy
91, // 138: mxaccess_gateway.v1.AlarmFeedMessage.active_alarm:type_name -> mxaccess_gateway.v1.ActiveAlarmSnapshot 91, // 138: mxaccess_gateway.v1.AlarmFeedMessage.active_alarm:type_name -> mxaccess_gateway.v1.ActiveAlarmSnapshot
89, // 139: mxaccess_gateway.v1.AlarmFeedMessage.transition:type_name -> mxaccess_gateway.v1.OnAlarmTransitionEvent 89, // 139: mxaccess_gateway.v1.AlarmFeedMessage.transition:type_name -> mxaccess_gateway.v1.OnAlarmTransitionEvent
96, // 140: mxaccess_gateway.v1.AlarmFeedMessage.provider_status:type_name -> mxaccess_gateway.v1.AlarmProviderStatus 96, // 140: mxaccess_gateway.v1.AlarmFeedMessage.provider_status:type_name -> mxaccess_gateway.v1.AlarmProviderStatus
1, // 141: mxaccess_gateway.v1.AlarmProviderStatus.mode:type_name -> mxaccess_gateway.v1.AlarmProviderMode 97, // 141: mxaccess_gateway.v1.AlarmFeedMessage.snapshot_status:type_name -> mxaccess_gateway.v1.AlarmSnapshotStatus
112, // 142: mxaccess_gateway.v1.AlarmProviderStatus.since:type_name -> google.protobuf.Timestamp 1, // 142: mxaccess_gateway.v1.AlarmProviderStatus.mode:type_name -> mxaccess_gateway.v1.AlarmProviderMode
5, // 143: mxaccess_gateway.v1.MxStatusProxy.category:type_name -> mxaccess_gateway.v1.MxStatusCategory 113, // 143: mxaccess_gateway.v1.AlarmProviderStatus.since:type_name -> google.protobuf.Timestamp
6, // 144: mxaccess_gateway.v1.MxStatusProxy.detected_by:type_name -> mxaccess_gateway.v1.MxStatusSource 5, // 144: mxaccess_gateway.v1.MxStatusProxy.category:type_name -> mxaccess_gateway.v1.MxStatusCategory
7, // 145: mxaccess_gateway.v1.MxValue.data_type:type_name -> mxaccess_gateway.v1.MxDataType 6, // 145: mxaccess_gateway.v1.MxStatusProxy.detected_by:type_name -> mxaccess_gateway.v1.MxStatusSource
112, // 146: mxaccess_gateway.v1.MxValue.timestamp_value:type_name -> google.protobuf.Timestamp 7, // 146: mxaccess_gateway.v1.MxValue.data_type:type_name -> mxaccess_gateway.v1.MxDataType
99, // 147: mxaccess_gateway.v1.MxValue.array_value:type_name -> mxaccess_gateway.v1.MxArray 113, // 147: mxaccess_gateway.v1.MxValue.timestamp_value:type_name -> google.protobuf.Timestamp
100, // 148: mxaccess_gateway.v1.MxValue.sparse_array_value:type_name -> mxaccess_gateway.v1.MxSparseArray 100, // 148: mxaccess_gateway.v1.MxValue.array_value:type_name -> mxaccess_gateway.v1.MxArray
7, // 149: mxaccess_gateway.v1.MxArray.element_data_type:type_name -> mxaccess_gateway.v1.MxDataType 101, // 149: mxaccess_gateway.v1.MxValue.sparse_array_value:type_name -> mxaccess_gateway.v1.MxSparseArray
102, // 150: mxaccess_gateway.v1.MxArray.bool_values:type_name -> mxaccess_gateway.v1.BoolArray 7, // 150: mxaccess_gateway.v1.MxArray.element_data_type:type_name -> mxaccess_gateway.v1.MxDataType
103, // 151: mxaccess_gateway.v1.MxArray.int32_values:type_name -> mxaccess_gateway.v1.Int32Array 103, // 151: mxaccess_gateway.v1.MxArray.bool_values:type_name -> mxaccess_gateway.v1.BoolArray
104, // 152: mxaccess_gateway.v1.MxArray.int64_values:type_name -> mxaccess_gateway.v1.Int64Array 104, // 152: mxaccess_gateway.v1.MxArray.int32_values:type_name -> mxaccess_gateway.v1.Int32Array
105, // 153: mxaccess_gateway.v1.MxArray.float_values:type_name -> mxaccess_gateway.v1.FloatArray 105, // 153: mxaccess_gateway.v1.MxArray.int64_values:type_name -> mxaccess_gateway.v1.Int64Array
106, // 154: mxaccess_gateway.v1.MxArray.double_values:type_name -> mxaccess_gateway.v1.DoubleArray 106, // 154: mxaccess_gateway.v1.MxArray.float_values:type_name -> mxaccess_gateway.v1.FloatArray
107, // 155: mxaccess_gateway.v1.MxArray.string_values:type_name -> mxaccess_gateway.v1.StringArray 107, // 155: mxaccess_gateway.v1.MxArray.double_values:type_name -> mxaccess_gateway.v1.DoubleArray
108, // 156: mxaccess_gateway.v1.MxArray.timestamp_values:type_name -> mxaccess_gateway.v1.TimestampArray 108, // 156: mxaccess_gateway.v1.MxArray.string_values:type_name -> mxaccess_gateway.v1.StringArray
109, // 157: mxaccess_gateway.v1.MxArray.raw_values:type_name -> mxaccess_gateway.v1.RawArray 109, // 157: mxaccess_gateway.v1.MxArray.timestamp_values:type_name -> mxaccess_gateway.v1.TimestampArray
7, // 158: mxaccess_gateway.v1.MxSparseArray.element_data_type:type_name -> mxaccess_gateway.v1.MxDataType 110, // 158: mxaccess_gateway.v1.MxArray.raw_values:type_name -> mxaccess_gateway.v1.RawArray
101, // 159: mxaccess_gateway.v1.MxSparseArray.elements:type_name -> mxaccess_gateway.v1.MxSparseElement 7, // 159: mxaccess_gateway.v1.MxSparseArray.element_data_type:type_name -> mxaccess_gateway.v1.MxDataType
98, // 160: mxaccess_gateway.v1.MxSparseElement.value:type_name -> mxaccess_gateway.v1.MxValue 102, // 160: mxaccess_gateway.v1.MxSparseArray.elements:type_name -> mxaccess_gateway.v1.MxSparseElement
112, // 161: mxaccess_gateway.v1.TimestampArray.values:type_name -> google.protobuf.Timestamp 99, // 161: mxaccess_gateway.v1.MxSparseElement.value:type_name -> mxaccess_gateway.v1.MxValue
8, // 162: mxaccess_gateway.v1.ProtocolStatus.code:type_name -> mxaccess_gateway.v1.ProtocolStatusCode 113, // 162: mxaccess_gateway.v1.TimestampArray.values:type_name -> google.protobuf.Timestamp
11, // 163: mxaccess_gateway.v1.MxAccessGateway.OpenSession:input_type -> mxaccess_gateway.v1.OpenSessionRequest 8, // 163: mxaccess_gateway.v1.ProtocolStatus.code:type_name -> mxaccess_gateway.v1.ProtocolStatusCode
13, // 164: mxaccess_gateway.v1.MxAccessGateway.CloseSession:input_type -> mxaccess_gateway.v1.CloseSessionRequest 11, // 164: mxaccess_gateway.v1.MxAccessGateway.OpenSession:input_type -> mxaccess_gateway.v1.OpenSessionRequest
16, // 165: mxaccess_gateway.v1.MxAccessGateway.Invoke:input_type -> mxaccess_gateway.v1.MxCommandRequest 13, // 165: mxaccess_gateway.v1.MxAccessGateway.CloseSession:input_type -> mxaccess_gateway.v1.CloseSessionRequest
15, // 166: mxaccess_gateway.v1.MxAccessGateway.StreamEvents:input_type -> mxaccess_gateway.v1.StreamEventsRequest 16, // 166: mxaccess_gateway.v1.MxAccessGateway.Invoke:input_type -> mxaccess_gateway.v1.MxCommandRequest
92, // 167: mxaccess_gateway.v1.MxAccessGateway.AcknowledgeAlarm:input_type -> mxaccess_gateway.v1.AcknowledgeAlarmRequest 15, // 167: mxaccess_gateway.v1.MxAccessGateway.StreamEvents:input_type -> mxaccess_gateway.v1.StreamEventsRequest
94, // 168: mxaccess_gateway.v1.MxAccessGateway.StreamAlarms:input_type -> mxaccess_gateway.v1.StreamAlarmsRequest 92, // 168: mxaccess_gateway.v1.MxAccessGateway.AcknowledgeAlarm:input_type -> mxaccess_gateway.v1.AcknowledgeAlarmRequest
10, // 169: mxaccess_gateway.v1.MxAccessGateway.QueryActiveAlarms:input_type -> mxaccess_gateway.v1.QueryActiveAlarmsRequest 94, // 169: mxaccess_gateway.v1.MxAccessGateway.StreamAlarms:input_type -> mxaccess_gateway.v1.StreamAlarmsRequest
12, // 170: mxaccess_gateway.v1.MxAccessGateway.OpenSession:output_type -> mxaccess_gateway.v1.OpenSessionReply 10, // 170: mxaccess_gateway.v1.MxAccessGateway.QueryActiveAlarms:input_type -> mxaccess_gateway.v1.QueryActiveAlarmsRequest
14, // 171: mxaccess_gateway.v1.MxAccessGateway.CloseSession:output_type -> mxaccess_gateway.v1.CloseSessionReply 12, // 171: mxaccess_gateway.v1.MxAccessGateway.OpenSession:output_type -> mxaccess_gateway.v1.OpenSessionReply
63, // 172: mxaccess_gateway.v1.MxAccessGateway.Invoke:output_type -> mxaccess_gateway.v1.MxCommandReply 14, // 172: mxaccess_gateway.v1.MxAccessGateway.CloseSession:output_type -> mxaccess_gateway.v1.CloseSessionReply
83, // 173: mxaccess_gateway.v1.MxAccessGateway.StreamEvents:output_type -> mxaccess_gateway.v1.MxEvent 63, // 173: mxaccess_gateway.v1.MxAccessGateway.Invoke:output_type -> mxaccess_gateway.v1.MxCommandReply
93, // 174: mxaccess_gateway.v1.MxAccessGateway.AcknowledgeAlarm:output_type -> mxaccess_gateway.v1.AcknowledgeAlarmReply 83, // 174: mxaccess_gateway.v1.MxAccessGateway.StreamEvents:output_type -> mxaccess_gateway.v1.MxEvent
95, // 175: mxaccess_gateway.v1.MxAccessGateway.StreamAlarms:output_type -> mxaccess_gateway.v1.AlarmFeedMessage 93, // 175: mxaccess_gateway.v1.MxAccessGateway.AcknowledgeAlarm:output_type -> mxaccess_gateway.v1.AcknowledgeAlarmReply
91, // 176: mxaccess_gateway.v1.MxAccessGateway.QueryActiveAlarms:output_type -> mxaccess_gateway.v1.ActiveAlarmSnapshot 95, // 176: mxaccess_gateway.v1.MxAccessGateway.StreamAlarms:output_type -> mxaccess_gateway.v1.AlarmFeedMessage
170, // [170:177] is the sub-list for method output_type 91, // 177: mxaccess_gateway.v1.MxAccessGateway.QueryActiveAlarms:output_type -> mxaccess_gateway.v1.ActiveAlarmSnapshot
163, // [163:170] is the sub-list for method input_type 171, // [171:178] is the sub-list for method output_type
163, // [163:163] is the sub-list for extension type_name 164, // [164:171] is the sub-list for method input_type
163, // [163:163] is the sub-list for extension extendee 164, // [164:164] is the sub-list for extension type_name
0, // [0:163] is the sub-list for field type_name 164, // [164:164] is the sub-list for extension extendee
0, // [0:164] is the sub-list for field type_name
} }
func init() { file_mxaccess_gateway_proto_init() } func init() { file_mxaccess_gateway_proto_init() }
@@ -9752,8 +9833,9 @@ func file_mxaccess_gateway_proto_init() {
(*AlarmFeedMessage_SnapshotComplete)(nil), (*AlarmFeedMessage_SnapshotComplete)(nil),
(*AlarmFeedMessage_Transition)(nil), (*AlarmFeedMessage_Transition)(nil),
(*AlarmFeedMessage_ProviderStatus)(nil), (*AlarmFeedMessage_ProviderStatus)(nil),
(*AlarmFeedMessage_SnapshotStatus)(nil),
} }
file_mxaccess_gateway_proto_msgTypes[88].OneofWrappers = []any{ file_mxaccess_gateway_proto_msgTypes[89].OneofWrappers = []any{
(*MxValue_BoolValue)(nil), (*MxValue_BoolValue)(nil),
(*MxValue_Int32Value)(nil), (*MxValue_Int32Value)(nil),
(*MxValue_Int64Value)(nil), (*MxValue_Int64Value)(nil),
@@ -9765,7 +9847,7 @@ func file_mxaccess_gateway_proto_init() {
(*MxValue_RawValue)(nil), (*MxValue_RawValue)(nil),
(*MxValue_SparseArrayValue)(nil), (*MxValue_SparseArrayValue)(nil),
} }
file_mxaccess_gateway_proto_msgTypes[89].OneofWrappers = []any{ file_mxaccess_gateway_proto_msgTypes[90].OneofWrappers = []any{
(*MxArray_BoolValues)(nil), (*MxArray_BoolValues)(nil),
(*MxArray_Int32Values)(nil), (*MxArray_Int32Values)(nil),
(*MxArray_Int64Values)(nil), (*MxArray_Int64Values)(nil),
@@ -9781,7 +9863,7 @@ func file_mxaccess_gateway_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mxaccess_gateway_proto_rawDesc), len(file_mxaccess_gateway_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_mxaccess_gateway_proto_rawDesc), len(file_mxaccess_gateway_proto_rawDesc)),
NumEnums: 10, NumEnums: 10,
NumMessages: 101, NumMessages: 102,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },
+10
View File
@@ -125,6 +125,16 @@ deletions from it. It is set-level degraded status, not a comment on the
record's own fidelity, and is distinct from `getDegraded()` (the subtag record's own fidelity, and is distinct from `getDegraded()` (the subtag
fallback provider). fallback provider).
`streamAlarms` also carries that completeness verdict at feed level, as a
message whose `getPayloadCase()` is `SNAPSHOT_STATUS` and whose
`getSnapshotStatus().getTruncated()` is true while the monitor's cached set
derives from a truncated fetch. One arrives at stream open (after the
`PROVIDER_STATUS` frame, before the cached `ACTIVE_ALARM` frames) so a late
joiner learns the current verdict, then one on every verdict change — including
the clearing frame sent when the gateway's alarm monitor restarts and drops a
truncated verdict. Track it if you need set completeness on a live feed without
polling `queryActiveAlarms`.
## Write Semantics And Common Pitfalls ## Write Semantics And Common Pitfalls
These are MXAccess parity behaviors that surprise new callers. The gateway These are MXAccess parity behaviors that surprise new callers. The gateway
File diff suppressed because it is too large Load Diff
@@ -48,6 +48,7 @@ import mxaccess_gateway.v1.MxaccessGateway.AcknowledgeAlarmReply;
import mxaccess_gateway.v1.MxaccessGateway.AcknowledgeAlarmRequest; import mxaccess_gateway.v1.MxaccessGateway.AcknowledgeAlarmRequest;
import mxaccess_gateway.v1.MxaccessGateway.ActiveAlarmSnapshot; import mxaccess_gateway.v1.MxaccessGateway.ActiveAlarmSnapshot;
import mxaccess_gateway.v1.MxaccessGateway.AlarmProviderStatus; import mxaccess_gateway.v1.MxaccessGateway.AlarmProviderStatus;
import mxaccess_gateway.v1.MxaccessGateway.AlarmSnapshotStatus;
import mxaccess_gateway.v1.MxaccessGateway.AlarmFeedMessage; import mxaccess_gateway.v1.MxaccessGateway.AlarmFeedMessage;
import mxaccess_gateway.v1.MxaccessGateway.BulkReadResult; import mxaccess_gateway.v1.MxaccessGateway.BulkReadResult;
import mxaccess_gateway.v1.MxaccessGateway.BulkWriteResult; import mxaccess_gateway.v1.MxaccessGateway.BulkWriteResult;
@@ -2282,7 +2283,8 @@ public final class MxGatewayCli implements Callable<Integer> {
/** /**
* Renders one {@link AlarmFeedMessage} in the CLI's plain-text output * Renders one {@link AlarmFeedMessage} in the CLI's plain-text output
* style, distinguishing the active-alarm snapshot, snapshot-complete * style, distinguishing the active-alarm snapshot, snapshot-complete
* sentinel, and transition cases of the message's {@code payload} oneof. * sentinel, transition, provider-status, and snapshot-status cases of the
* message's {@code payload} oneof.
*/ */
private static String formatAlarmFeedMessage(AlarmFeedMessage message) { private static String formatAlarmFeedMessage(AlarmFeedMessage message) {
return switch (message.getPayloadCase()) { return switch (message.getPayloadCase()) {
@@ -2307,6 +2309,10 @@ public final class MxGatewayCli implements Callable<Integer> {
"provider-status mode=%s degraded=%b reason=%s", "provider-status mode=%s degraded=%b reason=%s",
status.getMode().name(), status.getDegraded(), status.getReason()); status.getMode().name(), status.getDegraded(), status.getReason());
} }
case SNAPSHOT_STATUS -> {
AlarmSnapshotStatus status = message.getSnapshotStatus();
yield String.format("snapshot-status truncated=%b", status.getTruncated());
}
case PAYLOAD_NOT_SET -> "unknown"; case PAYLOAD_NOT_SET -> "unknown";
}; };
} }
+10
View File
@@ -122,6 +122,16 @@ poll. Treat the set as possibly incomplete rather than reconciling deletions
from it. It is set-level degraded status, not a comment on the record's own from it. It is set-level degraded status, not a comment on the record's own
fidelity, and is distinct from `degraded` (the subtag fallback provider). fidelity, and is distinct from `degraded` (the subtag fallback provider).
`stream_alarms` also carries that completeness verdict at feed level, as a
message whose `WhichOneof("payload")` is `snapshot_status` and whose
`snapshot_status.truncated` is true while the monitor's cached set derives from
a truncated fetch. One arrives at stream open (after the `provider_status`
frame, before the cached `active_alarm` frames) so a late joiner learns the
current verdict, then one on every verdict change — including the clearing frame
sent when the gateway's alarm monitor restarts and drops a truncated verdict.
Track it if you need set completeness on a live feed without polling
`query_active_alarms`.
Canceling a Python task cancels the client-side gRPC call or stream wait. It Canceling a Python task cancels the client-side gRPC call or stream wait. It
does not abort an in-flight MXAccess COM call inside the worker process. does not abort an in-flight MXAccess COM call inside the worker process.
File diff suppressed because one or more lines are too long
+9
View File
@@ -132,6 +132,15 @@ poll. Treat the set as possibly incomplete rather than reconciling deletions
from it. It is set-level degraded status, not a comment on the record's own from it. It is set-level degraded status, not a comment on the record's own
fidelity, and is distinct from `degraded` (the subtag fallback provider). fidelity, and is distinct from `degraded` (the subtag fallback provider).
`AlarmFeedStream` also carries that completeness verdict at feed level, as an
`alarm_feed_message::Payload::SnapshotStatus` frame whose `truncated` field is
true while the monitor's cached set derives from a truncated fetch. One arrives
at stream open (after the `ProviderStatus` frame, before the cached
`ActiveAlarm` frames) so a late joiner learns the current verdict, then one on
every verdict change — including the clearing frame sent when the gateway's
alarm monitor restarts and drops a truncated verdict. Track it if you need set
completeness on a live feed without polling `query_active_alarms`.
The session helpers keep MXAccess handles visible: The session helpers keep MXAccess handles visible:
```rust ```rust
+9 -1
View File
@@ -2231,7 +2231,7 @@ fn event_value_to_json(value: &ProtoMxValue) -> Value {
} }
/// Render a streamed [`AlarmFeedMessage`] as a terse one-line summary that /// Render a streamed [`AlarmFeedMessage`] as a terse one-line summary that
/// distinguishes the four `payload` oneof cases. /// distinguishes the five `payload` oneof cases.
fn alarm_feed_message_summary(message: &AlarmFeedMessage) -> String { fn alarm_feed_message_summary(message: &AlarmFeedMessage) -> String {
match &message.payload { match &message.payload {
Some(alarm_feed_message::Payload::ActiveAlarm(snapshot)) => { Some(alarm_feed_message::Payload::ActiveAlarm(snapshot)) => {
@@ -2259,6 +2259,9 @@ fn alarm_feed_message_summary(message: &AlarmFeedMessage) -> String {
status.reason status.reason
) )
} }
Some(alarm_feed_message::Payload::SnapshotStatus(status)) => {
format!("snapshot-status truncated={}", status.truncated)
}
None => "(empty)".to_owned(), None => "(empty)".to_owned(),
} }
} }
@@ -2308,6 +2311,11 @@ fn alarm_feed_message_to_json(message: &AlarmFeedMessage) -> Value {
})), })),
} }
}), }),
Some(alarm_feed_message::Payload::SnapshotStatus(status)) => json!({
"snapshotStatus": {
"truncated": status.truncated,
}
}),
None => Value::Null, None => Value::Null,
} }
} }
@@ -1018,6 +1018,10 @@ message AlarmFeedMessage {
// Provider-mode status. Emitted once on stream open and again on every // Provider-mode status. Emitted once on stream open and again on every
// failover/failback so late joiners learn the current mode immediately. // failover/failback so late joiners learn the current mode immediately.
AlarmProviderStatus provider_status = 4; AlarmProviderStatus provider_status = 4;
// Snapshot-completeness status. Emitted once on stream open and again on
// every change of the truncation verdict, so late joiners learn whether the
// feed's active-alarm set may be incomplete.
AlarmSnapshotStatus snapshot_status = 5;
} }
} }
@@ -1028,6 +1032,23 @@ message AlarmProviderStatus {
google.protobuf.Timestamp since = 4; google.protobuf.Timestamp since = 4;
} }
// Feed-level snapshot-completeness status. Emitted once on StreamAlarms open
// (after the initial provider_status frame, before the cached active_alarm
// frames) so late joiners learn the current verdict, and again on every change
// of the truncation verdict when a reconcile reports a different verdict, and
// when the gateway's alarm monitor restarts and drops a truncated verdict with
// the cache generation it described (feed subscribers outlive that monitor
// session, so they are sent the clearing frame). Mirrors the per-record
// ActiveAlarmSnapshot.from_truncated_snapshot caveat at feed level so live
// consumers can reason about completeness without polling QueryActiveAlarms.
message AlarmSnapshotStatus {
// True while the monitor's cached active-alarm set derives from a truncated
// (capped) worker fetch the set may be missing alarms. Distinct from
// provider degradation (AlarmProviderStatus.degraded), which describes the
// fidelity of the records rather than the completeness of the set.
bool truncated = 1;
}
message MxStatusProxy { message MxStatusProxy {
// Mirrors the `success` member of the MXAccess MXSTATUS_PROXY struct // Mirrors the `success` member of the MXAccess MXSTATUS_PROXY struct
// (a 16-bit signed value in the COM struct, widened to int32 on the // (a 16-bit signed value in the COM struct, widened to int32 on the
+6 -1
View File
@@ -273,7 +273,7 @@ bearer). Each hub class is `[Authorize(Policy = HubClientsPolicy)]`.
| Hub | Path | Producer | Payload | Routing | | Hub | Path | Producer | Payload | Routing |
|---|---|---|---|---| |---|---|---|---|---|
| `DashboardSnapshotHub` | `/hubs/snapshot` | `DashboardSnapshotPublisher` (BackgroundService consuming `IDashboardSnapshotService.WatchSnapshotsAsync`) | `DashboardSnapshot` | Sent to all connected clients on every snapshot tick, but only while at least one client is connected (see "Idle gating" below); new connections receive the current snapshot synchronously in `OnConnectedAsync`. | | `DashboardSnapshotHub` | `/hubs/snapshot` | `DashboardSnapshotPublisher` (BackgroundService consuming `IDashboardSnapshotService.WatchSnapshotsAsync`) | `DashboardSnapshot` | Sent to all connected clients on every snapshot tick, but only while at least one client is connected (see "Idle gating" below); new connections receive the current snapshot synchronously in `OnConnectedAsync`. |
| `AlarmsHub` | `/hubs/alarms` | `AlarmsHubPublisher` (BackgroundService consuming `IGatewayAlarmService.StreamAsync(filter: null)`) | `AlarmFeedMessage` (`active_alarm` / `snapshot_complete` / `transition`) | Connected clients auto-join `__alarms__`; all clients receive every message. Publisher auto-reconnects every 5s on stream faults. The alarm value fields (`current_value` / `limit_value`) are stripped from a deep-cloned copy of the message when `Dashboard:ShowTagValues` is false (the default) — on both value-bearing payload arms, so neither a live transition nor a snapshot record leaks a process value; every other field still renders. The source message is never mutated: it fans out from the same feed to gRPC `StreamAlarms` subscribers, which this dashboard-display flag does not govern. Arms carrying no value are forwarded as-is, uncloned. | | `AlarmsHub` | `/hubs/alarms` | `AlarmsHubPublisher` (BackgroundService consuming `IGatewayAlarmService.StreamAsync(filter: null)`) | `AlarmFeedMessage` (`active_alarm` / `snapshot_complete` / `transition` / `provider_status` / `snapshot_status`) | Connected clients auto-join `__alarms__`; all clients receive every message. Publisher auto-reconnects every 5s on stream faults. The alarm value fields (`current_value` / `limit_value`) are stripped from a deep-cloned copy of the message when `Dashboard:ShowTagValues` is false (the default) — on both value-bearing payload arms, so neither a live transition nor a snapshot record leaks a process value; every other field still renders. The source message is never mutated: it fans out from the same feed to gRPC `StreamAlarms` subscribers, which this dashboard-display flag does not govern. Arms carrying no value are forwarded as-is, uncloned. |
| `EventsHub` | `/hubs/events` | `DashboardEventBroadcaster` invoked by each session's internal dashboard-mirror subscriber on its `SessionEventDistributor` (registered when the session becomes Ready) | `MxEvent` | Clients call `SubscribeSession(sessionId)` to join `session:{id}`, which also registers them in `EventsHubViewerRegistry` — the mirror is gated on that registry, which counts hub and in-process viewers alike (see "Mirror gating" below). The dashboard is a first-class distributor subscriber, so it receives the session's events whether or not a gRPC client is streaming. It sees RAW session events — not the per-gRPC-subscriber `AfterWorkerSequence` filtering that `EventStreamService` applies at its own boundary — because the dashboard is a separate LDAP-authenticated monitoring view meant to show the session's full event activity. Tag values are stripped from the mirrored `MxEvent` copy by `DashboardEventBroadcaster` when `Dashboard:ShowTagValues` is false (the default) — event metadata (tag reference, quality, status, timestamps) still renders, but the value fields are blanked, so no value leaks through this seam. `SubscribeSession` is gated by `IDashboardSessionAcl` (SEC-25 / TST-15): a denied caller gets a `HubException`, is not joined to the group, and is not registered as a viewer, so the mirror stays off for a session nobody is legitimately watching. The same ACL gates the in-process seam the session-details page uses, so neither path is the weaker one. Value redaction remains an independent layer — it bounds what a *permitted* subscriber sees. | | `EventsHub` | `/hubs/events` | `DashboardEventBroadcaster` invoked by each session's internal dashboard-mirror subscriber on its `SessionEventDistributor` (registered when the session becomes Ready) | `MxEvent` | Clients call `SubscribeSession(sessionId)` to join `session:{id}`, which also registers them in `EventsHubViewerRegistry` — the mirror is gated on that registry, which counts hub and in-process viewers alike (see "Mirror gating" below). The dashboard is a first-class distributor subscriber, so it receives the session's events whether or not a gRPC client is streaming. It sees RAW session events — not the per-gRPC-subscriber `AfterWorkerSequence` filtering that `EventStreamService` applies at its own boundary — because the dashboard is a separate LDAP-authenticated monitoring view meant to show the session's full event activity. Tag values are stripped from the mirrored `MxEvent` copy by `DashboardEventBroadcaster` when `Dashboard:ShowTagValues` is false (the default) — event metadata (tag reference, quality, status, timestamps) still renders, but the value fields are blanked, so no value leaks through this seam. `SubscribeSession` is gated by `IDashboardSessionAcl` (SEC-25 / TST-15): a denied caller gets a `HubException`, is not joined to the group, and is not registered as a viewer, so the mirror stays off for a session nobody is legitimately watching. The same ACL gates the in-process seam the session-details page uses, so neither path is the weaker one. Value redaction remains an independent layer — it bounds what a *permitted* subscriber sees. |
### Default cadences ### Default cadences
@@ -652,6 +652,11 @@ Show read-only effective configuration:
- auth mode, - auth mode,
- SQLite auth database path with sensitive parts redacted if needed, - SQLite auth database path with sensitive parts redacted if needed,
- dashboard enabled state, - dashboard enabled state,
- the LDAP group mappings that decide what a signed-in user may see —
`Dashboard:GroupToRole` (group → `Administrator` / `Viewer`) and
`Dashboard:GroupToTag` (group → the session tags it grants),
- `Dashboard:UntaggedSessionVisibility`, which decides who sees a session whose
owning API key carries no dashboard tags,
- protocol version. - protocol version.
Do not show API key secrets or pepper values. Do not show API key secrets or pepper values.