@kusinta/iot-schema 0.2.0-beta.6 → 0.2.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kusinta/iot-schema",
3
- "version": "0.2.0-beta.6",
3
+ "version": "0.2.0-beta.9",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "files": ["src"],
@@ -24,6 +24,7 @@
24
24
  "./space": "./src/kusinta/iot/space/v1/space_pb.js",
25
25
  "./access": "./src/kusinta/iot/access/v1/acl_pb.js",
26
26
  "./access/roles": "./src/kusinta/iot/access/v1/roles_pb.js",
27
+ "./link": "./src/kusinta/iot/link/v1/link_pb.js",
27
28
  "./connector": "./src/kusinta/iot/connector/v1/connector_pb.js",
28
29
  "./connector/service": "./src/kusinta/iot/connector/v1/connector_service_pb.js",
29
30
  "./webrtc": "./src/kusinta/iot/webrtc/v1/envelope_pb.js",
@@ -85,9 +85,11 @@ export declare type PairingWindow = Message<"kusinta.iot.common.v1.PairingWindow
85
85
  * rather than any person's. It does not suit a caller whose pairing mints personal
86
86
  * ownership.
87
87
  *
88
- * A hint and a batch cannot be combined, and that is a contradiction rather than a
89
- * limitation: device_hint names one device, so a window restricted to it can never produce
90
- * a second arrival to attribute.
88
+ * Ignored where device_hint is set, and narrowed to one rather than refused: a hint names
89
+ * one device, so a window restricted to it can never produce a second arrival to attribute.
90
+ * The combination is meaningless rather than dangerous, and there is no honest code in
91
+ * PairingError for "your request contradicted itself" — refusing it would mean answering a
92
+ * malformed request with an entitlement decision that was never made.
91
93
  *
92
94
  * @generated from field: optional uint32 max_devices = 3;
93
95
  */
@@ -7,6 +7,7 @@ import type { Message } from "@bufbuild/protobuf";
7
7
  import type { ConnectorId, DeviceId, GatewayId } from "../../identity/v1/identity_pb.js";
8
8
  import type { ConnectorTransport } from "../../common/v1/types_pb.js";
9
9
  import type { Device } from "../../device/v1/device_pb.js";
10
+ import type { DeviceLink, LinkFunction, LinkState } from "../../link/v1/link_pb.js";
10
11
  import type { Timestamp } from "@bufbuild/protobuf/wkt";
11
12
  import type { AttributeWriteRequest, CommandError, DeviceCommand } from "../../webrtc/v1/command_pb.js";
12
13
  import type { PairingErrorDetail, PairingWindow } from "../../common/v1/pairing_pb.js";
@@ -74,6 +75,22 @@ export declare type ConnectorHandshake = Message<"kusinta.iot.connector.v1.Conne
74
75
  * @generated from field: repeated kusinta.iot.device.v1.Device known_devices = 2;
75
76
  */
76
77
  knownDevices: Device[];
78
+
79
+ /**
80
+ * Every link the hub currently holds, reported the way known_devices is.
81
+ *
82
+ * Links are hub state, not gateway state: they outlive a connector restart and
83
+ * can be changed by anyone with access to the hub. The gateway's records are a
84
+ * statement of intent that can drift, so the handshake is the moment to
85
+ * reconcile them against what is really there. A link in the gateway's records
86
+ * and not here has gone; one here and not in the records was made elsewhere.
87
+ *
88
+ * Empty means "states nothing" — a connector that does not model linking is not
89
+ * asserting that no links exist.
90
+ *
91
+ * @generated from field: repeated kusinta.iot.link.v1.DeviceLink known_links = 3;
92
+ */
93
+ knownLinks: DeviceLink[];
77
94
  };
78
95
 
79
96
  /**
@@ -82,6 +99,163 @@ export declare type ConnectorHandshake = Message<"kusinta.iot.connector.v1.Conne
82
99
  */
83
100
  export declare const ConnectorHandshakeSchema: GenMessage<ConnectorHandshake>;
84
101
 
102
+ /**
103
+ * Asks the connector to make a link, gateway to connector.
104
+ *
105
+ * Names two devices and a function; resolving that into whatever set of
106
+ * underlying connections the hub needs is the connector's work. It is expected to
107
+ * build the set atomically and roll back a partial one, because a half-built set
108
+ * is a link that lists as healthy and carries nothing.
109
+ *
110
+ * The connector is also expected to repair whatever the operation disturbs. On at
111
+ * least one vendor, both making and removing a link leaves the receiving device
112
+ * in a state it was not in before, with settings that must be captured
113
+ * beforehand and put back after.
114
+ *
115
+ * @generated from message kusinta.iot.connector.v1.CreateLink
116
+ */
117
+ export declare type CreateLink = Message<"kusinta.iot.connector.v1.CreateLink"> & {
118
+ /**
119
+ * assigned by the gateway, echoed in the result
120
+ *
121
+ * @generated from field: string link_id = 1;
122
+ */
123
+ linkId: string;
124
+
125
+ /**
126
+ * @generated from field: kusinta.iot.identity.v1.DeviceId sender = 2;
127
+ */
128
+ sender?: DeviceId | undefined;
129
+
130
+ /**
131
+ * @generated from field: kusinta.iot.identity.v1.DeviceId receiver = 3;
132
+ */
133
+ receiver?: DeviceId | undefined;
134
+
135
+ /**
136
+ * @generated from field: kusinta.iot.link.v1.LinkFunction function = 4;
137
+ */
138
+ function: LinkFunction;
139
+ };
140
+
141
+ /**
142
+ * Describes the message kusinta.iot.connector.v1.CreateLink.
143
+ * Use `create(CreateLinkSchema)` to create a new message.
144
+ */
145
+ export declare const CreateLinkSchema: GenMessage<CreateLink>;
146
+
147
+ /**
148
+ * Asks the connector to remove a link it previously made.
149
+ *
150
+ * @generated from message kusinta.iot.connector.v1.RemoveLink
151
+ */
152
+ export declare type RemoveLink = Message<"kusinta.iot.connector.v1.RemoveLink"> & {
153
+ /**
154
+ * @generated from field: string link_id = 1;
155
+ */
156
+ linkId: string;
157
+
158
+ /**
159
+ * @generated from field: kusinta.iot.identity.v1.DeviceId sender = 2;
160
+ */
161
+ sender?: DeviceId | undefined;
162
+
163
+ /**
164
+ * @generated from field: kusinta.iot.identity.v1.DeviceId receiver = 3;
165
+ */
166
+ receiver?: DeviceId | undefined;
167
+
168
+ /**
169
+ * @generated from field: kusinta.iot.link.v1.LinkFunction function = 4;
170
+ */
171
+ function: LinkFunction;
172
+ };
173
+
174
+ /**
175
+ * Describes the message kusinta.iot.connector.v1.RemoveLink.
176
+ * Use `create(RemoveLinkSchema)` to create a new message.
177
+ */
178
+ export declare const RemoveLinkSchema: GenMessage<RemoveLink>;
179
+
180
+ /**
181
+ * Asks the connector what links the hub holds, for reconciliation outside a
182
+ * handshake.
183
+ *
184
+ * @generated from message kusinta.iot.connector.v1.ListLinks
185
+ */
186
+ export declare type ListLinks = Message<"kusinta.iot.connector.v1.ListLinks"> & {
187
+ /**
188
+ * Unset asks for every link the hub holds.
189
+ *
190
+ * @generated from field: kusinta.iot.identity.v1.DeviceId device_id = 1;
191
+ */
192
+ deviceId?: DeviceId | undefined;
193
+ };
194
+
195
+ /**
196
+ * Describes the message kusinta.iot.connector.v1.ListLinks.
197
+ * Use `create(ListLinksSchema)` to create a new message.
198
+ */
199
+ export declare const ListLinksSchema: GenMessage<ListLinks>;
200
+
201
+ /**
202
+ * What became of a CreateLink or RemoveLink, connector to gateway.
203
+ *
204
+ * Reports the link's observed state rather than merely whether the call was
205
+ * accepted. A hub will report a link as present and healthy while the devices
206
+ * ignore it, so "the request did not fail" is not the same claim as "the link is
207
+ * carrying" and must not be encoded as though it were.
208
+ *
209
+ * @generated from message kusinta.iot.connector.v1.LinkResult
210
+ */
211
+ export declare type LinkResult = Message<"kusinta.iot.connector.v1.LinkResult"> & {
212
+ /**
213
+ * @generated from field: string link_id = 1;
214
+ */
215
+ linkId: string;
216
+
217
+ /**
218
+ * @generated from field: bool success = 2;
219
+ */
220
+ success: boolean;
221
+
222
+ /**
223
+ * @generated from field: kusinta.iot.link.v1.LinkState state = 3;
224
+ */
225
+ state: LinkState;
226
+
227
+ /**
228
+ * Why not, when success is false. For a person; never parsed.
229
+ *
230
+ * @generated from field: string detail = 4;
231
+ */
232
+ detail: string;
233
+ };
234
+
235
+ /**
236
+ * Describes the message kusinta.iot.connector.v1.LinkResult.
237
+ * Use `create(LinkResultSchema)` to create a new message.
238
+ */
239
+ export declare const LinkResultSchema: GenMessage<LinkResult>;
240
+
241
+ /**
242
+ * Every link the hub holds, connector to gateway, in reply to ListLinks.
243
+ *
244
+ * @generated from message kusinta.iot.connector.v1.LinksReported
245
+ */
246
+ export declare type LinksReported = Message<"kusinta.iot.connector.v1.LinksReported"> & {
247
+ /**
248
+ * @generated from field: repeated kusinta.iot.link.v1.DeviceLink links = 1;
249
+ */
250
+ links: DeviceLink[];
251
+ };
252
+
253
+ /**
254
+ * Describes the message kusinta.iot.connector.v1.LinksReported.
255
+ * Use `create(LinksReportedSchema)` to create a new message.
256
+ */
257
+ export declare const LinksReportedSchema: GenMessage<LinksReported>;
258
+
85
259
  /**
86
260
  * @generated from message kusinta.iot.connector.v1.HandshakeAck
87
261
  */
@@ -521,6 +695,18 @@ export declare type SessionRequest = Message<"kusinta.iot.connector.v1.SessionRe
521
695
  */
522
696
  value: PairingModeEnded;
523
697
  case: "pairingModeEnded";
698
+ } | {
699
+ /**
700
+ * @generated from field: kusinta.iot.connector.v1.LinkResult link_result = 12;
701
+ */
702
+ value: LinkResult;
703
+ case: "linkResult";
704
+ } | {
705
+ /**
706
+ * @generated from field: kusinta.iot.connector.v1.LinksReported links_reported = 13;
707
+ */
708
+ value: LinksReported;
709
+ case: "linksReported";
524
710
  } | { case: undefined; value?: undefined };
525
711
  };
526
712
 
@@ -594,6 +780,28 @@ export declare type SessionResponse = Message<"kusinta.iot.connector.v1.SessionR
594
780
  */
595
781
  value: EnterPairingMode;
596
782
  case: "enterPairingMode";
783
+ } | {
784
+ /**
785
+ * The link operations. Separate cases rather than one with a verb, so a
786
+ * connector that models none of them fails to match rather than having to
787
+ * decode a request it cannot serve.
788
+ *
789
+ * @generated from field: kusinta.iot.connector.v1.CreateLink create_link = 11;
790
+ */
791
+ value: CreateLink;
792
+ case: "createLink";
793
+ } | {
794
+ /**
795
+ * @generated from field: kusinta.iot.connector.v1.RemoveLink remove_link = 12;
796
+ */
797
+ value: RemoveLink;
798
+ case: "removeLink";
799
+ } | {
800
+ /**
801
+ * @generated from field: kusinta.iot.connector.v1.ListLinks list_links = 13;
802
+ */
803
+ value: ListLinks;
804
+ case: "listLinks";
597
805
  } | { case: undefined; value?: undefined };
598
806
  };
599
807
 
@@ -10,13 +10,14 @@ import { file_kusinta_iot_device_v1_device } from "../../device/v1/device_pb.js"
10
10
  import { file_kusinta_iot_device_v1_device_event } from "../../device/v1/device_event_pb.js";
11
11
  import { file_kusinta_iot_device_v1_property_update } from "../../device/v1/property_update_pb.js";
12
12
  import { file_kusinta_iot_identity_v1_identity } from "../../identity/v1/identity_pb.js";
13
+ import { file_kusinta_iot_link_v1_link } from "../../link/v1/link_pb.js";
13
14
  import { file_kusinta_iot_webrtc_v1_command } from "../../webrtc/v1/command_pb.js";
14
15
 
15
16
  /**
16
17
  * Describes the file kusinta/iot/connector/v1/connector.proto.
17
18
  */
18
19
  export const file_kusinta_iot_connector_v1_connector = /*@__PURE__*/
19
- fileDesc("CihrdXNpbnRhL2lvdC9jb25uZWN0b3IvdjEvY29ubmVjdG9yLnByb3RvEhhrdXNpbnRhLmlvdC5jb25uZWN0b3IudjEi5QEKDUNvbm5lY3RvckluZm8SOgoMY29ubmVjdG9yX2lkGAEgASgLMiQua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuQ29ubmVjdG9ySWQSFAoMZGlzcGxheV9uYW1lGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSPAoJdHJhbnNwb3J0GAQgASgOMikua3VzaW50YS5pb3QuY29tbW9uLnYxLkNvbm5lY3RvclRyYW5zcG9ydBIQCghlbmRwb2ludBgFIAEoCRIhChlzdXBwb3J0ZWRfZGV2aWNlX3R5cGVfaWRzGAYgAygNIoEBChJDb25uZWN0b3JIYW5kc2hha2USNQoEaW5mbxgBIAEoCzInLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5Db25uZWN0b3JJbmZvEjQKDWtub3duX2RldmljZXMYAiADKAsyHS5rdXNpbnRhLmlvdC5kZXZpY2UudjEuRGV2aWNlImgKDEhhbmRzaGFrZUFjaxIQCghhY2NlcHRlZBgBIAEoCBIOCgZyZWFzb24YAiABKAkSNgoKZ2F0ZXdheV9pZBgDIAEoCzIiLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkdhdGV3YXlJZCJxChJEZXZpY2VBbm5vdW5jZW1lbnQSLQoGZGV2aWNlGAIgASgLMh0ua3VzaW50YS5pb3QuZGV2aWNlLnYxLkRldmljZRIaChJwYWlyaW5nX3JlcXVlc3RfaWQYAyABKAlKBAgBEAJSCmRlc2NyaXB0b3IiVQoNRGV2aWNlUmVtb3ZhbBI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIOCgZyZWFzb24YAiABKAkiCwoJSGVhcnRCZWF0IkcKD1N1YnNjcmliZURldmljZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJJChFVbnN1YnNjcmliZURldmljZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJBCgxHYXRld2F5RXJyb3ISDAoEY29kZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJEhIKCnJlcXVlc3RfaWQYAyABKAki7QEKFkNvbm5lY3RvckNvbW1hbmRSZXN1bHQSEgoKcmVxdWVzdF9pZBgBIAEoCRIPCgdzdWNjZXNzGAIgASgIEjAKDGNvbXBsZXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASMgoFZXJyb3IYBSABKAsyIy5rdXNpbnRhLmlvdC53ZWJydGMudjEuQ29tbWFuZEVycm9yEjMKCnNldHRsZXNfYnkYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSACIAQFCDQoLX3NldHRsZXNfYnlKBAgDEAQiXAoQRW50ZXJQYWlyaW5nTW9kZRISCgpyZXF1ZXN0X2lkGAEgASgJEjQKBndpbmRvdxgCIAEoCzIkLmt1c2ludGEuaW90LmNvbW1vbi52MS5QYWlyaW5nV2luZG93IqMBChFQYWlyaW5nTW9kZVJlc3VsdBISCgpyZXF1ZXN0X2lkGAEgASgJEhAKCGFjY2VwdGVkGAIgASgIEjgKBWVycm9yGAMgASgLMikua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdFcnJvckRldGFpbBIuCgpleHBpcmVzX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJ8ChBQYWlyaW5nTW9kZUVuZGVkEhIKCnJlcXVlc3RfaWQYASABKAkSGgoSZGV2aWNlc19hdHRyaWJ1dGVkGAIgASgNEjgKBWVycm9yGAMgASgLMikua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdFcnJvckRldGFpbCLRBQoOU2Vzc2lvblJlcXVlc3QSEgoKbWVzc2FnZV9pZBgBIAEoCRIrCgdzZW50X2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBJBCgloYW5kc2hha2UYAyABKAsyLC5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuQ29ubmVjdG9ySGFuZHNoYWtlSAASRQoPcHJvcGVydHlfdXBkYXRlGAQgASgLMioua3VzaW50YS5pb3QuZGV2aWNlLnYxLlByb3BlcnR5VXBkYXRlQmF0Y2hIABJIChBkZXZpY2VfYW5ub3VuY2VkGAUgASgLMiwua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkRldmljZUFubm91bmNlbWVudEgAEkEKDmRldmljZV9yZW1vdmVkGAYgASgLMicua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkRldmljZVJlbW92YWxIABJKCg5jb21tYW5kX3Jlc3VsdBgHIAEoCzIwLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5Db25uZWN0b3JDb21tYW5kUmVzdWx0SAASOAoJaGVhcnRiZWF0GAggASgLMiMua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkhlYXJ0QmVhdEgAEkAKDWRldmljZV9ldmVudHMYCSABKAsyJy5rdXNpbnRhLmlvdC5kZXZpY2UudjEuRGV2aWNlRXZlbnRCYXRjaEgAEkoKE3BhaXJpbmdfbW9kZV9yZXN1bHQYCiABKAsyKy5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuUGFpcmluZ01vZGVSZXN1bHRIABJIChJwYWlyaW5nX21vZGVfZW5kZWQYCyABKAsyKi5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuUGFpcmluZ01vZGVFbmRlZEgAQgkKB3BheWxvYWQivQQKD1Nlc3Npb25SZXNwb25zZRISCgptZXNzYWdlX2lkGAEgASgJEisKB3NlbnRfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEj8KDWhhbmRzaGFrZV9hY2sYAyABKAsyJi5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuSGFuZHNoYWtlQWNrSAASPgoJc3Vic2NyaWJlGAUgASgLMikua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLlN1YnNjcmliZURldmljZUgAEkIKC3Vuc3Vic2NyaWJlGAYgASgLMisua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLlVuc3Vic2NyaWJlRGV2aWNlSAASNwoFZXJyb3IYByABKAsyJi5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuR2F0ZXdheUVycm9ySAASPwoPZXhlY3V0ZV9jb21tYW5kGAggASgLMiQua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZUNvbW1hbmRIABJPChdleGVjdXRlX2F0dHJpYnV0ZV93cml0ZRgJIAEoCzIsLmt1c2ludGEuaW90LndlYnJ0Yy52MS5BdHRyaWJ1dGVXcml0ZVJlcXVlc3RIABJIChJlbnRlcl9wYWlyaW5nX21vZGUYCiABKAsyKi5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuRW50ZXJQYWlyaW5nTW9kZUgAQgkKB3BheWxvYWRKBAgEEAVCAkgBYgZwcm90bzM", [file_google_protobuf_timestamp, file_kusinta_iot_common_v1_pairing, file_kusinta_iot_common_v1_types, file_kusinta_iot_device_v1_device, file_kusinta_iot_device_v1_device_event, file_kusinta_iot_device_v1_property_update, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_webrtc_v1_command]);
20
+ fileDesc("CihrdXNpbnRhL2lvdC9jb25uZWN0b3IvdjEvY29ubmVjdG9yLnByb3RvEhhrdXNpbnRhLmlvdC5jb25uZWN0b3IudjEi5QEKDUNvbm5lY3RvckluZm8SOgoMY29ubmVjdG9yX2lkGAEgASgLMiQua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuQ29ubmVjdG9ySWQSFAoMZGlzcGxheV9uYW1lGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSPAoJdHJhbnNwb3J0GAQgASgOMikua3VzaW50YS5pb3QuY29tbW9uLnYxLkNvbm5lY3RvclRyYW5zcG9ydBIQCghlbmRwb2ludBgFIAEoCRIhChlzdXBwb3J0ZWRfZGV2aWNlX3R5cGVfaWRzGAYgAygNIrcBChJDb25uZWN0b3JIYW5kc2hha2USNQoEaW5mbxgBIAEoCzInLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5Db25uZWN0b3JJbmZvEjQKDWtub3duX2RldmljZXMYAiADKAsyHS5rdXNpbnRhLmlvdC5kZXZpY2UudjEuRGV2aWNlEjQKC2tub3duX2xpbmtzGAMgAygLMh8ua3VzaW50YS5pb3QubGluay52MS5EZXZpY2VMaW5rIroBCgpDcmVhdGVMaW5rEg8KB2xpbmtfaWQYASABKAkSMQoGc2VuZGVyGAIgASgLMiEua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuRGV2aWNlSWQSMwoIcmVjZWl2ZXIYAyABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIzCghmdW5jdGlvbhgEIAEoDjIhLmt1c2ludGEuaW90LmxpbmsudjEuTGlua0Z1bmN0aW9uIroBCgpSZW1vdmVMaW5rEg8KB2xpbmtfaWQYASABKAkSMQoGc2VuZGVyGAIgASgLMiEua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuRGV2aWNlSWQSMwoIcmVjZWl2ZXIYAyABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIzCghmdW5jdGlvbhgEIAEoDjIhLmt1c2ludGEuaW90LmxpbmsudjEuTGlua0Z1bmN0aW9uIkEKCUxpc3RMaW5rcxI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJtCgpMaW5rUmVzdWx0Eg8KB2xpbmtfaWQYASABKAkSDwoHc3VjY2VzcxgCIAEoCBItCgVzdGF0ZRgDIAEoDjIeLmt1c2ludGEuaW90LmxpbmsudjEuTGlua1N0YXRlEg4KBmRldGFpbBgEIAEoCSI/Cg1MaW5rc1JlcG9ydGVkEi4KBWxpbmtzGAEgAygLMh8ua3VzaW50YS5pb3QubGluay52MS5EZXZpY2VMaW5rImgKDEhhbmRzaGFrZUFjaxIQCghhY2NlcHRlZBgBIAEoCBIOCgZyZWFzb24YAiABKAkSNgoKZ2F0ZXdheV9pZBgDIAEoCzIiLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkdhdGV3YXlJZCJxChJEZXZpY2VBbm5vdW5jZW1lbnQSLQoGZGV2aWNlGAIgASgLMh0ua3VzaW50YS5pb3QuZGV2aWNlLnYxLkRldmljZRIaChJwYWlyaW5nX3JlcXVlc3RfaWQYAyABKAlKBAgBEAJSCmRlc2NyaXB0b3IiVQoNRGV2aWNlUmVtb3ZhbBI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIOCgZyZWFzb24YAiABKAkiCwoJSGVhcnRCZWF0IkcKD1N1YnNjcmliZURldmljZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJJChFVbnN1YnNjcmliZURldmljZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJBCgxHYXRld2F5RXJyb3ISDAoEY29kZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJEhIKCnJlcXVlc3RfaWQYAyABKAki7QEKFkNvbm5lY3RvckNvbW1hbmRSZXN1bHQSEgoKcmVxdWVzdF9pZBgBIAEoCRIPCgdzdWNjZXNzGAIgASgIEjAKDGNvbXBsZXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASMgoFZXJyb3IYBSABKAsyIy5rdXNpbnRhLmlvdC53ZWJydGMudjEuQ29tbWFuZEVycm9yEjMKCnNldHRsZXNfYnkYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSACIAQFCDQoLX3NldHRsZXNfYnlKBAgDEAQiXAoQRW50ZXJQYWlyaW5nTW9kZRISCgpyZXF1ZXN0X2lkGAEgASgJEjQKBndpbmRvdxgCIAEoCzIkLmt1c2ludGEuaW90LmNvbW1vbi52MS5QYWlyaW5nV2luZG93IqMBChFQYWlyaW5nTW9kZVJlc3VsdBISCgpyZXF1ZXN0X2lkGAEgASgJEhAKCGFjY2VwdGVkGAIgASgIEjgKBWVycm9yGAMgASgLMikua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdFcnJvckRldGFpbBIuCgpleHBpcmVzX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJ8ChBQYWlyaW5nTW9kZUVuZGVkEhIKCnJlcXVlc3RfaWQYASABKAkSGgoSZGV2aWNlc19hdHRyaWJ1dGVkGAIgASgNEjgKBWVycm9yGAMgASgLMikua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdFcnJvckRldGFpbCLRBgoOU2Vzc2lvblJlcXVlc3QSEgoKbWVzc2FnZV9pZBgBIAEoCRIrCgdzZW50X2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBJBCgloYW5kc2hha2UYAyABKAsyLC5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuQ29ubmVjdG9ySGFuZHNoYWtlSAASRQoPcHJvcGVydHlfdXBkYXRlGAQgASgLMioua3VzaW50YS5pb3QuZGV2aWNlLnYxLlByb3BlcnR5VXBkYXRlQmF0Y2hIABJIChBkZXZpY2VfYW5ub3VuY2VkGAUgASgLMiwua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkRldmljZUFubm91bmNlbWVudEgAEkEKDmRldmljZV9yZW1vdmVkGAYgASgLMicua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkRldmljZVJlbW92YWxIABJKCg5jb21tYW5kX3Jlc3VsdBgHIAEoCzIwLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5Db25uZWN0b3JDb21tYW5kUmVzdWx0SAASOAoJaGVhcnRiZWF0GAggASgLMiMua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkhlYXJ0QmVhdEgAEkAKDWRldmljZV9ldmVudHMYCSABKAsyJy5rdXNpbnRhLmlvdC5kZXZpY2UudjEuRGV2aWNlRXZlbnRCYXRjaEgAEkoKE3BhaXJpbmdfbW9kZV9yZXN1bHQYCiABKAsyKy5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuUGFpcmluZ01vZGVSZXN1bHRIABJIChJwYWlyaW5nX21vZGVfZW5kZWQYCyABKAsyKi5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuUGFpcmluZ01vZGVFbmRlZEgAEjsKC2xpbmtfcmVzdWx0GAwgASgLMiQua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkxpbmtSZXN1bHRIABJBCg5saW5rc19yZXBvcnRlZBgNIAEoCzInLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5MaW5rc1JlcG9ydGVkSABCCQoHcGF5bG9hZCLyBQoPU2Vzc2lvblJlc3BvbnNlEhIKCm1lc3NhZ2VfaWQYASABKAkSKwoHc2VudF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASPwoNaGFuZHNoYWtlX2FjaxgDIAEoCzImLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5IYW5kc2hha2VBY2tIABI+CglzdWJzY3JpYmUYBSABKAsyKS5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuU3Vic2NyaWJlRGV2aWNlSAASQgoLdW5zdWJzY3JpYmUYBiABKAsyKy5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuVW5zdWJzY3JpYmVEZXZpY2VIABI3CgVlcnJvchgHIAEoCzImLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5HYXRld2F5RXJyb3JIABI/Cg9leGVjdXRlX2NvbW1hbmQYCCABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGV2aWNlQ29tbWFuZEgAEk8KF2V4ZWN1dGVfYXR0cmlidXRlX3dyaXRlGAkgASgLMiwua3VzaW50YS5pb3Qud2VicnRjLnYxLkF0dHJpYnV0ZVdyaXRlUmVxdWVzdEgAEkgKEmVudGVyX3BhaXJpbmdfbW9kZRgKIAEoCzIqLmt1c2ludGEuaW90LmNvbm5lY3Rvci52MS5FbnRlclBhaXJpbmdNb2RlSAASOwoLY3JlYXRlX2xpbmsYCyABKAsyJC5rdXNpbnRhLmlvdC5jb25uZWN0b3IudjEuQ3JlYXRlTGlua0gAEjsKC3JlbW92ZV9saW5rGAwgASgLMiQua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLlJlbW92ZUxpbmtIABI5CgpsaXN0X2xpbmtzGA0gASgLMiMua3VzaW50YS5pb3QuY29ubmVjdG9yLnYxLkxpc3RMaW5rc0gAQgkKB3BheWxvYWRKBAgEEAVCAkgBYgZwcm90bzM", [file_google_protobuf_timestamp, file_kusinta_iot_common_v1_pairing, file_kusinta_iot_common_v1_types, file_kusinta_iot_device_v1_device, file_kusinta_iot_device_v1_device_event, file_kusinta_iot_device_v1_property_update, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_link_v1_link, file_kusinta_iot_webrtc_v1_command]);
20
21
 
21
22
  /**
22
23
  * Describes the message kusinta.iot.connector.v1.ConnectorInfo.
@@ -32,94 +33,129 @@ export const ConnectorInfoSchema = /*@__PURE__*/
32
33
  export const ConnectorHandshakeSchema = /*@__PURE__*/
33
34
  messageDesc(file_kusinta_iot_connector_v1_connector, 1);
34
35
 
36
+ /**
37
+ * Describes the message kusinta.iot.connector.v1.CreateLink.
38
+ * Use `create(CreateLinkSchema)` to create a new message.
39
+ */
40
+ export const CreateLinkSchema = /*@__PURE__*/
41
+ messageDesc(file_kusinta_iot_connector_v1_connector, 2);
42
+
43
+ /**
44
+ * Describes the message kusinta.iot.connector.v1.RemoveLink.
45
+ * Use `create(RemoveLinkSchema)` to create a new message.
46
+ */
47
+ export const RemoveLinkSchema = /*@__PURE__*/
48
+ messageDesc(file_kusinta_iot_connector_v1_connector, 3);
49
+
50
+ /**
51
+ * Describes the message kusinta.iot.connector.v1.ListLinks.
52
+ * Use `create(ListLinksSchema)` to create a new message.
53
+ */
54
+ export const ListLinksSchema = /*@__PURE__*/
55
+ messageDesc(file_kusinta_iot_connector_v1_connector, 4);
56
+
57
+ /**
58
+ * Describes the message kusinta.iot.connector.v1.LinkResult.
59
+ * Use `create(LinkResultSchema)` to create a new message.
60
+ */
61
+ export const LinkResultSchema = /*@__PURE__*/
62
+ messageDesc(file_kusinta_iot_connector_v1_connector, 5);
63
+
64
+ /**
65
+ * Describes the message kusinta.iot.connector.v1.LinksReported.
66
+ * Use `create(LinksReportedSchema)` to create a new message.
67
+ */
68
+ export const LinksReportedSchema = /*@__PURE__*/
69
+ messageDesc(file_kusinta_iot_connector_v1_connector, 6);
70
+
35
71
  /**
36
72
  * Describes the message kusinta.iot.connector.v1.HandshakeAck.
37
73
  * Use `create(HandshakeAckSchema)` to create a new message.
38
74
  */
39
75
  export const HandshakeAckSchema = /*@__PURE__*/
40
- messageDesc(file_kusinta_iot_connector_v1_connector, 2);
76
+ messageDesc(file_kusinta_iot_connector_v1_connector, 7);
41
77
 
42
78
  /**
43
79
  * Describes the message kusinta.iot.connector.v1.DeviceAnnouncement.
44
80
  * Use `create(DeviceAnnouncementSchema)` to create a new message.
45
81
  */
46
82
  export const DeviceAnnouncementSchema = /*@__PURE__*/
47
- messageDesc(file_kusinta_iot_connector_v1_connector, 3);
83
+ messageDesc(file_kusinta_iot_connector_v1_connector, 8);
48
84
 
49
85
  /**
50
86
  * Describes the message kusinta.iot.connector.v1.DeviceRemoval.
51
87
  * Use `create(DeviceRemovalSchema)` to create a new message.
52
88
  */
53
89
  export const DeviceRemovalSchema = /*@__PURE__*/
54
- messageDesc(file_kusinta_iot_connector_v1_connector, 4);
90
+ messageDesc(file_kusinta_iot_connector_v1_connector, 9);
55
91
 
56
92
  /**
57
93
  * Describes the message kusinta.iot.connector.v1.HeartBeat.
58
94
  * Use `create(HeartBeatSchema)` to create a new message.
59
95
  */
60
96
  export const HeartBeatSchema = /*@__PURE__*/
61
- messageDesc(file_kusinta_iot_connector_v1_connector, 5);
97
+ messageDesc(file_kusinta_iot_connector_v1_connector, 10);
62
98
 
63
99
  /**
64
100
  * Describes the message kusinta.iot.connector.v1.SubscribeDevice.
65
101
  * Use `create(SubscribeDeviceSchema)` to create a new message.
66
102
  */
67
103
  export const SubscribeDeviceSchema = /*@__PURE__*/
68
- messageDesc(file_kusinta_iot_connector_v1_connector, 6);
104
+ messageDesc(file_kusinta_iot_connector_v1_connector, 11);
69
105
 
70
106
  /**
71
107
  * Describes the message kusinta.iot.connector.v1.UnsubscribeDevice.
72
108
  * Use `create(UnsubscribeDeviceSchema)` to create a new message.
73
109
  */
74
110
  export const UnsubscribeDeviceSchema = /*@__PURE__*/
75
- messageDesc(file_kusinta_iot_connector_v1_connector, 7);
111
+ messageDesc(file_kusinta_iot_connector_v1_connector, 12);
76
112
 
77
113
  /**
78
114
  * Describes the message kusinta.iot.connector.v1.GatewayError.
79
115
  * Use `create(GatewayErrorSchema)` to create a new message.
80
116
  */
81
117
  export const GatewayErrorSchema = /*@__PURE__*/
82
- messageDesc(file_kusinta_iot_connector_v1_connector, 8);
118
+ messageDesc(file_kusinta_iot_connector_v1_connector, 13);
83
119
 
84
120
  /**
85
121
  * Describes the message kusinta.iot.connector.v1.ConnectorCommandResult.
86
122
  * Use `create(ConnectorCommandResultSchema)` to create a new message.
87
123
  */
88
124
  export const ConnectorCommandResultSchema = /*@__PURE__*/
89
- messageDesc(file_kusinta_iot_connector_v1_connector, 9);
125
+ messageDesc(file_kusinta_iot_connector_v1_connector, 14);
90
126
 
91
127
  /**
92
128
  * Describes the message kusinta.iot.connector.v1.EnterPairingMode.
93
129
  * Use `create(EnterPairingModeSchema)` to create a new message.
94
130
  */
95
131
  export const EnterPairingModeSchema = /*@__PURE__*/
96
- messageDesc(file_kusinta_iot_connector_v1_connector, 10);
132
+ messageDesc(file_kusinta_iot_connector_v1_connector, 15);
97
133
 
98
134
  /**
99
135
  * Describes the message kusinta.iot.connector.v1.PairingModeResult.
100
136
  * Use `create(PairingModeResultSchema)` to create a new message.
101
137
  */
102
138
  export const PairingModeResultSchema = /*@__PURE__*/
103
- messageDesc(file_kusinta_iot_connector_v1_connector, 11);
139
+ messageDesc(file_kusinta_iot_connector_v1_connector, 16);
104
140
 
105
141
  /**
106
142
  * Describes the message kusinta.iot.connector.v1.PairingModeEnded.
107
143
  * Use `create(PairingModeEndedSchema)` to create a new message.
108
144
  */
109
145
  export const PairingModeEndedSchema = /*@__PURE__*/
110
- messageDesc(file_kusinta_iot_connector_v1_connector, 12);
146
+ messageDesc(file_kusinta_iot_connector_v1_connector, 17);
111
147
 
112
148
  /**
113
149
  * Describes the message kusinta.iot.connector.v1.SessionRequest.
114
150
  * Use `create(SessionRequestSchema)` to create a new message.
115
151
  */
116
152
  export const SessionRequestSchema = /*@__PURE__*/
117
- messageDesc(file_kusinta_iot_connector_v1_connector, 13);
153
+ messageDesc(file_kusinta_iot_connector_v1_connector, 18);
118
154
 
119
155
  /**
120
156
  * Describes the message kusinta.iot.connector.v1.SessionResponse.
121
157
  * Use `create(SessionResponseSchema)` to create a new message.
122
158
  */
123
159
  export const SessionResponseSchema = /*@__PURE__*/
124
- messageDesc(file_kusinta_iot_connector_v1_connector, 14);
160
+ messageDesc(file_kusinta_iot_connector_v1_connector, 19);
125
161
 
@@ -7,6 +7,7 @@ import type { Message } from "@bufbuild/protobuf";
7
7
  import type { ConnectorId, DeviceId, SpaceId, UserId } from "../../identity/v1/identity_pb.js";
8
8
  import type { DeviceLifecycleState, DeviceOwnershipType } from "../../common/v1/types_pb.js";
9
9
  import type { Timestamp } from "@bufbuild/protobuf/wkt";
10
+ import type { LinkCapability } from "../../link/v1/link_pb.js";
10
11
  import type { HomematicDeviceIdentity } from "../../vendor/homematic/v1/homematic_pb.js";
11
12
 
12
13
  /**
@@ -126,6 +127,18 @@ export declare type DeviceDescriptor = Message<"kusinta.iot.device.v1.DeviceDesc
126
127
  */
127
128
  bridgedBy?: DeviceId | undefined;
128
129
 
130
+ /**
131
+ * What this device can be linked as, if anything — see link.v1.LinkCapability.
132
+ *
133
+ * Declared by the connector that models the device, because only it knows
134
+ * which of a device's connections can lead, which can follow, and what a hub
135
+ * will actually broker. Empty means "states nothing", never "cannot be
136
+ * linked": a connector that does not model linking says nothing here.
137
+ *
138
+ * @generated from field: repeated kusinta.iot.link.v1.LinkCapability link_capabilities = 20;
139
+ */
140
+ linkCapabilities: LinkCapability[];
141
+
129
142
  /**
130
143
  * @generated from oneof kusinta.iot.device.v1.DeviceDescriptor.vendor_identity
131
144
  */
@@ -6,13 +6,14 @@ import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
6
6
  import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
7
7
  import { file_kusinta_iot_common_v1_types } from "../../common/v1/types_pb.js";
8
8
  import { file_kusinta_iot_identity_v1_identity } from "../../identity/v1/identity_pb.js";
9
+ import { file_kusinta_iot_link_v1_link } from "../../link/v1/link_pb.js";
9
10
  import { file_kusinta_iot_vendor_homematic_v1_homematic } from "../../vendor/homematic/v1/homematic_pb.js";
10
11
 
11
12
  /**
12
13
  * Describes the file kusinta/iot/device/v1/descriptor.proto.
13
14
  */
14
15
  export const file_kusinta_iot_device_v1_descriptor = /*@__PURE__*/
15
- fileDesc("CiZrdXNpbnRhL2lvdC9kZXZpY2UvdjEvZGVzY3JpcHRvci5wcm90bxIVa3VzaW50YS5pb3QuZGV2aWNlLnYxIrkGChBEZXZpY2VEZXNjcmlwdG9yEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEhMKC3ZlbmRvcl9uYW1lGAMgASgJEhQKDHByb2R1Y3RfbmFtZRgEIAEoCRIVCg1zZXJpYWxfbnVtYmVyGAUgASgJEhIKCm5vZGVfbGFiZWwYBiABKAkSEQoJdmVuZG9yX2lkGAcgASgNEhIKCnByb2R1Y3RfaWQYCCABKA0SHwoXaGFyZHdhcmVfdmVyc2lvbl9zdHJpbmcYCSABKAkSHwoXc29mdHdhcmVfdmVyc2lvbl9zdHJpbmcYCiABKAkSOgoMY29ubmVjdG9yX2lkGAsgASgLMiQua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuQ29ubmVjdG9ySWQSMgoIc3BhY2VfaWQYDCABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEj0KCW93bmVyc2hpcBgNIAEoDjIqLmt1c2ludGEuaW90LmNvbW1vbi52MS5EZXZpY2VPd25lcnNoaXBUeXBlEj4KCWxpZmVjeWNsZRgOIAEoDjIrLmt1c2ludGEuaW90LmNvbW1vbi52MS5EZXZpY2VMaWZlY3ljbGVTdGF0ZRI2Cg1vd25lcl91c2VyX2lkGA8gASgLMh8ua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuVXNlcklkEi4KCmNsYWltZWRfYXQYECABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjoKCmJyaWRnZWRfYnkYEyABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZEgBiAEBEk0KCWhvbWVtYXRpYxgSIAEoCzI4Lmt1c2ludGEuaW90LnZlbmRvci5ob21lbWF0aWMudjEuSG9tZW1hdGljRGV2aWNlSWRlbnRpdHlIAEIRCg92ZW5kb3JfaWRlbnRpdHlCDQoLX2JyaWRnZWRfYnlKBAgCEANKBAgREBJSFW1hdHRlcl9kZXZpY2VfdHlwZV9pZFIJZW5kcG9pbnRzQgJIAWIGcHJvdG8z", [file_google_protobuf_timestamp, file_kusinta_iot_common_v1_types, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_vendor_homematic_v1_homematic]);
16
+ fileDesc("CiZrdXNpbnRhL2lvdC9kZXZpY2UvdjEvZGVzY3JpcHRvci5wcm90bxIVa3VzaW50YS5pb3QuZGV2aWNlLnYxIvkGChBEZXZpY2VEZXNjcmlwdG9yEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEhMKC3ZlbmRvcl9uYW1lGAMgASgJEhQKDHByb2R1Y3RfbmFtZRgEIAEoCRIVCg1zZXJpYWxfbnVtYmVyGAUgASgJEhIKCm5vZGVfbGFiZWwYBiABKAkSEQoJdmVuZG9yX2lkGAcgASgNEhIKCnByb2R1Y3RfaWQYCCABKA0SHwoXaGFyZHdhcmVfdmVyc2lvbl9zdHJpbmcYCSABKAkSHwoXc29mdHdhcmVfdmVyc2lvbl9zdHJpbmcYCiABKAkSOgoMY29ubmVjdG9yX2lkGAsgASgLMiQua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuQ29ubmVjdG9ySWQSMgoIc3BhY2VfaWQYDCABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEj0KCW93bmVyc2hpcBgNIAEoDjIqLmt1c2ludGEuaW90LmNvbW1vbi52MS5EZXZpY2VPd25lcnNoaXBUeXBlEj4KCWxpZmVjeWNsZRgOIAEoDjIrLmt1c2ludGEuaW90LmNvbW1vbi52MS5EZXZpY2VMaWZlY3ljbGVTdGF0ZRI2Cg1vd25lcl91c2VyX2lkGA8gASgLMh8ua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuVXNlcklkEi4KCmNsYWltZWRfYXQYECABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjoKCmJyaWRnZWRfYnkYEyABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZEgBiAEBEj4KEWxpbmtfY2FwYWJpbGl0aWVzGBQgAygLMiMua3VzaW50YS5pb3QubGluay52MS5MaW5rQ2FwYWJpbGl0eRJNCglob21lbWF0aWMYEiABKAsyOC5rdXNpbnRhLmlvdC52ZW5kb3IuaG9tZW1hdGljLnYxLkhvbWVtYXRpY0RldmljZUlkZW50aXR5SABCEQoPdmVuZG9yX2lkZW50aXR5Qg0KC19icmlkZ2VkX2J5SgQIAhADSgQIERASUhVtYXR0ZXJfZGV2aWNlX3R5cGVfaWRSCWVuZHBvaW50c0ICSAFiBnByb3RvMw", [file_google_protobuf_timestamp, file_kusinta_iot_common_v1_types, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_link_v1_link, file_kusinta_iot_vendor_homematic_v1_homematic]);
16
17
 
17
18
  /**
18
19
  * Describes the message kusinta.iot.device.v1.DeviceDescriptor.
@@ -253,8 +253,11 @@ export declare type Device = Message<"kusinta.iot.device.v1.Device"> & {
253
253
  endpoints: Endpoint[];
254
254
 
255
255
  /**
256
- * When the gateway last had evidence this device exists and is reachable — the
257
- * most recent PropertyUpdate, announcement, or command result concerning it.
256
+ * When the gateway last had evidence this device itself — the
257
+ * most recent PropertyUpdate (wheter or not the property changed) or command
258
+ * result concerning it. Should not be advanced on a device announcement: a
259
+ * connector typically re-announces from its own device list, so a device with a
260
+ * flat battery would otherwise keep looking freshly seen.
258
261
  * Gateway-observed, not connector-reported: no message on either leg carries a
259
262
  * per-device liveness timestamp, so this is as precise as the device's own report
260
263
  * interval. A device that reports every 15 minutes looks stale for 15 minutes.